Ochrana SSH démona proti útokům (3)
Kromě vypnutí autentizace na základě jména a hesla v konfiguraci ssh démona a povolení autentizace na základě klíčů (viz 2. díl) a kromě použití programu sshdfilter nebo podobného na blokování portu 22 (s využitím iptables) při detekci většího počtu neúspěšných pokusů o přihlášení (viz 1. díl) můžeme využít ještě další možnost jak ochánit ssh démona před útoky a přitom si nijak výrazně neomezit vzdálený přístup. Jedná se o ochranu pomocí tzv. port knockingu. Výhodou této metody je, že si vystačíme pouze se stavovým filtrem, tedy s iptables.
Jak to funguje?
Pomocí iptables a především modulu recent
můžeme firewall nastavit tak, že se port 22 otevře (obvykle pouze na pár vteřin) na základě "zaťukání"
(port knockingu) na námi stanovené porty (například: 250 100 150 200). Není
to sice nejpohodlnější metoda, ale když si napíšeme jednoduchý skript, který
za nás například pomocí programu telnet
nebo nmap
dané porty kontaktuje a poté se přes otevřený ssh port připojí k ssh serveru,
tak to zase nijak pracné nebude.
Nastavení
#!/bin/bash # smazeme predchozi nastaveni pravidel a nami nadefinovanych retezcu /sbin/iptables -F /sbin/iptables -X # nastavime defaultni politiky /sbin/iptables -P INPUT DROP /sbin/iptables -P FORWARD DROP /sbin/iptables -P OUTPUT ACCEPT /sbin/iptables -N MYKNOCK2 /sbin/iptables -A MYKNOCK2 -m recent --name KNOCK1 --remove /sbin/iptables -A MYKNOCK2 -m recent --name KNOCK2 --set /sbin/iptables -A MYKNOCK2 -j LOG --log-prefix "MYKNOCK2: " /sbin/iptables -N MYKNOCK3 /sbin/iptables -A MYKNOCK3 -m recent --name KNOCK2 --remove /sbin/iptables -A MYKNOCK3 -m recent --name KNOCK3 --set /sbin/iptables -A MYKNOCK3 -j LOG --log-prefix "MYKNOCK3: " /sbin/iptables -N MYKNOCK4 /sbin/iptables -A MYKNOCK4 -m recent --name KNOCK3 --remove /sbin/iptables -A MYKNOCK4 -m recent --name KNOCK4 --set /sbin/iptables -A MYKNOCK4 -j LOG --log-prefix "MYKNOCK4: " /sbin/iptables -A INPUT -m recent --update --name KNOCK1 /sbin/iptables -A INPUT -m tcp -p tcp --dport 250 -m recent --set --name KNOCK1 /sbin/iptables -A INPUT -m tcp -p tcp --dport 100 -m recent --rcheck --name KNOCK1 -j MYKNOCK2 /sbin/iptables -A INPUT -m tcp -p tcp --dport 150 -m recent --rcheck --name KNOCK2 -j MYKNOCK3 /sbin/iptables -A INPUT -m tcp -p tcp --dport 200 -m recent --rcheck --name KNOCK3 -j MYKNOCK4 /sbin/iptables -A INPUT -p tcp --dport 22 -m recent --rcheck --seconds 5 --name KNOCK4 -j ACCEPT /sbin/iptables -A INPUT -i lo -j ACCEPT /sbin/iptables -A INPUT -m icmp -p icmp --icmp-type any -j ACCEPT /sbin/iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT /sbin/iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited
Případný výstup z programu iptables-save bude vypadat následovně:
# Generated by iptables-save v1.3.5 on Thu Oct 19 16:26:20 2006 *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] :MYKNOCK2 - [0:0] :MYKNOCK3 - [0:0] :MYKNOCK4 - [0:0] -A INPUT -m recent --update --name KNOCK1 --rsource -A INPUT -p tcp -m tcp --dport 250 -m recent --set --name KNOCK1 --rsource -A INPUT -p tcp -m tcp --dport 100 -m recent --rcheck --name KNOCK1 --rsource -j MYKNOCK2 -A INPUT -p tcp -m tcp --dport 150 -m recent --rcheck --name KNOCK2 --rsource -j MYKNOCK3 -A INPUT -p tcp -m tcp --dport 200 -m recent --rcheck --name KNOCK3 --rsource -j MYKNOCK4 -A INPUT -p tcp -m tcp --dport 22 -m recent --rcheck --seconds 5 --name KNOCK4 --rsource -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p icmp -m icmp --icmp-type any -j ACCEPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A MYKNOCK2 -m recent --remove --name KNOCK1 --rsource -A MYKNOCK2 -m recent --set --name KNOCK2 --rsource -A MYKNOCK2 -j LOG --log-prefix "MYKNOCK2: " -A MYKNOCK3 -m recent --remove --name KNOCK2 --rsource -A MYKNOCK3 -m recent --set --name KNOCK3 --rsource -A MYKNOCK3 -j LOG --log-prefix "MYKNOCK3: " -A MYKNOCK4 -m recent --remove --name KNOCK3 --rsource -A MYKNOCK4 -m recent --set --name KNOCK4 --rsource -A MYKNOCK4 -j LOG --log-prefix "MYKNOCK4: " COMMIT # Completed on Thu Oct 19 16:26:20 2006
Skript pro port knocking pomocí telnetu a následné připojení pomocí ssh klienta na danou IP adresu. Tento skript je jen jako názorný příklad, samozřejmě by se dal podstatně vylepšit a parametrizovat.
#!/bin/bash for port in 250 100 150 200 do telnet 192.168.2.100 $port > /dev/null 2>&1; done ssh ondra@192.168.2.100
Druhý skript se stejnou funkčností, ale využívající místo telnetu program nmap.
for port in 250 100 150 200 do nmap -P0 -sT -p $port --host_timeout 250 192.168.2.100 > /dev/null 2>&1; done ssh ondra@192.168.2.100