Einleitung
iptables ist eine Befehlszeilenschnittstelle zur Verwaltung von Paketfilterregeln unter Linux. Obwohl viele moderne Distributionen diese Regeln über ein nftables-Backend umsetzen, treffen Administratoren weiterhin auf Aufgaben und bestehende Systeme, die die Befehlssyntax von iptables verwenden.
Ein hilfreiches Modell für Einsteiger ist, sich eine Firewall als eine geordnete Prüfliste vorzustellen. Ein Paket gelangt in eine Kette, und jede Regel prüft, ob das Paket Bedingungen wie Schnittstelle, Protokoll oder Port erfüllt. Ein Ziel wie ACCEPT oder REJECT legt anschließend fest, was geschieht. Die Kette INPUT verarbeitet Pakete, die an den lokalen Rechner adressiert sind. Da die Regeln von oben nach unten ausgewertet werden, sind sowohl ihr Inhalt als auch ihre Position entscheidend.
In diesem Labor arbeiten Sie mit einem lokalen Webdienst und nehmen nur eng begrenzte Änderungen an dessen TCP-Port vor. Sie untersuchen die aktuelle Firewall, fügen eine Regel hinzu, die Anfragen zurückweist, weisen die Wirkung anhand echten Datenverkehrs nach, ersetzen die Regel durch eine explizite Allow-Regel und entfernen anschließend die im Labor angelegte Regel, ohne den übrigen Firewall-Zustand zu leeren oder umzuschreiben.
Firewall und Testdienst untersuchen
In diesem Schritt ermitteln Sie, welche iptables-Implementierung installiert ist, und stellen sicher, dass der lokale Testdienst funktioniert, bevor Sie eine Firewall-Regel ändern.
Wechseln Sie in das Projektverzeichnis, damit alle folgenden Befehle im Arbeitsverzeichnis des Kurses beginnen.
cd /home/labex/project
Verwenden Sie command -v, um die ausführbare Datei zu ermitteln, die Ihre Shell ausführt.
command -v iptables
Diese Prüfung ist zuverlässiger, als einfach anzunehmen, dass ein Befehl installiert ist: Sie zeigt den aufgelösten Pfad der ausführbaren Datei, normalerweise /usr/sbin/iptables, und liefert einen Status ungleich null, wenn die Shell den Befehl nicht findet.
Geben Sie Versions- und Backend-Informationen aus. Auf diesem Ubuntu-Host enthält die Ausgabe normalerweise nf_tables. Das bedeutet, dass die vertraute iptables-Syntax in das moderne Regelwerk-Backend des Kernels übersetzt wird.
sudo iptables --version
Die Ausgabe sollte ungefähr so aussehen:
iptables v1.8... (nf_tables)
Der Name des Backends ändert nichts an den Befehlen in diesem Labor. Sie erstellen und untersuchen Regeln weiterhin mit iptables; die Implementierung kümmert sich um deren Darstellung im Kernel.
Rufen Sie vor der Filterung des Ports dessen Health-Endpunkt auf. Eine erfolgreiche Antwort bestätigt, dass die Anwendung bereit ist. Ein späterer Fehlschlag lässt sich dadurch der Firewall-Regel zuordnen.
curl --noproxy '*' --fail --silent http://127.0.0.1:18086/health
127.0.0.1 ist hier die IPv4-Loopback-Adresse. Der Datenverkehr verlässt und erreicht den Rechner daher über die lokale Schnittstelle lo, ohne ein externes Netzwerk zu durchlaufen. --noproxy '*' verhindert, dass Proxy-Einstellungen die Anfrage umleiten, --fail lässt HTTP-Fehler einen Fehlerstatus erzeugen, und --silent blendet die Fortschrittsanzeige aus, damit die Antwort des Dienstes gut lesbar bleibt.
Der Dienst antwortet mit:
iptables filter service ready
Die INPUT-Kette untersuchen und eine REJECT-Regel hinzufügen
In diesem Schritt lesen Sie die aktuelle Kette INPUT aus und fügen eine präzise Regel ein, die TCP-Datenverkehr über die Loopback-Schnittstelle zum Testport zurückweist.
Die Option -S gibt Regeln in einer befehlsähnlichen Form aus. Durch die Angabe von INPUT wird die Ausgabe auf Pakete begrenzt, die für diesen Rechner bestimmt sind.
sudo iptables -S INPUT
Die erste Zeile zeigt normalerweise die Richtlinie der Kette, zum Beispiel -P INPUT ACCEPT. Diese Richtlinie dient nur als Standardaktion, wenn keine vorherige Regel eine abschließende Entscheidung trifft. Die folgenden Zeilen, die mit -A INPUT beginnen, enthalten die Regeln, die derzeit an diese Kette angehängt sind.
Für eine praxisnahe Übersicht listet -L die Kette auf, -n verhindert eine langsame Namensauflösung, und --line-numbers zeigt die Position jeder Regel. Die Reihenfolge ist wichtig, da das erste passende Ziel mit abschließender Wirkung das Ergebnis für das Paket bestimmt.
Fügen Sie die Laborregel mit -I INPUT 1 an Position 1 ein. Sie trifft auf die Loopback-Schnittstelle lo, TCP und den Zielport 18086 zu. Das Ziel REJECT mit tcp-reset weist die Verbindung sofort zurück, anstatt den Client auf eine Zeitüberschreitung eines verworfenen Pakets warten zu lassen.
sudo iptables -I INPUT 1 -i lo -p tcp --dport 18086 -j REJECT --reject-with tcp-reset
Lesen Sie den Befehl von links nach rechts: -i lo beschränkt die eingehende Schnittstelle, -p tcp wählt das Protokoll, --dport 18086 den Dienst, und -j REJECT springt zum zurückweisenden Ziel. -I fügt eine Regel an einer bestimmten Position ein. Im Gegensatz dazu würde -A die Regel am Ende anhängen, wo eine frühere passende Regel verhindern könnte, dass sie überhaupt erreicht wird. Diese enge Kombination blockiert weder andere Ports noch externe Schnittstellen.
REJECT und DROP sind nicht identisch. REJECT sendet eine Fehlermeldung zurück, während DROP das Paket stillschweigend verwirft. Ein TCP-Reset lässt diesen lokalen Test schnell und vorhersehbar fehlschlagen und ist dadurch leichter zu diagnostizieren als eine ablaufende Zeitüberschreitung.
Verwenden Sie -C, um zu prüfen, ob genau diese Regel vorhanden ist. Eine erfolgreiche Prüfung endet mit dem Status null. Auf diesem Host gibt die nftables-basierte Implementierung zusätzlich die normalisierte Vergleichsregel aus; andere Implementierungen arbeiten möglicherweise ohne Ausgabe.
sudo iptables -C INPUT -i lo -p tcp --dport 18086 -j REJECT --reject-with tcp-reset
Für -C ist der Exit-Status das portable Prüfergebnis, nicht die Frage, ob Text auf dem Bildschirm erscheint. Dadurch eignet sich derselbe Befehl auch für Shell-Skripte und Überprüfungen.
Listen Sie die Kette erneut auf. Die neue Regel sollte als Regel 1 erscheinen und tcp dpt:18086 enthalten.
sudo iptables -L INPUT -n --line-numbers
Die beiden Ansichten dienen unterschiedlichen Zwecken: -S ist praktisch, wenn Sie eine wiederverwendbare Regelsyntax benötigen, während -L Positionen, Paket-Zähler und eine schnelle operative Übersicht liefert.
Den blockierten Datenverkehr überprüfen
In diesem Schritt wiederholen Sie die ursprüngliche Anfrage und untersuchen die Regelzähler, um nachzuweisen, dass die Firewall und nicht die Anwendung den Datenverkehr zurückgewiesen hat.
Führen Sie die Anfrage innerhalb einer if-Anweisung aus. Da die Anfrage erwartungsgemäß fehlschlägt, wandelt der else-Zweig diesen erwarteten Fehler in eine eindeutige Meldung um und ermöglicht gleichzeitig die Fortsetzung des geführten Ablaufs.
if curl --noproxy '*' --fail --silent http://127.0.0.1:18086/health; then
echo "Unexpected: request succeeded"
else
echo "Expected: iptables rejected the request"
fi
Shell-Bedingungen treffen Entscheidungen anhand des Exit-Status eines Befehls: Null wählt then, ein Wert ungleich null else. Der von der Firewall gesendete Reset bewirkt, dass curl einen Wert ungleich null zurückgibt. Daher ist das Erreichen des else-Zweigs hier das erwartete Ergebnis.
Die erwartete Meldung lautet:
Expected: iptables rejected the request
Listen Sie die Kette nun mit -v und ausführlichen Zählern auf. Die Paket- und Byte-Zähler der Regel für Port 18086 sollten nach der Anfrage größer als null sein.
sudo iptables -L INPUT -n -v --line-numbers
In der Ausgabe zählt die Spalte pkts die passenden Pakete, während bytes deren Gesamtgröße zählt. Zähler liefern einen wichtigen Nachweis: Mit -C weisen Sie nach, dass die Regel vorhanden ist, während ein Anstieg des Zählers bestätigt, dass echter Datenverkehr die Regel erreicht und auf sie zugetroffen hat. Bleibt der Zähler bei null, überprüfen Sie Schnittstelle, Protokoll, Port und Regelposition, bevor Sie die Anwendung als Ursache vermuten.
Die REJECT-Regel durch eine Allow-Regel ersetzen
In diesem Schritt löschen Sie die exakte Zurückweisungsregel, fügen für denselben Datenverkehr eine explizite Allow-Regel hinzu und überprüfen, dass der Zugriff wieder möglich ist.
Die folgende Form von -D identifiziert die Regel anhand ihrer vollständigen Übereinstimmungsbedingungen und ihres Ziels. Das ist sicherer als das Leeren der Kette, da ausschließlich die im Labor vorgenommene Änderung entfernt wird.
sudo iptables -D INPUT -i lo -p tcp --dport 18086 -j REJECT --reject-with tcp-reset
Regeln können auch anhand ihrer Zeilennummer gelöscht werden. Zeilennummern ändern sich jedoch jedes Mal, wenn Regeln eingefügt oder entfernt werden. Das Löschen anhand der exakten Spezifikation ist in einem wiederholbaren Verfahren eindeutiger und verringert das Risiko, eine benachbarte Regel zu entfernen. Verwenden Sie hier nicht iptables -F: Das Leeren würde sämtliche Regeln der ausgewählten Kette entfernen, auch solche, die nicht zu diesem Labor gehören.
Fügen Sie eine ACCEPT-Regel für dieselbe Schnittstelle, dasselbe Protokoll und denselben Port ein.
sudo iptables -I INPUT 1 -i lo -p tcp --dport 18086 -j ACCEPT
ACCEPT erlaubt einem passenden Paket, den Netzwerkstapel weiter zu durchlaufen. Die Regel wird an Position 1 eingefügt, damit ihr Ergebnis nicht durch eine frühere abschließende Regel verborgen wird. Beachten Sie, dass die Übereinstimmungsbedingungen genauso eng bleiben wie zuvor; lediglich das Ziel ändert sich.
Überprüfen Sie die exakte Allow-Regel.
sudo iptables -C INPUT -i lo -p tcp --dport 18086 -j ACCEPT
Wiederholen Sie die ursprüngliche Health-Anfrage.
curl --noproxy '*' --fail --silent http://127.0.0.1:18086/health
Die Antwort ist wieder verfügbar:
iptables filter service ready
Die im Labor angelegte Regel entfernen
In diesem Schritt entfernen Sie die vorübergehende Allow-Regel und bestätigen, dass keine Regel aus dieser Übung bestehen bleibt.
Löschen Sie die exakte ACCEPT-Regel. Wie zuvor wird dadurch weder die Kette geleert noch werden Regeln verändert, die der Plattform oder einem anderen Administrator gehören.
sudo iptables -D INPUT -i lo -p tcp --dport 18086 -j ACCEPT
Das Entfernen einer expliziten Allow-Regel bedeutet nicht automatisch, dass der Dienst blockiert wird. Sobald die Regel verschwunden ist, bestimmen die verbleibenden Regeln und schließlich die Richtlinie der Kette über das Schicksal des Pakets. In dieser vorbereiteten Umgebung erlaubt die ursprüngliche Firewall die lokale Anfrage.
Prüfen Sie die Regel erneut. Diesmal ist ein Fehlschlag zu erwarten. Deshalb führt || die Meldung auf der rechten Seite nur dann aus, wenn iptables -C einen Status ungleich null zurückgibt.
sudo iptables -C INPUT -i lo -p tcp --dport 18086 -j ACCEPT 2>/dev/null || echo "Lab allow rule removed"
Sie sollten Folgendes sehen:
Lab allow rule removed
Bestätigen Sie abschließend, dass das Entfernen der expliziten Regel die Anwendung nicht angehalten hat. Die ursprüngliche Richtlinie und die verbleibenden Regeln der Kette bestimmen wieder den Zugriff.
curl --noproxy '*' --fail --silent http://127.0.0.1:18086/health
Zusammenfassung
Sie haben die iptables-Implementierung und die Kette INPUT untersucht, eine eng begrenzte REJECT-Regel eingefügt und überprüft, ihre Wirkung anhand echten Datenverkehrs und der Zähler nachgewiesen, sie durch eine Allow-Regel ersetzt und ausschließlich die im Labor vorgenommene Änderung entfernt. Diese Befehle vermitteln die notwendige praktische Erfahrung mit Paketfiltern, um sicher zu arbeiten, ohne den übrigen Firewall-Zustand zu leeren.



