Port Knocking ist eine Methode, um einen Server abzusichern, indem Firewall-Ports geschlossen bleiben, selbst jene, von denen Sie wissen, dass sie normalerweise verwendet werden. Diese Ports werden nur dann geöffnet, wenn eine Verbindungsanfrage mit dem korrekten, geheimen Klopfmuster eingeht.
Port Knocking: Ein „geheimes Klopfen“
In den 1920er Jahren, während der Prohibition, war es notwendig, ein geheimes Klopfzeichen zu kennen, um Zutritt zu einer Flüsterkneipe zu erhalten.
Port Knocking funktioniert ähnlich. Wenn Sie möchten, dass Benutzer auf Dienste Ihres Computers zugreifen können, ohne die Firewall für das gesamte Internet zu öffnen, können Sie Port Knocking verwenden. Es erlaubt Ihnen, die Ports Ihrer Firewall, die normalerweise eingehende Verbindungen erlauben, geschlossen zu halten. Sie werden automatisch geöffnet, sobald ein vorher festgelegtes Muster von Verbindungsversuchen erfolgt. Diese Sequenz von Versuchen dient als das geheime Klopfen. Ein weiteres geheimes Klopfen kann den Port wieder schließen.
Port Knocking ist eine interessante Technik, aber es ist wichtig zu verstehen, dass sie unter das Konzept der Sicherheit durch Verschleierung fällt, welche als grundsätzlich fehlerhaft gilt. Die Sicherheit basiert hier auf dem Geheimnis des Zugangs zum System. Sobald dieses Geheimnis jedoch gelüftet wird – sei es durch Enthüllung, Beobachtung, Erraten oder Ausfindigmachen – ist die Sicherheit kompromittiert. Es ist besser, Ihren Server mit robusteren Methoden zu schützen, wie z.B. schlüsselbasierte Anmeldungen für einen SSH-Server.
Die effektivsten Cybersicherheitsansätze sind mehrschichtig. Daher könnte Port Knocking eine dieser Schichten sein. Je mehr Schichten, desto besser, oder? Man könnte aber auch argumentieren, dass Port Knocking einem gut gehärteten, sicheren System nicht viel hinzufügt.
Cybersicherheit ist ein komplexes Thema, und Port Knocking sollte nicht als Ihre einzige Verteidigungsmethode betrachtet werden.
Installation von Knockd
Um Port Knocking zu demonstrieren, verwenden wir es zur Steuerung von Port 22, dem SSH-Port. Wir verwenden dazu ein Werkzeug namens Knockd. Installieren Sie dieses Paket mit apt-get, wenn Sie Ubuntu oder eine andere Debian-basierte Distribution verwenden. Bei anderen Linux-Distributionen verwenden Sie stattdessen das jeweilige Paketverwaltungstool.
Geben Sie Folgendes ein:
sudo apt-get install knockd
Wahrscheinlich haben Sie bereits die iptables-Firewall installiert, aber Sie benötigen möglicherweise das Paket `iptables-persistent`. Es sorgt dafür, dass gespeicherte iptables-Regeln automatisch geladen werden.
Geben Sie Folgendes ein, um es zu installieren:
sudo apt-get install iptables-persistent
Wenn der IPv4-Konfigurationsbildschirm angezeigt wird, drücken Sie die Leertaste, um „Ja“ auszuwählen.
Drücken Sie im IPv6-Konfigurationsbildschirm erneut die Leertaste, um „Ja“ auszuwählen und fortzufahren.
Der folgende Befehl weist iptables an, fortlaufende Verbindungen zu akzeptieren. Wir geben dann einen weiteren Befehl aus, um den SSH-Port zu schließen.
Wenn jemand per SSH verbunden ist, während wir diesen Befehl ausgeben, wollen wir nicht, dass die Verbindung unterbrochen wird:
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Dieser Befehl fügt der Firewall eine Regel hinzu, die besagt:
-A: Hängen Sie die Regel an die Firewall-Regeltabelle an, d.h. fügen Sie sie am Ende hinzu.
INPUT: Dies ist eine Regel für eingehende Verbindungen.
-m conntrack: Firewall-Regeln wirken sich auf Netzwerkverkehr (Pakete) aus, der den Kriterien entspricht. Der Parameter -m bewirkt, dass iptables zusätzliche Paket-Matching-Module verwendet – in diesem Fall das Modul `conntrack`, welches mit den Netzwerkverfolgungsfunktionen des Kernels interagiert.
–ctstate ESTABLISHED,RELATED: Dies spezifiziert den Verbindungstyp, für den die Regel gilt, nämlich `ESTABLISHED` und `RELATED`-Verbindungen. Eine `ESTABLISHED`-Verbindung ist eine, die bereits besteht. Eine `RELATED`-Verbindung ist eine, die als Folge einer Aktion einer bestehenden Verbindung etabliert wird. Zum Beispiel kann jemand, der bereits verbunden ist, eine Datei herunterladen; das kann eine neue, vom Host initiierte Verbindung beinhalten.
-j ACCEPT: Wenn der Datenverkehr der Regel entspricht, wird zum `ACCEPT`-Ziel in der Firewall gesprungen. Das bedeutet, der Verkehr wird akzeptiert und darf die Firewall passieren.
Nun können wir den Befehl zum Schließen des Ports ausgeben:
sudo iptables -A INPUT -p tcp --dport 22 -j REJECT
Dieser Befehl fügt der Firewall eine Regel hinzu, die besagt:
-A: Hängen Sie die Regel an die Firewall-Regeltabelle an, d.h. fügen Sie sie am Ende hinzu.
INPUT: Diese Regel betrifft eingehende Verbindungen.
-p tcp: Diese Regel gilt für Verkehr, der das Transmission Control Protocol verwendet.
–dport 22: Diese Regel gilt speziell für TCP-Verkehr, der auf Port 22 (den SSH-Port) abzielt.
-j REJECT: Wenn der Verkehr der Regel entspricht, wird zum `REJECT`-Ziel in der Firewall gesprungen. Das heißt, der Verkehr wird abgewiesen und nicht durch die Firewall gelassen.
Wir müssen den `netfilter-persistent`-Daemon starten. Wir können dies mit dem folgenden Befehl tun:
sudo systemctl start netfilter-persistent
Wir wollen, dass `netfilter-persistent` einen Speicher- und Ladezyklus durchläuft, so dass es die iptables-Regeln lädt und kontrolliert.
Geben Sie die folgenden Befehle ein:
sudo netfilter-persistent save
sudo netfilter-persistent reload
Sie haben nun die notwendigen Werkzeuge installiert und der SSH-Port ist geschlossen (hoffentlich ohne Ihre Verbindung zu beenden). Nun ist es an der Zeit, das geheime Klopfen zu konfigurieren.
Knockd konfigurieren
Es gibt zwei Dateien, die Sie zur Konfiguration von Knockd bearbeiten müssen. Die erste ist die Konfigurationsdatei von Knockd selbst:
sudo gedit /etc/knockd.conf
Der gedit-Editor öffnet sich mit der geladenen Knockd-Konfigurationsdatei.
Wir werden diese Datei an unsere Bedürfnisse anpassen. Die relevanten Abschnitte sind „openSSH“ und „closeSSH“. Jeder Abschnitt enthält die folgenden vier Einträge:
Sequence: Die Reihenfolge der Ports, die jemand erreichen muss, um Port 22 zu öffnen oder zu schließen. Die Standardports sind 7000, 8000 und 9000 zum Öffnen und 9000, 8000 und 7000 zum Schließen. Sie können diese ändern oder der Liste weitere Ports hinzufügen. Für unsere Zwecke behalten wir die Standardeinstellungen bei.
seq_timeout: Der Zeitraum, in dem die Ports erreicht werden müssen, um das Öffnen oder Schließen auszulösen.
command: Der Befehl, der an die iptables-Firewall gesendet wird, wenn das Öffnen oder Schließen ausgelöst wird. Diese Befehle fügen entweder eine Regel zur Firewall hinzu (zum Öffnen des Ports) oder entfernen sie (zum Schließen des Ports).
tcpflags: Der Pakettyp, den jeder Port in der geheimen Sequenz empfangen muss. Ein SYN (Synchronize)-Paket ist das erste in einer TCP-Verbindungsanfrage, auch Three-Way Handshake genannt.
Der Abschnitt „openSSH“ kann so interpretiert werden: „Eine TCP-Verbindungsanfrage muss an die Ports 7000, 8000 und 9000 gesendet werden – in dieser Reihenfolge und innerhalb von 5 Sekunden – damit der Befehl zum Öffnen von Port 22 an die Firewall gesendet wird.“
Der Abschnitt „closeSSH“ kann so interpretiert werden: „Eine TCP-Verbindungsanfrage muss an die Ports 9000, 8000 und 7000 gesendet werden – in dieser Reihenfolge und innerhalb von 5 Sekunden – damit der Befehl zum Schließen von Port 22 an die Firewall gesendet wird.“
Die Firewall-Regeln
Die „command“-Einträge in den Abschnitten `openSSH` und `closeSSH` bleiben bis auf einen Parameter gleich. Sie setzen sich wie folgt zusammen:
-A: Fügt die Regel am Ende der Firewall-Regelliste an (für den `openSSH`-Befehl).
-D: Löscht die Regel aus der Firewall-Regelliste (für den `closeSSH`-Befehl).
INPUT: Diese Regel betrifft eingehenden Netzwerkverkehr.
-s %IP%: Die IP-Adresse des Geräts, das eine Verbindung anfordert.
-p: Netzwerkprotokoll; in diesem Fall ist es TCP.
–dport: Der Zielport; in unserem Beispiel ist es Port 22.
-j ACCEPT: Springt zum `ACCEPT`-Ziel innerhalb der Firewall. Mit anderen Worten, das Paket kann die verbleibenden Regeln durchlaufen, ohne darauf zu reagieren.
Bearbeitung der Knockd-Konfigurationsdatei
Die Änderungen, die wir an der Datei vornehmen, sind unten rot markiert:
Wir verlängern das `seq_timeout` auf 15 Sekunden. Das ist großzügig, aber wenn jemand Verbindungsanfragen manuell abfeuert, benötigt er möglicherweise so viel Zeit.
Im Abschnitt `openSSH` ändern wir die Option `-A` (anhängen) im Befehl in `-I` (einfügen). Dieser Befehl fügt eine neue Firewall-Regel am Anfang der Firewall-Regelliste ein. Wenn Sie die Option `-A` beibehalten, wird die Liste der Firewall-Regeln am Ende angehängt.
Eingehender Datenverkehr wird von oben nach unten gegen jede Firewall-Regel in der Liste getestet. Wir haben bereits eine Regel, die Port 22 schließt. Wenn also eingehender Datenverkehr zuerst gegen diese Regel getestet wird, bevor die Regel die den Zugriff erlaubt, greift die Abweisung. Wenn die neue Regel zuerst erreicht wird, ist der Zugriff erlaubt.
Der Befehl `close` entfernt die von `openSSH` hinzugefügte Regel aus den Firewall-Regeln. Der SSH-Verkehr wird wieder von der vorhandenen Regel „Port 22 ist geschlossen“ behandelt.
Nach diesen Änderungen speichern Sie die Konfigurationsdatei.
Bearbeitung der Knockd-Steuerdatei
Die Steuerdatei von Knockd ist einfacher. Bevor wir eintauchen und diese bearbeiten, müssen wir jedoch den internen Namen unserer Netzwerkverbindung kennen. Um diesen zu finden, geben Sie den folgenden Befehl ein:
ip addr
Die Verbindung, mit der dieses Gerät diesen Artikel recherchiert, heißt `enp0s3`. Notieren Sie sich den Namen Ihrer Verbindung.
Der folgende Befehl bearbeitet die Steuerdatei von Knockd:
sudo gedit /etc/default/knockd
Hier ist die Knockd-Datei in gedit.
Die wenigen Änderungen, die wir vornehmen müssen, sind rot hervorgehoben:
Wir haben den Eintrag „START_KNOCKD=“ von 0 auf 1 geändert.
Außerdem haben wir das Rautezeichen # am Anfang des Eintrags `KNOCKD_OPTS=` entfernt und `eth1` durch den Namen unserer Netzwerkverbindung `enp0s3` ersetzt. Wenn Ihre Netzwerkverbindung `eth1` ist, müssen Sie diese natürlich nicht ändern.
Der Beweis liegt im Pudding
Es ist an der Zeit, zu testen, ob das funktioniert. Wir starten den Knockd-Daemon mit dem folgenden Befehl:
sudo systemctrl start knockd
Jetzt wechseln wir zu einem anderen Computer und versuchen, eine Verbindung herzustellen. Wir haben das Knockd-Tool auch auf diesem Computer installiert, nicht weil wir hier Port Knocking einrichten wollen, sondern weil das Knockd-Paket ein anderes Tool namens `knock` mitbringt. Wir werden diese Maschine verwenden, um unsere geheime Sequenz zu senden und das Klopfen für uns durchzuführen.
Verwenden Sie den folgenden Befehl, um Ihre geheime Folge von Verbindungsanfragen an die Ports des Port-Knocking-Host-Computers mit der IP-Adresse `192.168.4.24` zu senden:
knock 192.168.4.24 7000 8000 9000 -d 500
Dies weist `knock` an, den Computer mit der IP-Adresse `192.168.4.24` zu adressieren und Verbindungsanfragen an die Ports 7000, 8000 und 9000 mit einer Verzögerung von 500 Millisekunden zwischen den Anfragen zu senden.
Ein Benutzer namens „dave“ sendet dann eine SSH-Anfrage an `192.168.4.24`:
ssh [email protected]
Seine Verbindung wird akzeptiert, er gibt sein Passwort ein und seine Remote-Sitzung beginnt. Seine Eingabeaufforderung ändert sich von `[email protected]` in `[email protected]` Um sich vom Remote-Computer abzumelden, gibt er Folgendes ein:
exit
Seine Eingabeaufforderung kehrt zu seinem lokalen Computer zurück. Er verwendet `knock` erneut, und dieses Mal zielt es auf die Ports in umgekehrter Reihenfolge ab, um den SSH-Port auf dem Remote-Computer zu schließen.
knock 192.168.4.24 9000 8000 7000 -d 500
Zugegeben, das war keine besonders produktive Remote-Session, aber sie demonstriert das Öffnen und Schließen des Ports per Port Knocking und passt in einen einzigen Screenshot.
Wie sah das von der anderen Seite aus? Der Systemadministrator auf dem Port-Knocking-Host verwendet den folgenden Befehl, um neue Einträge im Systemprotokoll anzuzeigen:
tail -f /var/log/syslog
Sie sehen drei `openSSH`-Einträge. Diese werden ausgelöst, wenn jeder Port vom Remote-Knock-Dienstprogramm angesprochen wird.
Wenn alle drei Phasen der Triggersequenz erfüllt sind, wird ein Eintrag mit der Aufschrift „SESAM ÖFFNE DICH“ protokolliert.
Der Befehl zum Einfügen der Regel in die iptables-Regelliste wird gesendet. Er erlaubt den Zugriff per SSH auf Port 22 von der spezifischen IP-Adresse des PCs, der das korrekte, geheime Klopfzeichen gesendet hat (192.168.4.33).
Der Benutzer „dave“ verbindet sich nur für wenige Sekunden und trennt dann die Verbindung.
Sie sehen drei `closeSSH`-Einträge. Diese werden ausgelöst, wenn jeder Port vom Remote-Knock-Dienstprogramm angesprochen wird – dies weist den Port-Knocking-Host an, Port 22 zu schließen.
Nachdem alle drei Stufen ausgelöst wurden, erhalten wir erneut die Meldung „SESAM ÖFFNE DICH“. Der Befehl wird an die Firewall gesendet, um die Regel zu entfernen. (Warum nicht „SESAM SCHLIEßE DICH“, wenn der Port geschlossen wird? Wer weiß?)
Nun ist die einzige Regel in der iptables-Regelliste bezüglich Port 22 diejenige, die wir zu Beginn eingegeben haben, um diesen Port zu schließen. Port 22 ist nun wieder geschlossen.
Fazit
Das ist der Trick von Port Knocking. Betrachten Sie es als eine zusätzliche Maßnahme, die man im Realbetrieb nicht überbewerten sollte. Oder, wenn es sein muss, verlassen Sie sich nicht darauf, dass es Ihre einzige Form der Sicherheit darstellt.