Knockd: Port-Knocking zur Systemsteuerung

Firewall

Fanatiker wasserdichter Systeme sollten womöglich nicht weiterlesen, dem Besitzer der Spielwiese sei ein neues Spielzeug in den Schoß gelegt.

Einleitung

Ursprünglich angedacht ist das klassische Port-Knocking zum Öffnen eines Ports/einer Reihe von Ports nach einer erkannten, vorab festgelegten Paket-Sequenz im Netzwerk innerhalb einer bestimmten Zeit.
So lässt sich etwa Port 8081/TCP öffnen, werden innerhalb von 3 Sekunden SYN-Pakete erst auf Port 7001/TCP und anschließend Port 8001/TCP empfangen.
Damit keine Missverständnisse entstehen: Die angeklopften Ports bedürfen vorab keiner Freischaltung im lokalen netfilter (via Iptables), ebenso spielt es keine Rolle, ob auf einem Port ein Dienst arbeitet oder nicht.
Eine vorgeschaltete Firewall müsste hingegen für die Weiterleitung der entsprechenden Pakete auf die Ziel-Ports des Ziel-Systems eingestellt werden.

Knockd bietet eine Überwachung des TCP- und UDP-Netzwerkverkehrs nach Auftreten von definierten Reihenfolgen.
Lautet ein Teil einer Sequenz etwa 7001/TCP, können bestimmte „Flags“/Pakete einbezogen- oder ausgeschlossen werden. Die gängiste Variante stellt das Lauschen nach SYN-Paketen dar. Diese Pakete werden zum TCP-Verbindungsaufbau verwendet.
Nicht zu empfehlen ist hingegen die ausschließliche Verwertung von ACK-Paketen. Jede aktive Verbindung zum Server (etwa via SSH) lässt unter Umständen große Mengen an ACK-Paketen im Netzwerk entstehen. Diese Pakete würde Knockd als Anklopfversuch werten und eine korrekte Sequenz im schlimmsten Fall unmöglich machen, da ein Versuch immer wieder von „ungewünschten“ Paketen unterbrochen würde.
UDP ist bekanntlich ein verbindungsloses Protokoll und kennt diese Flags nicht. Hier kommt entweder „etwas“ an, oder eben nicht…

Installation

Knockd befindet sich seit einiger Zeit in den Paketquellen der großen Distributionen, zu installieren etwa via „apt-get“ in Debian und Derivaten:

sudo apt-get install knockd

Um Knockd als Dienst zu betreiben, was durchaus sinnvoll ist, wird dieser in der Datei „/etc/default/knockd“ erst aktiviert…

echo START_KNOCKD=1 > /etc/default/knockd

…und im Anschluss gestartet:

service knockd start

Bedenkt, dass jede Konfigurationsänderung einen Neustart des Dienstes notwendig macht.

Konfigurationsbeispiele

Ein klassisches und simples Beispiel, welches ich um die notwendigsten Erklärungen ergänzt habe:

[options] # Allgemeine Optionen
    UseSyslog # Logging in das Syslog ist erwuenscht.

[einbeispiel] # Der Name darf frei gewaehlt werden.
    sequence      = 1234:tcp,5678:tcp,9012 # Die Reihenfolge; ohne Angabe von UDP/TCP wird TCP angenommen, daher ist "9012" gleichbedeutend "9012:tcp".
    seq_timeout   = 15 # Die Zeit, die für einen Anklopfversuch maximal aufgebracht werden darf. 
    tcpflags      = syn # Beachtet werden lediglich SYN-Pakete.
    start_command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT # Dieser Befehl wird bei Erfolg ausgefuehrt. %IP% entspricht der IP des Klopfers.
    cmd_timeout   = 30 # 30 Sekunden nach "start_command" wird der "stop_command" ausgefuehrt.
    stop_command  = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT # Wird nach dem Timeout ausgefuehrt.

Lautet eine Firewall-Policy „alles ablehnen, was nicht erlaubt ist“, würde obiges Beispiel bei erkannter Sequenz an erster Stelle die Akzeptanz der Verbindungen von %IP% auf Port 22/TCP einfügen (-Insert). %IP% entsprecht der IP des Klopfers.
Der „stop_command“ löscht (-Delete) die erstellte Regel wieder, wird der Timeout „cmd_timeout“ erreicht.
Eine Verbindung zum SSH-Server bliebe jedoch bestehen, wenn ein entspechender Eintrag für bereits hergestellte und verwandte Verbindungen vorhanden ist:

