SSH Port Forwarding

Forwarding, generic bir kelimedir. Datanın bir noktadan diğer noktaya taşınması/iletimi sürecine forwarding denilir. Örneğin:

  • Switch cihazı kendisine gelen paketin MAC adresine bakıp paketi hedefe iletir.
  • Router cihazı kendisine gelen paketin IP adresine bakıp paketi hedefe iletir/yönlendirir.
  • Uygulama kendisine gelen paketin port bilgisine bakıp paketi hedefe iletir/yönlendirir.

SSH protokolü uygulamaları tcp port forwarding yani tünelleme özelliğine sahiptir.

SSH ile 4 farklı şekilde tcp port forwarding gerçekleştirebilirsiniz.

  1. Local Port Forwarding
  2. Remote Port Forwarding
  3. Dynamic Port Forwarding
  4. Reverse Dynamic Port Forwarding

# Gereksinimler

  • Örneklerimizde SSH2 protokolü ile %100 uyumlu olan OpenSSH baz alınmıştır.  Openssh ın güncel sürümlerinden biri yüklü olması beklenmektedir.
    • Özellikle Reverse Dynamic Port Forwarding için Openssh 7.6 ve üzeri bir sürümünün yüklü olması beklenmektedir.
  • TCP Port Forwarding yapabilmek için SSH sunucusunda (sshd_config)  aşağıdaki seçeneğin aktif olması gerekir.
    • AllowTcpForwarding yes
  • Analiz bölümündeki bahsedilen örneklerimizde kullandığımız sistemler:
    • kali: 192.168.80.199
    • centos: 192.168.80.249

1. Local Port Forwarding

localportforwarding - SSH Port Forwarding

Localdeki bir porta (application client)  gelen istekler belirtilen host/port a ssh server (application server) üzerinden iletilir.

Örnek Kullanım Amaçları:

  • SSH sunucuyu jump server olarak kullanmak
  • SSH sunucuyu internete çıkış için kullanmak

Syntax:

> ssh -L [bind_address:]port:host:hostport ssh_server
  • -L : Local port forwarding i belirtir.
  • [bind_address:] : Opsiyoneldir. Belirtilmediği takdirde 127.0.0.1 bind edilir. Tüm interfacelerin bind edilmesi isteniyorsa * ifadesi kullanılabilir.
  • port: Localde bind olunacak local port.
  • host: Paketin iletileceği hedef host.
  • hostport: Paketin iletileceği hedef hostdaki port
  • ssh_server: ssh sunucu

Örnekler:

> ssh -L *:12345:gokhankesici.com:443 [email protected]
> ssh -L 12345:gokhankesici.com:443 [email protected]
> ssh -4L 12345:gokhankesici.com:443 [email protected]
> ssh -L 12345:localhost:2345 [email protected]
> ssh -L 192.168.80.199:12345:gokhankesici.com:443 [email protected]
  • İlk örnekte client tarafında tüm interface lerdeki listen durumdaki 12345 portuna gelen istekler gokhankesici.com:443 e 192.168.80.249 ile olan ssh bağlantısı üzerinden iletilir.
  • İkinci örnekte  client tarafında listen durumdaki localhost:12345 portuna gelen istekler gokhankesici.com:443 e 192.168.80.249 ile olan ssh bağlantısı üzerinden iletilir.
  • Üçüncü örnekte client tarafında listen durumdaki sadece ipv4 localhost:12345 portuna gelen istekler gokhankesici.com:443e 192.168.80.249 ile olan ssh bağlantısı üzerinden iletilir.
  • Dördüncü örnekte client tarafında listen durumdaki localhost:12345 portuna gelen istekler 192.168.80.249 ile olan ssh bağlantısı üzerinden ssh sunucusu üzerindeki localhosta iletilir.
  • Beşinci örnekte client tarafında listen durumdaki 192.168.80.199:12345 portuna gelen istekler gokhankesici.com:443e 192.168.80.249 ile olan ssh bağlantısı üzerinden iletilir.

Analiz:

Yukarıdaki ilk örneğimiz üzerinden detaylı bir analiz gerçekleştirelim:

Komut ilk çalıştırıldığında client 192.168.80.249  adresine bağlantı sağlanarak güvenli bir kanal oluşturulur.

Bağlantı sağladıktan sonra 12345 portu ssh client prosesi tarafından kendi hostunda dinleme modunda açılır.

localpf - SSH Port Forwarding

12345 portuna bir istek yapıldığında ssh prosesi kendisine gelen bu paketi alır ve encrypted bir şekilde ssh sunucuya iletir. SSH sunucuda paketi decrypt eder ve forwarding aktif olduğu için paketlerimizi hedef host ve portuna iletir. Dönen yanıtları da tam tersi şekilde döner.

