Tek Port Üzerinden HTTPS, SSH, OpenVPN Servislerinin Hizmet Vermesi

sunucu disk

Elinizde kullanılabilir tek bir ip adresi var ve bu ip adresi üzerinde aynı portu kullanan birden fazla uygulama kullanmak istiyorsanız tek portta protokol başlık bilgisine göre paketleri ayırt edebilen bir yazılım kullanmak sorunu çözecektir. SSLH bu amaçla geliştirilmiş bir yazılımdır.  SSLH belittiğiniz bir portu dinler  ve bu porta gelen bağlantı isteklerini inceleyerek isteğin hangi protokole ait olduğunu tespit ettikten sonra bağlantıyı ilgili servise yönlendirme işlemini gerçekleştirir.

Bu şekilde örneğin tcp 443 üzerinden HTTPS, OpenVPN ve SSH himetlerini aynı anda sunabilirsiniz. Bu yazı özellikle bazı durumlar için gayet kullanışlı bir araç olan sslh ile ilgili kurulum, yapılandırma ve testleri içerecek şekilde detaylı bilgi içermektedir.

SSLH Nedir?

Default olarak HTTP, SSL, SSH, OpenVPN, tinc, XMP protokollerini tespit edebilen ve farklı protokoller için de kendi regex patternlerinizi yazmanıza da izin veren sslhın yukarıda belirtildiği  gibi tcp 443 üzerinde hem HTTPS hem de SSH servisi vermek gibi yaygın bir kullanım şekli var. Bu şekilde örneğin firewall üzerinden sadece tcp 80 ve 443 geçişi olan bir sunucuya SSH üzerinden erişmek üzere sslh kullanılabilir. Bir başka deyişle firewall arkasında bulunan ve SSH portuna erişim olmayan bir sisteme, 443 gibi (muhtemelen) firewall tarafından engelli olmayan bir port üzerinden erişmek için sslh kullanabilirsiniz.

Çalışma Prensibi

Verdiğimiz örneğe bağlı kalarak sslhı 443 üzerinden çalıştıracağımızı ve HTTPS ile SSH hizmeti vereceğimizi düşünelim. Bu senaryoda, -detaylarını yapılandırma kısmında anlatacağım üzere – sslhı kullanmak istediğimiz ağ arayüzününün  443. portunu dinleyecek şekilde yapılandırıyoruz. Sonrasında HTTPS servisini localhost:443 ve SSH servisini localhost:22′yi dinlemeleri üzere ayarlayıp, sslha HTTPS’in 127.0.0.1 443′de, SSH’ın da 127.0.0.1 22′de olduğunu söyleyerek uygulamayı çalıştırıyoruz.

Bu şekilde ilgili hosta gelen SSH bağlantıları 22. porta yönlendirilirken HTTPS bağlantıları localhost 443. porta yönlendiriliyor. Yani sslh proxy görevi görevi görüyor. Uygulamanın servisleri nasıl ayırt ettiği konusu ise şu şekilde cereyan ediyor:

Protokol Tespiti

sslh temel olarak gelen bağlantı isteklerinin ilk bir kaç byteını okuyarak bağlantı protokolünü tespit etmeye çalışıyor. Örnek olarak SSH bağlantılarında sunucu ile client arasında gerçekleşen ilk iş iki ucun birbirine ssh versiyonlarını plain-text olarak ‘SSH-x.0′ şeklinde bildirmelerinden ibarettir. İşte sslh da bağlantının SSH olup olmadığını anlamak için ilk paketlerin içerisinde “SSH-” stringini arıyor ve bulması durumunda bağlantıyı ilgili servisin portuna yönlendiriyor. HTTPS trafiği için ise benzer bir şeklilde trafik başlangıcında ClientHello (0×16) ve TLS versiyon bilgisinin (0×0301) olup olmadığına bakıyor.

Diğer protokoller için örneğin XMPP testinde “jabber” ibaresi, HTTP trafiği için “HTTP” ibaresi ya da versiyon belirtilmemişse OPTIONS, GET vs. gibi methodların olup olmadığına bakarak yönlendirmeyi yapıyor.

sslh trafik tespiti için öntanımlı 2 saniye timeout süresi kullanır bu süre zarfında protokol tespit edilemezse trafik, yapılandırma dosyasında belirlenen ilk protokole (default kurulumda SSH’a ) yönlendirilir. Örnek olarak  versiyon bilgisini sunucuya bildirmeyen bir client üzerinden gelen SSH bağlantısı sslh tarafından tespit edilemeyeceği için bu timeout mekanizması önemlidir.

