Кука працуе першы раз, а пасля трох паўторных падключэнняў у ланцугу тры копіі аднаго і таго ж правіла. Нішто не правалілася гучна; скрыпт проста рабіў тое, што яму казалі, пры кожным запуску. Кука 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

Тэрмін жыцця інтэрфейса таксама належыць да праекта. Паўторнае падключэнне можа стварыць прыладу з іншай назвай, таму правіла, якое жорстка задае назву другога тунэля, састарэе, хоць яшчэ выглядае сапраўдным. Аддавайце перавагу ідэнтычнасці, якую выкрывае само падключэнне, і перачытвайце яе пры кожным запуску. Праверце тры падзеі асобна: паўторнае падключэнне, заменнае падключэнне і выключэнне. Дазволены трафік павінен перажыць усе тры без дублікатаў, а староннія службы павінны застацца некранутымі.

Праходка сканчаецца, калі кука мае ўладальніка, праверку для кожнага дададзенага правіла, адзін серыялізаваны шлях і разбурэнне, якое выдаляе толькі свой стан. Кука, якую бяспечна запускаць двойчы, каштоўнейшая за куку, якая адзін раз разумная.

Падобныя артыкулы