lfcurl - SSH Port Forwarding

LocalForward Directive:

Client tarafında her bağlantıda -L parametresini belirtmeden local forwarding yapmak istiyorsanız LocalForward direktifi ile bunu gerçekleştirebilirsiniz.

İlk örneğimiz için aşağıdaki gibi bir direktif girebiliriz.

Host 192.168.80.249
LocalForward *:12345 gokhankesici.com:443

localforwarddirective - SSH Port Forwarding

LocalForward direktifi kullanıldığında tekrar ek bir bağlantı yapılması durumunda  adresin/portun kullanıldığına dair aşağıdaki gibi bir hata alınır. Bu sorunu yaşamamak  için bağlantı sırasında ClearAllForwardings opsiyonu kullanılır.

clearallforwardings - SSH Port Forwarding

Remote Connection

Listen durumdaki portun interfacesi localhost dışında bir interface ise dışarıdan bu interfacee gelecek istekler de forward edilir.

Yukarıdaki beşinci örneğimizde komutu çalıştırdığımızı düşünelim. Bu durumda dışarıdan gelecek bir istek forward edilir.

remoteconnectlocalport - SSH Port Forwarding

2. Remote Port Forwarding

remoteportforw - SSH Port Forwarding

Remote Port Forwarding, Local Port Forwarding ile benzer olmakla birlikte temel fark forward edilen trafik ters yöndedir.

Örnek Kullanım Amaçları:

  • SSH client kaynaklarına istenildiğinde erişebilmek.

Syntax:

> ssh -R [bind_address:]port:host:hostport ssh_server
  • -R : Remote port forwarding i belirtir.
  • [bind_address:] : Opsiyoneldir. Belirtilmediği takdirde 127.0.0.1 bind edilir. Tüm interfacelerin bind edilmesi isteniyorsa * ifadesi kullanılabilir.
  • port: Remoteda bind olunacak remote port.
  • host: Paketin iletileceği hedef host.
  • hostport: Paketin iletileceği hedef hostdaki port
  • ssh_server: ssh sunucu

Örnekler:

> ssh -R *:12345:gokhankesici.com:443 [email protected]
> ssh -R 12345:gokhankesici.com:443 [email protected]
> ssh -4R 12345:gokhankesici.com:443 [email protected]
> ssh -R 12345:localhost:2345 [email protected]
> ssh -R 192.168.80.249:12345:gokhankesici.com:443 [email protected]
  • İlk örnekte ssh sunucundaki tüm interface lerdeki listen durumdaki 12345 portuna gelen istekler gokhankesici.com:443 e 192.168.80.199 ile olan ssh bağlantısı üzerinden iletilir.
  • İkinci örnekte  ssh sunucusundaki listen durumdaki localhost:12345 portuna gelen istekler gokhankesici.com:443 e 192.168.80.199 ile olan ssh bağlantısı üzerinden iletilir.
  • Üçüncü örnekte ssh sunucusundaki listen durumdaki sadece ipv4 localhost:12345 portuna gelen istekler gokhankesici.com:443e 192.168.80.199 ile olan ssh bağlantısı üzerinden iletilir.
  • Dördüncü örnekte ssh sunucusunda listen durumdaki localhost:12345 portuna gelen istekler 192.168.80.199 ile olan ssh bağlantısı üzerinden ssh client üzerindeki localhosta iletilir.
  • Beşinci örnekte ssh sunucusunda listen durumdaki 192.168.80.249:12345 portuna gelen istekler gokhankesici.com:443e 192.168.80.199 ile olan ssh bağlantısı üzerinden iletilir.

Analiz:

Yukarıdaki ilk örneğimiz üzerinden detaylı bir analiz gerçekleştirelim:

Komut ilk çalıştırıldığında client 192.168.80.249  adresine bağlantı sağlanarak güvenli bir kanal oluşturulur.

Bağlantı sağladıktan sonra 12345 portu ssh sunucusunun sshd prosesi tarafından kendi hostunda dinleme modunda açılır.

remoteforwardrconnection - SSH Port Forwarding

SSH sunucu tarafında 12345 portuna bir istek yapıldığında sshd prosesi kendisine gelen bu paketi alır ve encrypted bir şekilde ssh clienta iletir. SSH sunucuda paketi decrypt eder ve forwarding aktif olduğu için paketlerimizi hedef host ve portuna iletir. Dönen yanıtları da tam tersi şekilde iletir.

remoteforwardanalysis - SSH Port Forwarding

RemoteForward Directive:

