En firewall, der kun lukker VPN-porten ind, er ikke én regel. Det er tre separate beslutninger, som tilfældigvis handler om det samme portnummer: inputkæden afgør, hvad der kan nå en lokal proces, forwardkæden afgør, hvad der kan passere gennem værten på vegne af tunnelklienter, og NAT-tabellen omskriver kildeadressen på vej ud. Tager du fejl i én af dem, er resultatet sjældent et rent afbrud. Du får en vært, der accepterer klienter, men ikke indlæser noget, eller en vært, der ser lukket ud, indtil nogen læser kæderækkefølgen.

Den ene port, der ikke kan lukkes

VPN-lytteren skal acceptere forbindelser fra adresser, du ikke kan forudsige, så den er per definition en offentlig tjeneste. Det er den eneste undtagelse, designet er bygget omkring: én UDP-port til OpenVPN, én UDP-port til WireGuard, én TCP-port til en SSL VPN. Alt andet hører til bag tunnelen, hvilket betyder, at applikationstjenester bør binde til tunneladressen eller til loopback frem for til alle grænseflader.

Binding er dog ikke håndhævelse. En proces bundet til 0.0.0.0 er kun tilgængelig, hvis en regel tillader det, og standardpolitikken er reservevejen for trafik, som ingen regel matchede, ikke reglen der styrer porten. En accept placeret over din drop er stadig en accept, og at flytte en tjeneste væk fra den offentlige adresse er en selvstændig forbedring frem for en erstatning for kæden.

Input, forward og NAT besvarer forskellige spørgsmål

Inputtrafik er bestemt til værten selv, så det er der, VPN-lytteren og den administrative vej bor. Forwardtrafik passerer gennem værten, og tunnelklienter har brug for det plus net.ipv4.ip_forward=1. Den klassiske halvbrudte konfiguration tillader den udgående strøm og glemmer returretningen, så klienten fuldfører sit håndtryk og derefter indlæses intet; en conntrack-regel for etableret og relateret trafik dækker den retning.

NAT er det tredje spørgsmål. Uden en postrouting-omskrivning forlader videresendte pakker med tunnelens private kilde og droppes længere oppe, fordi intet netværk uden for værten ved, hvordan puljen skal routes tilbage. Kilde-præfikset i den regel skal matche VPN-puljen, ikke værtens egen adresse, og det samme gælder forwardreglen, der navngiver klientundernettet.

IPv6 er en anden politik, ikke en eftertanke. En vært med en streng IPv4-kæde og en åben ip6tables-politik har ikke lukket noget; tjenesterne er stadig tilgængelige over den anden familie. Enten spejl regelsættet med ip6tables, eller deaktiver IPv6 bevidst på den offentlige grænseflade, og skriv ned, hvilken du valgte.

En baseline, du kan læse i ét gennemløb

Start med drop, og tilføj derefter kun det, værten har brug for. Loopback og svar først, derefter den administrative vej, derefter tunnel-lytteren, derefter forwardpolitikken for klienter:

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

Grænsefladenavnene, porten og puljen er pladsholdere; læs dem fra serveren i stedet for at kopiere dem. At gemme resultatet er lige så vigtigt som at skrive det, for et regelsæt, der kun lever i hukommelsen, forsvinder ved næste genstart og åbner stille værten igen. Gør det vedvarende med distributionens mekanisme, og hold en kopi uden for maskinen til den dag, maskinen ikke vil starte.

Luk den sidste port uden at miste værten

Der er en hage i designet. Hvis SSH kun findes gennem tunnelen, tager en fejlet VPN-tjeneste SSH med sig, og den eneste vej tilbage kan være en konsol, du aldrig har åbnet. Før du lukker den sidste offentlige port, skal du bekræfte, at konsollen findes, og at du faktisk kan bruge den, eller beholde én smal administrativ vej, der ikke afhænger af tunnelen: SSH fra en fast adresse, kun nøgler, adgangskodegodkendelse slået fra.

Anvend ændringen fra en session, der allerede er etableret, ikke gennem den forbindelse, du er ved at filtrere. Planlæg en tilbagerulning, så en fejl udløber i stedet for at blive permanent, for eksempel et systemd-run --on-active=10min-job, der gendanner det forrige regelsæt, og hold en anden SSH-session åben, mens du tester den første. Bekræft derefter, at tilbagerulningsjobbet faktisk udløses, for uafprøvet gendannelse er det samme som ingen gendannelse.

Verificer vejen, ikke scriptet

Læs de indlæste regler, ikke filen, der skulle have indlæst dem. Fra en autoriseret ekstern vært, bekræft at kun de tilsigtede porte svarer; indefra tunnelen, bekræft at de tjenester, du ville offentliggøre, er tilgængelige. En standardafvisningspolitik, der også blokerer tunneltrafik, ser identisk ud med en fungerende lockdown, indtil nogen forsøger at bruge den.

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

Noter den tilladte port, klientpuljen, tunnelgrænsefladen, den administrative kilde og konsolproceduren ved siden af konfigurationen. Den næste ændring af puljen eller grænsefladenavnet skal matche både i filteret og i NAT-reglen, ellers vender værten tilbage til en halvåben tilstand, uden at nogen bemærker det.

Én vane er mere værd end regelsættet: efter hver ændring, bevis forwardvejen med en klientanmodning og bevis gendannelsesvejen med en anden session. En lockdown, du ikke har brugt, er en hypotese.

Relaterede artikler