Saldırı haritasında tek bir ülkenin üzerinde yoğun bir leke var ve «ülkeyi tümüyle yasaklayalım» kuralı kendiliğinden akla geliyor. Bu neredeyse hiçbir şey kazandırmaz: çıkış ülkesini değiştirmek saldırgana birkaç dakikaya mal olur, yasağın altında ise kendi ziyaretçileriniz ve yolculuktayken siz kalırsınız. Daha kötüsü, tek bir buluttan gelen görünür tarayıcı, engelden sonra ev adreslerine taşınır ve insanlardan ayırt edilemez hale gelir.
Aşağıda, aynı sunucuda gerçekten sonuç veren beş adım var: tarayıcıları kesmek, hızı sınırlamak, gerekli olanı kesmemek ve gerçekten gerekiyorsa doğru engellemek. Hepsi tek oturuşta denetlenip kurulabilir.
Adım 1. Lekeyi aslında kimin oluşturduğuna bakın
Önce istek günlüğünü bulun. Birkaç site barındıran bir sunucuda access.log çoğu zaman boştur, kayıtlar ise ilgili sanal konağın günlüğüne gider:
sudo ls -lS /var/log/apache2/*access*.log /var/log/apache2/*requests*.log 2>/dev/null
Sonraki bütün komutlarda bu listenin başına çıkan dosya yazılır. Önce gün içindeki önde gelen adresler, sonra en üstte duranın tam olarak ne istediği:
sudo awk '{print $1}' /var/log/apache2/access.log | sort | uniq -c | sort -rn | head -20
sudo grep '^203\.0\.113\.' /var/log/apache2/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20
İkinci komut asıl soruyu yanıtlar. Çıktıda kendi sitenizin onlarca farklı sayfası varsa bu bir içerik toplayıcıdır: zararsızdır ve onu ziyaretçi saymamak yeterlidir. Orada /wp-login.php, /.env, /phpmyadmin ve sizde hiç bulunmayan başka şeyler varsa bu bir tarayıcıdır ve onunla adım 2 ilgilenir. Nginx’te günlükler /var/log/nginx/ dizinindedir, alanlar aynıdır.
Adım 2. Sizde olmayan şeylere yapılan isteklere karşı bir jail
İstenen yol taklit edilemez — adresin ve User-Agent’ın aksine niyetin kendisidir. Süzgeç, /etc/fail2ban/filter.d/web-probes.local:
[Definition]
failregex = ^<HOST> .* "(GET|POST|HEAD) /(wp-login\.php|wp-admin|xmlrpc\.php|\.env|\.git/|phpmyadmin|administrator/)
ignoreregex =
Jail, /etc/fail2ban/jail.d/web-probes.local:
[web-probes]
enabled = true
port = http,https
filter = web-probes
logpath = /var/log/apache2/*access.log
maxretry = 1
findtime = 1h
bantime = 1d
Burada maxretry = 1 yerindedir: başkasının yönetim paneline rastgele girilmez. Uygulayın ve süzgecin kendi günlüğünüzdeki satırları yakaladığından emin olun:
sudo fail2ban-regex /var/log/apache2/access.log /etc/fail2ban/filter.d/web-probes.local
sudo systemctl reload fail2ban && sudo fail2ban-client status web-probes
Adım 3. Hızı sınırlayın
Tarayıcı da gezgin de hangi ülkeden geldiğinden bağımsız olarak hızıyla ele verir kendini. Tek bir adresten dakikada otuz sayfa, katalogu karıştıran bir insanı etkilemeyen bir eşiktir:
[http-flood]
enabled = true
port = http,https
filter = apache-overflows
logpath = /var/log/apache2/site_access.log
maxretry = 30
findtime = 60
bantime = 1h
Belirleyici ayrıntı, logpath satırında hangi günlüğün yazdığıdır. Desenin kapsamına yönetim panelinin ya da yönetim bölümünün günlüğü girerse kendinizi engellersiniz: oradaki tek bir sayfa, biçem ve betik dosyaları için bir düzine istek sürükler, otuz istek ise iki tıklamada birikir. Bu yüzden panele, jail’in desenine uymayan ayrı bir günlük dosyası verilir; durağan dosyalara ise uzun bir önbellek süresi verilir ki tarayıcı her sayfa geçişinde onları yeniden istemesin. Yine de olduysa belirtisi şudur: HTML gelir, görünüm gelmez, sayfa asılı kalır. Engeli kaldırmak için:
sudo fail2ban-client set http-flood unbanip 203.0.113.10
Adım 4. Kesilmemesi gerekeni koruyun
Engelleri açmadan önce ayrık tutulacakları yazın — yoksa ilk olarak gerekli olan onların altına düşer:
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 203.0.113.0/24 66.249.64.0/19
Bu satırda mutlaka bulunması gerekenler ve nedenleri:
- Kendi adresiniz ya da ofisin alt ağı. Sunucuya erişimi yitirmenin en sık nedeni saldırı değil, kendi kuralınızdır;
66.249.64.0/19aralığı. Google’ın arama robotu User-Agent ile tanınır, ancak onun JavaScript çalıştıran bölümü sıradan birChrome/Linuxolarak gelir ve kendini tanıtmaz. «Veri merkezlerinden gelen trafiği engelleyelim» türünden her kural tam da onu vurur, ardından sayfalar sessizce dizinden düşer. Şüpheli bir adres ters sorguyla denetlenebilir:dig -x 66.249.66.1 +shortkomutugooglebot.combölgesinde bir ad döndürmelidir;- Ödeme bildirimlerinin adresleri. Ödeme sistemlerinin webhook’ları AWS ve Azure sunucularından gelir. Bu bulutları tümüyle kapatırsanız ödeme onayları ulaşmaz olur ve bunu, bir müşteri paranın çekildiğini ama erişimin olmadığını yazdığında öğrenirsiniz. Aralıklar ödeme sağlayıcınızın belgelerinden alınır.
Adım 5. Engel yine de gerekiyorsa — ülkeyi değil, alt ağı engelleyin
Tek bir ağdan gelen, günlerce süren ve aynı türden isteklerle birlikte giden kalıcı bir yoğunlaşma, bir liste üzerinden ilerleyen tek bir uygulayıcıdır. Bu durum noktasal ve süreli olarak engellenir:
sudo ufw deny from 198.51.100.0/22 to any
sudo ufw status numbered
İkinci komutla kural numarasını not edin: engel daha sonra tam da onun üzerinden kaldırılacaktır, sudo ufw delete <numara>. Kendinizle bir süre üzerinde anlaşın — örneğin bir ay — ve kaldırmayı takvime yazın. «Sonsuza dek» konan kurallar bir yıl sonra kimsenin dokunmaya cesaret edemediği bir listeye dönüşür, çünkü o adreslerin oraya neden düştüğünü kimse hatırlamaz.
Hangi alt ağın engelleneceği, ilk adımdaki adresten öğrenilebilir: whois 198.51.100.17 | grep -iE 'route|cidr|netname'.
Bu beş adımdan sonra ne değişir
Tarayıcılar kökene göre değil niyete göre kesilir ve ilk istekte yakalanır. Gezginler hız sınırına çarpar. Arama robotu ve ödeme bildirimleri geçmeye devam eder. Geniş kalan tek engel noktasaldır, bilinen bir süresi ve anlaşılır bir nedeni vardır.
Harita bu arada yok olmaz, ama rolü değişir: ülkeleri kapatmak için değil, yoğunlaşmayı fark etmek ve onu bir hafta öncesiyle karşılaştırmak için gereklidir. Bunun için geçmiş gerekir, o günün anlık görüntüsü değil. Böyle bir haritanın engel günlüğü ve açık bağlantı noktaları listesiyle birlikte nasıl göründüğünü aşağıdaki tanıtım sayfaları gösteriyor.