Å merke trafikk frå éin cgroup er den enkle delen. Tre skilde avgjerder må stemme før éin applikasjon går ut gjennom det fysiske grensesnittet medan alt anna blir i tunnelen: kva socket som høyrer til unntaket, kva ruteoppslag merket utløyser, og kva kjeldeadresse pakken ber når han går ut. Dei fleste mislukka forsøka treff den første, halvtreff den andre, og ser aldri på den tredje.

Tre avgjerder, ikkje éi

Klassifisering svarar på kven som er unnateken. Ruting svarar på kvar den merkte pakken går i staden. Kjeldeval svarar på kva den andre enden vil sjå og kvar svaret skal kome tilbake.

Desse feilar uavhengig. Ein pakke kan klassifiserast, rutast om til det fysiske grensesnittet, og framleis bera ei privat adresse som ingen oppstraums ruter kan returnere, noko som gjev ein tidsavbrot som ser nøyaktig ut som ein brannmurblokkering. Ingenting i klassifiseringstrinnet varslar deg om det. Ingenting i rutingtrinnet heller.

Rekkjefølgja har òg noko å seie. Klassifisering skjer når pakken blir generert, ruting skjer etter det, og omsetjing skjer ved utgangspunktet.

Viss du ikkje kan namngje kva av dei tre stega som er øydelagt, feilsøkjer du ikkje, du omorganiserer reglar og håpar.

Match ein cgroup som framleis finst i morgon

nftables kan teste cgroup v2-medlemskapen til ein socket, noko som er verkeleg nyttig fordi det følgjer prosessen og ikkje destinasjonen. Haka er identifikatoren. Ein skrivebordsapplikasjon starta frå ei meny lever ofte i ein mellombels scope der namnet blir endra ved neste oppstart.

nft list ruleset
systemctl status session.slice 2>/dev/null
cat /proc/self/cgroup

Å kopiere eit scope-namn frå éi økt og hardkode det gjev ein regel som verkar i dag og stille sluttar å stemme i morgon. Set applikasjonen i ein medviten, stabil køyringskontekst i staden, til dømes ein eigen scope eller unit du styrer, og match han. Regelen overlever då omstart og pakkeoppdateringar. Han blir òg noko ein kollega kan tenkje over utan økthistorikken din.

Ver òg presis på kva mekanisme du brukar. net_cls-klassifisering i cgroup v1 og socket-matching i cgroup v2 er ulike ting, og eit likt namngjeve felt i dokumentasjonen gjer dei ikkje utbyttbare.

Det er rute-kjeda som utløyser det andre oppslaget

For lokalt generert trafikk avgjer kjedetypen om noko skjer etter at merket er sett. Ei output-kjede av filter-typen kan merke ein pakke, og kjernen vil halde fram med å bruke ruta han alt har valt. Ei kjede av route-typen er mekanismen som ber om eit nytt oppslag.

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 200

Merket treng då ein policyregel som sender det til ein tabell, og den tabellen må vere komplett: ei standardrute, lokale mål applikasjonen framleis treng, og ein oppstraums gateway som faktisk svarar.

Vel merkeverdien medvite. WireGuard brukar sin eigen fwmark for ytre transporttrafikk, og å lande på same nummer ved eit uhell kan forstyrre ruteunntaket til sjølve tunnelen på måtar som er vonde å diagnostisere.

Kjeldeadressa følgjer ikkje ruta

Ein socket som alt har valt ei kjeldeadresse for tunnelbana, held på den adressa etter omrutinga. Ingenting i ruteendringa skriv henne om, og difor går pakken ut gjennom det fysiske grensesnittet med ei privat kjelde som oppstraumsnettet ikkje kan returnere.

Det synlege symptomet er ein applikasjon som ser ut til å sende data og aldri får svar, og ein brannmurlogg som ikkje viser noko fordi pakken aldri kom tilbake.

Den smale rettinga er ein kjeldeomsetjingsregel som er avgrensa til merket til den applikasjonen og det faktiske utgangsgrensesnittet hans, integrert med den NAT-en som alt finst i staden for å erstatte han:

table inet bypass {
  chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
    meta mark 0x1 oifname "wlan0" masquerade
  }
}

Omset unntaket og ingenting anna. Ein generell masquerade-regel rettar symptomet og øydelegg evna di til å seie kva trafikk som tok kva veg. Match på merket, det faktiske utgangsgrensesnittet og, viss du kan, adressa til applikasjonen sjølv. Breie reglar er lette å skrive og nesten umoglege å revidere seinare.

Kva som framleis slepp unna unntaket

Namneoppslag kan kome frå ein skild resolverprosess i ein annan cgroup, so å klassifisere socketen til nettlesaren klassifiserer ikkje oppslaga hans. Viss spørjefråga til resolveren blir i tunnelen medan tilkoplinga går utanfor han, kan split-horizon-svar ikkje stemme med vegen. Det misforholdet gjev feil som ser ut som DNS-feil og ikkje er det.

Barneprosessar arvar cgroup i dei fleste oppsett, men ein hjelpar som flyttar seg inn i sin eigen scope gjer det ikkje. Sjekk i staden for å gå ut frå noko, særleg for alt som køyrer seg sjølv på nytt.

Til slutt, avgjer kva som skal skje når tunnelen er nede. Eit unntak som stille blir ein full bypass er ein annan tryggleiksposisjon enn eit som feilar lukka, og berre eitt av dei er det du meinte.

Relaterte artiklar