Så här låser du Linux utgång så att inget läcker när VPN:en faller
Routing och filtrering är separata beslut. Lås utgångskroken och begränsa sedan undantagen för slutpunkt, DNS och administration som tunneln behöver för att återansluta.
Föreställ dig en medielåda på en hemmaanslutning som bara ska nå internet genom en tunnel. När tunneln faller bör applikationen stanna i stället för att tyst fortsätta över det fysiska gränssnittet. Att få det beteendet är ett brandväggsproblem och inte ett routingproblem, och skillnaden spelar roll eftersom en rutt kan ersättas av en omstart av daemonen medan ett filter stannar där du placerade det. Här följer hur paketvägen faktiskt avgör, och sedan hur undantagen som håller tunneln återansluten begränsas.
Lokal utgång är en annan krok än vidarebefordran
Ett paket som lämnar en applikation på maskinen passerar utgångskroken; ett paket som maskinen routar för en annan värd passerar vidarebefordran. En policy som bara nämner forward begränsar den andra och lämnar den första vidöppen, och därför ser så många utgångslås korrekta ut och gör ingenting. Gränssnittsmatchning hör till samma regel: oifname "tun0" accept släpper igenom trafik som redan routats ut genom tunneln. Routing och filtrering är också fortsatt separata beslut, så en uplink-rutt kan finnas medan filtret avvisar paketet. Det är den separationen du förlitar dig på.
En gateway som vidarebefordrar för andra enheter behöver båda krokarna. Att låsa bara utgången skyddar maskinen själv och lämnar varje klient längre ned fri att läcka.
Skriv undantagslistan från slutpunkten och utåt
Börja med tunnelns slutpunkt: en destinationsadress eller en liten godkänd mängd, transportprotokollet och destinationsporten, till exempel udp dport 1194 ip daddr 203.0.113.7 accept. Om klienten slår upp ett värdnamn behöver det inledande DNS-utbytet en egen regel begränsad till resolvern och till port 53, inte ett blankt tillstånd till den resolverns adress. Varje undantag bör namnge skälet till att det finns. Ett tillstånd för all UDP-trafik till VPN-porten täcker långt mer än den enda autentiserade tjänst du hade i åtanke.
Första uppslagningen är där låsen vanligtvis ruttnar. En adressmängd som uppdateras på en timer behöver definierat beteende när uppdateringen misslyckas, och det beteendet kan inte vara att öppna anslutningen förrän det lyckas. Uppdatera genom tunneln medan tunneln är uppe, och fall annars tillbaka på den senast kända friska slutpunkten.
Lokal administration behöver samma behandling. Ett administrationssubnät är inte pålitligt bara för att adresserna är privata, och en regel som litar på det bjuder in en andra väg runt låset.
Gränssnittsmatchning är inte bevis på en frisk tunnel
Regler som accepterar allt som lämnar tun0 antar att ett paket på det gränssnittet kom från tunneln. Gränssnittsnamn skapas om, och ett namn är inte en kryptografisk identitet. Peeren kan också vara borta medan gränssnittet står kvar, vilket gör regeln till en mycket övertygande icke-åtgärd.
Anslutningsspårning lägger till en besläktad fälla. En bred regel för etablerade anslutningar spelar upp tillståndet ett flöde fick tidigare, så en session som startade innan tunneln föll fortsätter efteråt. Begränsa tillståndsbaserat accepterande till de gränssnitt och adresser du faktiskt menar, annars har du byggt ett lås som öppnar sig självt. In- och utregler svarar också på olika frågor, och att härda den ena medan du ignorerar den andra lämnar maskinen nåbar i den riktning du inte tänkte på.
Vad som överlever en daemonkrasch
Ett filter som installeras av ett skript som körs efter att tunneln kommit upp försvinner tillsammans med tunneln, precis i det ögonblick det behövdes. Läs in låset vid start och låt daemonen bara hantera sina undantag.
Att ta bort standardrutten är inte heller någon ersättning. Rutten är tillstånd som daemonen äger och skriver om, och att ta bort den kan ta bort den väg som behövs för att återansluta. IPv6 behöver sin egen plan, eftersom grannupptäckt och routerannonseringar är länktjänster som måste fortsätta fungera medan vanlig trafik är blockerad. DHCP hör till samma kategori. Skriv ned dessa som undantag med ett syfte, i stället för att upptäcka dem senare som avbrott.
Återställningsväg före driftsättning
Testa låset så som det kommer att misslyckas: starta utan tunnel, döda daemonen, ändra slutpunkten och återanslut. Varje fall bör stoppa applikationerna och lämna återställningskanalen fungerande. Gör det från en konsol, eftersom ett fjärrskal är den session som mest sannolikt låses ute av din egen regel.
Kontrollera sedan vad en vanlig applikation fortfarande kan nå, med en ofarlig destination och en begäran du kan verifiera. Det resultat du vill ha är en avvisning på länken och framgång genom tunneln, inte en tvetydig timeout som kan betyda båda. Håll regeluppsättningen under samma ägare som resten av brandväggen i stället för att ersätta hela tabellen från ett skalskript. En policy där varje tillstånd kan motivera sig självt är värd mer än en lång regeluppsättning som ingen kan förklara.