Калі скрыпт client-connect завяршаецца з ненулявым кодам, OpenVPN адхіляе кліента, і адміністратары звычайна мяркуюць, што адпаведны скрыпт client-disconnect усё прыбярэ. Часта ён наогул не запускаецца, бо апрацоўка disconnect залежыць ад таго, што паспеў завяршыць этап connect. Разгляд адхілення і адкату як аднаго механізму — гэта тое, што ператварае няўдалы ўваход у працёкшае правіла экрана або запіс без гаспадара. Гэта два асобныя абавязкі, і толькі адзін з іх аўтаматычны. Прачытайце ўласны шлях выхаду хука, перш чым вінаваціць сервер у пакінутым стане.

Ненулявы выхад адхіляе кліента, але не адкочвае вашу працу

Статус выхаду client-connect — гэта рашэнне аб допуску. Нуль азначае допуск, любое іншае значэнне — разбурэнне асобніка да поўнага ўсталявання. Нішто ў гэтым кантракце не правярае, што скрыпт ужо зрабіў з знешнім светам. Калі скрыпт дадаў правіла iptables, запісаў радок або павялічыў лічыльнік, гэтыя змены перажываюць адхіленне.

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

Адхіленне аўтаматычнае, ачыстка — не

Дакументацыя OpenVPN 2.6 звязвае апрацоўку client-disconnect з паспяховым завяршэннем папярэдняй апрацоўкі connect. Задакументаванае выключэнне ахоплівае каскадныя ланцугі: калі адзін крок connect ужо вярнуў поспех, адпаведныя крокі disconnect усё роўна выконваюцца пры разбурэнні асобніка, нават калі пазнейшы крок connect пацярпеў няўдачу. Гэтае выключэнне вузкае і залежыць ад колькасці наладжаных зваротных выклікаў, таму тэставанне аднаго shell-скрыпта нічога не кажа пра ланцуг.

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

What the hook did before failingWhat the client seesWhat stays behind
Created a firewall entryA rejection, with no tunnelA rule matching an address nobody owns
Wrote a state rowA rejection, with no tunnelA record of a session that never started
Allocated a tunnel addressA rejection, with no tunnelAn address marked busy until something releases it

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

Кампенсуйце ўнутры скрыпта, які пацярпеў няўдачу

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

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

Зрабіце кампенсацыю ідэмпатэнтнай і з уласнікам

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

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

Праверце тры шляхі, якія сапраўды розняцца

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

Запісвайце этап хука, статус выхаду і тое, што было размеркавана або вызвалена, без уліковых даных. Журнал хука, які называе створаны рэсурс, — гэта тое, што робіць працёкшае правіла знаходным праз шэсць месяцаў.

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