SSH absichern und Mehr mit knockd

Aus AdminWiki

Wechseln zu: Navigation, Suche

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!