Ubuntu VPS’te Sadece Iptables Kullanarak Port Knocking Nasıl Yapılandırılır?
Giriş
Günümüzün dijital dünyasında, sunucu güvenliği her zamankinden daha kritik bir öneme sahiptir. Özellikle Ubuntu tabanlı bir Sanal Özel Sunucu (VPS) kullanıyorsanız, olası saldırılara karşı savunma mekanizmalarınızı güçlendirmek hayati bir adımdır. Açık portlar, kötü niyetli kişilerin sunucunuzu taraması ve zafiyet arayışı için birer hedef teşkil eder. Port knocking, bu tür tehditlere karşı alışılmadık ama son derece etkili bir savunma katmanı sunar. Bu makalede, herhangi bir ek yazılım (örneğin knockd) kullanmadan, sadece Linux’un yerleşik güvenlik duvarı olan iptables ve onun recent modülü ile port knocking’i nasıl yapılandıracağınızı ayrıntılı bir şekilde inceleyeceğiz.
Port knocking, bir servise (örneğin SSH) erişim izni vermeden önce, belirli bir dizi “kapı vuruşu” (yani belirli portlara bağlantı denemeleri) yapılması prensibine dayanır. Bu vuruşlar genellikle kapalı veya gizli (stealth) portlara yapılır ve güvenlik duvarı bu vuruş dizisini doğru algıladığında, asıl servisin portunu geçici olarak açar. Bu sayede, SSH gibi kritik servisleriniz varsayılan olarak kapalı kalır ve yalnızca doğru “şifreyi” bilenler tarafından erişilebilir hale gelir. Bu yaklaşım, otomatik port tarayıcılarını ve rastgele saldırıları büyük ölçüde engeller, çünkü dışarıdan bakıldığında sunucunuzun ilgili portları tamamen kapalı görünür.
Bu makale boyunca, iptables‘ın recent modülünü kullanarak bu karmaşık ancak güçlü mekanizmayı adım adım nasıl kuracağınızı, hangi komutları kullanacağınızı ve güvenlik için nelere dikkat etmeniz gerektiğini öğreneceksiniz. Amacımız, Ubuntu VPS’inizi daha güvenli hale getirirken, mevcut kaynakları en verimli şekilde kullanmaktır.
Port Knocking Nedir ve Neden Kullanılmalıdır?
Port knocking, bir sunucudaki belirli bir servise erişimi kontrol etmek için kullanılan bir ağ erişim kontrol mekanizmasıdır. Temel fikir, bir kullanıcının önceden belirlenmiş bir “knock” (vuruş) dizisini, yani bir dizi kapalı veya açık portta belirli bir sırada bağlantı denemeleri yapmasını gerektirmesidir. Bu dizi doğru şekilde tamamlandığında, güvenlik duvarı kullanıcının IP adresine belirli bir servisin portunu (örneğin SSH için 22 numaralı port) geçici olarak açar.
Neden Kullanılmalıdır?
1. Gelişmiş Güvenlik: En belirgin faydası, sunucunuzun açık portlarını dış dünyaya karşı gizlemesidir. Normalde açık olan SSH portu (22), port knocking uygulandığında dışarıdan kapalı görünür. Bu, otomatik port tarayıcılarının ve botların sunucunuzu hedef almasını zorlaştırır.
2. Saldırı Yüzeyinin Azaltılması: Açık portlar, saldırı yüzeyini artırır. Port knocking, bu yüzeyi önemli ölçüde küçülterek, potansiyel zafiyetlerin keşfedilme olasılığını azaltır.
3. Brute-Force Saldırılarına Karşı Koruma: SSH gibi servisler sıkça brute-force saldırılarına maruz kalır. Port knocking, bu tür saldırıları daha başlamadan engeller, çünkü saldırgan doğru knock dizisini bilmediği sürece SSH portuna erişemez.
4. Kaynak Verimliliği: iptables tabanlı bir çözüm, ek bir daemon çalıştırmadığı için sistem kaynaklarını minimal düzeyde tüketir. Bu, özellikle sınırlı kaynaklara sahip VPS’ler için önemlidir.
5. Esneklik: iptables kuralları ile port knocking’i, istediğiniz karmaşıklıkta ve istediğiniz servisler için yapılandırabilirsiniz.
Port knocking tek başına bir çözüm olmamakla birlikte, mevcut güvenlik önlemlerinize (güçlü parolalar, SSH anahtarları, fail2ban vb.) güçlü bir ek katman sağlar.
Ön Gereksinimler
Bu rehbere başlamadan önce aşağıdaki ön koşulların karşılandığından emin olmanız gerekmektedir:
1. Ubuntu VPS: Çalışır durumda bir Ubuntu tabanlı Sanal Özel Sunucuya sahip olmalısınız. Rehber Ubuntu 20.04 veya 22.04 LTS sürümleri için geçerlidir.
2. Root Erişimi veya Sudo Yetkileri: iptables kurallarını değiştirmek için root kullanıcısı olmanız veya sudo yetkilerine sahip bir kullanıcı ile oturum açmış olmanız gerekmektedir.
3. Temel Iptables Bilgisi: iptables komutlarının genel yapısı, zincirler (INPUT, OUTPUT, FORWARD) ve hedefler (ACCEPT, DROP, REJECT) hakkında temel bilgiye sahip olmanız faydalı olacaktır.
4. SSH Erişimi: Kuralları yapılandırırken sunucunuza SSH üzerinden erişiyor olmanız önemlidir. Yanlış yapılandırma durumunda kendinizi dışarıda bırakmamak için, VPS sağlayıcınızın web tabanlı konsol erişiminin (VNC veya benzeri) olduğundan emin olun. Bu, kritik bir güvenlik önlemidir.
5. Ağ Temelleri Bilgisi: TCP/UDP portları, IP adresleri ve temel ağ iletişimi hakkında bilgi sahibi olmanız, kuralları anlamanıza yardımcı olacaktır.
Bu ön koşullar sağlandığında, port knocking yapılandırmasına güvenle başlayabiliriz.
Iptables ve Recent Modülü: Port Knocking’in Temel Taşı
iptables, Linux çekirdeğinin netfilter çerçevesi için bir kullanıcı alanı programıdır. Paket filtreleme, ağ adresi çevirisi (NAT) ve bağlantı takibi gibi görevleri yerine getirir. Port knocking için iptables‘ın gücünü, özellikle recent modülü ile birleştirerek kullanacağız.
recent Modülü Nedir?
recent modülü, iptables‘a belirli bir IP adresinden gelen bağlantı denemelerini izleme ve kaydetme yeteneği kazandırır. Bu modül sayesinde, belirli bir süre içinde belirli bir IP adresinden kaç tane bağlantı denemesi yapıldığını, hangi portlara yapıldığını ve bu IP adresini belirli bir listeye ekleyip çıkarmayı kontrol edebiliriz. Port knocking için bu özellikler vazgeçilmezdir.
recent modülünün temel parametreleri şunlardır:
* --set: Belirli bir IP adresini, belirtilen recent listesine ekler. Eğer IP zaten listedeyse, zaman damgasını günceller.
* --rcheck: Belirli bir IP adresinin, belirtilen recent listesinde olup olmadığını kontrol eder. Eğer listede ise kuralı eşleştirir.
* --seconds : IP’nin listede kalma süresini saniye cinsinden belirtir. Bu süre içinde listede olması gerekir.
* --hitcount : IP’nin listede belirtilen sayıda vuruş yapmış olması gerekir.
* --update: --rcheck ile birlikte kullanılır. Eğer IP listedeyse ve eşleşirse, IP’nin zaman damgasını günceller.
* --remove: Belirli bir IP adresini, belirtilen recent listesinden kaldırır.
* --name : Kullanılacak recent listesinin adını belirtir. Varsayılan olarak DEFAULT kullanılır. Her bir knocking aşaması için farklı bir liste adı kullanacağız (örn. KNOCK_1, KNOCK_2, ACCESS).
* --rsource / --rdest: Kaynak IP adresini (--rsource) veya hedef IP adresini (--rdest) izlemek için kullanılır. Genellikle --rsource kullanılır.
Bu parametreleri kullanarak, bir kullanıcının doğru port dizisini takip edip etmediğini kontrol eden karmaşık bir mantık oluşturacağız. Örneğin, ilk porta vuran IP’yi bir listeye ekleyeceğiz, ikinci porta vuran ve ilk listede olan IP’yi ikinci bir listeye ekleyip ilk listeden çıkaracağız ve bu şekilde devam edeceğiz.
Adım Adım Yapılandırma
Bu bölümde, iptables kullanarak port knocking’i adım adım nasıl yapılandıracağınızı öğreneceksiniz. Güvenli bir şekilde ilerlemek için adımları dikkatlice takip edin.
Mevcut Iptables Kurallarını Yedekleme
Herhangi bir güvenlik duvarı değişikliğine başlamadan önce, mevcut kurallarınızı yedeklemek kritik öneme sahiptir. Bu, bir sorunla karşılaştığınızda kolayca geri dönebilmenizi sağlar.
sudo iptables-save > /etc/iptables/rules.v4.bak
sudo ip6tables-save > /etc/iptables/rules.v6.bak
Varsayılan Politikaları Belirleme
Güvenliği artırmak için INPUT zincirinin varsayılan politikasını DROP olarak ayarlamak en iyi uygulamadır. Bu, açıkça izin verilmeyen tüm bağlantıların engelleneceği anlamına gelir. OUTPUT ve FORWARD zincirlerini genellikle ACCEPT olarak bırakabiliriz, ancak daha sıkı güvenlik gereksinimleriniz varsa bunları da özelleştirebilirsiniz.
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
UYARI: Bu komutu çalıştırdıktan sonra, mevcut SSH oturumunuz da dahil olmak üzere tüm bağlantılar kesilebilir! Bu yüzden, öncelikle SSH portunu açan kuralları eklemeniz veya bu adımı, tüm knocking kurallarını ekledikten sonra en son çalıştırmanız önerilir. En güvenli yol, SSH erişiminizi açan kuralı (knock sonrası) ekledikten sonra bu varsayılan politikayı uygulamaktır. Ancak, bu makalede knocking mekanizmasını kurduktan sonra SSH erişimi sağlayacağımız için, varsayılan olarak DROP ile başlayıp, knocking ile erişim sağlayacağız.
Gerekli Modülleri Yükleme
recent modülü genellikle varsayılan olarak yüklüdür, ancak emin olmak için kontrol edebilirsiniz:
sudo modprobe xt_recent
Eğer herhangi bir hata vermezse, modül zaten yüklü demektir.
SSH Portunu Kapatma (Knock Öncesi Durum)
Varsayılan olarak, SSH portu (genellikle 22) dışarıdan erişilebilir olmamalıdır. Eğer mevcut kurallarınızda SSH portunu açan bir kural varsa, onu silmeniz veya devre dışı bırakmanız gerekir. Bizim senaryomuzda, INPUT zincirinin varsayılan politikası DROP olduğu için, SSH portu zaten kapalı olacaktır.
Ancak, kendi IP adresinizden SSH erişimine izin veren bir kuralınız varsa, bunu şimdilik koruyun veya VPS konsol erişiminizin olduğundan emin olun. Bu rehberde, SSH portunun tamamen kapalı olduğunu ve sadece knock dizisi ile açılacağını varsayıyoruz.
Lokal Loopback Arayüzüne İzin Verme:
Sunucunun kendisiyle iletişim kurabilmesi için lo arayüzüne izin verilmelidir. Bu, birçok servisin düzgün çalışması için gereklidir.
sudo iptables -A INPUT -i lo -j ACCEPT
Mevcut Bağlantılara İzin Verme:
Halihazırda kurulmuş bağlantıların devam etmesine izin vermek ve güvenlik duvarı kurallarının yeni bağlantılar için geçerli olmasını sağlamak önemlidir.
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Port Knocking Zincirlerini Oluşturma
Port knocking mantığını uygulamak için özel iptables zincirleri oluşturacağız. Bu zincirler, knocking aşamalarını ve erişim iznini yönetecek.
* KNOCKING_STAGE_1: İlk vuruşu bekler.
* KNOCKING_STAGE_2: İkinci vuruşu bekler.
* KNOCKING_STAGE_3: Üçüncü vuruşu bekler.
* ACCESS_GRANTED: Doğru vuruş dizisinden sonra erişim izni verir.
* INVALID_KNOCK: Hatalı vuruşları yönetir ve recent listelerini temizler.
sudo iptables -N KNOCKING_STAGE_1
sudo iptables -N KNOCKING_STAGE_2
sudo iptables -N KNOCKING_STAGE_3
sudo iptables -N ACCESS_GRANTED
sudo iptables -N INVALID_KNOCK
Knocking Aşamalarını Tanımlama
Şimdi, her bir knocking aşaması için kuralları tanımlayacağız. Örnek olarak, 3 aşamalı bir knocking dizisi kullanacağız: 10001 (TCP), 10002 (UDP), 10003 (TCP). SSH portunu 22 olarak kabul ediyoruz.
1. Hatalı Vuruşları Yönetme (INVALID_KNOCK)
Bu zincir, herhangi bir aşamada yanlış bir porta veya yanlış sırayla gelen bir bağlantı denemesini yakalayarak, ilgili IP adresini tüm recent listelerinden temizler ve potansiyel saldırganları sıfırlar. Bu, birinin knocking dizisini tahmin etmeye çalışırken kilitlenmesini sağlar.
# INVALID_KNOCK zinciri: IP'yi tüm knocking listelerinden kaldır
sudo iptables -A INVALID_KNOCK -m recent --name KNOCK_1 --remove -j LOG --log-prefix "INVALID_KNOCK: KNOCK_1 removed "
sudo iptables -A INVALID_KNOCK -m recent --name KNOCK_2 --remove -j LOG --log-prefix "INVALID_KNOCK: KNOCK_2 removed "
sudo iptables -A INVALID_KNOCK -m recent --name KNOCK_3 --remove -j LOG --log-prefix "INVALID_KNOCK: KNOCK_3 removed "
sudo iptables -A INVALID_KNOCK -m recent --name ACCESS --remove -j LOG --log-prefix "INVALID_KNOCK: ACCESS removed "
sudo iptables -A INVALID_KNOCK -j DROP # Hatalı vuruşları düşür
Not: LOG kuralları, /var/log/syslog veya /var/log/kern.log dosyalarına hatalı denemelerin kaydedilmesini sağlar. Bu, güvenlik denetimi için faydalıdır.
2. Erişim Verme Zinciri (ACCESS_GRANTED)
Bu zincir, doğru knock dizisi tamamlandığında çağrılır. Belirli bir IP adresine SSH portuna erişim izni verir ve bu IP’yi ACCESS listesine ekler.
# ACCESS_GRANTED zinciri: SSH erişimi verir ve ACCESS listesine ekler
Eğer IP zaten ACCESS listesindeyse, zaman damgasını güncelle
sudo iptables -A ACCESS_GRANTED -m recent --name ACCESS --set -j ACCEPT
SSH portunu aç (örneğin 22)
sudo iptables -A ACCESS_GRANTED -p tcp --dport 22 -j ACCEPT
Diğer açılacak servisler buraya eklenebilir
sudo iptables -A ACCESS_GRANTED -p tcp --dport 80 -j ACCEPT
sudo iptables -A ACCESS_GRANTED -p tcp --dport 443 -j ACCEPT
3. Knocking Aşamaları Kuralları
Şimdi ana INPUT zincirine kurallar ekleyeceğiz. Bu kurallar, gelen bağlantı denemelerini yakalayacak ve doğru knocking zincirlerine yönlendirecektir.
Knock Dizisi:
* 1. Knock: TCP port 10001
* 2. Knock: UDP port 10002
* 3. Knock: TCP port 10003
a. Birinci Knock (10001/TCP)
İlk porta gelen bağlantı denemesini yakalar. Eğer bir IP bu porta vurursa, KNOCK_1 listesine eklenir ve KNOCKING_STAGE_1 zincirine yönlendirilir.
# INPUT zincirinden KNOCKING_STAGE_1'e yönlendirme
sudo iptables -A INPUT -p tcp --dport 10001 -m recent --name KNOCK_1 --set -j KNOCKING_STAGE_1
sudo iptables -A KNOCKING_STAGE_1 -j DROP # Bu portu dışarıdan kapalı tut
Açıklama:
* -p tcp --dport 10001: TCP 10001 portuna gelen paketleri eşleştir.
* -m recent --name KNOCK_1 --set: Paketin kaynak IP adresini KNOCK_1 adlı recent listesine ekle.
* -j KNOCKING_STAGE_1: Eşleşen paketi KNOCKING_STAGE_1 zincirine yönlendir.
* iptables -A KNOCKING_STAGE_1 -j DROP: KNOCKING_STAGE_1 zincirine gelen paketleri düşür. Bu, knocking portlarının dışarıdan kapalı görünmesini sağlar.
b. İkinci Knock (10002/UDP)
İkinci porta gelen bağlantı denemesini yakalar. Ancak, bu denemenin geçerli sayılması için IP’nin önce KNOCK_1 listesinde olması gerekir. Eğer öyleyse, IP KNOCK_2 listesine eklenir ve KNOCK_1 listesinden çıkarılır.
# INPUT zincirinden KNOCKING_STAGE_2'e yönlendirme
sudo iptables -A INPUT -p udp --dport 10002 -m recent --name KNOCK_1 --rcheck --seconds 15 --hitcount 1 \
-m recent --name KNOCK_2 --set -j KNOCKING_STAGE_2
sudo iptables -A KNOCKING_STAGE_2 -j DROP # Bu portu dışarıdan kapalı tut
Açıklama:
* -p udp --dport 10002: UDP 10002 portuna gelen paketleri eşleştir.
* -m recent --name KNOCK_1 --rcheck --seconds 15 --hitcount 1: Kaynak IP’nin KNOCK_1 listesinde olup olmadığını kontrol et. Son 15 saniye içinde en az 1 kez bu listeye eklenmiş olmalı.
* -m recent --name KNOCK_2 --set: Eğer kontrol başarılıysa, IP’yi KNOCK_2 listesine ekle.
* -j KNOCKING_STAGE_2: Eşleşen paketi KNOCKING_STAGE_2 zincirine yönlendir.
* iptables -A KNOCKING_STAGE_2 -j DROP: KNOCKING_STAGE_2 zincirine gelen paketleri düşür.
c. Üçüncü Knock (10003/TCP)
Üçüncü porta gelen bağlantı denemesini yakalar. Bu denemenin geçerli sayılması için IP’nin önce KNOCK_2 listesinde olması gerekir. Eğer öyleyse, IP ACCESS listesine eklenir ve KNOCK_2 listesinden çıkarılır.
# INPUT zincirinden KNOCKING_STAGE_3'e yönlendirme
sudo iptables -A INPUT -p tcp --dport 10003 -m recent --name KNOCK_2 --rcheck --seconds 15 --hitcount 1 \
-m recent --name ACCESS --set -j KNOCKING_STAGE_3
sudo iptables -A KNOCKING_STAGE_3 -j DROP # Bu portu dışarıdan kapalı tut
Açıklama:
* -p tcp --dport 10003: TCP 10003 portuna gelen paketleri eşleştir.
* -m recent --name KNOCK_2 --rcheck --seconds 15 --hitcount 1: Kaynak IP’nin KNOCK_2 listesinde olup olmadığını kontrol et. Son 15 saniye içinde en az 1 kez bu listeye eklenmiş olmalı.
* -m recent --name ACCESS --set: Eğer kontrol başarılıysa, IP’yi ACCESS listesine ekle.
* -j KNOCKING_STAGE_3: Eşleşen paketi KNOCKING_STAGE_3 zincirine yönlendir.
* iptables -A KNOCKING_STAGE_3 -j DROP: KNOCKING_STAGE_3 zincirine gelen paketleri düşür.
d. Knocking Listelerini Temizleme (Önemli!)
Her başarılı aşamadan sonra bir önceki aşamanın listesinden IP’yi çıkarmak önemlidir. Bu, dizinin doğru sırada takip edildiğinden emin olur ve eski durumların karışmasını önler. Bu kuralları ilgili KNOCKING_STAGE_X zincirlerinin içine koymak en mantıklı yaklaşımdır.
# KNOCKING_STAGE_1 zinciri
sudo iptables -A KNOCKING_STAGE_1 -j DROP # İlk knock portuna gelenleri düşür
KNOCKING_STAGE_2 zinciri
sudo iptables -A KNOCKING_STAGE_2 -m recent --name KNOCK_1 --remove -j DROP # KNOCK_1'den kaldır ve düşür
KNOCKING_STAGE_3 zinciri
sudo iptables -A KNOCKING_STAGE_3 -m recent --name KNOCK_2 --remove -j ACCESS_GRANTED # KNOCK_2'den kaldır ve ACCESS_GRANTED'e yönlendir
Yukarıdaki DROP komutları, knock portlarına yapılan bağlantı denemelerinin yanıt vermemesini (yani kapalı görünmesini) sağlar.
e. Erişim İzni Süresi ve Temizleme
ACCESS listesindeki IP’ler için belirli bir süre sonra erişimi otomatik olarak sonlandırmak önemlidir. Bu, eğer bağlantı kesilirse veya unutulursa açık kalmasını engeller. Bu kuralı INPUT zincirinin başına ekleyeceğiz, ancak ESTABLISHED,RELATED kurallarından sonra.
# ACCESS listesindeki IP'lerin SSH erişimine izin ver
Eğer IP ACCESS listesindeyse ve 60 saniye içinde tekrar bağlantı denemesi yaparsa, zaman damgasını güncelle
Bu kural, ACCESS_GRANTED'dan sonra çalışır, bu yüzden ACCESS_GRANTED zinciri aslında sadece bir kez çağrılır
ve IP'yi ACCESS listesine ekler. Buradaki kural ise o listedeki IP'lere sürekli erişim sağlar.
sudo iptables -A INPUT -m recent --name ACCESS --rcheck --seconds 60 --update -j ACCEPT
Açıklama:
* -m recent --name ACCESS --rcheck --seconds 60 --update: Kaynak IP ACCESS listesinde mi? Son 60 saniye içinde bir kez eşleşti mi? Eğer evet ise, zaman damgasını güncelle.
* -j ACCEPT: Bu IP’den gelen tüm bağlantılara (örneğin SSH) izin ver.
Bu kural, kullanıcının SSH oturumu sırasında veya 60 saniye içinde başka bir bağlantı denemesi yaptığında, ACCESS listesindeki IP’nin zaman damgasını güncelleyerek erişimin devamlılığını sağlar. Eğer 60 saniye içinde hiçbir aktivite olmazsa, IP ACCESS listesinden otomatik olarak çıkarılır ve SSH erişimi kapanır.
f. Hatalı Knock Denemelerini Yakalama
Ana INPUT zincirinde, yukarıdaki knocking kurallarıyla eşleşmeyen her türlü bağlantı denemesini INVALID_KNOCK zincirine yönlendirmeliyiz. Bu, yanlış porta vuran veya doğru sırayı takip etmeyen IP’leri temizler.
# Knocking portlarına (10001, 10002, 10003) gelen ancak kurallarla eşleşmeyen veya
diğer tüm istenmeyen bağlantı denemelerini INVALID_KNOCK zincirine yönlendir.
Bu kural en sonda olmalı.
sudo iptables -A INPUT -j INVALID_KNOCK
Bu kural, INPUT zincirindeki diğer tüm kurallardan sonra gelmelidir.
Tüm Iptables Kuralları (Özet):
Şimdi tüm kuralları mantıksal bir sıraya koyalım. Bu sırayla komutları çalıştırmanız gerekmektedir.
# Mevcut kuralları temizle (Dikkatli olun, kendinizi dışarıda bırakabilirsiniz!)
sudo iptables -F
sudo iptables -X
Varsayılan politikaları ayarla
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
Gerekli temel izinler
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Özel zincirleri oluştur
sudo iptables -N KNOCKING_STAGE_1
sudo iptables -N KNOCKING_STAGE_2
sudo iptables -N KNOCKING_STAGE_3
sudo iptables -N ACCESS_GRANTED
sudo iptables -N INVALID_KNOCK
INVALID_KNOCK zinciri: Hatalı denemelerde tüm listelerden IP'yi kaldır
sudo iptables -A INVALID_KNOCK -m recent --name KNOCK_1 --remove -j LOG --log-prefix "INVALID_KNOCK: KNOCK_1 removed "
sudo iptables -A INVALID_KNOCK -m recent --name KNOCK_2 --remove -j LOG --log-prefix "INVALID_KNOCK: KNOCK_2 removed "
sudo iptables -A INVALID_KNOCK -m recent --name KNOCK_3 --remove -j LOG --log-prefix "INVALID_KNOCK: KNOCK_3 removed "
sudo iptables -A INVALID_KNOCK -m recent --name ACCESS --remove -j LOG --log-prefix "INVALID_KNOCK: ACCESS removed "
sudo iptables -A INVALID_KNOCK -j DROP
ACCESS_GRANTED zinciri: SSH erişimi verir ve ACCESS listesine ekler
sudo iptables -A ACCESS_GRANTED -m recent --name ACCESS --set -j ACCEPT
sudo iptables -A ACCESS_GRANTED -p tcp --dport 22 -j ACCEPT # SSH portu
sudo iptables -A ACCESS_GRANTED -p tcp --dport 80 -j ACCEPT # Diğer servisler
sudo iptables -A ACCESS_GRANTED -p tcp --dport 443 -j ACCEPT # Diğer servisler
sudo iptables -A ACCESS_GRANTED -j RETURN # Geri dön
Knocking aşamaları
1. Knock: TCP 10001
sudo iptables -A INPUT -p tcp --dport 10001 -m recent --name KNOCK_1 --set -j KNOCKING_STAGE_1
sudo iptables -A KNOCKING_STAGE_1 -j DROP
2. Knock: UDP 10002 (KNOCK_1 listesinde olmalı)
sudo iptables -A INPUT -p udp --dport 10002 -m recent --name KNOCK_1 --rcheck --seconds 15 --hitcount 1 \
-m recent --name KNOCK_2 --set -j KNOCKING_STAGE_2
sudo iptables -A KNOCKING_STAGE_2 -m recent --name KNOCK_1 --remove -j DROP
3. Knock: TCP 10003 (KNOCK_2 listesinde olmalı)
sudo iptables -A INPUT -p tcp --dport 10003 -m recent --name KNOCK_2 --rcheck --seconds 15 --hitcount 1 \
-m recent --name ACCESS --set -j KNOCKING_STAGE_3
sudo iptables -A KNOCKING_STAGE_3 -m recent --name KNOCK_2 --remove -j ACCESS_GRANTED
ACCESS listesindeki IP'lerin SSH erişimine izin ver (60 saniye zaman aşımı ile)
sudo iptables -A INPUT -m recent --name ACCESS --rcheck --seconds 60 --update -j ACCEPT
Diğer açık olması gereken portlar (örneğin DNS sorguları için UDP 53)
sudo iptables -A INPUT -p udp --dport 53 -j ACCEPT
Hatalı knock denemelerini yakala ve INVALID_KNOCK zincirine yönlendir
sudo iptables -A INPUT -j INVALID_KNOCK
Bu komutları çalıştırdıktan sonra sudo iptables -L -n -v komutu ile kuralları kontrol edebilirsiniz.
Iptables Kurallarını Kaydetme
iptables kuralları varsayılan olarak kalıcı değildir. Sunucu yeniden başlatıldığında kaybolurlar. Kuralları kalıcı hale getirmek için kaydetmeniz gerekir. Ubuntu’da netfilter-persistent paketi bu işi yapar.
sudo apt update
sudo apt install netfilter-persistent iptables-persistent -y
Kurulum sırasında mevcut kuralları kaydetmek isteyip istemediğiniz sorulacaktır. “Evet” yanıtını verin. Eğer daha sonra kuralları güncellerseniz, manuel olarak kaydetmeniz gerekir:
sudo netfilter-persistent save
Port Knocking Uygulaması (Client Tarafı)
Sunucu tarafında kuralları yapılandırdığımıza göre, istemci tarafından nasıl “kapı çalacağımızı” öğrenmemiz gerekiyor. Bunun için nmap veya netcat gibi basit araçları kullanabiliriz.
1. Nmap Kullanarak Knocking:
nmap, port tarama için popüler bir araçtır, ancak aynı zamanda knocking için de kullanılabilir.
nmap -Pn --host-timeout 200 --max-retries 0 -p 10001,10002U,10003 YOUR_VPS_IP
* -Pn: Host discovery’yi atla (ping atma).
* --host-timeout 200: Her bir host için maksimum bekleme süresi 200ms.
* --max-retries 0: Her porta sadece bir deneme yap.
* -p 10001,10002U,10003: Belirli portları hedefle. U eki UDP portunu belirtir (10002U = UDP 10002).
Bu komut, belirtilen portlara sırayla SYN paketleri gönderir. iptables bu paketleri yakalayacak ve kuralları işleyecektir.
2. Netcat (nc) Kullanarak Knocking:
netcat daha basit bir araçtır ve her bir knock için ayrı ayrı komut çalıştırmanız gerekir.
# 1. Knock (TCP 10001)
nc -vz YOUR_VPS_IP 10001 -w 1
2. Knock (UDP 10002)
nc -vu YOUR_VPS_IP 10002 -w 1
3. Knock (TCP 10003)
nc -vz YOUR_VPS_IP 10003 -w 1
* -v: Ayrıntılı çıktı.
* -z: Tarama modu (veri göndermeden sadece bağlantı denemesi).
* -w 1: 1 saniye zaman aşımı.
* -u: UDP için.
Bu komutları sırayla çalıştırdıktan sonra, 60 saniye içinde SSH bağlantısı kurmayı deneyebilirsiniz:
ssh user@YOUR_VPS_IP
Eğer bağlantı başarılı olursa, port knocking düzgün çalışıyor demektir.
Otomatik Knocking Betiği (Bash):
Her seferinde manuel olarak komut yazmak yerine, küçük bir betik oluşturabilirsiniz:
#!/bin/bash
VPS_IP="YOUR_VPS_IP"
KNOCK_PORTS="10001 10002 10003" # TCP UDP TCP
echo "Port knocking başlatılıyor..."
Knock 1 (TCP)
echo "Knocking TCP port 10001..."
nc -vz $VPS_IP 10001 -w 1 > /dev/null 2>&1
Knock 2 (UDP)
echo "Knocking UDP port 10002..."
nc -vu $VPS_IP 10002 -w 1 > /dev/null 2>&1
Knock 3 (TCP)
echo "Knocking TCP port 10003..."
nc -vz $VPS_IP 10003 -w 1 > /dev/null 2>&1
echo "Knocking tamamlandı. Şimdi SSH ile bağlanmayı deneyebilirsiniz."
ssh user@$VPS_IP
Bu betiği bir dosyaya kaydedip (knock.sh gibi), chmod +x knock.sh ile çalıştırılabilir hale getirdikten sonra ./knock.sh ile kullanabilirsiniz.
Güvenlik Hususları ve En İyi Uygulamalar
Port knocking, güçlü bir güvenlik katmanı sunsa da, bazı hususları göz önünde bulundurmak ve en iyi uygulamaları takip etmek önemlidir.
1. Port Dizisi Karmaşıklığı: Knocking için kullanılan portlar tahmin edilmesi zor, standart olmayan portlar olmalıdır. Örneğin, 10001, 10002 gibi sıralı portlar yerine 4567, 23456, 1234 gibi rastgele portlar seçin. Protokol (TCP/UDP) sırasını da karıştırın.
2. Knock Dizisi Uzunluğu: Daha uzun bir knock dizisi (4-5 port) daha fazla güvenlik sağlar. Her bir aşama, tahmin etme olasılığını katlanarak azaltır.
3. Zaman Aşımı (Timeout) Ayarları: recent modülündeki --seconds parametresi, bir knock aşaması için IP’nin listede ne kadar kalacağını belirler. Bu süreyi çok kısa tutmak, kullanıcı deneyimini kötüleştirebilir; çok uzun tutmak ise saldırganlara daha fazla zaman tanıyabilir. Genellikle 10-30 saniye arası uygun bir aralıktır. Erişim izni için belirlenen süre de (örneğin 60 saniye) dikkatlice seçilmelidir.
4. Günlükleme (Logging): INVALID_KNOCK zincirindeki LOG kuralları sayesinde başarısız knock denemelerini izleyebilirsiniz. Bu, potansiyel saldırı girişimlerini veya yanlış yapılandırmaları tespit etmenize yardımcı olur. /var/log/syslog veya /var/log/kern.log dosyalarını düzenli olarak kontrol edin.
5. DDoS Saldırılarına Karşı Direnç: Port knocking, brute-force saldırılarına karşı etkilidir ancak yoğun bir DDoS (Distributed Denial of Service) saldırısına karşı tek başına yeterli değildir. iptables‘ın recent modülü, belirli bir IP’den gelen çok sayıda denemeyi bir dereceye kadar sınırlayabilir, ancak büyük ölçekli bir DDoS, sunucunuzu yine de yorabilir. DDoS koruması için ek çözümler (CDN, özel donanım/yazılım) gerekebilir.
6. Tek Yönlü Knocking: Genellikle sadece SYN (TCP) veya UDP paketleri kullanılarak knocking yapılır. Sunucunun bu portlara yanıt vermemesi (yani DROP hedefi kullanılması), portların dışarıdan kapalı görünmesini sağlar ve bilgi sızmasını önler.
7. Servislerin Güvenliği: Port knocking, bir ek güvenlik katmanıdır. Asıl servislerinizin (SSH, web sunucusu vb.) kendilerinin de güvenli olduğundan emin olun. Güçlü parolalar, SSH anahtar tabanlı kimlik doğrulama, fail2ban gibi araçlar hala gereklidir.
8. IP Adresi Kısıtlamaları: Mümkünse, port knocking’i sadece belirli güvenilir IP adreslerinden (statik IP’niz varsa) gelen bağlantılara izin verecek şekilde yapılandırabilirsiniz. Bu, genel güvenlik seviyesini daha da artırır.
9. Kurtarma Planı: Yanlış yapılandırma durumunda kendinizi sunucudan kilitleme riski her zaman vardır. Bu nedenle, VPS sağlayıcınızın web tabanlı konsol erişimine (VNC veya benzeri) sahip olduğunuzdan emin olun. Bu, kritik bir güvenlik önlemidir.
10. Test Etme: Kuralları uygulamadan önce veya uyguladıktan hemen sonra, farklı senaryoları (doğru knock, yanlış knock, eksik knock, zaman aşımı) test ederek sistemin beklendiği gibi çalıştığından emin olun.
Avantajlar ve Dezavantajlar
Avantajlar:
1. Yüksek Güvenlik: Açık portları gizleyerek saldırı yüzeyini önemli ölçüde azaltır. Otomatik tarayıcılar ve botlar için sunucunuz “ölü” görünür.
2. Brute-Force Koruması: SSH gibi servislere yönelik brute-force saldırılarını daha başlamadan engeller.
3. Kaynak Verimliliği: iptables‘ın yerleşik recent modülünü kullandığı için ek bir daemon çalıştırmaya gerek kalmaz, bu da sistem kaynaklarını minimal düzeyde tüketir.
4. Esneklik: iptables kuralları sayesinde, knocking dizisini, zaman aşımlarını ve erişim verilecek servisleri tamamen kendi ihtiyaçlarınıza göre özelleştirebilirsiniz.
5. Obscurity (Gizlilik): Güvenliği gizlilikle artırır. Bir saldırgan, hangi portların açılması gerektiğini veya hangi sırayla vurulması gerektiğini bilmediği sürece erişim sağlayamaz.
Dezavantajlar:
1. Karmaşık Yapılandırma: iptables kuralları, özellikle recent modülü ile birlikte kullanıldığında, doğru bir şekilde yapılandırmak ve hata ayıklamak karmaşık olabilir. Yanlış bir kural, kendinizi sunucudan kilitlemenize neden olabilir.
2. Erişim Sorunları: Eğer knocking dizisini unutursanız veya yanlış girerseniz, sunucunuza erişim sağlayamayabilirsiniz. Bu durum, özellikle acil durumlarda sorun yaratabilir.
3. Paket Yakalama (Packet Sniffing) Zafiyeti: Eğer knocking dizisi şifrelenmemiş bir ağ üzerinden gönderilirse, kötü niyetli bir kişi paket yakalama (packet sniffing) yoluyla bu diziyi öğrenebilir. Bu nedenle, knocking dizisini mümkünse güvenli ağlar üzerinden kullanmak veya ek güvenlik önlemleri almak önemlidir.
4. DDoS’a Tam Dirençsizlik: Port knocking, hedefli DDoS saldırılarına karşı tam bir koruma sağlamaz. Yoğun trafik, iptables kurallarını işleyen sunucuyu yine de yorabilir.
5. İstemci Tarafı Araç Gereksinimi: Sunucuya erişmek için istemci tarafında belirli araçlar (nmap, netcat veya özel bir betik) kullanmanız gerekir. Bu, mobil cihazlardan veya kısıtlı ortamlardan erişimi zorlaştırabilir.
6. Kullanıcı Deneyimi: Her bağlantıdan önce knocking yapmak, özellikle sık sık bağlantı kuran kullanıcılar için ek bir adım ve potansiyel bir gecikme anlamına gelir.
Bu avantaj ve dezavantajları göz önünde bulundurarak, port knocking’in sizin güvenlik modelinize uygun olup olmadığına karar vermelisiniz. Genellikle, diğer güvenlik önlemleriyle birlikte kullanıldığında çok güçlü bir katman sağlar.
Sonuç
Bu makalede, Ubuntu VPS’inizde sadece iptables ve recent modülünü kullanarak port knocking’i nasıl yapılandıracağınızı ayrıntılı bir şekilde inceledik. Port knocking, sunucunuzun açık portlarını dış dünyaya karşı gizleyerek, otomatik tarayıcılardan ve brute-force saldırılarından korunmak için oldukça etkili bir yöntemdir.
Adım adım yapılandırma sürecini takip ederek, özel iptables zincirleri oluşturduk, knocking aşamalarını tanımladık ve recent modülünün set, rcheck, update ve remove parametrelerini kullanarak karmaşık bir erişim kontrol mekanizması kurduk. Ayrıca, istemci tarafından nmap ve netcat gibi araçlarla knocking işlemini nasıl gerçekleştireceğinizi ve bu süreci otomatikleştirmek için basit bir betik örneği sunduk.
Unutulmamalıdır ki, port knocking tek başına bir güvenlik çözümü değildir, ancak mevcut güvenlik önlemlerinize (SSH anahtarları, güçlü parolalar, fail2ban vb.) güçlü bir ek katman sağlar. Doğru yapılandırma, karmaşık bir knock dizisi, uygun zaman aşımı ayarları ve düzenli günlük denetimi ile sunucunuzun güvenliğini önemli ölçüde artırabilirsiniz. Her zaman olduğu gibi, güvenlik duvarı kurallarını değiştirirken dikkatli olun ve kendinizi sunucudan kilitlememek için bir kurtarma planınız olduğundan emin olun. Bu rehber, VPS’inizin güvenliğini bir üst seviyeye taşımak için size sağlam bir temel sunmaktadır.