At føre én port uden om VPN kræver policy-routing
En NAT-regel omskriver adresser, men vælger ikke et udgående link. Her er reglen, tabellen og mærket, som faktisk holder én TCP-port uden for tunnelen.
Anmodningen er altid en variant af den samme sætning: behold VPN til browsing, men lad SSH eller et backupjob bruge den normale forbindelse. Det råd, der cirkulerer om dette, at videresende porten med iptables NAT-regler, gør det ikke. En NAT-regel omskriver adresser og porte inde i en strøm; den vælger aldrig, hvilken grænseflade pakken forlader via. Den beslutning hører til ruteopslaget, og ruteopslaget har brug for hjælp til at se en port.
Hvorfor en almindelig rute ikke kan matche en port
Linux vælger en rute ved at slå destinationsadressen op i en tabel, efter at kandidattabeller er filtreret gennem policy-regler. De regler kan matche et firewall-mærke, en kildeadresse, en indgående grænseflade eller en UID. Selve ruteindgangen har intet portfelt, fordi ruten vælges, før transportheaderen betyder noget.
Nutidens iproute2 og kerner udvider reglens vælger: ipproto, sport og dport accepteres, så ip rule add ipproto tcp dport 22 table 100 udtrykker hensigten på én linje. Kør ip rule add help på den faktiske vært for at se, om din build viser dport. Hvis den gør, er du færdig med én kommando; hvis ikke, er mærkevejen nedenfor ækvivalenten.
Uanset hvad er reglen kun en pegepind. Tabel 100 har stadig brug for en rute, og det er den del, folk glemmer.
Tre dele, eller én
Den moderne form er den enkelte regel ovenfor plus en rute i den alternative tabel. Den klassiske form tilføjer netfilter i midten: mærk pakken, og match så mærket i en regel. Begge ender i samme opslag; de adskiller sig i, hvor porten læses.
Mærketilgangen findes, fordi netfilter ser transportheaderen, og rutekoden historisk ikke gjorde. Det er hele mekanismen, og den forklarer, hvorfor reservevejen er tre samarbejdende dele og ikke én smart kommando.
De tre dele i rækkefølge
Først markeres de strømme, du vil omdirigere, i en kæde, der kører tidligt nok til, at mærket findes før rutebeslutningen:
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 0x1Dernæst sendes markerede pakker til en separat tabel:
ip rule add fwmark 0x1/0x1 table 100For det tredje gives den tabel en standardrute gennem det fysiske link. Adresserne er eksempler; indsæt dine egne:
ip route add default via 192.168.1.1 dev wlan0 table 100Spring tredje trin over, og den markerede pakke finder ingen rute i tabel 100, så den fejler. Symptomet ligner, at reglen brød netværket, mens den i virkeligheden fjernede den eneste vej, pakken havde tilbage.
Hvad holder det kørende efter den første pakke
Mærker gælder for udgående pakker. Svaret ankommer på den fysiske grænseflade med den adresse, linket tildelte, og hovedtabellen foretrækker måske stadig tunnelen for den destination. To mekanismer holder svarvejen konsistent: en kildebaseret regel for linkadressen og forbindelsessporing, der bevarer beslutningen hele strømmens levetid. At gemme mærket i conntrack og gendanne det på svaret er den sædvanlige måde at gøre en tilstandsfuld undtagelse stabil.
Filtrering af omvendt vej er den anden tavse dræber. Hvis kernen validerer returvejen strengt, og svaret ankommer på en grænseflade, hovedtabellen ikke ville vælge, kasseres pakken uden en meddelelse. rp_filter standardværdier varierer efter distribution og efter, om grænsefladen videresendes, så læs den effektive værdi i stedet for at antage, at den er slået fra.
Mærk ikke tunnelens egen transport. En WireGuard- eller UDP OpenVPN-tunnel er ikke TCP 22, så opskriften ovenfor er sikker, men en undtagelse skrevet som alt undtagen tunnelens destination kan fange de krypterede pakker og bryde tunnelen på en måde, der ligner en ruteløkke.
Kontroller det i stedet for at antage
Spørg kernen, hvilken vej den ville tage, for destinationen og for porten, og kør så den rigtige overførsel:
ip route get 203.0.113.10
ip rule show
nft list rulesetHvis mærket findes, men tællerne aldrig flytter sig, matcher reglen ikke. Tællere er forskellen på en konfiguration, du skrev, og en politik, kernen anvender.
Hvornår er det det forkerte værktøj
Portbaserede undtagelser er skrøbelige af natur. Tjenester flytter porte, HTTP/3 kommer som UDP 443, og én applikation kan åbne flere strømme af forskellige slags. Hvis det egentlige krav er, at dette program bruger det normale link, er rutelaget det forkerte sted; et netværksnavnerum eller en proxy pr. applikation passer bedre.
Hvis kravet er, at dette subnet bruger det normale link, så spring mærkerne helt over og tilføj en mere specifik rute. Det er enklere, det er synligt i én tabel, og den næste person kan revidere det uden at læse et regelsæt.
Skriv ned, hvilket af de tre krav du egentlig har, før du rører firewallen. Mekanismen ovenfor er præcis, og præcision anvendt på det forkerte lag er bare en længere nedetid.