Prečo hook firewallu VPN pridáva to isté pravidlo dvakrát
Opätovné pripojenie môže váš hook spustiť znova, preto navrhujte pre požadovaný stav: vlastné reťazce, test pred vložením, jednu serializovanú zmenu a úzke odstránenie.
Hook funguje napoprvé a po troch opätovných pripojeniach drží reťazec tri kópie toho istého pravidla. Nič nezlyhalo nahlas; skript jednoducho pri každom spustení urobil, čo mu povedali. VPN hook je konfiguračná operácia, ktorá môže bežať viac ako raz, preto potrebuje vlastníka, požadovaný stav a serializovanú zmenu. Choďte v tomto poradí a duplikáty prestanú.
Dajte pravidlám vlastníka, skôr než nejaké napíšete
Rozhodnite, ktorý reťazec alebo tabuľku táto integrácia vlastní, skôr než napíšete jediné pravidlo. Vyhradený reťazec, ktorý hook vytvára a vyprázdňuje, je najjasnejšia forma vlastníctva, pretože upratovanie potom môže tento reťazec odstrániť bez toho, aby sa dotklo cudzej politiky. Ak musíte pridávať pravidlá do zdieľaného reťazca, označte ich komentárom, aby neskoršie hľadanie našlo práve tie vaše. Vlastníctvo robí odstránenie bezpečným a odstránenie je tá časť, ktorá ticho zlyháva.
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
Komentár tu nie je dekorácia. Je to rozdiel medzi odstránením vášho pravidla a odstránením pravidla, ktoré náhodou vyzerá podobne, a prežíva v uloženej sade pravidiel. Napíšte komentár raz do premennej a používajte ten istý reťazec v každom príkaze, ktorý pridáva, testuje alebo maže.
Testujte požadovaný stav namiesto opätovného pridávania
Zapíšte, čo má existovať, kým je tunel hore: ktoré rozhrania, ktorý zdroj a cieľ, ktorý protokol a ktorý port. Potom vyjadrite každé pravidlo ako test, po ktorom nasleduje vloženie, aby druhé spustenie pravidlo našlo a nič neurobilo. Kontrolný príkaz skončí nulou, keď pravidlo existuje, a to je presne signál, ktorý skript potrebuje. Referencia iptables dokumentuje tu použité formy kontroly, pridania a vloženia.
iptables -C VPN_HOOK -i tun0 -p tcp --dport 443 -j ACCEPT ||
iptables -A VPN_HOOK -i tun0 -p tcp --dport 443 -j ACCEPT
Dávajte pozor na pozíciu. Skontrolovať pravidlo a vložiť ho na začiatok môže posunúť povolenie pred zámerné odmietnutie, ktoré predtým prichádzalo prvé, takže druhé spustenie zmení správanie, aj keď nič nepridá. Pridávajte na koniec vnútri vlastného reťazca a poradie ovládajte miestom skoku do tohto reťazca. Ak na poradí vnútri reťazca záleží, zostavte reťazec znova zo známeho zoznamu, namiesto záplatovania pravidlo po pravidle.
Zastavte sa, ak požadované pravidlo nemožno vyjadriť ako stabilný test. To zvyčajne znamená, že požadovaný stav je stále nejasný.
Serializujte zmenu namiesto nádeje, že vydrží
Dve volania hooku sa môžu prekrývať a obe môžu vidieť chýbajúce pravidlo, skôr než ho jedno z nich pridá. Voľba čakania v xtables prinúti príkaz čakať na zámok, ale nerobí sled kontroly a pridania atomickým cez dva príkazy. Serializujte celú operáciu vlastným zámkom alebo použite správcu, ktorý aplikuje deklarovanú dávku ako jednu transakciu. nftables dokáže to druhé, čo je jeden z dôvodov uprednostniť ho na hostiteľoch, kde je dostupný.
flock /run/vpn-hook.lock /usr/local/sbin/vpn-firewall-apply
nft -f /etc/nftables/vpn-hook.nft
Nech si vyberiete akýkoľvek mechanizmus, držte kritickú sekciu krátku a urobte ju znovu vstupnou: hook, ktorý zlyhá v polovici, musí byť bezpečné znova spustiť. Zaznamenajte výsledok, aby bolo opakované spustenie vidieť v journali, namiesto odvodzovania z počtu pravidiel. Ak môžu hook volať dvaja rôzni supervizori, najprv to opravte; žiadny zámok nespraví dvoch vlastníkov.
Odstraňujte len to, čo vlastníte
Odstránenie musí rozlíšiť náhradné spojenie od toho, ktoré poslalo do dôchodku, a musí prežiť udalosť, ktorá nikdy nedostane riadne čistenie. Mažte podľa rovnakých identifikátorov, ktoré ste použili pri pridávaní, a nikdy nevyprázdňujte zdieľaný reťazec, aby ste zjednodušili čistenie. Po tvrdom zastavení spustite pri ďalšom štarte priechod zosúladenia, namiesto predpokladu, že down hook prebehol.
iptables -D VPN_HOOK -i tun0 -p tcp --dport 443 -j ACCEPT
iptables -F VPN_HOOK
ip -brief link show type tun
Životnosť rozhrania patrí tiež do návrhu. Opätovné pripojenie môže vytvoriť zariadenie s iným názvom, takže pravidlo, ktoré natvrdo kóduje názov druhého tunela, zastará, aj keď stále vyzerá platne. Uprednostnite identitu, ktorú odhaľuje samotné spojenie, a pri každom spustení ju znova prečítajte. Otestujte tri udalosti oddelene: opakované pripojenie, náhradné pripojenie a vypnutie. Povolená prevádzka má prežiť všetky tri bez duplikátov a nesúvisiace služby majú zostať nedotknuté.
Priechod končí, keď hook má vlastníka, test pre každé pravidlo, ktoré pridá, jednu serializovanú cestu a odstránenie, ktoré odstraňuje len jeho vlastný stav. Hook, ktorý je bezpečné spustiť dvakrát, má väčšiu cenu než hook, ktorý je raz múdry.