Jeden profil vpnc łączy się czysto po roamingu; trzy z nich na zmianę psują sobie nawzajem gniazda, trasy i stan resolvera. Skrypt ponownego łączenia z pakietu jest napisany dla jednego tunelu, więc restartuje każdy profil, gdy tylko którykolwiek z nich jest wyłączony. Naprawa wymaga trzech rzeczy: osobnych portów lokalnych, sondy sprawdzającej prawdziwą usługę dla każdego profilu i jednego uporządkowanego łańcucha, który nigdy nie uruchamia dwóch połączeń naraz.

Daj każdemu profilowi własny port lokalny

Profil vpnc pozostawiony na domyślnym porcie lokalnym konkuruje z profilem, który już działa. Drugie połączenie zawodzi, gdy pierwsze trzyma port, a wiersz w logu wygląda na problem bramy, a nie na lokalny konflikt. Zamiast tego ustaw po jednym wierszu na plik profilu:

Local Port 0

Zero pozwala jąderu wybrać port efemeryczny, więc dwa profile mogą być ustanowione jednocześnie. Nazwij każdy plik od bramy i grupy, której służy, trzymaj go czytelnym tylko dla roota i zawsze łącz się z pasującym profilem, a nie ze wspólnym domyślnym. Wspólny plik domyślny to sposób, w jaki skrypt ponownie łączy niewłaściwy tunel po tym, jak ktoś zmieni nazwę profilu.

Pliki profili zawierają dane logowania, więc uprawnienia są częścią projektu, a nie porządków. Plik czytelny dla wszystkich pod /etc/vpnc przekazuje sekret grupy każdemu lokalnemu użytkownikowi. Trzymaj tryb 0600 z rootem jako właścicielem i pozwól skryptom czytać plik jako root, zamiast kopiować sekrety do argumentów. Dlatego skrypt sondy nigdy nie powinien wypisywać zawartości pliku do logu.

Testuj jedną usługę na profil, a nie adres tunelu

Żądanie echa na własny adres tunelu dowodzi głównie, że interfejs istnieje. Nie mówi nic o tym, czy host za nim nadal dociera do aplikacji, która uzasadnia tunel. Interfejs może być włączony, gdy trasa za nim już zniknęła.

Testuj jedną usługę na profil z krótkim limitem TCP i ponownie łącz tylko ten profil, którego sonda zawiodła. Dwie sekundy dzielą ścieżkę martwą od wolnej, a sonda TCP nie zależy od tego, czy ICMP jest gdzieś po drodze dozwolone. Zmieniaj między profilami tylko cel i nazwę konfiguracji:

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

Zapisz to jako /usr/local/bin/ensure-vpn-ops.sh, nadaj prawa wykonania i powtórz dla każdego profilu, zmieniając tylko cel sondy i nazwę konfiguracji. Sonda, która odpowiada na pytanie protokołu, przetrwa bramy, które zrzucają echo, ale nadal przekazują usługi ważne dla użytkowników.

Połącz sondy łańcuchem, aby nigdy się nie ścigały

Skrypt ponownego łączenia z pakietu może wywoływać twoje sondy po kolei, a kolejność jest tu całym sensem. Dwa wywołania vpnc-connect działające razem przepisują tablicę routingu w kolejności, której nikt nie kontroluje, i tak zdrowy profil traci swoją trasę.

Trzymaj wywołania na pierwszym planie, dodaj krótkie opóźnienie ustabilizowania dla interfejsu pod spodem i zaplanuj łańcuch z tabeli cron roota, ponieważ tylko root może przepisać trasy tunelu:

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

Trzymaj kolejność identyczną między skryptem startowym a wpisem cron, bo łańcuch działający przy starcie w innej kolejności jest w praktyce innym programem. Gdy jeden profil zależy od tras drugiego, umieść zależność na początku i pozwól późniejszej sondzie bezpiecznie zawieść, gdy wcześniejszy tunel jeszcze się podnosi.

Obserwuj log, a potem celowo zepsuj jeden

Zapisuj jeden wiersz na przebieg z profilem, celem sondy, wynikiem i podjętym działaniem. Bez tego tunel, który migocze co minutę, wygląda dokładnie jak taki, który nigdy nie padł, a błędu sondy nie da się odróżnić od awarii bramy. Log dowodzi też, że łańcuch dotknął tylko profilu, który zawiódł. Zapisuj go tam, gdzie przetrwa restart, inaczej dowody odchodzą razem z procesem.

Potem celowo zepsuj tunel i zobacz, co się stanie. Zatrzymaj jeden profil i potwierdź, które procesy i trasy nadal istnieją:

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

Ponownie połączony powinien zostać tylko zatrzymany profil, a pozostałe sesje powinny zachować zarówno procesy, jak i trasy. Jeśli restartują się dwa profile, twój łańcuch działa równolegle gdzieś, gdzie się tego nie spodziewałeś.

Czego watchdoga nie wolno robić

Watchdog, który restartuje wszystko, gdy tylko coś zawiedzie, wygląda zdrowo podczas testów i powoduje awarię w oknie serwisowym. Restartuj per profil, nigdy globalnie.

Preferuj utrzymywanego klienta, gdy brama oferuje takiego dla tego samego protokołu, i nigdy nie zapisuj hasła na stałe w skrypcie ani nie przekazuj go w wierszu poleceń, bo plik profilu już trzyma sekret. Jeśli zadanie ma działać jako zwykły użytkownik po podniesieniu tunelu, obniż uprawnienia wewnątrz skryptu, zamiast uruchamiać cały łańcuch na tym koncie. Na koniec przeczytaj trasy ponownie po ponownym połączeniu, bo profil może wrócić z innym przydzielonym adresem i zostawić nieaktualną trasę, której żadna sonda skierowana na adres tunelu nigdy nie zauważy.

Powiązane artykuły