Kurulum ve Yapılandırma

sslh’ın RHEL, Debian ve FreeBSD tabanlı sistemler için önceden derlenmiş paketleri bulunuyor ve ilgili sistemlerin paket yöneticileri üzerinden kurulabiliyor. Ancak kaynak koddan derleyerek kurmak da çok kolay olduğu için burada bu şekilde kurulumun nasıl yapılabileceğinden bahsedeceğim.

Gereksinimler

sslh, libconfig ve libwrap paketlerine ihtiyaç duyuyor; bu nedenle öncesinde bu paketleri sisteminize kurmanız gerekiyor. Bu işlem için aşağıdaki adımları izleyin:

Debian/Ubuntu tabanlı sistemler:

# apt-get install libwrap0-dev libconfig8-dev

RHEL/CentOS tabanlı sistemler:

# yum install libconfig libconfig-devel

Böylece sistem sslh kurulumu için hazır hale geliyor.

Kaynak Kod’dan Kurulum

Şimdi, http://www.rutschle.net/tech/sslh.shtml adresinden sslhı indireceğiz.

# wget 

Sonrasında da paketi açarak kurulumu gerçekleştiriyoruz:

# tar xvfz sslh-v1.16.tar.gz
# cd sslh-v1.16
# make install

Make install dediğiniz zaman ilgili dizinde sslh-fork ve sslh-select isimli iki farklı sslh versiyonu oluşturulur.

İlk versiyon olan sslh-fork her yeni bir bağlantı isteği yeni bir sslh süreci oluşturur. Bu versiyon iyi test edildiğinden ve stabil olduğundan dolayı kurulum sırasında /usr/local/sbin/sslh ismi ile sisteme kopyalanır ve default olarak kullanılır. Ancak bu sürüm, çok fazla istek alan sunucular için çok sayıda süreç oluşmasına ve sistem kaynaklarının bu oranda kullanılmasına yol açmaktadır. Çok çok fazla sayıda bağlantı karşılamak için bu anlamda ideal olmayabilir.

İkinci versiyon olan sslh-select ise daha az test edilmiş ve yeni bir sslh versiyonudur ancak  tüm bağlantları tek bir süreç üzerinden handle eder ve her bir bağlantının sadece 16byte’lık bir sistem kaynağı maliyeti vardır. Fakat, sslh bir şekilde kapanırsa ve ssh için kullanıyorsanuz sunucuya uzaktan erişiminiz kesilebilir. Yine de bu sürümü kullanmak isterseniz kendisini /usr/local/sbin/ dizinine sslh ismi ile kopyalayabilirsiniz.

Yapılandırma

Şimdi ilk olarak scripts dizinindeki init scriptini sslh ismi ile init.d’nin altına kopyalayıp, sslh servisini startup’a ekleyeceğiz:

Debian/Ubuntu Sistemler:

# cp scripts/etc.init.d.sslh /etc/init.d/sslh
# update-rc.d sslh defaults

RHEL/CentOS Sistemler:

# cp scripts/etc.init.d.sslh /etc/init.d/sslh
# chkconfig sslh on

RHEL sistemlerde ayrıca, /etc/init.d/sslh dosyası içerisindeki “PREFIX=” satırını aşağıdaki şekilde güncelliyoruz:

PREFIX=/usr/local

Ana Yapılandırma

Şimdi ana yapılandırma ayarlarına geçeceğiz. Sslh’ın ana yapılandırma dosyası /etc/default/sslh’dır. Bu dosya Debian ve RHEL sistemlerde mantık aynı olsa da farklılık göstermektedir. Bu yüzden ikisinden ayrı ayrı bahsedeceğim.

Debian/Ubuntu Sistemler:

İlgili dosyanın içeriği aşağıdaki gibibir ve düzenlenmesi gereken alanlar bold ve kırmızı renk ile işaretlenmiştir:

# Default options for sslh initscript
# sourced by /etc/init.d/sslh
# Disabled by default, to force yourself
# to read the configuration:
# - /usr/share/doc/sslh/README.Debian (quick start)
# - /usr/share/doc/sslh/README, at "Configuration" section
# - sslh(8) via "man sslh" for more configuration details.
# Once configuration ready, you *must* set RUN to yes here
# and try to start sslh (standalone mode only)

