Кука ради први пут, а након три поновна повезивања ланац држи три копије истог правила. Ништа није гласно пало; скрипта је једноставно радила оно што јој је речено при сваком покретању. VPN кука је конфигурацијска радња која може радити више пута, зато јој требају власник, жељено стање и серијализована промена. Идите тим редом и дупликати престају.

Дајте правилима власника пре него што иједно напишете

Одлучите који ланац или табела припада овој интеграцији пре него што напишете иједно правило. Наменски ланац који кука ствара и празни најјаснији је облик власништва, јер чишћење тада може уклонити тај ланац без дирања туђе политике. Ако правила морате додавати у заједнички ланац, означите их коментаром да каснија претрага пронађе управо ваша. Власништво чини уклањање сигурним, а уклањање је део који тихо пада.

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

Коментар овде није украс. Он је разлика између уклањања вашег правила и уклањања правила које случајно изгледа слично, и преживљава у сачуваном скупу правила. Напишите коментар једном у променљиву и користите исти низ у свакој наредби која додаје, тестира или брише.

Тестирајте жељено стање уместо поновног додавања

Запишите шта треба да постоји док је тунел подигнут: која сучеља, који извор и одредиште, који протокол и који порт. Затим изразите свако правило као тест након којег следи уметање, да друго покретање пронађе правило и не учини ништа. Наредба за проверу излази са нулом кад правило постоји, и то је управо сигнал који скрипти треба. Референца за iptables документује овде коришћене облике провере, додавања и уметања.

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

Будите пажљиви с положајем. Провера правила и уметање на чело може померити дозволу испред намерног одбијања које је пре долазило прво, па друго покретање мења понашање иако ништа не додаје. Додајте на крај унутар властитог ланца и контролишите редослед местом скока у тај ланац. Ако је редослед унутар ланца важан, обновите ланац из познатог списка уместо да га крпите правило по правило.

Зауставите се ако потребно правило не може бити изражено као стабилан тест. То обично значи да је жељено стање још нејасно.

Серијализујте промену уместо наде да ће се одржати

Два позива куке могу се преклопити и оба могу видети одсутно правило пре него што га иједан дода. Опција чекања у xtables чини да наредба чека брава, али не чини слијед провери-па-додај атомским преко двије наредбе. Серијализујте целу радњу властитом бравом или користите управљач који декларисани пакет примењује као једну трансакцију. nftables може ово друго, што је један разлог да га преферирате на домаћинима где је доступан.

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

Који год механизам одабрали, држите критични одељак кратким и учините га поново улазним: кука која падне на пола пута треба бити сигурна за поновно покретање. Забележите исход да поновљено покретање буде видљиво у журналу уместо да се изводи из броја правила. Ако два различита надзорника могу позвати куку, прво то поправите; ниједна брава не поправља два власника.

Уклоните само оно што поседујете

Уклањање мора разликовати заменску везу од оне коју је умировило и мора преживјети догађај који никад не добије уредно чишћење. Бришите по истим идентификаторима које сте користили за додавање и никада не празните заједнички ланац да бисте поједноставили чишћење. Након тврдог заустављања покрените пролаз усклађивања при следећем старту уместо да претпостављате да је доња кука радила.

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

Животни вијек сучеља такође припада дизајну. Поновно повезивање може створити уређај с другим именом, па правило које тврдо кодира име другог тунела застаријева док још изгледа ваљано. Преферирајте идентитет који сама веза открива и поново га читајте при сваком покретању. Тестирајте три догађаја одвојено: поновљено повезивање, замјенско повезивање и искључивање. Дозвољени саобраћај треба преживјети сва три без дупликата, а неповезане услуге требају остати нетакнуте.

Шетња завршава кад кука има власника, тест за свако правило које додаје, једну серијализовану стазу и уклањање које уклања само властито стање. Кука која је сигурна за два покретања вреди више од куке која је једном паметна.

Повезани чланци