Ang paglampas sa VPN para sa isang port ay nangangailangan ng policy routing
Binabago ng NAT rule ang mga address, pero hindi ito pumipili ng palabas na link. Narito ang rule, table at mark na talagang nagpapanatili ng isang TCP port sa labas ng tunnel.
Ang kahilingan ay palaging isang bersyon ng parehong pangungusap: panatilihin ang VPN para sa pag-browse, pero hayaang gumamit ang SSH o isang backup job ng normal na koneksyon. Ang payong umiikot tungkol dito, ang i-forward ang port gamit ang mga NAT rule ng iptables, ay hindi iyon ginagawa. Binabago ng NAT rule ang mga address at port sa loob ng isang flow; hindi ito kailanman pumipili kung aling interface lalabas ang packet. Ang desisyong iyon ay pag-aari ng paghahanap ng ruta, at ang paghahanap ng ruta ay kailangan ng tulong upang makita ang isang port.
Bakit hindi matugma ng ordinaryong ruta ang isang port
Pumipili ang Linux ng ruta sa pamamagitan ng paghahanap ng destinasyong address sa isang table, pagkatapos salain ang mga kandidatong table sa pamamagitan ng mga policy rule. Ang mga rule na iyon ay maaaring tumugma sa mark ng firewall, source address, papasok na interface o UID. Ang route entry mismo ay walang port field, dahil pinipili ang ruta bago maging mahalaga ang transport header.
Pinalalawak ng kasalukuyang iproute2 at mga kernel ang rule selector: ipproto, sport at dport ay tinatanggap, kaya ip rule add ipproto tcp dport 22 table 100 ay nagpapahayag ng layunin sa isang linya. Patakbuhin ang ip rule add help sa aktwal na host upang makita kung nakalista sa build mo ang dport. Kung oo, tapos ka sa isang command; kung hindi, ang mark path sa ibaba ang katumbas.
Sa alinmang paraan, ang rule ay pointer lamang. Kailangan pa rin ng table 100 ng ruta, at iyon ang bahaging nakakalimutan ng mga tao.
Tatlong piraso, o isa
Ang modernong anyo ay ang nag-iisang rule sa itaas kasama ang ruta sa alternatibong table. Ang klasikong anyo ay nagdaragdag ng netfilter sa gitna: markahan ang packet, pagkatapos itugma ang mark sa isang rule. Pareho silang nagtatapos sa parehong paghahanap; nagkakaiba sila sa kung saan binabasa ang port.
Umiiral ang mark approach dahil nakikita ng netfilter ang transport header at historically ay hindi ito nakikita ng routing code. Iyon ang buong mekanismo, at ipinapaliwanag nito kung bakit ang fallback ay tatlong pirasong nagtutulungan sa halip na isang matalinong command.
Ang tatlong piraso sa ayos
Una, markahan ang mga flow na gusto mong ilihis, sa isang chain na tumatakbo nang sapat na maaga upang umiral ang mark bago ang desisyon sa ruta:
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 0x1Ikalawa, ipadala ang mga markadong packet sa hiwalay na table:
ip rule add fwmark 0x1/0x1 table 100Ikatlo, bigyan ang table na iyon ng default na ruta sa pisikal na link. Ang mga address ay halimbawa lamang; palitan ng sa iyo:
ip route add default via 192.168.1.1 dev wlan0 table 100Laktawan ang ikatlong hakbang at ang markadong packet ay walang makitang ruta sa table 100, kaya nabigo ito. Ang sintomas ay parang sinira ng rule ang network, gayong inalis lang nito ang natitirang tanging landas ng packet.
Ano ang nagpapanatili nitong gumagana pagkatapos ng unang packet
Naaangkop ang mga mark sa mga palabas na packet. Dumarating ang tugon sa pisikal na interface na may address na itinalaga ng link, at maaaring mas gusto pa rin ng pangunahing table ang tunnel para sa destinasyong iyon. Dalawang mekanismo ang nagpapanatili ng tugmang landas ng tugon: isang rule na nakabatay sa source para sa address ng link, at connection tracking na nag-iingat ng desisyon sa buong buhay ng flow. Ang pag-save ng mark sa conntrack at pag-restore nito sa tugon ay ang karaniwang paraan upang gawing matatag ang isang exception na may state.
Ang reverse-path filtering ang isa pang tahimik na killer. Kung mahigpit na vine-validate ng kernel ang pabalik na landas at dumarating ang tugon sa interface na hindi pipiliin ng pangunahing table, itinatapon ang packet nang walang mensahe. rp_filter ang mga default ay nagkakaiba ayon sa distribution at sa kung ipinapasa ang interface, kaya basahin ang epektibong halaga sa halip na ipagpalagay na patay ito.
Huwag markahan ang sariling transport ng tunnel. Ang WireGuard o UDP OpenVPN tunnel ay hindi TCP 22, kaya ligtas ang recipe sa itaas, pero ang exception na isinulat bilang lahat maliban sa destinasyon ng tunnel ay maaaring mahuli ang mga naka-encrypt na packet at sirain ang tunnel sa paraang parang routing loop.
Suriin sa halip na ipagpalagay
Tanungin ang kernel kung aling landas ang tatahakin nito, para sa destinasyon at para sa port, pagkatapos patakbuhin ang tunay na paglilipat:
ip route get 203.0.113.10
ip rule show
nft list rulesetKung umiiral ang mark pero hindi gumagalaw ang mga counter, hindi tumutugma ang rule. Ang mga counter ang pagkakaiba ng configuration na isinulat mo at ng policy na inilalapat ng kernel.
Kung kailan ito ang maling tool
Ang mga exception na nakabatay sa port ay marupok sa kalikasan. Naglilipat ng port ang mga serbisyo, dumarating ang HTTP/3 bilang UDP 443, at ang isang application ay maaaring magbukas ng ilang flow na iba't ibang uri. Kung ang tunay na pangangailangan ay gamitin ng programang ito ang normal na link, mali ang routing layer; mas bagay ang network namespace o proxy kada application.
Kung ang pangangailangan ay gamitin ng subnet na ito ang normal na link, laktawan nang lubusan ang mga mark at magdagdag ng mas tiyak na ruta. Mas simple ito, nakikita sa isang table, at masusuri ito ng susunod na tao nang hindi binabasa ang isang ruleset.
Isulat kung alin sa tatlong pangangailangan ang tunay na mayroon ka bago hawakan ang firewall. Tumpak ang mekanismo sa itaas, at ang katumpakang inilapat sa maling layer ay mas mahabang downtime lang.