Cum sa opriți atacuri brute prin iptables
Conform Wikipedia, definiția unui atac brut bazat pe dicționare este:
În criptanaliză și securitatea computerelor, un atac de dicționar este o tehnică prin care se poate sparge un cifru sau un mecanism de autentificare prin încercarea de a determina cheia sa de decriptare sau fraza de protecție prin căutarea de posibilități probabile.
Un atac de dicționar utilizează o tehnică de tip brute-force cu încercări succesive ale tuturor cuvintelor dintr-o listă exhaustivă denumită dicționar (dintr-o listă de valori pre-aranjate). În contrast cu un atac de tip brute-force normal, în care este căutată în mod sistematic o cheie-spațiu proporțională, un atac dicționar încearcă doar acele posibilități care sunt cele mai probabile în a reuși, derivate de obicei dintr-o listă de cuvinte, de exemplu un dicționar (devenind prin urmare un atac de dicționar), sau o biblie, etc. În general, atacurile de dicționar reușesc deoarece foarte multe persoane au tendința de a alege parole scurte (de șapte sau mai puține caractere), cuvinte unice regăsite în dicționare sau variațiuni de cuvinte simple și predictibile, cum ar fi adăugarea unei cifre.
Deci, după cum vedeți, avem două tipuri de atacuri tip brute-force, cele care utilizează un dicționar și cele care nu. Totuși, există tehnici prin care ne putem proteja de amândouă tipurile de atacuri.
Una dintre aceste tehnici este folosirea iptables din mediul Linux pentru a bloca un anumit IP, care This technique, uses iptables to block a particular IP, care a trecut pragul de un anumit număr de conexiuni într-o anumită perioadă de timp.
Iată câteva exemple cu reguli iptables de bază prin care se poate proteja un server web de atacuri brute-force. Aceste exemple pot fi adaptate și pentru alte scenarii.
Ca regulă de bază, vom deschide doar porturile 80 (http) și 22 (ssh)
Exemplul următor poate fi folosit sub formă de script care poate rula de fiecare dată când pornește serverul nostru sau, poate fi configurat să ruleze iptables ca daemon, metodă exemplificată mai târziu.
iptables -F
iptables -A INPUT -i lo -p all -j ACCEPT
iptables -A OUTPUT -o lo -p all -j ACCEPT
iptables -A INPUT -i eth0 -m state –state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp ! –tcp-option 2 -j REJECT –reject-with tcp-reset
iptables -A INPUT -p tcp –dport ssh -j ACCEPT
iptables -A INPUT -p tcp –dport www -j ACCEPT
iptables -P INPUT DROP
Acest exemplu de script iptables va închide toate porturile cu excepția ssh și www, însă serverul nostru încă este deschis către atacuri brute-force. Parte din protecția la atacuri o putem realiza prin adăugarea a două noi reguli care vor permite doar un anumit număr de conexiuni la serverul nostru de la un anumit IP.
Oprirea atacurilor brute-force
Iată un exemplu prin care putem opri atacuri de tip brute-force.
iptables -F
iptables -A INPUT -i lo -p all -j ACCEPT
iptables -A OUTPUT -o lo -p all -j ACCEPT
iptables -A INPUT -i eth0 -m state –state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp ! –tcp-option 2 -j REJECT –reject-with tcp-reset
iptables -A INPUT -p tcp –dport ssh -j ACCEPT
iptables -A INPUT -p tcp –dport www -j ACCEPT
iptables -I INPUT -p tcp –dport 22 -i eth0 -m state –state NEW -m recent –set
iptables -I INPUT -p tcp –dport 22 -i eth0 -m state –state NEW -m recent –update –seconds 600
–hitcount 2 -j DROP
iptables -P INPUT DROP
Dacă rulăm acuma comanda sudo iptables -L (listarea regulilor), vom primi următorul output:
Chain INPUT (policy DROP)
target prot opt source destination
DROP tcp — anywhere anywhere tcp dpt:ssh state NEW recent: UPDATE seconds: 600 hit_count: 2 name: DEFAULT side: source
tcp — anywhere anywhere tcp dpt:ssh state NEW recent: SET name: DEFAULT side: source
ACCEPT all — anywhere anywhere
ACCEPT all — anywhere anywhere state RELATED,ESTABLISHED
REJECT tcp — anywhere anywhere tcp option=!2 reject-with tcp-reset
ACCEPT tcp — anywhere anywhere tcp dpt:ssh
ACCEPT tcp — anywhere anywhere tcp dpt:wwwChain FORWARD (policy ACCEPT)
target prot opt source destinationChain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all — anywhere anywhere
Ultimele două rânduri fac de fapt toată treaba.
Iată o explicație simplă pentru ce fac practic cele două rânduri de reguli:
Prima regulă:
iptables -I INPUT -p tcp –dport 22 -i eth0 -m state –state NEW -m recent –set
Inițiază o tabelă care conține fiecare IP care inițiază o conexiune la portul ssh.
A doua regulă:
iptables -I INPUT -p tcp –dport 22 -i eth0 -m state –state NEW -m recent –update –seconds 600
–hitcount 2 -j DROP
Numără câte conexiuni realizează fiecare IP către serverul nostru într-un interval de 600 de secunde, iar dacă numărul de conexiuni este mai mare de două (hitcount), serverul nu va mai accepta alte conexiuni de la respectivul IP pentru următoarele 600 de secunde.
Valorile se pot ajusta în funție de necesități. De exemplu, se poate mări timpul de restricție de 600 de secunde sau modifica numărul maxim de conexiuni de la care se aplică restricția.
Automatizare
Dacă serverul nostru rulează Debian sau Ubuntu, pentru a automatiza acest script, putem rula următoarea comandă:
sudo /etc/init.d/iptables save
Dacă serverul rulează Arch Linux, comanda va fi următoarea:
sudo /etc/rc.d/iptables save
Nu uitați să adăugați iptable la partea daemons din fișierul /etc/rc.conf.
Jurnalizarea conexiunilor
Dacă dorim să păstrăm un jurnal al conexiunilor cu eroare, vom modifica script-ul în felul următor:
iptables -F
iptables -A INPUT -i lo -p all -j ACCEPT
iptables -A OUTPUT -o lo -p all -j ACCEPT
iptables -A INPUT -i eth0 -m state –state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp ! –tcp-option 2 -j REJECT –reject-with tcp-reset
iptables -A INPUT -p tcp –dport ssh -j ACCEPT
iptables -A INPUT -p tcp –dport www -j ACCEPT
iptables -I INPUT -p tcp –dport 22 -i eth0 -m state –state NEW -m recent –set
iptables -I INPUT -p tcp –dport 22 -i eth0 -m state –state NEW -m recent –update –seconds 600
–hitcount 2 -j LOG
iptables -I INPUT -p tcp –dport 22 -i eth0 -m state –state NEW -m recent –update –seconds 600
–hitcount 3 -j DROP
iptables -P INPUT DROP
Observați că linia LOG are o valoare hitcount mai mică decât linia DROP, asta va face ca iptables să scrie o linie precum (exemplu):
Apr 26 20:44:44 arch kernel: IN=eth0 OUT= MAC=00:19:d1:ea:e6:3f:00:11:2f:8f:f8:f8:08:00 SRC=97.107.x.x DST=200.87.x.x LEN=60 TOS=0x00 PREC=0x00 TTL=52 ID=37839 DF PROTO=TCP SPT=50094 DPT=22 WINDOW=5840 RES=0x00 SYN URGP=0
în fișierul /var/log/messages sau /var/log/iptables.log în funcție de distribuția Linux folosită.
Aceste reguli funcționează foarte bine pentru ssh. Exemplele date în acest articol sunt exemple mai restrictive (de exemplu pentru scp), dar prin modificarea unor valori precum numărul de conexiuni din 2 în 8 sau 10 pentru ssh pot oferi o libertate mai mare.
De asemenea, dacă dorim să utilizăm iptables pentru portul 80 (www), vom folosi –limit
Apache sau alte servere web pot manipula foarte multe conexiuni per IP, așadar chiar și aceste reguli pot fi poate puțin prea restrictive:
iptables -I INPUT -p tcp –dport 80 -m state –state NEW -m limit –limit 30/minute –limit -burst 5 -j ACCEPT
Dar, modul de configurație este la urma urmelor la latitudinea fiecăruia, diferind de la caz la caz în funcție de necesități.