VPS-Firewall: nur den VPN-Port öffnen und es dann beweisen
Ein Port muss öffentlich bleiben, sonst verbindet sich kein Client. Verwerfen Sie den Rest, halten Sie Weiterleitung und Eingang getrennt und lassen Sie einen vorab getesteten Rückweg offen.
Eine Firewall, die nur den VPN-Port zulässt, ist keine einzelne Regel. Sie besteht aus drei getrennten Entscheidungen, die zufällig dieselbe Portnummer betreffen: Die Eingabekette bestimmt, was einen lokalen Prozess erreichen darf, die Weiterleitungskette bestimmt, was im Namen von Tunnelclients durch den Host passieren darf, und die NAT-Tabelle schreibt die Quelladresse auf dem Weg nach draußen um. Macht man eine davon falsch, ist das Ergebnis selten ein sauberer Ausfall. Man bekommt einen Host, der Clients annimmt, aber nichts lädt, oder einen Host, der abgeriegelt aussieht, bis jemand die Reihenfolge der Ketten liest.
Der eine Port, der nicht geschlossen werden darf
Der VPN-Listener muss Verbindungen von Adressen annehmen, die man nicht vorhersagen kann, ist also per Definition ein öffentlicher Dienst. Das ist die einzige Ausnahme, um die herum das Design gebaut ist: ein UDP-Port für OpenVPN, ein UDP-Port für WireGuard, ein TCP-Port für ein SSL VPN. Alles andere gehört hinter den Tunnel, was bedeutet, dass Anwendungsdienste an die Tunneladresse oder an Loopback binden sollten und nicht an jede Schnittstelle.
Binden ist jedoch keine Durchsetzung. Ein an 0.0.0.0 gebundener Prozess ist nur erreichbar, wenn eine Regel ihn zulässt, und die Standardrichtlinie ist der Rückfall für Verkehr, auf den keine Regel passte, nicht die Regel, die den Port steuert. Ein Accept oberhalb Ihres Drop bleibt ein Accept, und einen Dienst von der öffentlichen Adresse wegzuziehen ist eine eigenständige Verbesserung und kein Ersatz für die Kette.
Eingang, Weiterleitung und NAT beantworten verschiedene Fragen
Eingangsverkehr ist an den Host selbst adressiert, dort liegen also der VPN-Listener und der administrative Pfad. Weiterleitungsverkehr passiert den Host, und Tunnelclients brauchen ihn plus net.ipv4.ip_forward=1. Die klassische halb kaputte Konfiguration erlaubt den ausgehenden Fluss und vergisst die Rückrichtung, sodass der Client seinen Handshake abschließt und danach nichts lädt; eine Conntrack-Regel für etablierten und verwandten Verkehr deckt diese Richtung ab.
NAT ist die dritte Frage. Ohne Umschreibung im Postrouting verlassen weitergeleitete Pakete den Host mit der privaten Tunnelquelle und werden weiter oben verworfen, weil kein Netz jenseits des Hosts weiß, wie der Pool zurückgeroutet wird. Das Quellpräfix in dieser Regel muss zum VPN-Pool passen, nicht zur eigenen Adresse des Hosts, und dasselbe gilt für die Weiterleitungsregel, die das Client-Subnetz nennt.
IPv6 ist eine zweite Richtlinie, kein Nachgedanke. Ein Host mit strikter IPv4-Kette und offener ip6tables-Richtlinie hat nichts geschlossen; die Dienste sind über die andere Familie weiterhin erreichbar. Entweder spiegeln Sie das Regelwerk mit ip6tables oder deaktivieren Sie IPv6 bewusst auf der öffentlichen Schnittstelle, und schreiben Sie auf, wofür Sie sich entschieden haben.
Eine Grundlage, die man in einem Durchgang liest
Beginnen Sie mit Drop und fügen Sie dann nur hinzu, was der Host braucht. Zuerst Loopback und Antworten, dann der administrative Pfad, dann der Tunnel-Listener, dann die Weiterleitungsrichtlinie für Clients:
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
iptables -A INPUT -p udp --dport 1194 -m conntrack --ctstate NEW -j ACCEPT
sysctl -w net.ipv4.ip_forward=1
iptables -A FORWARD -i tun0 -o eth0 -s 10.8.0.0/24 -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADESchnittstellennamen, Port und Pool sind Platzhalter; lesen Sie sie vom Server, statt sie zu kopieren. Das Ergebnis zu speichern ist genauso wichtig wie das Schreiben, denn ein Regelwerk, das nur im Speicher lebt, verschwindet beim nächsten Neustart und öffnet den Host stillschweigend wieder. Machen Sie es mit dem Mechanismus der Distribution dauerhaft und halten Sie eine Kopie außerhalb der Maschine für den Tag, an dem die Maschine nicht mehr startet.
Den letzten Port schließen, ohne den Host zu verlieren
Im Design steckt ein Haken. Existiert SSH nur über den Tunnel, nimmt ein ausgefallener VPN-Dienst SSH mit, und der einzige Weg zurück ist vielleicht eine Konsole, die Sie nie geöffnet haben. Bevor Sie den letzten öffentlichen Port schließen, bestätigen Sie, dass diese Konsole existiert und Sie sie tatsächlich nutzen können, oder halten Sie einen schmalen administrativen Pfad offen, der nicht vom Tunnel abhängt: SSH von einer festen Adresse, nur Schlüssel, Passwortauthentifizierung aus.
Wenden Sie die Änderung aus einer bereits bestehenden Sitzung an, nicht über die Verbindung, die Sie gerade filtern wollen. Planen Sie einen Rücklauf ein, damit ein Fehler ausläuft, statt dauerhaft zu werden, zum Beispiel einen systemd-run --on-active=10min-Job, der das vorherige Regelwerk wiederherstellt, und halten Sie eine zweite SSH-Sitzung offen, während Sie die erste testen. Prüfen Sie dann, ob der Rücklauf-Job wirklich auslöst, denn ungetestete Wiederherstellung ist dasselbe wie keine Wiederherstellung.
Den Pfad prüfen, nicht das Skript
Lesen Sie die geladenen Regeln, nicht die Datei, die sie hätte laden sollen. Bestätigen Sie von einem autorisierten externen Host, dass nur die vorgesehenen Ports antworten; bestätigen Sie von innerhalb des Tunnels, dass die Dienste, die Sie veröffentlichen wollten, erreichbar sind. Eine Standard-Deny-Richtlinie, die auch Tunnelverkehr blockiert, sieht genauso aus wie eine funktionierende Abschottung, bis jemand versucht, sie zu benutzen.
iptables -S
iptables -t nat -S
ss -lntup
ip -4 addr showNotieren Sie den erlaubten Port, den Client-Pool, die Tunnelschnittstelle, die administrative Quelle und das Konsolenverfahren neben der Konfiguration. Die nächste Änderung am Pool oder am Schnittstellennamen muss sowohl im Filter als auch in der NAT-Regel nachgezogen werden, sonst kehrt der Host in einen halb offenen Zustand zurück, ohne dass es jemand merkt.
Eine Gewohnheit ist mehr wert als das Regelwerk: Nach jeder Änderung beweisen Sie den Weiterleitungspfad mit einer Client-Anfrage und den Wiederherstellungspfad mit einer zweiten Sitzung. Eine Abschottung, die Sie nicht benutzt haben, ist eine Hypothese.