SSH absichern und Mehr mit knockd
Aus AdminWiki
Inhaltsverzeichnis |
Einleitung
Gelegentlich kommt man in die Verlegenheit dass man daran gebunden ist SSH auf dem Standardport 22 zu betreiben, was sich dann schon nach kurzer Zeit in andauernden Bruteforceattacken niederschlägt. Für diesen Fall ist neben fail2ban oder denyhosts der knockd ein guter Weg den Server gegen unerwünschte Angriffe abzusichern. Doch der Anklopfserver kann noch mehr - er verhindert von vornherein dass Angreifern die Extistenz bestimmter Dienste überhaupt bekannt wird oder kann im Notfall den Webserver neu starten.
Der knockd beobachtet ob auf Bestimmten, vorher festgelegten Ports Pakete in der vorher festgelegten Reihenfolge eintreffen und führt, wenn dies der Fall sein sollte, einen beliebigen Befehl aus. Praktisch nutzt man diese Funktion nun also dazu, das vorher über iptables gesperrte SSH durch das einfügen einer passenden Regel in in die iptables freizuschalten.
Installation
Zunächst installiert man den daemon über die Paketverwaltung des Betriebssystems - in diesem Fall Debian (Abwandlungen bei anderen Distributionen sind möglich).
aptitude install knockd
Konfiguration
Standardmäßig muss der Eintrag START_KNOCKD in der /etc/default/knockd auf 1 angepasst werden damit der Daemon überhaupt startet. Bei Bedarf kann hier auch das Interface angepasst werden, auf dem der Daemon lauscht. Anschließend wird das configfile /etc/knockd.conf angepasst - für SSH könnte das z.B. so aussehen:
[options] UseSyslog
[opencloseSSH] sequence = 9000,8000,7000 seq_timeout = 15 tcpflags = syn start_command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT cmd_timeout = 10 stop_command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
Durch die Option UseSyslog werden Wichtige Informationen ins Syslog geschrieben. Wenn nun innerhalb des seq_timeout (in Sekunden) nacheinander Pakete mit dem in tcpflags festgelegten Flag an die in sequence festgelgten TCP-Ports gesandt werden wird das start_command ausgeführt. Nach Ablaufen des cmd_timeout wird das stop_command ausgeführt. Hierbei sollte man sequence unbedingt durch eigene Werte ersetzen und dabei auch mehr als nur 3 Ports verwenden (5-8 eignen sich gut).
=Testen im Debug-Modus und Start"
Nun empfiehlt es sich den daemon nicht gleich zu starten sondern zunächst mit
knockd --debug --verbose
im Debugmode zu schauen ob denn auch alles so läuft wies soll. Ein Beispiel:
server: $ knockd --debug --verbose [...] Local IP: 192.168.0.18 listening on eth0...
client: $ knock 192.168.0.18 9000 8000 7000
server: 2009-09-21 18:53:32: tcp: 192.168.0.121:49087 -> 192.168.0.18:9000 74 bytes 192.168.0.121: opencloseSSH: Stage 1 2009-09-21 18:53:32: tcp: 192.168.0.121:58850 -> 192.168.0.18:8000 74 bytes 192.168.0.121: opencloseSSH: Stage 2 2009-09-21 18:53:32: tcp: 192.168.0.121:44580 -> 192.168.0.18:7000 74 bytes 192.168.0.121: opencloseSSH: Stage 3 192.168.0.121: opencloseSSH: OPEN SESAME <-- Der Server hat die sequenz erkannt. opencloseSSH: running command: /sbin/iptables -I INPUT -s 192.168.0.121 -p tcp --dport 22 -j ACCEPT <-- öffnet den Port. 192.168.0.121: opencloseSSH: command timeout <-- 10 Sekunden Später ... opencloseSSH: running command: /sbin/iptables -D INPUT -s 192.168.0.121 -p tcp --dport 22 -j ACCEPT <-- ... wird der Port wieder geschlossen
Wenn das alles so funktioniert und der Eintrag währen dieser 10 Sekunden auch mit
iptables -L
angezeigt wird. Kann der Daemon über das initscript /etc/init.d/knockd gestartet werden. Allerdings passiert zumindest auf einem Standardsystem hier noch nicht viel, da standardmäßig SSH natürlich nicht gesperrt ist. Dies könnte beispielsweise über
iptables -A INPUT -p tcp --dport 22 --syn -j REJECT
geändert werden. Wie man sieht werden nur syn-Pakete gedropt. Dadurch werden bestehende Verbindungen nicht beeinträchtigt. Sonst würde die frisch hergestellte Verbindung ja binnen 10 Sekunden wieder getrennt werden. Wenn alles funktioniert sollte der Eintrag über die /etc/rc.local übernommen werden damit die Firewall auch bei jedem Neustart wieder angepasst wird.
Wenn das ganze über eine SSH-Verbindung eingerichtet wird sollte diese offen gehalten werden bis alle Tests abgeschlossen sind, wenn was schief geht kommt man sonst womöglich nie wieder an seinen Server ;-). Falls vorher schon eine iptables Konfiguration existiert müssen die Befehle natürlich daran angepasst werden.
Beispiel-Config
Noch eine Beispielkonfiguration wie man openvpn starten und stoppen könnte:
[options] UseSyslog
[startOpenVPN] sequence = 7000,8000,9000 seq_timeout = 5 command = /etc/init.d/openvpn start tcpflags = syn
[stopOpenVPN] sequence = 9000,8000,7000 seq_timeout = 5 command = /etc/init.d/openvpn stop tcpflags = syn
OK
knock 192.168.0.18 7000 8000 9000 startet nun openvpn und knock 192.168.0.18 9000 8000 7000 stoppt es.
Weblinks & Info
Dieser Artikel ist eine Kopie eines Blogposts von "fep" auf dem Admin-Blog.com. Kommentare und weitere Hinweise sind dort zu finden!
