Kuka radi prvi put, a nakon tri ponovna povezivanja veriga drži tri kopije istog pravila. Ništa nije glasno palo; skripta je jednostavno činila što joj je rečeno pri svakom pokretanju. VPN kuka je konfiguracijska radnja koja može raditi više puta, zato joj trebaju vlasnik, željeno stanje i serijalizirana promjena. Idite tim redom i duplikati prestaju.

Dajte pravilima vlasnika prije nego što ijedno napišete

Odlučite koja veriga ili tablica pripada ovoj integraciji prije nego što napišete ijedno pravilo. Namjenska veriga koju kuka stvara i prazni najjasniji je oblik vlasništva, jer čišćenje tada može ukloniti tu verigu bez diranja tuđe politike. Ako pravila morate dodavati u zajedničku verigu, označite ih komentarom da kasnija pretraga pronađe upravo vaša. Vlasništvo čini uklanjanje sigurnim, a uklanjanje je dio koji tiho pada.

iptables -N VPN_HOOK 2>/dev/null || true
iptables -C INPUT -j VPN_HOOK 2>/dev/null || iptables -I INPUT -j VPN_HOOK
iptables -S VPN_HOOK

Komentar ovdje nije ukras. On je razlika između uklanjanja vašeg pravila i uklanjanja pravila koje slučajno izgleda slično, i preživljava u spremljenom skupu pravila. Napišite komentar jednom u varijablu i rabite isti niz u svakoj naredbi koja dodaje, testira ili briše.

Testirajte željeno stanje umjesto ponovnog dodavanja

Zapišite što treba postojati dok je tunel podignut: koja sučelja, koji izvor i odredište, koji protokol i koji port. Zatim izrazite svako pravilo kao test nakon kojeg slijedi umetanje, da drugo pokretanje pronađe pravilo i ne učini ništa. Naredba za provjeru izlazi s nulom kad pravilo postoji, i to je upravo signal koji skripti treba. Referenca za iptables dokumentira ovdje rabljene oblike provjere, dodavanja i umetanja.

iptables -C VPN_HOOK -i tun0 -p tcp --dport 443 -j ACCEPT ||
  iptables -A VPN_HOOK -i tun0 -p tcp --dport 443 -j ACCEPT

Budite pažljivi s položajem. Provjera pravila i umetanje na čelo može pomaknuti dopuštenje ispred namjernog odbijanja koje je prije dolazilo prvo, pa drugo pokretanje mijenja ponašanje iako ništa ne dodaje. Dodajte na kraj unutar vlastite verige i kontrolirajte redoslijed mjestom skoka u tu verigu. Ako je redoslijed unutar verige važan, obnovite verigu iz poznatog popisa umjesto da je krpate pravilo po pravilo.

Zaustavite se ako pravilo koje vam treba ne može biti izraženo kao stabilan test. To obično znači da je željeno stanje još nejasno.

Serijalizirajte promjenu umjesto nade da će se održati

Dva poziva kuke mogu se preklopiti i oba mogu vidjeti odsutno pravilo prije nego što ga ijedan doda. Opcija čekanja u xtablesu čini da naredba čeka bravu, ali ne čini slijed provjeri-pa-dodaj atomskim preko dvije naredbe. Serijalizirajte cijelu radnju vlastitom bravom ili rabite upravitelja koji primjenjuje deklarirani paket kao jednu transakciju. nftables može ovo drugo, što je jedan razlog da ga preferirate na hostovima gdje je dostupan.

flock /run/vpn-hook.lock /usr/local/sbin/vpn-firewall-apply
nft -f /etc/nftables/vpn-hook.nft

Koji god mehanizam odabrali, držite kritični odjeljak kratkim i učinite ga ponovno ulaznim: kuka koja padne na pola puta treba biti sigurna za ponovno pokretanje. Zabilježite ishod da ponovljeno pokretanje bude vidljivo u journalu umjesto da se izvodi iz broja pravila. Ako dva različita nadzornika mogu pozvati kuku, prvo to popravite; nijedna brava ne popravlja dva vlasnika.

Uklonite samo ono što posjedujete

Uklanjanje mora razlikovati zamjensku vezu od one koju je umirovilo i mora preživjeti događaj koji nikad ne dobije uredno čišćenje. Brišite po istim identifikatorima koje ste rabili za dodavanje i nikad ne praznite zajedničku verigu da biste pojednostavili čišćenje. Nakon tvrdog zaustavljanja pokrenite prolaz usklađivanja pri sljedećem startu umjesto da pretpostavljate da je donja kuka radila.

iptables -D VPN_HOOK -i tun0 -p tcp --dport 443 -j ACCEPT
iptables -F VPN_HOOK
ip -brief link show type tun

Životni vijek sučelja također pripada dizajnu. Ponovno povezivanje može stvoriti uređaj s drugim imenom, pa pravilo koje tvrdo kodira ime drugog tunela zastarijeva dok još izgleda valjano. Preferirajte identitet koji sama veza otkriva i ponovno ga čitajte pri svakom pokretanju. Testirajte tri događaja odvojeno: ponovljeno povezivanje, zamjensko povezivanje i isključivanje. Dopušteni promet treba preživjeti sva tri bez duplikata, a nepovezane usluge trebaju ostati netaknute.

Šetnja završava kad kuka ima vlasnika, test za svako pravilo koje dodaje, jednu serijaliziranu stazu i uklanjanje koje uklanja samo vlastito stanje. Kuka koja je sigurna za dva pokretanja vrijedi više od kuke koja je jednom pametna.

Povezani članci