RUN=no
# binary to use: forked (sslh) or single-thread (sslh-select) version
DAEMON=/usr/sbin/sslh
DAEMON_OPTS="--user sslh --listen 0.0.0.0:443 --ssh 127.0.0.1:22 --ssl 127.0.0.1:443 --pidfile /var/run/sslh/sslh.pid"

İlk olarak RUN bölümünü “yes” olarak düzenliyoruz.

RUN=yes

–listen 0.0.0.0:443 bölümü SSLH’ın hangi portu hangi ip üzerinden dinleyeceğinin belirleneceği yerdir. Biz burada sslhi sistemimizin gerçek ipsine bind edeceğiz, örnek olarak ip adresiniz 1.1.1.1 ise bu alanı 1.1.1.1:443 olarak set ediyoruz:

Not: Bu noktada web sunucunuzu 443. port için sadece 127.0.0.1 üzerinden hizmet vermesi için yapılandırmayı unutmamanız gerekiyor. Aksi halde 443. port sslh tarafından kullanımda olduğu için web sunucunuz hata verecekir.

–ssh 127.0.0.1:22 ise 443 üzerinden gelen ssh isteklerinin 127.0.0.1:22′ye yönlendirilmesini söylüyor.

–ssl 127.0.0.1:443 ise aynı mantıkla SSL/TLS bağlantılarının 127.0.0.1:443′e atılmasını ifade ediyor.

Değişiklikleri tamamladıktan sonra, sslh’ı start ediyoruz:

# /etc/init.d/sslh start

RHEL/CentOS Sistemler

RHEL tabanlı sistemlerde ise mantık aynı olmakla birlikte yapılandırma dosyası aşağıdaki gibidir:

LISTEN=ifname:443
SSH=localhost:22
SSL=localhost:443
USER=nobody
PID=/var/run/sslh.pid

Bu dosya içerisinde en üstte, SSLH’ın hangi ip ve port üzerinden hizmet vereceğini belirtiyoruz ki yukarıda da bahsettiğim gibi bu alanı sistemimizin external ip’si olarak set ediyoruz. Örnek olarak ip adresiniz 1.1.1.1 ise bu alanı 1.1.1.1:443 olarak set ediyoruz:

LISTEN=1.1.1.1:443

Not: Bu noktada web sunucunuzu 443. port için sadece 127.0.0.1 üzerinden hizmet vermesi için yapılandırmayı unutmamanız gerekiyor. Aksi halde 443. port sslh tarafından kullanımda olduğu için web sunucunuz hata verecekir.

Sonrasında da debian sistemler kısmında detaylarına değinildiği şekilde ssh ve ssl servislerinin localhost 22 ve 443 üzerinden verilmesi için ilgili kısımları olduğu şekilde bırakıyoruz.

Son olarak servisi start edelim:

# /etc/init.d/sslh start

Evet, kurulum ve yapılandırma kısmı bu şekilde tamamlanıyor. Şimdi sistemi test edelim?

Test

Şu anda servis çalışıyor ve netstat ile baktığımız zaman aşağıdaki gibi bir çıktı alıyoruz:

# netstat -antp |grep LISTEN
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      1522/sshd
tcp        0      0 127.0.0.1:443               0.0.0.0:*                   LISTEN      1794/httpd
tcp        0      0 1.1.1.1:443                 0.0.0.0:*                   LISTEN      1780/sslh

Görüldüğü gibi 1.1.1.1:443′i sslh dinlerken, 127.0.0.1:443′ü olması gerektiği gibi httpd dinliyor ve ssh da 0.0.0.0:22 üzerinden hizmet veriyor.

Şimdi dışarıdan 1.1.1.1′e ssh bağlantısı kurarsanız isteği sslh karşılayacak ve ssh servisine iletecektir.

Tüm detaylar için https://github.com/yrutschle/sslh adresine göz atabilirsiniz.

Cihat IŞIK

1 Yorum

  1. Şükrü Aydın 22 Eylül 2015 13:16

    o zaman 443 portu üzerinden sızma işlemi gerçekleştirebiliriz gerekli olan exploitle

Yorum Yaz

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*
*

Mail listemize üye olarak eğitim fırsatlarını kaçırmayın!
Eğitim ve ücretsiz etkinliklerizden haberdar olmak için e-posta listesimize üye olun!.