NAT av LAN genom tun0 på en OpenBSD VPN-gateway
Välj mellan käll-NAT och en returväg för LAN-trafik som lämnar en OpenBSD tun0-utgång, placera sedan nat-to-regeln där pf fortfarande släpper igenom den.
Två ingenjörer med samma OpenBSD-gateway ger dig ofta två olika regelverk för att nå ett avlägset nätverk, och båda går att försvara. Valet mellan källöversättning och en returväg är inte alls en syntaxfråga. Allt hänger på vad den andra sidan redan vet om 192.168.88.0/24 och vad du behöver behålla i loggarna. Gör fel här och nat-to-raden ser perfekt ut medan svaren försvinner i den avlägsna standardgatewayen.
Routing och omskrivning svarar på olika frågor
Routingtabellen avgör att 172.20.0.0/16 går att nå via tun0, och det beslutet fattas innan någon pf-översättning konsulteras. Källöversättningen ändrar sedan paketets huvud så att fjärrsidan ser gatewayens tunneladress i stället för en LAN-värd. Ingen av mekanismerna ersätter den andra: en nat-regel kan inte trolla fram en rutt, och en rutt kan inte övertyga en avlägsen router som aldrig hört talas om ditt privata subnät. När den andra sidan saknar returväg kastas svaren eller skickas vidare till dess standardgateway, och ingen mängd regeljustering fixar det.
Enkelt uttryckt svarar vidarebefordran på vart trafiken tar vägen och översättning på varifrån den ser ut att komma. Håll dem i separata mentala lådor medan du designar regelverket.
Tre villkor som avgör
Ställ tre frågor i ordning och designen väljer sig oftast själv. Har fjärrnätverket en statisk rutt som pekar på tunneladressen för 192.168.88.0/24, eller kontrollerar dess administratör routrarna på den vägen? Om ja, låt LAN-adresserna färdas oförändrade och hoppa över översättningen helt. Behöver du synlighet per klient på andra sidan, antingen för åtkomstpolicy eller för spårbarhet? Om ja, är det värt routingarbetet att bevara källan. Är tunneladressen stabil nog att skrivas in i en avlägsen rutt, eller flyttar den sig mellan återanslutningar?
Om något svar är nej eller okänt är nat-to det pragmatiska alternativet, och det är också det som går att backa. En översättningsregel tas bort på en rad när den andra sidan lägger till en ordentlig rutt. En returväg som aldrig installerades kostar dig en supporttråd varje gång någon frågar varför tunneln bara fungerar åt ett håll.
Placera fragmentet så att pf faktiskt utvärderar det
Fragmentet nedan förutsätter att LAN är 192.168.88.0/24, fjärrnätverket är 172.20.0.0/16 och tunnelgränssnittet är tun0. Inget i det väljer nästa hopp. Det skriver bara om källan på paket som redan lämnar via tunneln.
match out on tun0 inet from 192.168.88.0/24 to 172.20.0.0/16 nat-to (tun0)
pass in on em0 inet from 192.168.88.0/24 to any keep state
Två detaljer i den första raden bär det mesta av tyngden. Parenteserna runt tun0 säger till pf att läsa gränssnittsadressen varje gång det bygger en tillståndspost, vilket spelar roll när tunneln numreras om efter en återanslutning. Ordet match betyder att regeln skriver om och sedan faller igenom, så en separat pass-regel måste fortfarande släppa igenom flödet. Gränssnittet som nämns i match-raden måste också vara det som routingtabellen väljer, annars utvärderar pf regeln på en annan utgående väg än den paketet faktiskt tar.
Glöm inte kärnsidan. IPv4-vidarebefordran måste vara aktiverad, och stateful pass-regler för tunnel och LAN måste finnas innan allt detta betyder något. PF NAT-avsnittet i OpenBSD FAQ är rätt referens för nyckelordsordningen här.
Verifiera regelverket innan du litar på trafiken
Kontrollera syntaxen först med pfctl -nf /etc/pf.conf, som tolkar filen utan att ladda den. Ladda sedan policyn och läs tillbaka vad kärnan faktiskt håller, eftersom en regel som tolkades rent fortfarande kan vara skuggad eller fäst vid fel gränssnitt. pfctl -sn skriver ut översättningsregler i laddad form och pfctl -sr skriver ut filterregler i utvärderingsordning.
Titta sedan på kabeln. På gatewayen visar tcpdump -ni tun0 'host 172.20.0.10' om källadressen som lämnar tunneln är tunneladressen eller LAN-värden. En snabb netstat -rn -f inet bekräftar vilket gränssnitt målet löses till. När trafiken börjar flöda listar pfctl -ss tillståndsposter; om ett flöde inte skapade något tillstånd träffade paketet aldrig en regel som skapar ett.
Om tunnelsidan ser rätt ut och svaren fortfarande inte kommer, sluta redigera pf. Det kvarvarande felet sitter i den avlägsna routern, där svaret skickas mot en privat adress som den sidan inte kan nå.
När översättningen kostar mer än den sparar
Översättning döljer klienter, och ibland är det precis fel byte. Överlappande subnät är ett fall: om den andra sidan även internt använder 192.168.88.0/24 gör det kollisionen värre, inte bättre, att presentera LAN-värdar som gatewayen. IPsec-policyer som väljer trafik efter adresspar är ett annat, eftersom säkerhetspolicy-databasen matchas före översättningen och aldrig ser det omskrivna paketet. Varje utrullning som fakturerar, stryper eller granskar per användare förlorar också den identitet den behöver i samma stund som källan kollapsar till en enda adress.
Portabla pf-derivat är en egen fälla. Produkter som genererar sina egna regelfiler förväntar sig att NAT konfigureras via deras gränssnitt, och handredigerade fragment skrivs över vid nästa omladdning. Regelverk kopierade från guider skrivna innan nyckelordet match fanns laddas inte på en nuvarande kärna, så porta syntaxen och läs felet i stället för att gissa.
Beslutsregeln som överlever kontakt med riktiga nätverk är kort: installera en returväg när du kan, översätt när du inte kan, och skriv ned vilket av de tre villkoren som fick dig att välja. Den anteckningen sparar nästa person en eftermiddag.