IPTables-Regel, um eingehende SSH-Verbindungen zuzulassen

11

Ziel dieses Skripts ist es, nur Datenverkehr über das VPN zuzulassen, mit Ausnahme von localhost <-> localhost und eingehendem SSH-Datenverkehr. Aber wenn ich das Skript über SSH ausführe, werde ich getrennt und gezwungen, die VM neu zu starten. Was ist los mit meinem Skript?

#!/bin/bash
iptables -F

#Allow over VPN
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A OUTPUT -o tun+ -j ACCEPT

#Localhost
iptables -A INPUT -s 127.0.0.1/8 -j ACCEPT
iptables -A OUTPUT -d 127.0.0.1/8 -j ACCEPT

#VPN
iptables -A INPUT -s 123.123.123.123 -j ACCEPT
iptables -A OUTPUT -d 123.123.123.123 -j ACCEPT

#SSH
iptables -A INPUT -p tcp --dport ssh -j ACCEPT

#Default Deny
iptables -A INPUT -j DROP
iptables -A OUTPUT -j DROP
Steven
quelle

Antworten:

10

Die Ausgabekette ist für das Ausgehen eines Pakets verantwortlich .

Ihr Skript erlaubt ausgehenden Paketen nur, die Schnittstelle, den lokalen Host und den Remote-Host unter 123.123.123.123 zu tunneln.

Wenn Sie eine Verbindung zum Server herstellen, bei der der SSH-Dämon Pakete an ein anderes Ziel als eines der oben genannten senden muss, darf der Datenverkehr nicht ausgehen.

Um ausgehende Pakete von Ihrem SSH-Daemon zum SSH-Client zuzulassen, müssen Sie die folgende Regel hinzufügen:

iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT

Möglicherweise möchten Sie der obigen Regel auch Ziel-IP-Kriterien hinzufügen, wenn Sie nur von einem einzigen Standort aus eine Verbindung herstellen. Diese Regel muss vor der endgültigen Regel "DROP irgendetwas anderes" für die Ausgabekette stehen.

hellodanylo
quelle
+1 Dies funktioniert und ist spezifischer als die Verwendung einer etablierten, verwandten Regel (was sie je nach Kontext entweder mehr oder weniger nützlich macht).
Goldlöckchen
Beide tolle Antworten, ich habe viel gelernt! Ich habe die @ SkyDan-Antwort getestet und sie funktioniert gut!
Steven
Nitpick: Die Ausgabekette ist nicht für weitergeleitete Pakete verantwortlich.
Björn Lindqvist
13

Ihre #SSHRegel impliziert, dass ssh eine Einwegkommunikationsform ist, die es nicht ist. Daten werden hin und zurück gesendet .

Der normale Weg, um damit umzugehen, besteht darin, Verbindungen zuzulassen, die als "hergestellt" oder "verwandt" mit einer hergestellten Verbindung gelten , da Sie die Portnummer auf der Clientseite nicht im Voraus kennen . Dazu benötigen Sie:

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Vor Ihren DROPRegeln (und vorzugsweise ganz oben, da die Regeln in der richtigen Reihenfolge verarbeitet werden und diese beiden für die meisten Pakete gelten).

Es gibt eine Erklärung, wie eine TCP - Verbindung wird hier ; Im Wesentlichen #SSH INPUTmacht es die Tatsache, dass der Server auf das von Ihrer Regel zugelassene Paket antwortet, so.

Goldlöckchen
quelle
1
Dies wird nicht funktionieren. Etabliert bedeutet, dass Pakete in beide Richtungen für eine bestimmte TCP-Verbindung gesehen wurden. Wenn Sie nur diese Regel hinzufügen, wird das erste ausgehende Paket weiterhin blockiert.
Hellodanylo
2
@SkyDan Hier ist eine Referenz dafür . Beachten Sie im Diagramm, dass, wenn der Server nach dem Empfang der Eröffnungssyn eine Syn / Ack an den Client zurücksendet, die Verbindung hergestellt wird, was bedeutet, dass iptables dieses Antwortpaket durchlässt: "Sobald er ein Paket (das SYN) gesehen hat, wird dies berücksichtigt Die Verbindung wird als NEU eingestuft. Sobald das Rückgabepaket (SYN / ACK) angezeigt wird, wird die Verbindung als EINGESTELLT betrachtet. " -> nochmal: iptables sieht das Rückpaket, das der Server senden möchte, stellt die Verbindung als hergestellt ein und lässt die Antwort durch.
Goldlöckchen
1
Okay, ich verstehe, warum es funktionieren wird. Es ist ein bisschen dunkel, da der iptables-Mann nur davon spricht, Pakete in beide Richtungen zu sehen, kein Wort darüber, dass die TCP-Handshake-Pakete eine Ausnahme bilden. Danke für den Hinweis!
Hellodanylo
2
@SkyDan Tatsächlich gilt die Logik nicht nur für TCP. Ich habe mich geirrt -p tcp, einen Unterschied in diesem Sinne zu machen, und die nachfolgende Erklärung für UDP auf dieser Seite gelesen (es ist dieselbe). Der Punkt ist, dass der Server antwortet, ohne zu wissen, ob iptables dies zulässt oder nicht, und wenn iptables diese Antwort vom Server auf dem lokalen System empfängt, hat er jetzt Datenverkehr in beide Richtungen gesehen (obwohl der Client dies noch nicht getan hat) Die Verbindung wurde hergestellt und die Antwort wird ausgegeben. Die "Technik" hängt davon ab, dass sich die Firewall in der Mitte der beiden Parteien befindet.
Goldlöckchen
1
Sie sind dort richtig. Jemand sollte diese Informationen wahrscheinlich in den iptables-Mann aufnehmen.
hellodanylo