3 Ağustos 2010 Salı

İlk SSH Oturumu Açılışında Fingerprint Kontrolü

SSH, ağ üzerindeki iki bilgisayarın güvenli bir şekilde iletişim kurmasını sağlayan bir iletişim protokolüdür. Aşağıdaki bilgi güvenliğine yönelik hususlar, SSH protokolü tarafından ele alınmaktadır:
  • Oturum açılması esnasında
    • İki tarafın da birbirinin kimliğinden emin olması (birbirlerinin açık anahtarları vasıtasıyla).
    • Oturum açılışında şifre kullanılıyorsa, şifrenin üçüncü taraflar tarafından edinilmesinin önlenmesi.
  • Oturum açıldıktan sonra
    • Transfer edilen verinin üçüncü taraflar tarafından edinilmesinin önlenmesi.
SSH protokolünün sağladığı bu güvenliği boşa çıkarabilecek bir husus, karşı tarafa ilk oturum açma esnasında gerekli güvenlik kontrollerinin yapılmasının ihmal edilmesidir. Bu durum DNS yönlendirmesi veya IP spoofing saldırısı yapılması durumunda bağlanmak istediğimiz sunucu yerine başka bir sunucuya yönlenmemize ve oturum açma bilgilerimizi (kullanıcı adı ve şifre) saldırgan makinaya vermemize yol açabilir.
İlk kez bir SSH oturumu açmaya kalktığımızda SSH istemcimiz bize şu uyarıyı yapar:
user1@host1.x.y:~$ ssh host2.x.y
The authenticity of host 'host2.x.y (10.0.0.1)' can't be established.
RSA key fingerprint is 12:45:1a:b3:81:0d:23:93:35:6a:21:91:ca:24:0b:20.
Are you sure you want to continue connecting (yes/no)?
Burada host1.x.y makinasındaki user1 kullanıcısı host2.x.y makinasına dogru ilk kez bir SSH oturumu açmak istemektedir. Oturum açma isteği aldığında SSH sunucusu, istemci tarafa kendi açık anahtarını ve yine bu açık anahtarın özetinin (fingerprint) kendi gizli anahtarı ile şifrelenmiş halini gönderir. İstemci bu şifrelenmiş özeti sunucunun açık anahtarını kullanarak açar. İstemcinin kendisi de sunucunun açık anahtarını aynı özet alma metoduna (hash algorithm) sokarak özet (fingerprint) üretir. Bu özet ile kendisine ağ üzerinden şifreli olarak gelen özeti karşılaştırır ve eşit olduğu taktirde, bu açık anahtarın karşı tarafa ait olduğundan ve karşı tarafın bu açık anahtara karşılık gelen bir gizli anahtara sahip olduğundan emin olur. Ancak emin olamadığı bir şey vardır: bu açık anahtar gerçekten bağlanmak istediği sunucuya mı ait?
Bu noktada bağlanmaya çalıştığımız kanalın dışında bir kanaldan doğrulama yapmamız gerekmektedir. host2.x.y makinasının konsolundan "root" olarak oturum açarak şu komutu çalıştıralım:
root@host2.x.y:~$ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub
2048 12:45:1a:b3:81:0d:23:93:35:6a:21:91:ca:24:0b:20 /etc/ssh/ssh_host_rsa_key.pub (RSA)
Burada gördüğümüz özet (fingerprint) değeri SSH istemcisinin bize sorduğu ile aynı ise, gelen açık anahtarın bağlanmak istediğimiz sunucudan geldiğinden emin olabiliriz. SSH oturumu açarken sorulan soruya "yes" diyerek devam edilirse bu açık anahtar ssh tarafından kaydedilir ve sonraki oturum açma isteklerimizde artık bu soru sorulmaz.

1 Ağustos 2010 Pazar

Dinamik DNS Desteği Sunmayan Ağ Erişim Cihazları İçin SNMP Kullanımı ve Dinamik DNS Güncellemesi