/sbin/iptables -A INPUT -m state — state ESTABLISHED,RELATED -j ACCEPT

Eine alternative Konfiguration mit nur einem Befehl würde beispielsweise lauten:

[options] # Allgemeine Optionen
    UseSyslog # Logging in das Syslog ist erwuenscht.

[einbeispiel] # Der Name darf frei gewaehlt werden.
    sequence      = 1234:tcp,5678:tcp,9012 # Die Reihenfolge; ohne Angabe von UDP/TCP wird TCP angenommen, daher ist "9012" gleichbedeutend "9012:tcp".
    seq_timeout   = 15 # Die Zeit, die für einen Anklopfversuch maximal aufgebracht werden darf. 
    tcpflags      = syn # Beachtet werden lediglich SYN-Pakete.
    start_command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 801 -j ACCEPT # Dieser Befehl wird bei Erfolg ausgefuehrt. %IP% entspricht der IP des Klopfers. "command" ist ein Alias für "start_command", beide Parameter sind gültig.

Erstellte Regel würde ergo nicht wieder entfernt-, lediglich eine neue angehangen (-Append“) werden.

Ähnlich einer TAN-Liste, lässt sich eine Liste mit einmaligen Sequenzen einbinden, welche von Knockd abgearbeitet wird. Benutzte Sequenzen werden durch das Symbol „#“ auskommentiert. „one_time_sequences“ erhält seine offizielle Daseinsberechtigung durch Schutz vor Spoofing, denn Mitlesen von Datenverkehr bedeutet im schlimmsten Fall auch Erkennen von Klopf-Sequenzen.
An dieser Stelle sollte ich mir jedoch Gedanken machen, ob ich auf einem hoch-sensiblen System, die Verwendung eines solchen Tools als sinnvoll erachte…

Eine solche Liste, etwa „/etc/knockd/one_time_sequences.list“, binde ich folgendermaßen in die Konfiguration ein:

...
[einbeispiel]
one_time_sequences = /etc/knockd/one_time_sequences.list
...

Die Formatierung der Werte in dieser Datei lautet „‚leerzeichen’nummerierung,port1,port2,port3“.
Ein Beispiel zum besseren Verständnis:

 1,1234:tcp,1236:udp
 2,9823:udp,1231:udp

Die Sequenzen sollten nicht bei gestartetem Dienst verändert werden!

Einen Generator für eine solche Liste, findet der interessierte Nutzer hier. Dieser ließe sich auch bei einem Neustart des Knockd Dienstes ausführen, um neue Werte zu generieren.

„command“/“start_command“ und „stop_command“ sind jedoch nicht auf Iptables beschränkt, hier lässt sich allerlei Spaß einbauen.

Praktische Beispiele könnten die Steuerung von Diensten sein.

start_command = service nginx restart

Mit „cmd_timeout“ sowie einem zusätzlichen „stop_command“, wäre eine Zeitspanne möglich, bis ein Dienst wieder gestartet wird.

Anklopfen

Linux Benutzer erfreuen sich über das Programm „knock“, welches praktischerweise mit Knockd ausgeliefert wird. Auch hier installiert der Benutzer das Paket „knockd“, lässt den Daemon aber im inaktiven Zustand.

Syntax: knock host port(:protokoll)
Ohne Angabe eines Protokolls wird TCP angenommen.

knock host 7000:tcp 5000:udp 1234:tcp

Windows Benutzer bekommen mit KnockKnock eine klassische und selbsterklärende GUI.

Das Anklopfen mit Nmap, Telnet, Netcat und sonstigen Tools ist ebenso denk- und machbar. Interessant finde ich die Idee eines kleinen Scripts, das erst die Sequenz abklopft und dann einen entsprechenden Befehl ausführt, um etwa eine Verbindung via SSH herzustellen.

Praktische Beispiele sind toll (…), daher lade ich ein, meine IP 79.143.178.158 mit der Sequenz 123, 456, 789 (tcp/syn) anzuklopfen, um http://www.debinux.de:801/ für 30 Sekunden freizuschalten. Bitte denkt daran, dass der Cache des Browsers die Seite womöglich zwischenspeichert und es nicht sofort ersichtlich ist, dass der Port wieder gesperrt wurde (> Cache löschen hilft an dieser Stelle).

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.