Ien Linux-programma oan in VPN ferbine mei UID-regels
In UID-regel sjocht allinnich lokale sockets, en de gewoane loopback-útsûndering deadet de tunnel. Rûte it akkount earst, en filterje en ferifiearje dêrnei elke stap.
Ien programma oan in VPN ferbine op Linux is benammen in routingprobleem, en de firewall-regel beslút allinnich wat der bart neidat de rûte keazen is. As jo de UID fan it programma yn OUTPUT matsjje foardat de tunnel de standertrûte hat, dan smyt de regel krekt it ferkear fuort dat jo beskermje woene. Deselde regel kin ek it resolverproses net sjen dat de DNS-fragen fan it programma beantwurdet. Krij de folchoarder goed en ien akkount sûnder privileezjes wurdt in betroubere selektor foar de splitstunnel.
Jou it akkount earst in rûte, dan in oardiel
De eigener-matching beantwurdet ien fraach: hat in lokale socket dy't by dizze UID heart it pakket boud? It kiest gjin ynterface en it kin gjin ferkear ferpleatse dat de haadtabel al troch de fysike NIC stjoert. Dêrom blokkearret in UID-regel sûnder byhearrende rûte it programma yn stee fan it om te lieden.
Stjoer it akkount earst troch syn eigen tabel, en lit de firewall dêrnei it resultaat befêstigje. Dit wurket op in host waans iproute2 uidrange begrypt, wat ip rule help yn ien rigel meldt. Tabel 100 hâldt in standertrûte troch de tunnel, en de regel stjoert allinnich UID 1000 nei dy tabel. Al it oare bliuwt op de haadtabel en brûkt de fysike keppeling.
ip rule add uidrange 1000-1000 table 100 ip route add default dev tun0 table 100
In twadde akkount dat in oare tunnel nedich hat, krijt tabel 101 en syn eigen regel, om't twa profilen net beide de standertrûte yn deselde tabel hawwe kinne. NetworkManager-profylen binne systeembreed, dus dit part bliuwt hânmjittich, en de regels ferdwine by in reboot as neat se weromset. Skriuw de tabellen yn in bootskript njonken de tunneldefinysje, sadat in werferbining ien akkount net op it ferkearde paad efterlitte kin.
Wêrom't de loopback-útsûndering de tunnel deadet
De measte kopiearre ferzjes fan 'e regel smite elk pakket fuort dat net troch loopback fuortgiet. De tunnel is gjin loopback, dus dy foarm smyt ek it tunnelferkear fuort, en it resultaat liket in deade VPN yn stee fan in firewallflater.
As OUTPUT rint, hat de kernel al in útgongsynterface keazen, dus -o wurdt ferlike mei it antwurd fan 'e rûte, net mei de pakketkop. De eigener-matching wurdt allinnich yn OUTPUT en POSTROUTING rieplachte, en trochstjoerde pakketten drage gjin socket dy't it lêze kin. Dy kombinaasje betsjut dat de útsûndering de tunnel-ynterface neame moat en dy matching ûntkenne, net loopback ûntkenne.
Loopback fertsjinnet noch altyd syn eigen ACCEPT boppe de DROP, om't it earste DNS-pakket fan it programma nei de lokale stub giet oer lo. Set de twa regels yn dizze folchoarder, en it akkount berikt de stub, dan de tunnel, en neat oars.
iptables -I OUTPUT 1 -o lo -m owner --uid-owner vpnapp -j ACCEPT iptables -A OUTPUT -m owner --uid-owner vpnapp ! -o tun0 -j DROP
IPv6 is in aparte regelset, en in pear allinnich foar v4 lit ip6tables ûnoantaaste. In programma dat AAAA-records foarkar jout, soe dan troch de fysike keppeling fuortgean sûnder ea de DROP te berikken. Spiegelje beide regels yn ip6tables, of skeakelje IPv6 op 'e host út as de tunnel gjin v6-adres draacht. Regels dy't mei de hân tafoege binne, ferdwine ek by in reboot, dus bewarje se mei netfilter-persistent save of bou dizze logika wer as in nftables-tabel dy't troch de boot-ienheid laden wurdt.
DNS-antwurden komme fan in oar proses
De fraach fan it programma oan 127.0.0.53 giet troch de loopback-ACCEPT, en dêr stopet de UID-matching. De stub-resolver stjoert fan syn eigen tsjinstakkount út omheech, dus in regel dy't oan vpnapp keppele is, sjocht de twadde fraach nea. As de resolver in LAN-server foar de keppeling kiest, komme de antwurden werom oer de fysike NIC wylst de eigen pakketten fan it programma yn 'e tunnel bliuwe. It sichtbere resultaat is in wurkjende tunnel mei stikene nammen, of nammen beantwurde troch in server dy't jo net keazen hawwe.
Reparisearje de nammeresolúsje op 'e tunnelkeppeling, net yn 'e tapassing. Jou it tunnelprofyl in DNS-server en in routingdomein, en befêstigje dan mei resolvectl query en resolvectl status tun0 dat de resolver it brûkt foar de nammen dy't der ta dogge. Binnen in netwurk-namromte ferdwynt it probleem, om't de resolver fan 'e romte allinnich de tunnel ken.
Kontrolearje de regel fan it akkount sels ôf
Freegje de kernel hokker rûte in UID krijt, meitsje dan in fersyk as dat akkount en fergelykje it útgongsadres mei dat fan jo eigen akkount. As beide itselde adres melde, matchet de regel wat oars as it ferkear dat jo teste. It earste kommando hjirûnder toant de rûtesyking sûnder in pakket te stjoeren, wat in routingflater fan in firewallflater skiedt.
ip route get 1.1.1.1 uid 1000 sudo -u vpnapp curl -s https://ifconfig.co
Tellers litte sjen oft in regel ea ôfgien is. Rin iptables -vnL OUTPUT, lês it pakkettal njonken elke regel, en behannelje in nul njonken de DROP nei echt ferkear as in matchingsflater.
Trochstjoerd ferkear falt bûten dit ûntwerp. In container of VM efter in brêge hat gjin lokale socket dy't vpnapp hat, dus de eigener-matching giet nea ôf en dy pakketten folgje yn stee de FORWARD-policy. As dy wurklast dutsen wurde moat, test it apart en skriuw in policy dy't oan 'e brêge of it containeradres keppele is. It ûntwerp hâldt as de tabel, de ynterface-útsûndering, de resolver en de v6-regels allegear deselde kant út wize; lit ien fan harren weil en it akkount lekt of ferliest ferbining.