Evinde veya ofisinde modem, router gibi cihazlar ile Internet erişimi sağlayan kullanıcılar, ev veya ofis dışından da bu cihazların arkasındaki bilgisayar ve diğer kaynaklara erişmek isteyebilirler. Bu durumda aşılması gereken ilk konu bu cihazlara konumlanabilmek, bir başka deyişle bu cihazların IP adreslerini öğrenmektir. Servis sağlayıcınız erişim cihazınıza statik IP atamış olabilir. Bu durumda zaten belirlenmiş olan bu IP adresini kullanarak ev veya ofis dışından erişim cihazınıza (ve arkasındaki bilgi kaynaklarınıza) bağlanabilirsiniz. Ancak statik IP kullanmıyorsanız, söz konusu IP adresi cihazınızın kapanıp açılması esnasında veya servis sağlayıcı tarafından bir şekilde kontrolünüz dışında değişebilir. Bu durumda cihazın başında olmaksızın güncel IP adresini öğrenmek için bir yol dinamik DNS servislerini kullanmaktır.
Dinamik DNS servisi kullanımında mekanizma, cihazınızın, sizin belirleyeceğiniz bir ağ arayüzündeki IP adresi değişikliklerini algılayarak otomatik olarak Dinamik DNS servisi aldığınız yerin sunucularında almış olduğunuz bir alan adına (domain name), yeni IP adresini bağlamaktan ibarettir.
Günümüz ağ erişim cihazları, özellikle ADSL modemler, dinamik DNS servislerine erişip DNS güncellemesi yapabilme yeteneğine sahiptirler. Ancak bu tür bir yeteneği olmayan cihazlarla aynı işi yapabilmenin bir yolu SNMP kullanmaktır.
SNMP (Simple Network Management Protocol), ağ üzerindeki her tür cihazdan veri toplama ve bu cihazları uzaktan yönetme amacıyla kullanılabilen bir iletişim protokolüdür. Cihazınız dinamik DNS desteği vermese de büyük ihtimalle SNMP desteği veriyor olmalıdır. Burada anlatacağımız yöntemde SNMP, ağ erişim cihazınızın güncel IP adresinin bu cihazın arkasında duran daha akıllı bir cihaz tarafından öğrenilmesi amacıyla kullanılacaktır.
Şu an elimizde şu tür bir konfigürasyon olduğunu varsayalım:
  • Bir adet ADSL modem. Bu modemde aşağıdaki gibi iki temel ağ arabirimini mevcut:
    • İç ağa bakacak şekilde bir adet ethernet arabirimi. (Örnek, eth0 ve IP'si 192.168.0.1)
    • Dış ağa bakacak şekilde bir adet ppp arabirimi.
  • İç ağda bir adet 7x24 çalışan bir sunucu. Örneğimizde bir Debian Linux sunucusu kullanıldı. Bu sunucunun erişim cihazına bağlı şekilde bir adet ethernet arabirimi mevcut.
Bu durumda aşağıdaki adımları uygulayarak, kendi özel dinamik DNS çözümümüze ulaşabiliriz:

ADSL Modemde SNMP Ajanının Aktive Edilmesi

  • SNMP v1 ve v2, erişimde doğrulama (authentication) amaçlı olarak Community tanımlamasını kullanmaktadır. Bu tanımlama erişim şifresi olarak düşünülebilir. Ancak bu tanımlama metni ağ üzerinden açık şekilde cihaza gidecektir. Dolayısıyla dinleyiciler (sniffer) tarafından kolayca elde edilebilir. Bu nedenle söz konusu SNMP versiyonları için sunucunun ADLS modeme kablolu ethernet üzerinden fiziksel olarak bağlı olması tercih edilmelidir.
  • İkinci olarak söz konusu Community tanımını en azından "public"  dışında sadece kendinizin bileceği bir değer atayarak yapmanız iyi olur. Örneğimizde "home" olarak belirlendi.
  • Son olarak bu Community üzerinden bağlantıları salt okunur (read-only) erişim yetkisi ile sınırlamak iyi olacaktır.

 Sunucuya SNMP kurulumu ve SNMP testleri

  • Aslında bu adım test amaçlı olarak kullanılacaktır:
    apt-get install snmp 
  • SNMP araçları sunucuya kurulduktan sonra aşağıdaki SNMP sorgusu ile ADSL modemden arabirim IP adreslerinin alınıp alınmadığı test edilir:
    snmpwalk -Oa -t 5 -c home -v 2c 192.168.0.1 ipAddrEntry.ipAdEntAddr
  • Bu sorgu sonucu aşağıdakine benzer bir rapor alınması muhtemeldir:
    IP-MIB::ipAdEntAddr.127.0.0.1 = IpAddress: 127.0.0.1
    IP-MIB::ipAdEntAddr.a.b.c.d = IpAddress: a.b.c.d
    IP-MIB::ipAdEntAddr.192.168.0.1 = IpAddress: 192.168.0.1
    ...

SNMP Üzerinden Güncel Ağ Adresinin Öğrenilmesi

  • Bu aşamada yazacağımız perl programcığı SNMP kütüphanesi kullanacaktır. Bu amaçla debian paket yöneticisi üzerinden gerekli modüllerin kurulumu tercih edildi:
    apt-get install libsnmp-perl
  • SNMP üzerinden ADSL modemin ppp arabiriminin güncel IP adresini öğrenecek olan perl programı (snmp-ip-fetcher.pl) :
    #!/usr/bin/perl
    
    use Data::Dumper;
    use SNMP;
    
    $sess = new SNMP::Session(DestHost => "192.168.0.1", Community => "home", Version => "2c", Timeout => 5000000);
    
    $leaf_id = "ipAdEntAddr";
    $invalid_ip_filter = "^(192\.168|127)";
    
    my $ip = "";
    $vb = new SNMP::Varbind();
    $vb->[0] = $leaf_id;
    while ($vb->[0] eq $leaf_id && defined($val = $sess->getnext($vb))) {
      # print Dumper($vb->[0], $val, $leaf_id);
    
      if ($vb->[0] ne $leaf_id || $val =~ m/$invalid_ip_filter/) {
        next;
      }
    
      if ($val =~ m/^\d+\.\d+\.\d+\.\d+$/) {
        $ip = $val;
      }
    }
    
    print "$ip";
    
  •  Bu program çalıştırıldığında yukarıdaki test adımında elde edilen sonuçlardan yanlızca ppp arayüz IP adresini (yukarıda a.b.c.d ile ifade edilmişti) getirmelidir.

Dinamik DNS Güncellemesi

  • Bu adımda dinamik DNS güncellemesinde kullanmak üzere ez-ipupdate aracı tercih edildi:
    apt-get install ez-ipupdate
    
  • Söz konusu araç ile DNS güncellemesi yapılıp yapılamadığı test ediliyor. Örneğimizde dinamik DNS servisi DynDNS'ten alındı ve test amaçlı olarak Internet üzerinde geçersiz (IANA Special Use) bir IP (10.0.0.1) kullanıldı:
    /usr/sbin/ez-ipupdate -S dyndns -u kullanici:sifre -h foo.dyndns.org -a 10.0.0.1

    Dinamik DNS Güncellemesini Yapacak Zamanlanmış Görev

    • Zamanlanmış görev olarak çalıştırılacak shell script (updater.sh):
      #!/bin/sh
      
      ip_fetcher=./snmp-ip-fetcher.pl
      ez_ipupdater=/usr/sbin/ez-ipupdate
      current_ip_file=.current
      dyndns_service=dyndns
      dyndns_auth=kullanici:sifre
      dyndns_hostname=foo.dyndns.org
      
      if [ ! -f $current_ip_file ]; then
        touch $current_ip_file
      fi
      
      read current_ip < $current_ip_file
      new_ip=`$ip_fetcher`
      
      if [ -n $new_ip ]; then
        if [ "$current_ip" != "$new_ip" ]; then
          cmd="$ez_ipupdater -r 10 -S $dyndns_service -u $dyndns_auth -h $dyndns_hostname -a $new_ip"
          result=`$cmd`
          if [ "$result" == "request successful" ]; then
            echo $new_ip > $current_ip_file
            echo "IP adresi DNS'e kaydedildi. Yeni IP : $new_ip"
          else
            echo "IP adresi DNS'e kaydedilemedi. Yeni IP : $new_ip"
          fi
        else
          echo "IP adresi degismemis. IP : $current_ip"
        fi
      fi
      
    • updater.sh ve snmp-ip-fetcher.pl dosyalarının aynı dizinde (örneğin /crontab/dnsupdate dizininde) olmasına özen gösterelim.
    •  Aşağıdaki crontab satırı ile saatlik olarak ADSL modemin ppp ağ arabiriminin IP adresi alınarak dinamik DNS servisi sunucusuna güncelleme emri gönderilecektir:
      0 * * * *     (cd /crontab/dnsupdate && ./updater.sh)