Označavanje saobraćaja iz jedne cgroup je lakši deo. Tri odvojene odluke moraju da se poklope pre nego što jedna aplikacija izađe kroz fizički interfejs, a sve ostalo ostane u tunelu: koji socket pripada izuzetku, koje pretraživanje rute oznaka pokreće i koju adresu izvora paket nosi kada izlazi. Većina neuspelih pokušaja prvi uradi tačno, drugi napola, a treći nikada ne pogleda.

Tri odluke, ne jedna

Klasifikacija odgovara ko je izuzet. Rutiranje odgovara gde označeni paket umesto toga ide. Izbor izvora odgovara šta će udaljena strana videti i gde odgovor treba da se vrati.

Ove stvari ne uspevaju nezavisno. Paket može biti klasifikovan, preusmeren na fizički interfejs i ipak nositi privatnu adresu koju nijedan nadređeni ruter ne može da vrati, što proizvodi istek vremena koji izgleda tačno kao blokada firewall-a. Ništa u koraku klasifikacije te ne upozorava na to. Ništa ni u koraku rutiranja.

Redosled je takođe važan. Klasifikacija se dešava kada se paket generiše, rutiranje posle toga, a prevođenje u tački izlaza.

Ako ne možeš da navedeš koja je od tri faze pokvarena, ne debaguješ, već preuređuješ pravila i nadaš se.

Uporodi cgroup koja će postojati i sutra

nftables može da proveri cgroup v2 pripadnost socket-a, što je zaista korisno jer prati proces, a ne odredište. Zamka je identifikator. Desktop aplikacija pokrenuta iz menija često živi u prolaznom scope-u čije se ime menja pri sledećem pokretanju.

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

Kopiranje imena scope-a iz jedne sesije i tvrdo kodiranje daje pravilo koje radi danas i tiho prestaje da se poklapa sutra. Umesto toga stavi aplikaciju u namerni, stabilni kontekst izvršavanja, kao što je poseban scope ili unit koji kontrolišeš, i uporedi sa njim. Pravilo tada preživljava restarte i ažuriranja paketa. Postaje i nešto o čemu kolega može da razmišlja bez tvoje istorije sesija.

Budi precizan i oko toga koji mehanizam koristiš. net_cls klasifikacija u cgroup v1 i uparivanje socket-a u cgroup v2 su različite stvari, a slično imenovano polje u dokumentaciji ne čini ih zamenljivim.

Drugo pretraživanje pokreće route lanac

Za lokalno generisan saobraćaj, tip lanca odlučuje da li se nešto dešava nakon što se oznaka postavi. output lanac tipa filter može da označi paket i kernel će nastaviti da koristi rutu koju je već izabrao. Lanac tipa route je mehanizam koji traži novo pretraživanje.

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

Oznaci zatim treba pravilo politike koje je šalje u tabelu, a ta tabela mora biti potpuna: podrazumevana ruta, lokalna odredišta koja su aplikaciji još potrebna i nadređeni gejtvej koji zaista odgovara.

Izaberi vrednost oznake namerno. WireGuard koristi sopstveni fwmark za spoljni transportni saobraćaj, a slučajno sletanje na isti broj može da omete sopstveni rutni izuzetak tunela na načine koje je bolno dijagnostikovati.

Adresa izvora ne prati rutu

Socket koji je već izabrao adresu izvora za putanju tunela zadržava tu adresu i posle preusmeravanja. Ništa u promeni rute je ne prepisuje, zato paket izlazi kroz fizički interfejs sa privatnim izvorom koji nadređena mreža ne može da vrati.

Vidljivi simptom je aplikacija koja kao da šalje podatke i nikada ne dobija odgovor, i dnevnik firewall-a koji ništa ne pokazuje jer se paket nikada nije vratio.

Uska ispravka je pravilo prevođenja izvora ograničeno na oznaku te aplikacije i njen stvarni izlazni interfejs, integrisano sa NAT-om koji već postoji umesto da ga zameni:

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

Prevedi izuzetak i ništa više. Opšte masquerade pravilo ispravlja simptom i uništava sposobnost da se kaže koji je saobraćaj kojim putem otišao. Uporedi oznaku, stvarni izlazni interfejs i, ako možeš, adresu same aplikacije. Široka pravila je lako napisati i skoro nemoguće kasnije revidirati.

Šta još izmiče izuzetku

Razrešavanje imena može da dođe iz odvojenog resolver procesa u drugoj cgroup, pa klasifikacija socket-a pregledača ne klasifikuje njegove pretrage. Ako upiti resolver-a ostanu u tunelu dok veza izlazi izvan njega, split-horizon odgovori mogu da se ne poklope sa putanjom. To neslaganje proizvodi kvarove koji izgledaju kao DNS greške i nisu.

Procesi deca nasleđuju cgroup u većini postavki, ali pomoćnik koji se premešta u sopstveni scope ne nasleđuje. Proveri umesto da pretpostavljaš, posebno za sve što se ponovo izvršava.

Na kraju, odluči šta treba da se desi kada je tunel dole. Izuzetak koji tiho postaje potpuni bypass je druga bezbednosna pozicija od onog koji se zatvara, i samo jedan od njih je ono što si mislio.

Povezani članci