Om een poort om die VPN te stuur vereis beleidsroetering
’n NAT-reel herskryf adresse, maar kies nie ’n uitgangskakel nie. Hier is die reel, tabel en merk wat werklik een TCP-poort buite die tonnel hou.
Die versoek is altyd ’n variant van dieselfde sin: hou die VPN vir blaai, maar laat SSH of ’n rugsteuntaak die gewone verbinding gebruik. Die raad wat hieroor rondgaan, om die poort met iptables NAT-reels deur te stuur, doen dit nie. ’n NAT-reel herskryf adresse en poorte binne ’n vloei; dit kies nooit watter koppelvlak die pakket verlaat nie. Daardie besluit hoort by die roeteringsoektog, en die roeteringsoektog het hulp nodig om ’n poort te sien.
Waarom ’n gewone roete nie ’n poort kan pas nie
Linux kies ’n roete deur die bestemmingsadres in ’n tabel op te soek, nadat kandidaattabelle deur beleidsreels gefiltreer is. Daardie reels kan ’n vuurmuurmerk, ’n bronadres, ’n inkomende koppelvlak of ’n UID pas. ’n Roetevermelding het self geen poortveld nie, want die roete word gekies voordat die vervoerheader saak maak.
Huidige iproute2 en kerne verbreed die reelkeuse: ipproto, sport en dport word aanvaar, so ip rule add ipproto tcp dport 22 table 100 druk die bedoeling in een reel uit. Voer ip rule add help op die werklike gasheer uit om te sien of jou bou dport lys. As dit wel doen, is jy in een opdrag klaar; as dit nie doen nie, is die merkpad hieronder die ekwivalent.
Hoe dit ook al sy, die reel is net ’n wyser. Tabel 100 het steeds ’n roete nodig, en dit is die stuk wat mense vergeet.
Drie stukke, of een
Die moderne vorm is die enkele reel hierbo plus ’n roete in die alternatiewe tabel. Die klassieke vorm voeg netfilter in die middel by: merk die pakket, pas dan die merk in ’n reel. Albei eindig by dieselfde soektog; hulle verskil in waar die poort gelees word.
Die merkbenadering bestaan omdat netfilter die vervoerheader sien en die roeteringskode histories nie. Dit is die hele meganisme, en dit verduidelik waarom die terugval drie samewerkende stukke is eerder as een slim opdrag.
Die drie stukke in volgorde
Eerstens, merk die vloeie wat jy wil omlei, in ’n ketting wat vroeg genoeg loop sodat die merk bestaan voordat die roetebesluit geneem word:
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 0x1Tweedens, stuur gemerkte pakkette na ’n aparte tabel:
ip rule add fwmark 0x1/0x1 table 100Derdens, gee daardie tabel ’n verstekroete deur die fisiese skakel. Die adresse is illustratief; vervang dit met jou eie:
ip route add default via 192.168.1.1 dev wlan0 table 100Slaan die derde stap oor en die gemerkte pakket vind geen roete in tabel 100 nie, so dit misluk. Die simptoom lyk of die reel netwerk gebreek het, terwyl dit in werklikheid die enigste pad wat die pakket oorgehad het, verwyder het.
Wat dit laat werk ná die eerste pakket
Merkte geld vir uitgaande pakkette. Die antwoord kom op die fisiese koppelvlak in met die adres wat daardie skakel toegeken het, en die hooftabel verkies dalk steeds die tonnel vir daardie bestemming. Twee meganismes hou die antwoordpad konsekwent: ’n brongebaseerde reel vir die skakeladres, en verbindingsnasporing wat die besluit vir die leeftyd van die vloei bewaar. Om die merk in conntrack te stoor en by die antwoord te herstel, is die gewone manier om ’n staatvolle uitsondering stabiel te maak.
Agteruitpadfiltering is die ander stil moordenaar. As die kernel die terugpad streng valideer en die antwoord op ’n koppelvlak aankom wat die hooftabel nie sou kies nie, word die pakket sonder ’n boodskap laat val. rp_filter se verstekwaardes verskil per verspreiding en daarvolgens of die koppelvlak deurgestuur word, so lees die werklike waarde in plaas daarvan om aan te neem dit is af.
Moenie die tonnel se eie vervoer merk nie. ’n WireGuard- of UDP OpenVPN-tonnel is nie TCP 22 nie, so die resep hierbo is veilig, maar ’n uitsondering wat geskryf is as alles behalwe die tonnelbestemming kan die versleutelde pakkette vang en die tonnel breek op ’n manier wat soos ’n roeteringslus lees.
Kontroleer dit in plaas daarvan om aan te neem
Vra die kernel watter pad dit sou volg, vir die bestemming en vir die poort, en voer dan die werklike oordrag uit:
ip route get 203.0.113.10
ip rule show
nft list rulesetAs die merk bestaan maar die tellers nooit beweeg nie, pas die reel nie. Tellers is die verskil tussen ’n konfigurasie wat jy geskryf het en ’n beleid wat die kernel toepas.
Wanneer dit die verkeerde gereedskap is
Poortgebaseerde uitsonderings is van nature bros. Dienste skuif poorte, HTTP/3 kom as UDP 443, en een toepassing kan verskeie vloeie van verskillende soorte oopmaak. As die werklike vereiste is dat hierdie program die gewone skakel gebruik, is die roeteringslaag die verkeerde plek; ’n netwerknaamruimte of ’n proxy per toepassing pas beter.
As die vereiste is dat hierdie subnet die gewone skakel gebruik, slaan die merke heeltemal oor en voeg ’n meer spesifieke roete by. Dit is eenvoudiger, dit is in een tabel sigbaar, en die volgende persoon kan dit oudit sonder om ’n reelstel te lees.
Skryf neer watter van die drie vereistes jy werklik het voordat jy aan die vuurmuur raak. Die meganisme hierbo is presies, en presiesheid wat op die verkeerde laag toegepas word, is net ’n langer onderbreking.