Czterdzieści plików .ovpn dla jednego kraju przychodzi od dostawcy, a plan wydaje się oczywisty: skopiować losowy na jego miejsce, a potem uruchomić tunel. Zapisany jako potok wewnątrz ExecStart, ten plan ginie przy starcie z kodem statusu, który niczego nie wyjaśnia. Plik jednostki nie jest skryptem, a naprawa polega albo na wyraźnym wprowadzeniu powłoki, albo na całkowitym zaprzestaniu wybierania plików.

Objaw: jednostka, która startuje i natychmiast ginie

Status pokazuje, że usługa zawiodła w ułamku sekundy, a linia dziennika wymienia polecenie, którego żadna powłoka nigdy by nie otrzymała. Nic o tunelu się nie pojawia, ponieważ tunel nigdy się nie zaczął.

Odczytanie dokładnej linii poleceń z dziennika to najszybszy sposób potwierdzenia tego. systemd odtwarza to, co wykonał, a ciąg pokaże znaki potoku jako dosłowne argumenty, a nie jako operatory.

Dlaczego ExecStart nie może uruchomić potoku

systemd sam dzieli linię poleceń, stosuje własne cytowanie i podstawianie zmiennych, a następnie wykonuje wynik bezpośrednio. Potoki, przekierowania, rozwijanie wzorców przez powłokę i podstawianie poleceń po prostu nie należą do tej gramatyki. To wybór projektowy, a nie przeoczenie: jednostka deklaratywnie mówi, co uruchomić, a logika powłoki należy do skryptu, który jednostka wywołuje. Obie naprawy z tego wynikają i żadna nie wymaga przyznania jednostce większych uprawnień.

To wyjaśnia też mylący kod wyjścia. Pierwszy argument jest traktowany jako plik binarny, więc błędna linia zawodzi, zanim cokolwiek z twojej logiki się uruchomi.

Dokonaj wyboru w ExecStartPre

Bezpośrednią naprawą jest krok przygotowawczy, który jawnie wywołuje powłokę i trzyma wybór oraz start w tej samej jednostce, aby awaria jednego nie pozostawiła drugiego działającego samotnie.

[Service]
Type=notify
ExecStartPre=/bin/bash -c "ls /etc/openvpn/profiles/au* | shuf -n 1 | xargs -r -I{} cp -f {} /etc/openvpn/%i.conf"
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/%i.conf

Trzy szczegóły decydują, czy przetrwa to spotkanie z prawdziwą maszyną. Nazewnictwo to pierwsza pułapka: systemd podstawia %i już podczas analizy jednostki, długo przed uruchomieniem bash, więc specyfikator musi stać poza pojedynczymi cudzysłowami. xargs -r zapobiega uruchomieniu cp bez argumentu, gdy wzorzec do niczego nie pasuje. A nieudany krok przygotowawczy zatrzymuje jednostkę i to jest właściwy wynik: startowanie z wczorajszą konfiguracją jest gorsze niż niestartowanie. Losowy wybór, który zawsze bierze ten sam plik, zwykle nie jest pechem. Sprawdź, czy kopiowany plik jest nadpisywany przez aktualizację pakietu, albo czy wzorzec pasuje tylko do jednego nieaktualnego wpisu.

Albo pozwól OpenVPN wybrać punkt końcowy

OpenVPN już potrafi trzymać kilka punktów końcowych w jednym profilu i wybierać spośród nich losowo, co całkowicie usuwa powłokę, kopiowanie i prawo zapisu ze ścieżki startu.

client
remote-random
<connection>
remote au1.example.net 1194 udp
</connection>
<connection>
remote au2.example.net 1194 udp
</connection>

Ta forma trzyma wybór serwera w pliku napisanym przez dostawcę, więc rotacja, która zmienia nazwy plików, nie psuje jednostki. Czyni też listę kandydatów audytowalną, czym wzorzec na katalogu nigdy nie jest. Tasowanie nadal ma swoje miejsce, gdy profile różnią się czymś więcej niż punktem końcowym: inne certyfikaty, inne dyrektywy routingu, inna polityka szyfrów. W takim przypadku wybór jest między całymi konfiguracjami, a krok z powłoką to uczciwy sposób jego wyrażenia.

Odczytaj z powrotem instancję i plik, którego użyła

Potwierdź, która jednostka naprawdę działa, zanim zaczniesz debugować jej zawartość. Spakowana usługa meta i szablon to infrastruktura; jednostki odpowiadające twoim plikom to instancje nazwane od nich.

systemctl list-units 'openvpn*'
systemctl cat [email protected]
journalctl -u openvpn@au -n 30 --no-pager

Instancja, o której nikt nie pamięta, że ją włączył, zwykle prowadzi do zabłąkanego pliku konfiguracji w katalogu pakietu. Wyłącz tę nazwaną instancję zamiast szablonu, inaczej następna aktualizacja pakietu ją przywróci. Po zmianie uruchom jednostkę i odczytaj linię poleceń, którą raportuje dziennik, a następnie potwierdź ścieżkę konfiguracji, którą rzeczywiście otworzyła. Ten jeden test oddziela działający losowy wybór od usługi, która po cichu używa ponownie pliku z zeszłego miesiąca.

Powiązane artykuły