Client tarafında her bağlantıda -R parametresini belirtmeden remote forwarding yapmak istiyorsanız RemoteForward direktifi ile bunu gerçekleştirebilirsiniz.

Host 192.168.80.249 
RemoteForward *:12345 gokhankesici.com:443

remoteforwarddirective - SSH Port Forwarding

RemoteForward direktifi kullanıldığında tekrar ek bir bağlantı yapılması durumunda  adresin/portun kullanıldığına dair aşağıdaki gibi bir hata alınır. Bu sorunu yaşamamak  için bağlantı sırasında ClearAllForwardings opsiyonu kullanılır.

remoteclear - SSH Port Forwarding

GatewayPort Directive

Listen durumdaki portun interfacesi localhost dışında bir interface ise dışarıdan bu interfacee gelecek istekler varsayılanda kabul edilmez.

Dışarıdan gelen istekleri kabul etmek için GatewayPorts direktifi kullanılır.

Yukarıdaki beşinci örneğimizde komutu çalıştırdığımızı düşünelim.

Gateway direktifi girilmezse biz ne kadar 192.168.80.249 olarak belirtmiş olsakta 127.0.0.1 listen edilir.

noogateway - SSH Port Forwarding

sshd yapılandırması içerisinde GatewayPorts aktif edilmiş olsun.

gwports - SSH Port Forwarding

Aktif olması durumunda dışarıdan başka bir ipden direkt ilgili porta erişebildim. GE

gwconnect - SSH Port Forwarding

3. Dynamic Port Forwarding

Local ve Remote Port forwardingde sadece 1 porta yönlendirilebiliriz. Dynamic Port forwarding, tek port kısıtlaması olmaksızın bir socks4/5 server gibi  davranış gösterir.

Dynamic Port Forwardingde port, local port forwarding de  olduğu gibi ssh client hostda listen edilir.

Örnek Kullanım Amaçları:

  • Uygulamaların Socks proxy olarak kullanmasını sağlamak

Syntax:

> ssh -D [bind_address:]port ssh_server
  • -D : Dynamic port forwarding i belirtir.
  • [bind_address:] : Opsiyoneldir. Belirtilmediği takdirde 127.0.0.1 bind edilir. Tüm interfacelerin bind edilmesi isteniyorsa * ifadesi kullanılabilir.
  • port: Localde bind olunacak port.
  • ssh_server: ssh sunucu.

Örnek:

> ssh -D 2345 [email protected]
  • ssh client 192.168.80.249 sunucuna bağlanır.  Bağlandıktan sonra 12345 portunu ssh prosesi localde listen statüsünde açar.

Analiz:

Yukarıdaki örneğimiz üzerinden detaylı bir analiz gerçekleştirelim:

dynamicpforw - SSH Port Forwarding

Örneğin apt paket yöneticimizin isteklerini oluşan bu tünel üzerinden hedefe iletebiliriz.

sockstunnel - SSH Port Forwarding

Yukarıda 192.168.80.249a bağlanıp ssh clientın localhostunda 2345 portunu dinleyen bir socks server oluşturduk. tsocks uygulaması apt update  isteklerimizi tsocks konfigürasyonunda belirtilen socks servera iletti. Socks serverımız da bu istekleri ssh sunucumuz  192.168.80.249 üzerinden kali repolarına iletti.

4. Reverse Dynamic Port Forwarding

Dynamic Port Forwardingin tersidir.

Reverse Dynamic Port Forwardingde port, remote port forwarding de  olduğu gibi ssh serverda listen edilir.

Reverse dynamic forwarding özelliği Openssha 7.6 sürümüyle gelmiştir. Redhat/Centos 7 distroları bile bu yazıyı yazdığım tarih itibariyle bile 7.4 sürümünü kullanıyor. OpenSSH serverınızının bir sürümü kontrol ediniz.

> ssh -v

Örnek Kullanım Amaçları:

  • Uygulamaların socks proxy olarak kullanmasını sağlamak

Syntax:

> ssh -R [bind_address:]port ssh_server
  • -R : Reverse (Remote) Dynamic port forwarding i belirtir.
  • [bind_address:] : Opsiyoneldir. Belirtilmediği takdirde 127.0.0.1 bind edilir. Tüm interfacelerin bind edilmesi isteniyorsa * ifadesi kullanılabilir.
  • port: Localde bind olunacak port.
  • ssh_server: ssh sunucu.

Örnek: 

> ssh -R 2345 [email protected]
  • ssh client 192.168.80.249 sunucuna bağlanır.  Bağlandıktan sonra 2345 portunu sshd prosesi, ssh sunucusu listen statüsünde açar.