Случаен избор на OpenVPN во systemd: зошто ExecStart не успева
systemd не е командна обвивка, затоа измешана копија во ExecStart умира. Преместете го изборот во ExecStartPre или оставете OpenVPN сам да избере сервер.
Четириесет .ovpn датотеки за една земја пристигнуваат од добавувач, и планот изгледа очигледен: копирајте случајна на нејзиното место, потоа стартувајте го тунелот. Напишан како цевковод во ExecStart, тој план умира при подигање со статусен код што не објаснува ништо. Датотеката на единицата не е скрипта, а поправката е или експлицитно да воведете обвивка или целосно да престанете да избирате датотеки.
Симптомот: единица што стартува и веднаш умира
Статусот покажува дека услугата паднала во дел од секунда, а редот во журналот именува команда што ниту една обвивка никогаш не би ја примила. Ништо за тунелот не се појавува, бидејќи тунелот никогаш не започна.
Читањето на точната командна линија од журналот е најбрзиот начин да го потврдите ова. systemd го повторува она што го извршил, а низата ќе ги прикаже знаците на цевководот како буквални аргументи, а не како оператори.
Зошто ExecStart не може да изврши цевковод
systemd сам ја дели командната линија, применува свои правила за наводници и замена на променливи, а потоа го извршува резултатот директно. Цевководите, преусмерувањето, глоб-проширувањето од обвивка и замената на команди едноставно не се дел од таа граматика. Тоа е дизајнерски избор, а не пропуст: единицата декларативно кажува што да се изврши, а логиката на обвивката припаѓа на скрипта што единицата ја повикува. Двете поправки произлегуваат од тоа и ниту една не бара да и се дадат повеќе привилегии на единицата.
Тоа го објаснува и заблудувачкиот излезен код. Првиот аргумент се третира како бинарна датотека, па погрешната линија паѓа пред да се изврши било кој дел од вашата логика.
Направете го изборот во ExecStartPre
Директната поправка е подготвителен чекор што експлицитно повикува обвивка и го држи изборот и стартувањето во истата единица, за да не може неуспехот во едниот да го остави другиот да работи сам.
[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
Три детали одлучуваат дали ова ќе го преживее контактот со вистинска машина. Именувањето е првата стапица: systemd го заменува %i уште при парсирање на единицата, долго пред bash да се изврши, па спецификаторот мора да стои надвор од единечните наводници. xargs -r спречува cp да се изврши без аргумент кога шаблонот не совпаѓа со ништо. А неуспешниот подготвителен чекор ја запира единицата, и тоа е точниот исход: стартување со вчерашната конфигурација е полошо од нестартување. Случаен избор што секогаш ја зема истата датотека обично не е лоша среќа. Проверете дали копираната датотека се препишува од ажурирање на пакетот, или дали шаблонот совпаѓа само со еден застарен запис.
Или оставете OpenVPN да ја избере крајната точка
OpenVPN веќе може да држи неколку крајни точки во еден профил и случајно да избира меѓу нив, што целосно ја отстранува обвивката, копијата и пристапот за пишување од патеката на подигање.
client
remote-random
<connection>
remote au1.example.net 1194 udp
</connection>
<connection>
remote au2.example.net 1194 udp
</connection>
Оваа форма го држи изборот на сервер во датотеката што ја напишал добавувачот, па ротацијата што преименува датотеки не ја крши единицата. Таа исто така ја прави листата на кандидати проверлива, што глоб над директориум никогаш не е. Мешањето сѐ уште го заслужува своето место кога профилите се разликуваат во повеќе од крајна точка: различни сертификати, различни директиви за рутирање, различна политика за шифри. Во тој случај изборот е меѓу цели конфигурации и чекорот со обвивка е чесниот начин тоа да се изрази.
Прочитајте ја повторно инстанцата и датотеката што ја користела
Потврдете која единица навистина работи пред да ја дебагирате нејзината содржина. Пакуваната мета-услуга и шаблонот се инфраструктура; единиците што одговараат на вашите датотеки се инстанците наречени по нив.
systemctl list-units 'openvpn*'
systemctl cat [email protected]
journalctl -u openvpn@au -n 30 --no-pager
Инстанца за која никој не памети дека ја овозможил обично води до залутана конфигурациска датотека во директориумот на пакетот. Исклучете ја токму таа именувана инстанца наместо шаблонот, инаку следното ажурирање на пакетот ќе ја врати. По промената, стартувајте ја единицата и прочитајте ја командната линија што ја пријавува журналот, потоа потврдете ја патеката на конфигурацијата што таа навистина ја отворила. Таа една проверка го одвојува случајниот избор што работи од услуга што тивко ја користи повторно датотека од минатиот месец.