Firewall, který pustí jen port VPN, není jedno pravidlo. Jsou to tři oddělená rozhodnutí, která se náhodou týkají stejného čísla portu: vstupní řetěz rozhoduje, co se může dostat k místnímu procesu, přesměrovací řetěz rozhoduje, co může projít hostitelem jménem klientů tunelu, a tabulka NAT přepisuje zdrojovou adresu na cestě ven. Spletete jedno z nich a výsledkem je málokdy čistý výpadek. Dostanete hostitele, který přijímá klienty, ale nic nenačte, nebo hostitele, který vypadá uzavřeně, dokud někdo nepřečte pořadí řetězů.

Jediný port, který nelze zavřít

Naslouchač VPN musí přijímat spojení z adres, které nemůžete předvídat, takže je to veřejná služba ze své podstaty. To je jediná výjimka, na které je návrh postaven: jeden port UDP pro OpenVPN, jeden port UDP pro WireGuard, jeden port TCP pro SSL VPN. Všechno ostatní patří za tunel, což znamená, že aplikační služby se mají vázat na adresu tunelu nebo na loopback, ne na všechna rozhraní.

Vázání ale není vynucení. Proces vázaný na 0.0.0.0 je dostupný jen tehdy, když ho pravidlo pustí, a výchozí politika je záloha pro provoz, který neodpovídal žádnému pravidlu, ne pravidlo, které řídí port. Povolení umístěné nad vaším zakázáním je pořád povolení a přesun služby z veřejné adresy je samostatné zlepšení, ne náhrada za řetěz.

Vstup, přesměrování a NAT odpovídají na různé otázky

Vstupní provoz je určen samotnému hostiteli, takže tam žijí naslouchač VPN a administrativní cesta. Provoz přesměrování prochází hostitelem a klienti tunelu ho potřebují spolu s net.ipv4.ip_forward=1. Klasická polofunkční konfigurace povolí odchozí tok a zapomene na zpětný směr, takže klient dokončí handshake a pak se nic nenačte; pravidlo conntrack pro navázaný a související provoz ten směr pokrývá.

NAT je třetí otázka. Bez přepisu v postroutingu odcházejí přesměrované pakety s privátním zdrojem tunelu a výše v síti se zahazují, protože žádná síť za hostitelem neumí směrovat pool zpět. Zdrojový prefix v tom pravidle musí odpovídat poolu VPN, ne vlastní adrese hostitele, a totéž platí pro pravidlo přesměrování, které jmenuje podsíť klientů.

IPv6 je druhá politika, ne dodatečná myšlenka. Hostitel s přísným řetězem IPv4 a otevřenou politikou ip6tables nic nezavřel; služby jsou pořád dostupné přes druhou rodinu. Buď zrcadlete sadu pravidel pomocí ip6tables, nebo IPv6 na veřejném rozhraní vědomě vypněte, a napište, kterou možnost jste zvolili.

Základ, který přečtete na jeden průchod

Začněte zakázáním a pak přidejte jen to, co hostitel potřebuje. Nejprve loopback a odpovědi, pak administrativní cestu, pak naslouchač tunelu, pak politiku přesměrování pro klienty:

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 MASQUERADE

Názvy rozhraní, port a pool jsou zástupné; čtěte je ze serveru, místo abyste je kopírovali. Uložení výsledku je stejně důležité jako jeho napsání, protože sada pravidel žijící jen v paměti zmizí při dalším restartu a tiše hostitele znovu otevře. Zajistěte trvalost mechanismem distribuce a kopii držte mimo stroj pro den, kdy se stroj nenabootuje.

Zavřít poslední port bez ztráty hostitele

V návrhu je háček. Pokud SSH existuje jen přes tunel, selhaná služba VPN vezme SSH s sebou a jediná cesta zpět může být konzole, kterou jste nikdy neotevřeli. Než zavřete poslední veřejný port, ověřte, že ta konzole existuje a že ji opravdu umíte použít, nebo si ponechte jednu úzkou administrativní cestu nezávislou na tunelu: SSH z pevné adresy, jen klíče, autentizace heslem vypnutá.

Změnu aplikujte z už navázané relace, ne přes spojení, které se chystáte filtrovat. Naplánujte návrat, aby chyba vypršela, místo aby se stala trvalou, například úlohu systemd-run --on-active=10min, která obnoví předchozí sadu pravidel, a druhou SSH relaci držte otevřenou, dokud testujete první. Pak ověřte, že se úloha návratu skutečně spustí, protože neotestované obnovení je totéž jako žádné obnovení.

Ověřte cestu, ne skript

Čtěte načtená pravidla, ne soubor, který je měl načíst. Z oprávněného vnějšího hostitele potvrďte, že odpovídají jen zamýšlené porty; zevnitř tunelu potvrďte, že služby, které jste chtěli publikovat, jsou dostupné. Politika zakázání ve výchozím nastavení, která blokuje i provoz tunelu, vypadá stejně jako fungující uzamčení, dokud to někdo nezkusí použít.

iptables -S
iptables -t nat -S
ss -lntup
ip -4 addr show

Zapište povolený port, pool klientů, rozhraní tunelu, administrativní zdroj a postup s konzolí vedle konfigurace. Příští změna poolu nebo názvu rozhraní se musí promítnout do filtru i do pravidla NAT, jinak se hostitel vrátí do polootevřeného stavu, aniž by si toho někdo všiml.

Jeden návyk je cennější než sada pravidel: po každé změně dokažte cestu přesměrování požadavkem klienta a cestu obnovy druhou relací. Uzamčení, které jste nepoužili, je hypotéza.

Související články