Linux'un güçlü bir güvenlik duvarı var. Giriş seviyesinde bazı noktalara değinmek istiyorum.
Bilgisayar trafiğinin 3 temel zincirden oluştuğu düşünülmüş: giriş (INPUT), çıkış (OUTPUT) ve yönlendirme (FORWARD). Mevcut kuralları görmek için
# iptables -L
veya daha ayrıntılı bilgiler için ek olarak -v (verbose) kullanılabilir. Bu anahtarla her kural ile engellenen paket sayıları gibi istatistikleri sıfırlamak için -Z anahtarı kullanılır. Her satırın numaralandırarak listelemek için
# iptables -L --line-numbers
kullanılabilir. Satır numararaları belli bir kuralı silmek veya öncesi/sonrasına yeni kural eklemek için kullanılır.
Sadece INPUT zincirinin kurallarını görmek için
# iptables -L INPUT
Farklı bir şekilde kuralların listesini almak için -S anahtarı kullanılabilir.
# iptables -S
Bir güvenlik duvarının temel amacı istenmeyen trafiği engellemektir. Bu trafik de genelde gelen trafiktir. Dolayısıyla giriş (INPUT) zincirine odaklanacağız. Çıkış (OUTPUT) ve yönlendirme (FORWARD) trafiklerinin varsayılan olarak izin verilen yapıda olduklarını kabul edeceğiz.
Bilgisayarımızda dış dünyayla paylaşacak hiçbir şeyimiz (bir web veya ssh sunucu) olmayabilir. Bu durumda gelen tüm trafiği engelle diyebiliriz:
# iptables -P INPUT DROP
Ama bu durumda Firefox'un internete bağlanma isteklerine alacağı cevapları bile engellemiş oluruz. Bu durumda sadece bunun gibi bizim bilgisayarımızdan dış dünyaya gönderilen istekler sonucu oluşturulmuş (ESTABLISHED) veya süre gelen bağlantılarla ilgili (RELATED) bir trafiğe izin verebilmek için şu komut gerekir:
# iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Eğer bir de bilgisayarımızda örneğin bir ssh sunucusu varsa ve buna ulaşmak istiyorsak varsayılan 22 portu üzerinden aşağıdaki gibi bir kural yazabiliriz:
# iptables -A INPUT -p tcp --dport 22 -j ACCEPT
İlk satırda verdiğim ve tüm gelen bağlantıları engelleyen varsayılan politikanın yerine, kurallar dizisinin en sonunda engelle kuralı da ekleyebiliriz:
# iptables -A INPUT -j DROP
Bu şekilde giriş zinciri için varsayılan politika izin ver (ACCEPT) olarak bırakılabilir, ama izin verdiğimiz 2 kural haricindeki bütün trafiği de en son girdiğimiz kuralla engellemiş de oluruz. Bunun tek avantajı, bir sebeple bütün kuralları silerek güvenlik duvarını sıfırlama ihtiyacı durumunda kendimizi de makineye uzaktan bağlanamaz durumda bırakmamaktır.
Listede INPUT zincirindeki 3 numaralı kuralı silmek için
# input -D INPUT 3
veya bütün kuralları (tüm zincirlerdeki) silmek için
# iptables -F
kullanabiliriz.
Mevcut kuralların bir yedeğini almak istersek
# iptables-save > fw_state.txt
Benzer şekilde bu dosyadan durumu geri yüklemek için de
# iptables-restore < fw_state.txt
kullanabiliz.
iptables komutu kullanarak oluşturduğumuz kurallar, geçicidir ve bir sonraki tekrar başlatma sonrasında silinirler. Bunları kuralları
# iptables-save
komutu ile kalıcı yapabiliriz.
Bunların dışında eğer gelen ping'lere cevap verilmesini gerektiren bir durum varsa (elbette en sonda bir DROP kuralı kullandıysak bundan önce bir yerlerde)
# iptables -A INPUT -p icmp -j ACCEPT
ve eğer engellenen trafiğin bir kaydını tutmak istersek de (kuralın yeri yukarıdaki gibi)
# iptables -A INPUT -j LOG --log-prefix "FW-REJECT "
kullanılabilir.
Başka bir güzel özellik de herhangi bir port için "bağlantı sınırı" (rate limitting) yapabilmesi. Örneğin 22/tcp (SSH) portu üzerinden yapılan bağlantılar için 60 saniyede 5 adet "yeni bağlantı" sınırlaması uygulamak için aşağıdaki satırlar yeterli.
# Yeni SSH bağlantıları için bir SSH listesi oluşturur
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
# Aynı IP'den son 60 saniye içinde 5 veya daha fazla yeni bağlantı girişimi olmuşsa bir kayıt tutar
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 5 \
--rttl --name SSH -j LOG --log-prefix 'SSH-HIT-RATE: '
# Aynı IP'den son 60 saniye içinde 5 veya daha fazla yeni bağlantı girişimi olmuşsa paketi kabul etmez (drop)
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 5 \
--rttl --name SSH -j DROP
Bu komut satırı arayüzü ilk başta biraz karmaşık geldiği için farklı linux dağıtımlarının bunu yönetmek için farklı çözümleri vardır. Örneğin Fedora ve türevleri firewalld'yi [4] kullanır. Bu arayüz üzerinden güvenlik duvarının mevcut durumunu görmek için
# firewall-cmd --state
kullanılır. Bunun sonucunda tek satırlık 'running' dönüyorsa güvenlik duvarı devrededir. Burada başka bir şey yazıyorsa systemctl ile firewalld.service durumu kontrol edilmelidir. Mevcut profili ve ayrıntıları görmek için
# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33
sources:
services: dhcpv6-client mdns ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
Profiller burada zone olarak isimlendirilirler. Mevcut zone'umuz ilk satırda yazan public zone'udur. Zone'ların listesini almak için (boşlukla ayrılmış tek satırlık liste)
# firewall-cmd --get-zones
ya da daha ayrıntılı bir bilgi için
# firewall-cmd --list-all-zones
Güvenlik duvarı üzerinden akan trafiği kontrol etmek için kaynak ve hedef IP adresleri, portlar ve hizmetler gibi kavramlar kullanılır. Örneğin firewall üzerinde basit bir port (örneğin TCP 514) açmak için
# firewall-cmd --add-port=514/tcp
kullanılır. Ya da bunu bir hizmet olarak yapmak için --add-service kullanılabilir:
# firewall-cmd --add-service=syslog
Benzer şekilde tanımlanmış hizmetlerin listesini görebilmek için
# firewall-cmd --list-services
kullanılabilir. Firewalld'nin iki modu vardır. Birincisi şu anda çalışan ayarları ifade eden çalışma zamanı (runtime) modu. Bu mod kaydedilmezse bir sonraki tekrar başlatmada kaybolur. Diğer mod ise en son kaydedilmeden sonraki durumu içeren kalıcı (permanent) moddur. Varsayılan olarak firewall-cmd ile yaptığımız tüm işlemler çalışma zamanı modunu değiştirir. Yaptığımız işlemlerin kalıcı modu etkilemesi için --permanent parametresi kullanılır. Çalışma zamanı mod için bir parametre yoktur, varsayılan olarak komutlar çalışma zamanını etkiler.
Çalışma zamanında yapılan ayarları kalıcı yapmak için
# firewall-cmd --runtime-to-permanent
kullanılır. Ya da kalıcı modda yapılan ayarları çalışma zamanına aktarmak için
# firewall-cmd --reload
kullanılır.
Ubuntu'da ise ufw (uncomplicated firewall) kullanılır. Durum kontrolü için
# ufw status
Güvenlik duvarını etkinleştirmek için
# ufw enable
22 numaralı TCP portunu açmak için
# ufw allow 22/TCP
Bir IP adresini engellemek için
# ufw deny from xxx.xxx.xxx.xxx to any
Her komut sonucu zaten kaydettiği için save gibi komutlar yok.
İleri Seviye Bazı teknikler
Dünya açtığınız bir hizmetin yaşayabileceği riskler çok büyüktür. Çeşitli tip ve sayıda port taraması, keşif yöntemleri vs maruz kalır. [5]'te söylendiği gibi karmaşık DDoS saldırılarına karşı sadece iptables'a güvenmemeliyiz. Ama en azından daha yetkinliğinin ilk günlerini yaşayan bir yavru hacker'ın (script kiddy veya lamer) kötü emellerine alet edilmekten kurtulmak için bazı şeyler yapılabilir. Şunlar önerilmiş:
# iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
Bu kural ile TCP bitlerinden hiçbirisi 1 olmayan paketlerin göz ardı edilmesi sağlanmış. İletişimi başlatan ilk paketlerin mutlaka bazı TCP özel alanları (TCP flags olarak bilinen) 1 olmalı. Olmayanlar, keşif amaçlı port taraması vs için gönderilmiş öncü saldırılardır.
# iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
Bu kural ile SYN-flood saldırısının engellenmesi sağlanır.
# iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
Bu kural ile de XMAS saldırısı olarak bilinen saldırı türünden korunma sğlanır.
---
[3] https://www.hostinger.com/tutorials/iptables-tutorial
[4] https://docs.fedoraproject.org/en-US/quick-docs/firewalld/
[5] https://www.digitalocean.com/community/tutorials/how-to-set-up-a-basic-iptables-firewall-on-centos-6
[6] https://www.digitalocean.com/community/tutorials/how-to-list-and-delete-iptables-firewall-rules
[7] https://linuxize.com/post/how-to-setup-a-firewall-with-firewalld-on-centos-7/
Hiç yorum yok:
Yorum Gönder