socat ile Gelişmiş Ağ Köprüleme ve Veri Yönlendirme
Ağ troubleshooting yaparken ya da bir servisi geçici olarak köprülemek gerektiğinde aklıma ilk gelen araç her zaman socat olmuştur. Netcat’i bilen herkes “nc yeterli değil mi?” diye sorar, ama socat’ın sunduğu esnekliği gördükten sonra bu soruyu sormayı bırakırlar. İki uç nokta arasında bidirectional veri akışı kuran bu araç, basit port yönlendirmesinden TLS tüneline, Unix socket köprülemesinden seri port erişimine kadar inanılmaz geniş bir kullanım yelpazesine sahip.
socat Nedir ve Neden Öğrenmeye Değer?
socat (SOcket CAT) temelde iki veri kanalını birbirine bağlayan bir araçtır. Her kanal bir TCP soketi, UDP soketi, dosya, Unix domain soketi, SSL bağlantısı, seri port veya başka bir şey olabilir. Bu kadar geniş bir adres tipi desteği, socat’ı diğer araçlardan ayıran temel özelliktir.
Bir senaryoyu düşünelim: Firewall arkasındaki bir veritabanı sunucusuna sadece belirli bir jump host üzerinden erişebiliyorsunuz ve geliştirici ekibi local makinelerinden doğrudan bağlanmak istiyor. Buraya kadar VPN, SSH tüneli gibi çözümler akla gelir. Ama bu tüneli dinamik, log’lanabilir ve kolayca yönetilebilir hale getirmek istiyorsanız socat devreye girer.
Kurulum basit:
# Debian/Ubuntu
apt install socat
# RHEL/CentOS/Rocky Linux
dnf install socat
# macOS (Homebrew ile)
brew install socat
Temel Söz Dizimi ve Adres Tipleri
socat’ın söz dizimi ilk bakışta karmaşık görünebilir ama mantığı anladıktan sonra her şey yerine oturur:
socat [seçenekler] <adres1> <adres2>
Her adres bir kaynak veya hedef tanımlar. İki adres birbirine bağlanır ve veri her iki yönde de akar.
Sık kullanılan adres tipleri:
- TCP:host:port: Belirtilen host ve porta TCP bağlantısı kurar
- TCP-LISTEN:port: Belirtilen portu dinler
- UDP:host:port: UDP üzerinden bağlantı
- UNIX-CONNECT:path: Unix domain soketine bağlanır
- UNIX-LISTEN:path: Unix domain soketi dinler
- SSL:host:port: TLS/SSL bağlantısı
- EXEC:komut: Bir komutu çalıştırır ve stdin/stdout’unu bağlar
- FILE:path: Dosyaya bağlanır
- STDIO: Standart giriş/çıkış
- PIPE: Named pipe
Adres seçenekleri virgülle eklenir:
socat TCP-LISTEN:8080,fork,reuseaddr TCP:backend-server:80
Burada fork her bağlantı için yeni bir process açar, reuseaddr ise portu hızlıca yeniden kullanılabilir hale getirir. Bu iki seçenek proxy benzeri kullanımlarda neredeyse zorunludur.
Gerçek Dünya Senaryoları
Senaryo 1: Basit TCP Port Yönlendirme
En klasik kullanım: Local makinenizden uzak bir servise port yönlendirme. Diyelim ki geliştirme ortamınızda bir uygulama 3000 portunu dinliyor ama siz 80 portunu kullanmak istiyorsunuz:
socat TCP-LISTEN:80,fork,reuseaddr TCP:localhost:3000
Ya da daha pratik bir senaryo: Production veritabanınız firewall arkasında ve sadece 5432 portundan değil, 15432’den erişilmesini istiyorsunuz (eski bir uygulama uyumluluğu için):
socat TCP-LISTEN:15432,fork,reuseaddr TCP:10.0.1.50:5432
Bu kadar. İki satır, problem çözüldü.
Senaryo 2: UDP Yönlendirme
UDP ile iş yaparken socat’ın netcat üzerindeki üstünlüğü daha da belirginleşir. Syslog trafiğini merkezi bir sunucuya yönlendirmek istediğinizi düşünün:
# Gelen UDP syslog trafiğini başka bir sunucuya bridge'le
socat UDP-RECVFROM:514,fork UDP-SENDTO:central-syslog.internal:514
SNMP trap’lerini yönlendirmek için de aynı mantık geçerli:
socat UDP-RECVFROM:162,fork UDP-SENDTO:snmp-manager.corp:162
Senaryo 3: Unix Socket ile TCP Arasında Köprü
Bu benim en çok kullandığım senaryolardan biri. Docker daemon’ı uzaktan yönetmek ya da bir Unix socket’i network üzerinden erişilebilir hale getirmek istediğinizde:
# Docker socket'ini TCP üzerinden erişilebilir yap (dikkatli kullanın!)
socat TCP-LISTEN:2375,fork,reuseaddr UNIX-CONNECT:/var/run/docker.sock
Tersini de yapabilirsiniz. Uzak bir TCP servisini local Unix socket olarak sunmak:
socat UNIX-LISTEN:/tmp/myservice.sock,fork,reuseaddr TCP:remote-host:8080
Bu teknik özellikle uygulama konfigürasyonunu değiştiremediğiniz durumlarda işe yarar. Uygulama Unix socket’i bekliyorsa ama siz TCP servisi kullanıyorsanız, socat ikisi arasında şeffaf bir köprü kurar.
Senaryo 4: TLS/SSL Tünel Oluşturma
Şifrelenmemiş bir protokolü TLS ile şifrelemek istiyorsanız socat mükemmel bir çözüm sunar. Bunu openssl kütüphanesi üzerinden yapar.
Önce sertifika hazırlayalım:
# Self-signed sertifika ve key oluştur
openssl req -newkey rsa:2048 -nodes -keyout server.key
-x509 -days 365 -out server.crt
# PEM formatında birleştir
cat server.key server.crt > server.pem
Şimdi TLS destekli bir dinleyici açalım:
# TLS üzerinden dinle, gelen bağlantıyı local servise ilet
socat SSL-LISTEN:8443,fork,reuseaddr,cert=server.pem,verify=0
TCP:localhost:8080
Client tarafında:
# TLS ile bağlan, şifresiz ilet
socat TCP-LISTEN:8080,fork,reuseaddr
SSL:secure-server.example.com:8443,verify=0
Production ortamında verify=0 kullanmayın. Bu sadece test için geçerlidir. Gerçek ortamda CA sertifikasıyla doğrulama yapılmalıdır:
socat SSL-LISTEN:8443,fork,reuseaddr,cert=server.pem,cafile=ca.crt
TCP:localhost:8080
Senaryo 5: Seri Port Erişimi ve Yönlendirme
Embedded sistemlerle, eski donanımlarla ya da network cihazlarının console portlarıyla uğraşanlar için socat hayat kurtarıcı olabilir. Serial port’u TCP üzerinden erişilebilir yapmak:
# /dev/ttyS0 seri portunu 9600 baud ile TCP 7000 üzerinden erişilebilir yap
socat TCP-LISTEN:7000,fork,reuseaddr
/dev/ttyS0,raw,echo=0,b9600,cs8,parenb=0,cstopb=0
Uzak bir noktadan bu porta bağlanmak için:
socat STDIO,raw,echo=0 TCP:remote-host:7000
Bu sayede uzak bir lokasyondaki seri konsola sanki local’de bağlıymış gibi erişebilirsiniz.
Senaryo 6: Basit Dosya Transfer Sunucusu
Hızlı bir dosya transfer sunucusu kurmak için:
# Gönderen tarafta
socat TCP-LISTEN:9999,reuseaddr FILE:buyuk_dosya.tar.gz
# Alan tarafta
socat TCP:kaynak-sunucu:9999 FILE:buyuk_dosya.tar.gz,creat
Netcat ile de yapılabilir ama socat’ın avantajı transfer tamamlandığında bağlantıyı düzgünce kapatması ve hata yönetiminin daha güvenilir olmasıdır.
Senaryo 7: Çift Yönlü Tünel ile Port Knocking Testi
Bir güvenlik testi senaryosu: Port knocking mekanizmasını test etmek ya da belirli bir sequence’ı simüle etmek için:
# Knock sequence simülasyonu için UDP paketleri gönder
for port in 7000 8000 9000; do
socat - UDP:target-host:$port <<< "knock"
sleep 0.5
done
# Açılan portu hemen kullan
socat TCP:target-host:22 STDIO
İleri Düzey Kullanım: Proxy Zinciri ve Veri İnceleme
Araya Girme ve Logging
socat’ın en güzel özelliklerinden biri: iki uç arasındaki veriyi log’layabilmek. Bir HTTP trafiğini incelemek istediğinizi düşünelim:
socat -v TCP-LISTEN:8080,fork,reuseaddr TCP:real-backend:80
-v parametresi her iki yönde akan veriyi stderr’e yazar. Daha ayrıntılı hex dump için:
socat -x -v TCP-LISTEN:8080,fork,reuseaddr TCP:real-backend:80 2>/tmp/traffic.log
Bu tekniği protokol analizi yaparken ya da bir client’ın tam olarak ne gönderdiğini anlamak istediğinizde sıkça kullanıyorum. Wireshark açmaya gerek kalmıyor çoğu zaman.
EXEC ile Script Entegrasyonu
socat’ın güçlü bir özelliği de herhangi bir komutu bir ağ servisi gibi sunabilmesi:
# Bağlanan herkese sistem bilgisi ver
socat TCP-LISTEN:7777,fork,reuseaddr EXEC:"uname -a && uptime && df -h"
# Daha güvenli bir yaklaşımla bash session sun (dikkatli kullanın!)
socat TCP-LISTEN:4444,fork,reuseaddr EXEC:"/bin/bash",pty,stderr,setsid,sigint
Son örnek güvenlik açısından kritik. Production sistemlerde asla böyle bir şey çalıştırmayın. Ama izole test ortamlarında ya da CTF senaryolarında oldukça işe yarar.
Relay Zinciri Kurma
Birden fazla socat instance’ını zincirleyerek multi-hop relay kurabilirsiniz:
# Sunucu A'da (ara nokta):
socat TCP-LISTEN:5000,fork,reuseaddr TCP:sunucu-b:6000
# Sunucu B'de (ara nokta):
socat TCP-LISTEN:6000,fork,reuseaddr TCP:hedef-sunucu:80
# Client'tan sunucu A'ya bağlanmak hedefe ulaşır
Bu VPN olmadan multi-hop atlatma yapmanın basit bir yoludur. Kurumsal ağlarda jump host zinciri olarak da kullanılabilir.
socat’ı systemd ile Kalıcı Servis Olarak Çalıştırmak
Geçici bir bridge kurmak yerine kalıcı bir servis istiyorsanız systemd unit dosyası oluşturun:
# /etc/systemd/system/socat-bridge.service dosyası
cat > /etc/systemd/system/socat-bridge.service << 'EOF'
[Unit]
Description=socat TCP Bridge - Port 8080 to Backend
After=network.target
Wants=network-online.target
[Service]
Type=simple
User=nobody
Group=nobody
ExecStart=/usr/bin/socat TCP-LISTEN:8080,fork,reuseaddr TCP:backend.internal:80
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now socat-bridge
systemctl status socat-bridge
User=nobody ile minimum yetkiyle çalıştırmak önemli. Eğer 1024’ün altında bir portu dinleyecekseniz ya root gerekecek ya da Linux capabilities kullanmanız gerekecek:
# socat binary'sine cap_net_bind_service ekle
setcap 'cap_net_bind_service=+ep' /usr/bin/socat
Güvenlik Konuları
socat kullanırken dikkat edilmesi gereken birkaç kritik nokta:
- Erişim kısıtlaması:
TCP-LISTENaçtığınızda, ağdaki herkes bağlanabilir.bindseçeneğiyle sadece belirli interface’i dinleyin:TCP-LISTEN:8080,bind=127.0.0.1,fork - Firewall entegrasyonu: socat ile açtığınız portları iptables/nftables kurallarıyla sınırlayın
- SSL verify: Test dışında
verify=0kullanmaktan kaçının - EXEC kullanımı: Kullanıcı girdisini doğrudan EXEC’e geçirmeyin, komut injection riski var
- Process limiti:
forkkullanırkenmax-childrenseçeneğiyle eş zamanlı bağlantı sayısını sınırlayın
# Maksimum 10 eş zamanlı bağlantı
socat TCP-LISTEN:8080,fork,max-children=10,reuseaddr TCP:backend:80
Hata Ayıklama ve Verbose Modlar
socat hata verdiğinde detaylı log almak için:
# Temel verbose
socat -v ...
# Daha fazla detay
socat -d -d ...
# En fazla detay (her şeyi loglar)
socat -d -d -d -d ...
Bir bağlantı sorununu debug ederken genellikle -d -d yeterli oluyor. Bu seviye adres çözümleme, bağlantı kurma ve veri transferi adımlarını ayrıntılı gösteriyor.
Sonuç
socat, ağ yönetiminde İsviçre çakısı rolünü fazlasıyla hak eden bir araç. Basit bir port yönlendirmesinden TLS tüneline, Unix socket köprülemesinden seri port yönetimine kadar tek bir araçla çok fazla şey yapabiliyorsunuz.
Özellikle acil durumlarda, kalıcı çözüm devreye alınana kadar geçici köprüler kurmak için socat’a güveniyorum. Bir servisi hızlıca başka bir porta taşımak, bir sertifika sorunu yaşayan servisi geçici bypass etmek, ya da bir protokolü debug etmek için arayacağınız ilk araç socat olmalı.
Öğrenmesi başlangıçta biraz zaman alıyor, özellikle adres sözdizimi kafayı karıştırabiliyor. Ama her senaryo için man sayfasına bakma alışkanlığı edinirseniz, man socat inanılmaz detaylı bir kaynak sunuyor. Hatta socat’ın man sayfası, Linux dünyasının en kapsamlı man sayfaları arasında gösterilir.
Son olarak: production ortamında socat ile açtığınız her port, potansiyel bir güvenlik açığıdır. Geçici çözümleri kalıcı hale getirmeden önce mutlaka firewall kurallarınızı güncelleyin ve erişim denetimini sağlayın. Bu araç güçlüdür, ama güç sorumluluk gerektirir.
