UFW ile Port Knocking: Gizli Erişim Yöntemiyle SSH Güvenliği
Sunucunuza yapılan brute force saldırıları, port taramaları ve otomatik botlar düşünüldüğünde SSH portunu varsayılan 22 numarada bırakmak artık kabul edilebilir bir risk değil. Port değiştirmek bir çözüm olsa da tek başına yeterli değil. İşte burada port knocking devreye giriyor: portlarınızı tamamen kapalı tutup yalnızca doğru “kapı vuruş sırasını” bilen kullanıcılara açıyorsunuz. Bu yazıda UFW ve knockd kullanarak SSH için güçlü bir port knocking sistemi kuracağız.
Port Knocking Nedir ve Neden İşe Yarar?
Port knocking, bir istemcinin belirli portlara belirli bir sırayla paket göndermesi üzerine güvenlik duvarının dinamik olarak bir portu açması prensibine dayanır. Dışarıdan bakıldığında sunucunuzda hiçbir port açık görünmez. Nmap taraması yapan bir saldırgan SSH portunu bulamaz çünkü gerçekten kapalıdır.
Klasik bir senaryo şöyle işler: Önce 7000 portuna, ardından 8000 portuna, son olarak 9000 portuna bağlantı denemesi yaparsınız. knockd daemon bu sırayı tanır ve güvenlik duvarına “şu IP için 22. portu aç” komutunu verir. 30 saniye içinde bağlanmazsanız port yeniden kapanır.
Avantajları:
- Tüm port tarayıcılarına karşı etkili
- Mevcut güvenlik duvarı kurallarınızı bozmaz
- Ek bir kimlik doğrulama katmanı ekler
- Saldırı yüzeyini dramatik biçimde küçültür
- Log dosyaları temizlenir, gereksiz bağlantı denemeleri ortadan kalkar
Dezavantajları:
- Ağ gecikmelerinde sıra bozulabilir
- Knock sırasını bilmeyen ekip üyeleri erişim sorunları yaşar
- Tek başına yeterli güvenlik sağlamaz, katmanlı güvenliğin parçası olmalıdır
Gereksinimler ve Ortam Hazırlığı
Bu rehberde Ubuntu 22.04 LTS kullanıyoruz ancak Debian ve diğer Ubuntu sürümlerinde de aynı adımlar geçerli. Başlamadan önce şunlara ihtiyacınız var:
- Root veya sudo yetkili bir kullanıcı
- UFW kurulu ve aktif olmalı
- Mevcut bir SSH bağlantısı (kurulum sırasında kendinizi kilitlememeye dikkat edin)
- Sunucuya fiziksel veya konsol erişimi (acil durum için)
Önemli uyarı: Bu işlemleri yaparken mutlaka mevcut SSH oturumunuzu açık tutun. Yeni bir terminal sekmesinde test edin. Kendinizi kilitlerseniz konsol erişiminiz olsun.
UFW Kurulumu ve Temel Yapılandırma
# UFW kurulumu
sudo apt update && sudo apt install ufw -y
# Mevcut durumu kontrol et
sudo ufw status verbose
# Varsayılan politikaları ayarla
sudo ufw default deny incoming
sudo ufw default allow outgoing
# UFW'yi etkinleştirmeden ÖNCE SSH'a izin ver (kendinizi kilitlemeyin!)
sudo ufw allow 22/tcp comment 'SSH - gecici olarak acik'
# UFW'yi etkinleştir
sudo ufw enable
knockd Kurulumu
# knockd paketini kur
sudo apt install knockd -y
# Servis durumunu kontrol et
sudo systemctl status knockd
# knockd'nin hangi arabirimi dinleyeceğini öğren
ip addr show
knockd Yapılandırması
knockd‘nin ana yapılandırma dosyası /etc/knockd.conf konumundadır. Önce yedek alın:
sudo cp /etc/knockd.conf /etc/knockd.conf.backup
sudo nano /etc/knockd.conf
Aşağıdaki yapılandırmayı kullanın. Burada TCP ve UDP karışımı kullanmak saldırıyı daha da zorlaştırır:
[options]
UseSyslog
LogFile = /var/log/knockd.log
Interface = eth0
[openSSH]
sequence = 7469,8253,9371
seq_timeout = 15
tcpflags = syn
command = /usr/sbin/ufw insert 1 allow from %IP% to any port 22 proto tcp comment 'knock-ssh-%IP%'
cmd_timeout = 30
stop_command = /usr/sbin/ufw delete allow from %IP% to any port 22 proto tcp
[closeSSH]
sequence = 9371,8253,7469
seq_timeout = 15
tcpflags = syn
command = /usr/sbin/ufw delete allow from %IP% to any port 22 proto tcp
Bu yapılandırmada birkaç kritik nokta var:
- sequence: Kapı vuruş sırasındaki port numaraları. Bunları kendinize göre değiştirin.
- seq_timeout: Tüm vuruşların tamamlanması için gereken maksimum süre (saniye).
- tcpflags: Yalnızca SYN paketleri sayılır, bu rastgele trafik gürültüsünü filtreler.
- cmd_timeout: Portu açık tutma süresi. 30 saniye sonra
stop_commandçalışır. - %IP%: knockd’nin dinamik olarak değiştirdiği, bağlanan istemcinin IP adresi.
- ufw insert 1: Kuralı listenin en başına ekler, diğer engelleyici kuralların önüne geçer.
Ağ Arabirimine Göre Düzenleme
Sunucunuzun ağ arabirimine göre Interface değerini düzenleyin:
# Aktif ağ arabirimini bul
ip route | grep default
# veya
nmcli device status
# Sanal sunucularda genellikle ens3, ens4 veya eth0 olur
# Çıktıya göre knockd.conf dosyasındaki Interface değerini güncelleyin
knockd Servisini Aktif Hale Getirme
knockd’yi başlatmadan önce /etc/default/knockd dosyasını düzenleyin:
sudo nano /etc/default/knockd
Dosya içeriğini şu şekilde güncelleyin:
START_KNOCKD=1
KNOCKD_OPTS="-i eth0"
Sonra servisi başlatın:
sudo systemctl enable knockd
sudo systemctl start knockd
sudo systemctl status knockd
# Log dosyasını izle
sudo tail -f /var/log/knockd.log
UFW’de SSH Portunu Kapatma
Şu ana kadar SSH portu hâlâ açık. Tüm sistemi test ettikten sonra bu kuralı kapatacaksınız. Bu adımı uygulamadan önce knockd’nin çalıştığını doğrulayın.
# Mevcut UFW kurallarını listele
sudo ufw status numbered
# SSH için açık kuralı kaldır (numara değişebilir, status çıktısına bakın)
sudo ufw delete allow 22/tcp
# Artık 22 numaralı port tamamen kapalı
sudo ufw status verbose
İstemci Tarafında Knock Yapma
Knock Aracı ile
# İstemciye knock paketini kur
sudo apt install knockd -y
# SSH portunu aç
knock -v SUNUCU_IP 7469 8253 9371
# Bağlan (30 saniyeniz var)
ssh kullanici@SUNUCU_IP
# İşiniz bitince portu kapat
knock -v SUNUCU_IP 9371 8253 7469
Nmap ile Knock Yapma
Eğer istemcide knock paketi yoksa nmap ile de yapabilirsiniz:
# nmap ile TCP SYN paketleri gönder
nmap -Pn --host-timeout 201 --max-retries 0 -p 7469 SUNUCU_IP
nmap -Pn --host-timeout 201 --max-retries 0 -p 8253 SUNUCU_IP
nmap -Pn --host-timeout 201 --max-retries 0 -p 9371 SUNUCU_IP
# Veya tek satırda
for port in 7469 8253 9371; do nmap -Pn --host-timeout 201 --max-retries 0 -p $port SUNUCU_IP; done
Bash Script ile Otomatik Knock
Günlük kullanımı kolaylaştırmak için bir script yazalım:
#!/bin/bash
# /usr/local/bin/ssh-knock.sh
SUNUCU_IP="${1:-SUNUCU_IP_ADRESI}"
KULLANICI="${2:-ubuntu}"
SSH_PORT=22
KNOCK_PORTS=(7469 8253 9371)
KNOCK_DELAY=0.3
echo "[*] Port knocking basliyor: $SUNUCU_IP"
for port in "${KNOCK_PORTS[@]}"; do
echo " Vuruluyor: $port"
knock "$SUNUCU_IP" "$port" 2>/dev/null ||
nmap -Pn --host-timeout 201 --max-retries 0 -p "$port" "$SUNUCU_IP" > /dev/null 2>&1
sleep "$KNOCK_DELAY"
done
echo "[*] Knock tamamlandi, SSH baglantisi kuruluyor..."
sleep 1
ssh -p "$SSH_PORT" "$KULLANICI@$SUNUCU_IP"
echo "[*] SSH oturumu sonlandi."
echo "[*] Portu kapatmak ister misiniz? (e/h)"
read -r cevap
if [[ "$cevap" == "e" || "$cevap" == "E" ]]; then
knock "$SUNUCU_IP" 9371 8253 7469
echo "[*] Port kapatildi."
fi
# Script'e çalışma izni ver
chmod +x /usr/local/bin/ssh-knock.sh
# Kullanımı
ssh-knock.sh 192.168.1.100 ubuntu
Güvenlik Duvarı Kurallarını Doğrulama
Knock işleminden sonra kuralların doğru oluşturulup silindiğini test edin:
# Knock öncesi UFW durumu (22 numaralı port görünmemeli)
sudo ufw status numbered
# Bir terminalde UFW değişikliklerini izle
watch -n 1 sudo ufw status numbered
# Başka bir terminalden knock yap ve kuralın eklenip silindiğini izle
knock -v SUNUCU_IP 7469 8253 9371
# knockd loglarını kontrol et
sudo journalctl -u knockd -f
Gelişmiş Yapılandırma: Çok Katmanlı Güvenlik
Port knocking tek başına yeterli değildir. Aşağıdaki UFW kurallarıyla birleştirin:
# Rate limiting ile brute force koruması (zaten açık portlar için)
sudo ufw limit ssh comment 'SSH rate limit'
# Belirli IP bloklarını engelle (ülke bazlı engellerle birleştirilebilir)
sudo ufw deny from 10.0.0.0/8 to any port 22
# Yalnızca belirli bir IP aralığından knock kabul et
# knockd.conf içinde bunu yapabilirsiniz ama UFW seviyesinde de ekstra koruma:
sudo ufw allow from 203.0.113.0/24 to any port 7469 proto tcp comment 'knock port 1'
sudo ufw allow from 203.0.113.0/24 to any port 8253 proto tcp comment 'knock port 2'
sudo ufw allow from 203.0.113.0/24 to any port 9371 proto tcp comment 'knock port 3'
fail2ban ile Entegrasyon
# fail2ban kurulumu
sudo apt install fail2ban -y
# SSH için jail yapılandırması
sudo nano /etc/fail2ban/jail.local
[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
ignoreip = 127.0.0.1/8 ::1
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
sudo fail2ban-client status sshd
Gerçek Dünya Senaryoları
Senaryo 1: VPS Yönetimi
Bir dijital ajansın 20’den fazla VPS’ini yöneten bir sysadmin olduğunuzu düşünün. Her sunucuda farklı knock sırası kullanın, bu sıraları şifreli bir parola yöneticisinde saklayın (Bitwarden, KeePass). Ekip üyeleri için ayrı knock profilleri oluşturun ve knock sıralarını dönemsel olarak değiştirin.
Senaryo 2: CI/CD Pipeline Entegrasyonu
GitHub Actions veya GitLab CI’dan otomatik deployment için:
# .github/workflows/deploy.yml içinde
# Önce knock, sonra deployment
- name: Deploy to server
run: |
# Knock sırasını çalıştır
for port in ${{ secrets.KNOCK_PORTS }}; do
nmap -Pn --host-timeout 201 --max-retries 0 -p $port ${{ secrets.SERVER_IP }} > /dev/null
sleep 0.5
done
# SSH ile deploy
ssh -o StrictHostKeyChecking=no deploy@${{ secrets.SERVER_IP }} 'bash /opt/deploy.sh'
Senaryo 3: Acil Erişim Prosedürü
Knock sırasını unuttuğunuzda veya acil erişim gerektiğinde:
# Bulut sağlayıcı konsolundan (AWS EC2, DigitalOcean Droplet Console)
# veya KVM/IPMI üzerinden erişip knockd'yi geçici durdur
sudo systemctl stop knockd
sudo ufw allow 22/tcp
# İşinizi bitirince
sudo ufw delete allow 22/tcp
sudo systemctl start knockd
Knock Sırası Güvenliği
Knock sırasını güvenli tutmak için bazı pratik öneriler:
- Port sayısını artırın: 3 yerine 5-6 port kullanmak kombinasyonları astronomik biçimde artırır
- Karışık protokol kullanın: TCP ve UDP portlarını karıştırın
- Yüksek port numarası seçin: 1024-65535 arası rastgele portlar seçin, bilinen port numaralarından kaçının
- Düzenli rotasyon: Knock sırasını ayda bir değiştirin
- Sırayı belgeleyin: Güvenli bir yerde (şifreli parola yöneticisi) mutlaka kaydedin
Örnek gelişmiş bir knock sırası yapılandırması:
[openSSH]
sequence = 45231:tcp,17834:udp,62947:tcp,33109:udp,51823:tcp
seq_timeout = 20
command = /usr/sbin/ufw insert 1 allow from %IP% to any port 22 proto tcp comment 'knock-%IP%'
cmd_timeout = 45
stop_command = /usr/sbin/ufw delete allow from %IP% to any port 22 proto tcp
Sorun Giderme
Sık karşılaşılan sorunlar ve çözümleri:
- knockd başlamıyor:
journalctl -u knockdile hata mesajını kontrol edin. Genellikle ağ arabirimi adı yanlıştır. - Knock çalışıyor ama port açılmıyor:
sudo tcpdump -i eth0 -n 'port 7469 or port 8253 or port 9371'ile paketlerin gerçekten sunucuya ulaşıp ulaşmadığını kontrol edin. - UFW kuralı ekleniyor ama SSH bağlanamıyor:
sudo ufw status numberedile kuralın sırasını kontrol edin.insert 1doğru çalışıyor mu? - Bulut sağlayıcı güvenlik grubu: AWS Security Group veya DigitalOcean Firewall gibi harici güvenlik duvarlarının da knockd portlarına izin vermesi gerekir.
- Sequence timeout: Ağ gecikmesi yüksekse
seq_timeoutdeğerini 20-30 saniyeye çıkarın.
# Canlı paket izleme ile debug
sudo tcpdump -i eth0 -n "tcp[tcpflags] & tcp-syn != 0 and port (7469 or 8253 or 9371)"
# knockd detaylı log modu
sudo knockd -D -i eth0 -c /etc/knockd.conf
Sonuç
UFW ile port knocking kombinasyonu, SSH güvenliğini katmanlı bir yaklaşımla ele almanın etkili yollarından biri. Bu yapılandırmayla sunucunuz dışarıdan bakıldığında tamamen “sessiz” görünür; hiçbir port tarayıcısı SSH portunu bulamaz çünkü gerçekten kapalıdır.
Ancak şunu unutmayın: port knocking bir güvenlik katmanıdır, tek başına bir kalkan değildir. En iyi güvenlik mimarisi şu unsurları bir arada barındırır: güçlü SSH anahtarları (parola ile SSH girişini devre dışı bırakın), port knocking ile gizlenmiş SSH portu, fail2ban ile brute force koruması ve UFW ile katmanlı güvenlik duvarı kuralları.
Kurulumu tamamladıktan sonra düzenli olarak knockd loglarını inceleyin, knock sıralarını dönemsel olarak değiştirin ve acil erişim prosedürünüzü belgelendirin. Bir gün o belgeye ihtiyaç duyduğunuzda kendinize teşekkür edeceksiniz.
