Az nftables cgroup-megkerüléshez forrásoldali címjavítás is kell
Egy cgroup megjelölése másik táblába küldi, a socket pedig megtartja a korábbi címét. Osztályozás, útvonalválasztás és címfordítás három külön lépésként.
Az egy cgroupból érkező forgalom megjelölése a könnyű rész. Három külön döntésnek kell összehangolódnia, mielőtt egyetlen alkalmazás kilép a fizikai interfészen, miközben minden más az alagútban marad: melyik socket tartozik a kivételhez, melyik útvonalkeresést indítja el a jelölés, és melyik forráscímet viszi a csomag kilépéskor. A legtöbb sikertelen próbálkozás az elsőt jól eltalálja, a másodikat félig, a harmadikat pedig soha nem nézi meg.
Három döntés, nem egy
Az osztályozás megválaszolja, ki mentesül. Az útvonalválasztás megválaszolja, hová megy helyette a megjelölt csomag. A forrásválasztás megválaszolja, mit lát a távoli vég, és hová kell visszatérnie a válasznak.
Ezek egymástól függetlenül hibáznak. Egy csomag lehet osztályozott, a fizikai interfészre átirányított, és mégis olyan privát címet hordozhat, amelyet egyetlen felsőbb router sem tud visszaküldeni, amiből olyan időtúllépés lesz, amely pontosan úgy néz ki, mint egy tűzfalblokk. Az osztályozási lépésben semmi sem figyelmeztet erre. Az útvonalválasztási lépésben sem.
A sorrend is számít. Az osztályozás a csomag keletkezésekor történik, az útvonalválasztás utána, a fordítás pedig a kilépési ponton.
Ha nem tudod megnevezni, melyik a három szakasz közül a hibás, akkor nem hibakeresel, hanem szabályokat rendezel át és reménykedsz.
Olyan cgroupot célozz, amely holnap is létezni fog
Az nftables képes egy socket cgroup v2-tagságát ellenőrizni, ami valóban hasznos, mert a folyamatot követi, nem a célt. A csapda az azonosító. A menüből indított asztali alkalmazás gyakran egy átmeneti scope-ban él, amelynek neve a következő indításnál megváltozik.
nft list ruleset
systemctl status session.slice 2>/dev/null
cat /proc/self/cgroupEgy scope nevének kimásolása egy munkamenetből és kemény kódolása olyan szabályt ad, amely ma működik, holnap pedig csendben megszűnik illeszkedni. Helyezd inkább az alkalmazást szándékosan stabil végrehajtási környezetbe, például egy általad irányított dedikált scope-ba vagy unitba, és ahhoz illeszkedj. Akkor a szabály túléli az újraindításokat és a csomagfrissítéseket. Azzá is válik, amiről egy kolléga a munkamenet-történeted nélkül is tud gondolkodni.
Légy pontos abban is, melyik mechanizmust használod. A cgroup v1 net_cls osztályozása és a cgroup v2 socket-illesztése különböző dolgok, és egy hasonló nevű mező a dokumentációban nem teszi őket felcserélhetővé.
A route típusú lánc az, amely elindítja a második keresést
A helyben keletkező forgalomnál a lánc típusa dönti el, történik-e valami a jelölés beállítása után. A filter típusú kimeneti lánc meg tud jelölni egy csomagot, és a kernel továbbra is a már kiválasztott útvonalat használja. A route típusú lánc az a mechanizmus, amely új keresést kér.
table inet bypass {
chain mark {
type route hook output priority mangle; policy accept;
socket cgroupv2 level 2 "app.slice" meta mark set 0x1 comment "app bypass"
}
}
ip rule add fwmark 0x1 lookup 200
ip route add default via 203.0.113.1 dev wlan0 table 200A jelölésnek ezután olyan szabályzati szabályra van szüksége, amely táblába küldi, és annak a táblának teljesnek kell lennie: alapértelmezett útvonal, minden helyi cél, amelyre az alkalmazásnak még szüksége van, és egy felsőbb átjáró, amely valóban válaszol.
Válaszd meg tudatosan a jelölés értékét. A WireGuard a saját fwmarkját használja a külső szállítási forgalomhoz, és ha véletlenül ugyanarra a számra kerülsz, az alagút saját útvonal-kivételét zavarhatja olyan módokon, amelyeket fájdalmas diagnosztizálni.
A forráscím nem követi az útvonalat
Az a socket, amely már kiválasztott forráscímet az alagútútvonalhoz, megtartja azt a címet az átirányítás után is. Az útvonalváltoztatásban semmi sem írja át, ezért a csomag olyan privát forrással hagyja el a fizikai interfészt, amelyet a felsőbb hálózat nem tud visszaküldeni.
A látható tünet egy alkalmazás, amely úgy tűnik, adatot küld, és soha nem kap választ, valamint egy tűzfalnapló, amely semmit sem mutat, mert a csomag soha nem jött vissza.
A szűk javítás egy forrásfordítási szabály, amely az adott alkalmazás jelölésére és valódi kimeneti interfészére korlátozódik, és a meglévő NAT-ba illeszkedik ahelyett, hogy lecserélné azt:
table inet bypass {
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
meta mark 0x1 oifname "wlan0" masquerade
}
}Csak a kivételt fordítsd, semmi mást. Egy átfogó masquerade-szabály kijavítja a tünetet és tönkreteszi a képességedet annak megmondására, melyik forgalom melyik útvonalat választotta. Illeszkedj a jelölésre, a valódi kimeneti interfészre és ha lehet, az alkalmazás saját címére. A széles szabályokat könnyű megírni és szinte lehetetlen később auditálni.
Mi szökik még meg a kivételt
A névfeloldás jöhet egy külön resolver-folyamatból egy másik cgroupban, így a böngésző socketjének osztályozása nem osztályozza a lekérdezéseit. Ha a resolver lekérdezései az alagútban maradnak, miközben a kapcsolat kifelé megy, a split-horizon válaszok nem illeszkedhetnek az útvonalhoz. Ez az eltérés olyan hibákat okoz, amelyek DNS-hibáknak látszanak, és nem azok.
A gyermekfolyamatok a legtöbb beállításban öröklik a cgroupot, de az a segéd, amely magát a saját scope-jába mozgatja, nem. Ellenőrizz ahelyett, hogy feltételeznéd, különösen mindennél, ami újra végrehajtja önmagát.
Végül döntsd el, mi történjen, amikor az alagút áll. Az a kivétel, amely csendben teljes megkerüléssé válik, más biztonsági álláspont, mint amely zártan hibázik, és csak az egyik az, amit szántál.