Един vpnc профил се свързва отново чисто след роуминг; три от тях се редуват да чупят сокетите, маршрутите и състоянието на резолвера един на друг. Скриптът за повторно свързване от пакета е написан за един тунел, затова рестартира всеки профил, когато някой от тях е спрян. За да се поправи това, са нужни три неща: отделни локални портове, проверка, която тества реална услуга за всеки профил, и една подредена верига, която никога не пуска две свързвания едновременно.

Дайте на всеки профил собствен локален порт

vpnc профил, оставен на порта по подразбиране, се конкурира с вече работещия профил. Второто свързване се проваля, докато първото държи порта, и редът в журнала изглежда като проблем с шлюза, а не като локален конфликт. Вместо това задайте по един ред за всеки файл на профил:

Local Port 0

Нулата позволява на ядрото да избере ефимерен порт, така че два профила могат да бъдат установени едновременно. Именувайте всеки файл по шлюза и групата, на която служи, дръжте го четим само за root и винаги се свързвайте със съответния профил, а не с общ профил по подразбиране. Общият файл по подразбиране е начинът, по който скриптът свързва отново грешния тунел, след като някой преименува профил.

Файловете на профилите носят идентификационни данни, затова правата са част от дизайна, а не от домакинската работа. Файл, четим от всички под /etc/vpnc, дава груповата тайна на всеки локален потребител. Дръжте режим 0600 със собственик root и оставете скриптовете да четат файла като root, вместо да копират тайни в аргументи. Затова и скриптът за проверка никога не бива да извежда съдържанието на файла в журнал.

Проверявайте една услуга за всеки профил, а не адреса на тунела

Ехо заявка към собствения адрес на тунела доказва предимно, че интерфейсът съществува. Тя не казва нищо за това дали хостът зад него все още достига приложението, което оправдава тунела. Интерфейсът може да е активен, докато маршрутът след него вече е изчезнал.

Проверявайте една услуга за всеки профил с кратък TCP таймаут и свързвайте отново само профила, чиято проверка се е провалила. Две секунди разделят мъртъв път от бавен, а TCP проверката не зависи от това дали ICMP е разрешен някъде по пътя. Променяйте само целта и името на конфигурацията между профилите:

#!/bin/bash
set -eu
if ! nc -z -w 2 10.63.7.20 8443; then
  /usr/sbin/vpnc-connect ops.conf
fi

Запазете това като /usr/local/bin/ensure-vpn-ops.sh, направете го изпълнимо и повторете за всеки профил, като промените само целта на проверката и името на конфигурацията. Проверка, която отговаря на протоколен въпрос, оцелява при шлюзове, които изхвърлят ехо, но продължават да препредават услугите, които са важни за потребителите.

Свържете проверките във верига, за да не се надпреварват

Скриптът за повторно свързване от пакета може да извиква вашите проверки последователно и последователността е целият смисъл. Две извиквания на vpnc-connect, работещи заедно, пренаписват таблицата за маршрутизация в ред, който никой не контролира, и точно така здрав профил губи маршрута си.

Дръжте извикванията на преден план, добавете кратка пауза за установяване на основния интерфейс и планирайте веригата от cron таблицата на root, тъй като само root може да пренаписва маршрутите на тунела:

#!/bin/bash
sleep 20
/usr/local/bin/ensure-vpn-ops.sh
/usr/local/bin/ensure-vpn-lab.sh

Дръжте реда еднакъв между скрипта за зареждане и записа в cron, защото верига, която при зареждане върви в различен ред, на практика е друга програма. Когато един профил зависи от маршрутите на друг, поставете зависимостта първа и оставете следващата проверка да се провали безвредно, докато по-ранният тунел още се вдига.

Наблюдавайте журнала, после чупете един нарочно

Записвайте по един ред на всяко изпълнение с профила, целта на проверката, резултата и предприетото действие. Без това тунел, който трепти всяка минута, изглежда точно като такъв, който никога не е падал, и грешка в проверката е неразличима от прекъсване на шлюза. Журналът също доказва, че веригата е докоснала само профила, който се е провалил. Пишете го някъде, където оцелява след рестарт, иначе доказателствата си отиват с процеса.

После чупете тунел нарочно и гледайте какво се случва. Спрете един профил и потвърдете кои процеси и маршрути все още присъстват:

pgrep -a vpnc
ip -4 route show | grep -E '10[.]63|10[.]90'
tail -n 5 /var/log/ensure-vpn.log

Само спреният профил трябва да се свърже отново, а другите сесии трябва да запазят и процесите, и маршрутите си. Ако два профила се рестартират, веригата ви работи паралелно някъде, където не сте очаквали.

Какво не бива да прави стражът

Страж, който рестартира всичко при всеки провал, изглежда здрав по време на тестове и причинява прекъсване в прозорец за поддръжка. Рестартирайте по профил, никога глобално.

Предпочитайте поддържан клиент, когато шлюзът предлага такъв за същия протокол, и никога не вграждайте парола в скрипта и не я подавайте в команден ред, защото файлът на профила вече пази тайната. Ако дадена задача трябва да се изпълнява като обикновен потребител, след като тунелът е вдигнат, намалете правата отвътре в скрипта, вместо да карате цялата верига да работи под този акаунт. Накрая, прочетете отново маршрутите след повторно свързване, защото профил може да се върне с различен зададен адрес и да остави остарял маршрут, който никоя проверка, насочена към адреса на тунела, няма да забележи.

Подобни статии