VPS-brannmur: åpne bare VPN-porten, og bevis det etterpå
Én port må forbli offentlig, ellers kobler ingen klient til. Avvis resten, hold videresending atskilt fra inngående trafikk, og la det stå igjen en gjenopprettingsvei du har testet på forhånd.
En brannmur som bare slipper inn VPN-porten, er ikke én regel. Det er tre separate beslutninger som tilfeldigvis gjelder samme portnummer: inngangskjeden avgjør hva som kan nå en lokal prosess, videresendingskjeden avgjør hva som kan passere gjennom verten på vegne av tunnelklienter, og NAT-tabellen skriver om kildeadressen på vei ut. Tar du feil på én av dem, er resultatet sjelden et rent avbrudd. Du får en vert som godtar klienter, men ikke laster noe, eller en vert som ser lukket ut helt til noen leser rekkefølgen i kjedene.
Den ene porten som ikke kan lukkes
VPN-lytteren må godta tilkoblinger fra adresser du ikke kan forutsi, og er derfor en offentlig tjeneste per definisjon. Dette er det eneste unntaket designet er bygget rundt: én UDP-port for OpenVPN, én UDP-port for WireGuard, én TCP-port for en SSL VPN. Alt annet hører til bak tunnelen, noe som betyr at applikasjonstjenester bør binde seg til tunneladressen eller til loopback i stedet for til alle grensesnitt.
Binding er likevel ikke håndheving. En prosess bundet til 0.0.0.0 er bare tilgjengelig hvis en regel slipper den inn, og standardpolicyen er reserveveien for trafikk som ingen regel matchet, ikke regelen som styrer porten. En accept plassert over din drop er fortsatt en accept, og å flytte en tjeneste bort fra den offentlige adressen er en selvstendig forbedring, ikke en erstatning for kjeden.
Inngang, videresending og NAT svarer på ulike spørsmål
Inngående trafikk er adressert til verten selv, så det er der VPN-lytteren og den administrative veien bor. Videresendingstrafikk passerer gjennom verten, og tunnelklienter trenger den i tillegg til net.ipv4.ip_forward=1. Den klassiske halvødelagte konfigurasjonen tillater den utgående strømmen og glemmer returretningen, så klienten fullfører håndtrykket og deretter lastes ingenting; en conntrack-regel for etablert og relatert trafikk dekker den retningen.
NAT er det tredje spørsmålet. Uten omskriving i postrouting forlater videresendte pakker verten med tunnelens private kilde og droppes lenger oppe, fordi ingen nettverk utenfor verten vet hvordan poolen skal rutes tilbake. Kilde-prefikset i den regelen må samsvare med VPN-poolen, ikke med vertens egen adresse, og det samme gjelder videresendingsregelen som navngir klientnettet.
IPv6 er en andre policy, ikke en ettertanke. En vert med streng IPv4-kjede og åpen policy på ip6tables har ikke lukket noe; tjenestene er fortsatt tilgjengelige over den andre familien. Enten speil regelsettet med ip6tables, eller deaktiver IPv6 bevisst på det offentlige grensesnittet, og skriv ned hvilket du valgte.
En grunnlinje du kan lese i én gjennomgang
Start med drop, og legg deretter bare til det verten trenger. Først loopback og svar, deretter den administrative veien, deretter tunnel-lytteren, deretter videresendingspolicyen 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 MASQUERADEGrensesnittnavnene, porten og poolen er plassholdere; les dem fra serveren i stedet for å kopiere dem. Å lagre resultatet er like viktig som å skrive det, for et regelsett som bare lever i minnet, forsvinner ved neste omstart og åpner verten stille igjen. Gjør det varig med distribusjonens mekanisme, og hold en kopi utenfor maskinen for den dagen maskinen ikke vil starte.
Lukke den siste porten uten å miste verten
Det er en hake i designet. Hvis SSH bare finnes gjennom tunnelen, tar en mislykket VPN-tjeneste SSH med seg, og den eneste veien tilbake kan være en konsoll du aldri har åpnet. Før du lukker den siste offentlige porten, bekreft at den konsollen finnes og at du faktisk kan bruke den, eller behold én smal administrativ vei som ikke avhenger av tunnelen: SSH fra en fast adresse, bare nøkler, passordautentisering av.
Bruk endringen fra en økt som allerede er etablert, ikke gjennom tilkoblingen du er i ferd med å filtrere. Planlegg en tilbakerulling slik at en feil utløper i stedet for å bli permanent, for eksempel en systemd-run --on-active=10min-jobb som gjenoppretter forrige regelsett, og hold en andre SSH-økt åpen mens du tester den første. Kontroller deretter at tilbakerullingsjobben faktisk utløses, for u-testet gjenoppretting er det samme som ingen gjenoppretting.
Verifiser veien, ikke skriptet
Les de lastede reglene, ikke filen som skulle laste dem. Fra en autorisert ekstern vert, bekreft at bare de tiltenkte portene svarer; fra innsiden av tunnelen, bekreft at tjenestene du ville publisere er tilgjengelige. En standard-avvisningspolicy som også blokkerer tunneltrafikk, ser identisk ut med en fungerende nedlåsing helt til noen prøver å bruke den.
iptables -S
iptables -t nat -S
ss -lntup
ip -4 addr showNoter den tillatte porten, klientpoolen, tunnelgrensesnittet, den administrative kilden og konsollprosedyren ved siden av konfigurasjonen. Den neste endringen i poolen eller grensesnittnavnet må følges opp både i filteret og i NAT-regelen, ellers går verten tilbake til en halvåpen tilstand uten at noen merker det.
Én vane er verdt mer enn regelsettet: etter hver endring, bevis videresendingsveien med en klientforespørsel og gjenopprettingsveien med en andre økt. En nedlåsing du ikke har brukt, er en hypotese.