Å omgå en VPN for én port krever policy-ruting
En NAT-regel skriver om adresser, men velger ikke en utgående lenke. Her er regelen, tabellen og merket som faktisk holder én TCP-port utenfor tunnelen.
Forespørselen er alltid en variant av den samme setningen: behold VPN-en for nettlesing, men la SSH eller en sikkerhetskopijobb bruke den vanlige forbindelsen. Rådet som sirkulerer om dette, å videresende porten med iptables NAT-regler, gjør ikke det. En NAT-regel skriver om adresser og porter inne i en strøm; den velger aldri hvilket grensesnitt pakken forlater. Den avgjørelsen hører til ruteoppslaget, og ruteoppslaget trenger hjelp for å se en port.
Hvorfor en vanlig rute ikke kan matche en port
Linux velger en rute ved å slå opp måladdressen i en tabell, etter at kandidattabeller er filtrert gjennom policy-regler. Disse reglene kan matche et brannmurmerke, en kildeaddresse, et innkommende grensesnitt eller en UID. En ruteoppføring har selv ikke noe portfelt, fordi ruten velges før transportoverskriften betyr noe.
Dagens iproute2 og kjerner utvider regelvelgeren: ipproto, sport og dport godtas, så ip rule add ipproto tcp dport 22 table 100 uttrykker intensjonen på én linje. Kjør ip rule add help på den faktiske verten for å se om bygget ditt lister dport. Hvis det gjør det, er du ferdig med én kommando; hvis ikke, er merkestien nedenfor ekvivalenten.
Uansett er regelen bare en peker. Tabell 100 trenger fortsatt en rute, og det er den biten folk glemmer.
Tre biter, eller én
Den moderne formen er den ene regelen ovenfor pluss en rute i den alternative tabellen. Den klassiske formen legger netfilter i midten: merk pakken, og match deretter merket i en regel. Begge ender i samme oppslag; de skiller seg i hvor porten leses.
Merkemetoden finnes fordi netfilter ser transportoverskriften og rutekoden historisk ikke gjorde det. Det er hele mekanismen, og det forklarer hvorfor reserveveien er tre samarbeidende biter i stedet for én smart kommando.
De tre bitene i rekkefølge
Først, merk strømmene du vil omdirigere, i en kjede som kjører tidlig nok til at merket finnes før ruteavgjørelsen:
nft add table inet vpnexempt
nft 'add chain inet vpnexempt out { type route hook output priority mangle; }'
nft add rule inet vpnexempt out tcp dport 22 meta mark set 0x1Deretter, send merkede pakker til en egen tabell:
ip rule add fwmark 0x1/0x1 table 100Til slutt, gi den tabellen en standardrute gjennom den fysiske lenken. Adressene er illustrative; bytt ut med dine egne:
ip route add default via 192.168.1.1 dev wlan0 table 100Hopp over det tredje trinnet og den merkede pakken finner ingen rute i tabell 100, så den feiler. Symptomet ser ut som om regelen ødela nettverket, mens den faktisk fjernet den eneste veien pakken hadde igjen.
Hva som holder det i gang etter den første pakken
Merker gjelder for utgående pakker. Svaret kommer inn på det fysiske grensesnittet med adressen lenken tildelte, og hovedtabellen kan fortsatt foretrekke tunnelen for det målet. To mekanismer holder svarveien konsistent: en kildebasert regel for lenkeadressen, og connection tracking som bevarer avgjørelsen gjennom hele strømmen. Å lagre merket i conntrack og gjenopprette det på svaret er den vanlige måten å gjøre et stateful unntak stabilt på.
Reverse-path-filtrering er den andre stille drapsmannen. Hvis kjernen validerer returveien strengt og svaret kommer inn på et grensesnitt hovedtabellen ikke ville velge, blir pakken droppet uten melding. rp_filter standardverdier varierer mellom distribusjoner og med om grensesnittet videresendes, så les den effektive verdien i stedet for å anta at den er av.
Ikke merk tunnelens egen transport. En WireGuard- eller UDP OpenVPN-tunnel er ikke TCP 22, så oppskriften ovenfor er trygg, men et unntak skrevet som alt unntatt tunnelmålet kan fange de krypterte pakkene og bryte tunnelen på en måte som ligner en ruteløkke.
Sjekk det i stedet for å anta
Spør kjernen hvilken vei den ville ta, for målet og for porten, og kjør deretter den virkelige overføringen:
ip route get 203.0.113.10
ip rule show
nft list rulesetHvis merket finnes men tellerne aldri beveger seg, matcher ikke regelen. Tellere er forskjellen mellom en konfigurasjon du skrev og en policy kjernen anvender.
Når dette er feil verktøy
Portbaserte unntak er skjøre av natur. Tjenester flytter porter, HTTP/3 kommer som UDP 443, og én applikasjon kan åpne flere strømmer av ulike slag. Hvis det virkelige kravet er at dette programmet bruker den vanlige lenken, er rutelaget feil sted; et nettverksnavnerom eller en proxy per applikasjon passer bedre.
Hvis kravet er at dette subnettet bruker den vanlige lenken, hopp over merkene helt og legg til en mer spesifikk rute. Det er enklere, det er synlig i én tabell, og den neste personen kan revidere det uten å lese et regelsett.
Skriv ned hvilket av de tre kravene du faktisk har før du rører brannmuren. Mekanismen ovenfor er presis, og presisjon brukt på feil lag er bare et lengre avbrudd.