Zahtev je uvek varijanta iste rečenice: zadrži VPN za pregledanje, ali pusti SSH ili posao rezervne kopije da koristi normalnu vezu. Savet koji kruži o tome, da se port prosledi NAT pravilima u iptables-u, to ne radi. NAT pravilo prepisuje adrese i portove unutar toka; ono nikada ne bira kroz koji interfejs paket izlazi. Ta odluka pripada pretrazi rute, a pretraga rute treba pomoć da vidi port.

Zašto obična ruta ne može da se poklopi sa portom

Linux bira rutu tražeći odredišnu adresu u tabeli, nakon što se kandidatske tabele filtriraju kroz pravila politike. Ta pravila mogu da se poklope sa oznakom firewall-a, izvornom adresom, dolaznim interfejsom ili UID-om. Sama stavka rute nema polje porta, jer se ruta bira pre nego što zaglavlje transporta postane važno.

Trenutni iproute2 i jezgra proširuju birač pravila: ipproto, sport i dport se prihvataju, pa ip rule add ipproto tcp dport 22 table 100 izražava nameru u jednoj liniji. Pokreni ip rule add help na stvarnom hostu da vidiš da li tvoj build navodi dport. Ako navodi, gotov si jednom komandom; ako ne, put preko oznake ispod je ekvivalent.

Kako god, pravilo je samo pokazivač. Tabeli 100 i dalje treba ruta, i to je deo koji ljudi zaborave.

Tri dela, ili jedan

Savremeni oblik je jedno pravilo iznad plus ruta u alternativnoj tabeli. Klasični oblik dodaje netfilter u sredinu: označi paket, pa poklopi oznaku u pravilu. Oba se završavaju istom pretragom; razlikuju se u tome gde se port čita.

Pristup sa oznakom postoji zato što netfilter vidi zaglavlje transporta, a kod za rutiranje ga istorijski nije video. To je ceo mehanizam i objašnjava zašto su rezervni put tri dela koja sarađuju, a ne jedna lukava komanda.

Tri dela po redu

Prvo, označi tokove koje želiš da preusmeriš, u lancu koji se izvršava dovoljno rano da oznaka postoji pre odluke o ruti:

nft add table inet vpnexempt
nft 'add chain inet vpnexempt out { type route hook output priority mangle; }'
nft add rule inet vpnexempt out tcp dport 22 meta mark set 0x1

Drugo, pošalji označene pakete u odvojenu tabelu:

ip rule add fwmark 0x1/0x1 table 100

Treće, daj toj tabeli podrazumevanu rutu kroz fizički link. Adrese su ilustrativne; zameni ih svojim:

ip route add default via 192.168.1.1 dev wlan0 table 100

Preskoči treći korak i označeni paket neće naći rutu u tabeli 100, pa će propasti. Simptom izgleda kao da je pravilo pokvarilo mrežu, dok je zapravo uklonilo jedini put koji je paketu ostao.

Šta ga održava u radu posle prvog paketa

Oznake važe za odlazne pakete. Odgovor dolazi na fizički interfejs sa adresom koju je link dodelio, a glavna tabela može i dalje da preferira tunel za to odredište. Dva mehanizma održavaju povratni put doslednim: pravilo zasnovano na izvoru za adresu linka i connection tracking koji čuva odluku tokom celog života toka. Čuvanje oznake u conntrack-u i njeno vraćanje pri odgovoru uobičajen je način da izuzetak sa stanjem bude stabilan.

Filtriranje obrnutog puta je drugi tihi ubica. Ako jezgro strogo proverava povratni put, a odgovor dolazi na interfejs koji glavna tabela ne bi izabrala, paket se odbacuje bez poruke. rp_filter podrazumevane vrednosti razlikuju se po distribuciji i po tome da li se interfejs prosleđuje, pa čitaj stvarnu vrednost umesto da pretpostaviš da je isključena.

Ne označavaj sopstveni transport tunela. WireGuard ili UDP OpenVPN tunel nije TCP 22, pa je gornji recept bezbedan, ali izuzetak napisan kao sve osim odredišta tunela može da uhvati šifrovane pakete i pokvari tunel na način koji liči na petlju rutiranja.

Proveri umesto da pretpostaviš

Pitaj jezgro kojim bi putem išlo, za odredište i za port, pa izvrši pravi prenos:

ip route get 203.0.113.10
ip rule show
nft list ruleset

Ako oznaka postoji ali brojači se nikad ne pomeraju, pravilo se ne poklapa. Brojači su razlika između konfiguracije koju si napisao i politike koju jezgro primenjuje.

Kada je ovo pogrešan alat

Izuzetci zasnovani na portu su po prirodi krhki. Servisi pomeraju portove, HTTP/3 dolazi kao UDP 443, a jedna aplikacija može da otvori nekoliko tokova različitih vrsta. Ako je pravi zahtev da ovaj program koristi normalan link, sloj rutiranja je pogrešno mesto; mrežni namespace ili proxy po aplikaciji se bolje uklapaju.

Ako je zahtev da ova podmreža koristi normalan link, potpuno preskoči oznake i dodaj konkretniju rutu. Jednostavnije je, vidljivo je u jednoj tabeli, a sledeća osoba može da ga pregleda bez čitanja skupa pravila.

Zapiši koji od tri zahteva zaista imaš pre nego što diraš firewall. Gornji mehanizam je precizan, a preciznost primenjena na pogrešan sloj je samo duži prekid.

Povezani članci