Yhden Linux-sovelluksen sitominen VPN:ään UID-säännöillä
UID-sääntö näkee vain paikalliset pistokkeet, ja tavallinen loopback-poikkeus tappaa tunnelin. Reititä tili ensin ja sitten suodata ja varmista jokainen vaihe.
Yhden ohjelman sitominen VPN:ään Linuxissa on enimmäkseen reititysongelma, ja palomuurisääntö päättää vain siitä, mitä tapahtuu sen jälkeen, kun reitti on valittu. Jos yhdistät ohjelman UID:n OUTPUTissa ennen kuin tunneli omistaa oletusreitin, sääntö pudottaa juuri sen liikenteen, jonka halusit suojata. Sama sääntö ei myöskään näe resolveriprosessia, joka vastaa ohjelman DNS-kyselyihin. Laita järjestys kuntoon, ja yhdestä tilistä ilman oikeuksia tulee jaetun tunnelin luotettava valitsija.
Anna tilille reitti ennen tuomiota
Omistajan täsmäytys vastaa yhteen kysymykseen: rakensiko tähän UID:hen kuuluva paikallinen pistoke paketin? Se ei valitse rajapintaa eikä voi siirtää liikennettä, jonka päätaulu lähettää jo fyysisen NIC:n kautta. Siksi UID-sääntö ilman vastaavaa reittiä estää ohjelman sen uudelleenohjaamisen sijaan.
Ohjaa tili ensin oman taulunsa läpi ja anna sitten palomuurin vahvistaa tulos. Tämä toimii isännällä, jonka iproute2 ymmärtää uidrangea, minkä ip rule help kertoo yhdellä rivillä. Taulu 100 pitää oletusreitin tunnelin läpi, ja sääntö lähettää vain UID 1000:n siihen tauluun. Kaikki muu pysyy päätaulussa ja käyttää edelleen fyysistä yhteyttä.
ip rule add uidrange 1000-1000 table 100 ip route add default dev tun0 table 100
Toinen tili, joka tarvitsee eri tunnelin, saa taulun 101 ja oman sääntönsä, koska kaksi profiilia ei voi molemmat omistaa oletusreittiä samassa taulussa. NetworkManagerin profiilit ovat järjestelmänlaajuisia, joten tämä osa pysyy käsityönä, ja säännöt katoavat uudelleenkäynnistyksessä, ellei jokin palauta niitä. Kirjoita taulut käynnistysskriptiin tunnelin määritelmän viereen, jotta uudelleenyhdistäminen ei voi jättää yhtä tiliä väärälle polulle.
Miksi loopback-poikkeus tappaa tunnelin
Useimmat kopioidut säännön versiot pudottavat jokaisen paketin, joka ei lähde loopbackin kautta. Tunneli ei ole loopback, joten tuo muoto pudottaa myös tunnelin liikenteen, ja tulos näyttää kuolleelta VPN:ltä eikä palomuurivirheeltä.
Kun OUTPUT suoritetaan, ydin on jo valinnut lähtörajapinnan, joten -o verrataan reitin vastaukseen eikä paketin otsikkoon. Omistajan täsmäytys tarkistetaan vain OUTPUTissa ja POSTROUTINGissa, eikä välitetyissä paketeissa ole pistoketta, jota se voisi lukea. Tämä yhdistelmä tarkoittaa, että poikkeuksen on nimettävä tunnelin rajapinta ja kiistettävä tuo täsmäytys, eikä kiistettävä loopbackia.
Loopback ansaitsee yhä oman ACCEPTinsa DROPin yläpuolella, koska ohjelman ensimmäinen DNS-paketti menee paikalliseen stubiin lo kautta. Laita kaksi sääntöä tähän järjestykseen, ja tili saavuttaa stubin, sitten tunnelin, eikä mitään muuta.
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 on erillinen sääntökokonaisuus, ja vain v4:lle tarkoitettu pari jättää ip6tables koskemattomaksi. Ohjelma, joka suosii AAAA-tietueita, lähtisi silloin fyysisen yhteyden kautta koskaan DROPia saavuttamatta. Peilaa molemmat säännöt ip6tables:iin, tai poista IPv6 käytöstä isännällä, kun tunneli ei kanna v6-osoitetta. Käsin lisätyt säännöt katoavat myös uudelleenkäynnistyksessä, joten tallenna ne netfilter-persistent save:llä tai rakenna sama logiikka uudelleen nftables-tauluna, jonka käynnistysyksikkö lataa.
DNS-vastaukset tulevat toisesta prosessista
Ohjelman kysely 127.0.0.53:lle ohittaa loopback-ACCEPTin, ja juuri siinä UID-täsmäytys pysähtyy. Stub-resolver välittää ylöspäin omalta palvelutililtään, joten sääntö, joka on sidottu vpnapp:een, ei näe koskaan toista kyselyä. Jos resolver valitsee yhteydelle LAN-palvelimen, vastaukset palaavat fyysisen NICin kautta, kun ohjelman omat paketit jäävät tunneliin. Näkyvä tulos on toimiva tunneli rikkinäisillä nimillä tai nimillä, joihin vastaa palvelin, jota et valinnut.
Korjaa nimien selvitys tunnelin yhteydellä, älä sovelluksessa. Anna tunneliprofiilille DNS-palvelin ja reititysverkkotunnus ja vahvista sitten resolvectl query ja resolvectl status tun0 avulla, että resolver käyttää sitä nimille, joilla on merkitystä. Verkkonimiavaruuden sisällä ongelma katoaa, koska avaruuden resolver tuntee vain tunnelin.
Tarkista sääntö tililtä itseltään
Kysy ytimeltä, minkä reitin UID saa, tee sitten pyyntö kyseisenä tilinä ja vertaa lähtöosoitetta oman tilisi osoitteeseen. Jos molemmat ilmoittavat saman osoitteen, sääntö täsmää jotain muuta kuin testaamaasi liikennettä. Ensimmäinen komento alla näyttää reittihaun lähettämättä pakettia, mikä erottaa reititysvirheen palomuurivirheestä.
ip route get 1.1.1.1 uid 1000 sudo -u vpnapp curl -s https://ifconfig.co
Laskurit näyttävät, laukesiko sääntö koskaan. Suorita iptables -vnL OUTPUT, lue pakettimäärä kunkin säännön vierestä ja pidä nollaa DROPin vieressä todellisen liikenteen jälkeen täsmäytysvirheenä.
Välitetty liikenne on tämän suunnittelun ulkopuolella. Sillan takana olevalla kontilla tai VM:llä ei ole paikallista pistoketta, jonka vpnapp omistaisi, joten omistajan täsmäytys ei koskaan laukea ja nuo paketit noudattavat sen sijaan FORWARD-käytäntöä. Jos tuo työkuorma on katettava, testaa se erikseen ja kirjoita käytäntö, joka on sidottu siltaan tai kontin osoitteeseen. Suunnittelu pitää, kun taulu, rajapintapoikkeus, resolver ja v6-säännöt osoittavat kaikki samaan suuntaan; jätä mikä tahansa niistä pois, ja tili joko vuotaa tai menettää yhteyden.