4 Nisan 2013 Perşembe

SSH Tunneling ve SSH Proxy

Artık Telnet protokolünün neredeyse tümüyle yerini alan SSH yani Secure Shell uzaktaki bir bilgisayarda bir UNIX kabuğu açıp sizin sanki o bilgisayardaymış gibi çalışmanıza olanak verir. Ben yazıyı okuyan kesimin SSH'yı az çok bildiğini varsayıp az bilinen yönlerinden bahsedeceğim. Bunlar başlıkta da yazdığım gibi tünelleme ve proxy özellikleri. Bunu yaparken sunucum yani sshd'nin çalıştığı makina Linux, istemci makinam Windows ve kullandığım istemci yazılımı PuTTY olacak.

Tünelleme Nedir?
Tünelleme bir firewall arkasındaki makinanın, firewall'da kapatılmış bir servisle iletişim kurmak istediğinde, firewall'daki açık portları kullanması ve bunu yaparken de giden gelen paketleri o hizmete aitmiş gibi göstermesi olarak anlatılabilir. ICQ zamanlarında bunu oldukça sık yapıyorduk. ICQ, yanlış hatırlamıyorsam TCP 5190 portunu kullanırdı. O zaman işyerlerinde bu port kapatıldığından ICQ ayarlarında HTTP Tunnelling seçeneğini seçince gidip gelen paketler TCP 80 portu aracılığıyla gidip gelir; firewall bu ağ trafiğini HTTP zannettiğinden izin verirdi. ICQ'da tünelleme kullanınca dosya gönderilemezdi. 

Tünellemede yapılan, ICQ'nun ürettiği veriler paketlenip (encapsulation) OSI 4. katmanda datagramlar haline getirildikten sonra (ayrıntılı bilgi için Eylül 2012'deki OSI TCP/IP yazısı) datagramlar veri olarak ele alınıp bir de HTTP olarak tekrar paketlenir, başlığa TCP 80 portu yazılır sonrasında, hedef IP olarak ICQ sunucusunun IP'si eklenip paketler internet ortamına salınırdı. Aslında denilebilir ki tünelleme veri olarak başka katmana ait veri yapılarını (datagram, paket, frame) veri olarak içeren paketlerin olduğu iletişimlere denir. ADSL'den internete bağlanırken seçilen PPPoE ayarının açılımı PPP over Ethernet anlamına gelir. PPP ve Ethernet her ikisi de bir ikinci katman protokolüdür. Günümüz altyapısı Ethernet olsa da PPP (Point to Point Protocol) doğrulama ve iletişim kalitesi açısından yada Ethernet'in kısıtlamalarından dolayı tercih edilebilir. Dolayısıyla Ethernet altyapısında PPP çerçeveleri taşımak için PPP'yi Ethernet çerçevelerinde paketlersiniz. 

Peki Proxy (Vekil Sunucu) Nedir?
Tam anlamıyla olmasa da bence her proxy bir tünellemedir denilebilir. Siz vekil sunucuya yine birden çok kere paketlemeden geçmiş verileri yollarsınız. Vekil sunucu bu paketleri açar, kendisine göre düzenler. Paketleri kendi üzerinden çıkıyormuş gibi IP başlığını değiştirir yada düzenler ve sizin asıl iletişim kurmak istediğiniz sunucuya gönderir. Sunucudan gelen cevabı yine kendisi alıp ve size iletir. Böylelikle siz bir firewall arkasındaysanız firewall'u "Hayır abi ben kesinlikle ICQ sunucusuyla haberleşmiyorum, Hindistan'daki bir sunucuyla haberleşiyorum." diyerek kandırabilir sizin yerinize Hindistan'daki sunucuyu ICQ sunucusuyla haberleştirebilir aynı zamanda da ICQ sunucusunu siz Hindistan'dan bağlanıyormuş gibi kekleyebilirsiniz.

Bunların yanısıra vekil sunucularda eğer aktifleştirilmişse sizin bağlandığınız sayfaları saklar ve gerektiğinde oraya bağlanmaksızın size daha hızlıca sakladığı kopyayı getirebilir. 

Gelelim bunların SSH ile nasıl yapılacağına. Öncelikle SSH neden Telnet'in yerini aldı? Çünkü SSH gidip gelen şifreleri ve kabuk komutlarını şifreleyerek gönderiyor ve sonuçları şifreleyerek iletiyor. Dolayısıyla siz bir tünelleme yada vekil sunucu olarak SSH kullanacaksanız bu durumun bir güzelliği de SSH sunucuyla bilgisayar arasındaki veriler de şifrelenerek gönderiliyor ve alınıyor. Diyelim ki bir internet kafedesiniz ve bir banka işlemi yapacaksınız. SSH makinanıza bağlanıp onu vekil sunucu olarak kullanarak işlemlerin internet kafenin switch ve yönlendiricisinden (router) şifrelenmiş olarak çıkmasını ve sizin sshd çalıştıran makinanıza kadar güvenli bir bağlantıyla (secure connection) iletilmesini sağlayabilirsiniz. 

İlk olarak PuTTY'i açıp bağlantı ayarlarını yapmak gerekli. Bize lazım olacak kısım Session ve Tunnels kısmı. Bağlanmaya çalışmadan önce sunucuya bağlanıp sshd'nin ayarlarını değiştirmek gerekli. Tunnels alanında birşey yapmadan önce Session alanında sshd'yi çalıştıran sunucunun adresinin veya IP'sinin girilmesi gerekiyor. IP'yi girip Open'a tıkladıktan sonra uzaktaki Linux bilgisayarda kullanıcı adı ve şifreyi soracak. Oradaki hesap bilgilerini girdikten sonra kabuk açılacak. Burada sshd'yi TCP paketlerini iletecek biçimde düzenlemek gerekiyor. O ayarlar da bende /etc/ssh/sshd_config dosyasında bulunuyor. (Dağıtıma göre farklılık gösterebilir.) Elbette üzerinde düzenlemeleri yalnızca root yapabilir. root ile dosyayı açıp, içerisinde AllowTcpForwarding değeri yoksa dosyaya ekleyip karşısına yes yazmak gerekiyor. Kurulumda normalde bu değer kapalıdır (comment out) ve varsayılan değeri de no'dur. Bu arada bu özellik bildiğim kadarıyla SSH'nin ikinci sürümünce destekleniyor. sshd kurulumunda yeni sürümler eğer istemci destekliyorsa v2 yoksa v1'den bağlanır. (Ayarlarda sadece v2 yada sadece v1 seçilebilir.). PuTTY de varsa v2 ile bağlanmayı tercih eder. Düşük bir olasılık ama bağlantı sorunu varsa bağlantı protokolünün sürümüne bir bakmakta yarar var.

no yerine yes olacak

Dosyayı kaydedip çıktıktan sonra Red Hat dağıtımlarında 'service sshd restart' yada '/etc/init.d/sshd restart' komutuyla daemon'u yeniden başlatınca artık Tcp paketleri iletilmeye hazır olacak. Bağlantıyı kapatmadan sol üst köşedeki PuTTY simgesinden Change Settings altında Tunnels'a ulaşılabilir ancak bağlantıyı kapatıp yeniden açmadan paketler gelmeyecektir.

Yukarıda banka örneğini vermiştim o nedenle buna benzer bir örnek vereyim. Session kısmında 'Hostname (or IP address)' yazan yere tekrar ssh sunucumun adını yazdım. Tunnels'a geldikten sonra Source Port kısmında çalıştığım (Windows) bilgisayarda açık olmayan bir port yazacağım. Örneğin httpd çalıştırıyorsam 80 yazamam. Açık olmayan herhangi bir port olabilir. Örneğin kaynak port 4567 ve erişmek istediğim sayfa www.google.com olacak. Destination bölümüne www.google.com:80 yazıp Add düğmesine tıklayınca 'Forwarded Ports' bölümüne L4567 ile başlayan bir kural eklendi. Open düğmesine basıp tekrar bağlandıktan sonra kabuk penceresi bir kenarda kalacak, tarayıcıyı açıp 127.0.0.1:4567 yazdığımda artık www.google.com'u görüyorum. 


Burada www.google.com'un DNS çözümlemesini yapan yine karşıdaki (sshd çalıştıran) makina. Eğer istersem DNS çözümlemesini kendi makinamda yapıp PuTTY'de 'Destination' kısmına IP de girebilirim. Windows'un komut satırı DNS çözümleme aracı nslookup'la aşağıdaki komutlarla yapılabilir:



Server komutu kullanılan DNS sunucunu yerine sorgulamayı başka bir sunucuda yapmak için gerekiyor, eğer varolan sunucu kullanılacaksa gerek yok. TTnet DNS'lerinden www.google.com'un IP'sini doğrudan sayfanın adını yazarak buluyorum. Google'ın birden fazla sunucusu olduğundan bana birden fazla IP cevabı geliyor. Bu IP'lerin herhangi birini Destination kısmına girerek aynı yönlendirme yapılabilir. Banka gibi https kullanan bağlantılarda http portu yerine https portunun açılması gerekmektedir.

Karşılaşılabilecek bir sorun da sshd'nin boşta kalan bağlantıları kapatması. Bunu engellemek için PuTTY'nin ayarlarında (en başta açarken yada çalışma esnasında sol üst köşedeki simgeden) 'Connection' bölümüne gelip belli zaman aralıklarında Keepalive paketleri göndertirseniz sorun düzelecektir.

Bu şekilde tünellemeyle bir LAN içerisinde kendinize ait makinanız varsa LAN dışına kapalı makinalarda lokaldeymiş gibi çalışmak da olanaklı. Yalnız bir konu var. Büyük httpd'lerde aynı sunucuda birden fazla sayfa olabilir. DNS kayıtlarından kontrol edilirse en.wikipedia.org, www.wikipedia.org ve tr.wikipedia.org aynı IP'lere sahip. Böyle bir durumda sunucu yazılımı muhtemelen HTTP başlığında hangi domain'in istendiğini tutan bir alana bakıyor (ben böyle tahmin ediyorum). Dolayısıyla bazı sayfalarda bu özellik varsa http://IP_Adresi yazarak giremiyorsunuz. Wikipedia'da böyle bir site. Bu sitelere tünellemeyle girmek istediğiniz zaman da sorun çıkabiliyor.

Bu sorunu çözümü, yazının da diğer kısmını oluşturan SSH'yı vekil sunucu olarak kullanmaktan geçiyor. Bunun için sunucu tarafında yapılması gereken ayarlar tünellemeyle aynı: AllowTcpForwarding yes olmalı ve SSHv2 ile bağlantı sağlanmalı. PuTTY'i açıp Hostname'e bağlanılacak sunucunun adresi yazılır. SSH altındaki 'Tunnels''da kaynak port için bir değer girilir ancak tünellemeden farklı olarak bu sefer aşağıda Local seçeneği yerine Dynamic seçeneği işaretlenir. Destination bölümüne herhangi bir şey yazılmaz. Add düğmesine basarak yeni bir kural eklenir. Open diyip bağlantı kurulduktan sonra yine terminal penceresiyle başka işimiz olmaz. 

SSH Proxy için bağlantı ayarı

Sıra geldi Windows makinadaki tarayıcıyı vekil sunucu kullanarak internete bağlanacak biçimde ayarlamaya. Firefox v19.x serisinde bu ayar Tools -> Options -> Advanced -> Settings altında bulunuyor. Sonuçta herkes kendi tarayıcısında vekil sunucu ayarlamayı biliyordur. Ayarlarda SOCKS sunucu 127.0.0.1, portu PuTTY ile girdiğiniz port ve SOCKSv5 seçili olacak. Bu ayarları yapıp OK düğmesine tıkladıktan sonra artık tarayıcı SSH tarafından oluşturulan güvenli kanaldan vekil sunucu aracılığıyla istenen herhangi bir sayfayı açabilir. Ancak sayfaya paketleri gönderen ve alan hala UNIX makinadır. http://www.whatismyip.com/ dan bakınca Windows makinanın değil UNIX makinanın IP'si görülebilir.


Hiç yorum yok:

Yorum Gönder