systemd зупиняє службу VPN: узгодьте Type= з клієнтом
VPN-юніт під час завантаження стає неактивним, коли Type= не відповідає часу життя клієнта. Узгодьте тип, виправте власника й упорядкуйте службу після тунелю.
Юніти можуть виглядати правильно, systemctl start може повідомляти про успіх, а через десять секунд служба стоїть неактивною. Або вона перезапускається що півхвилини, доки її не зупинить межа запусків. Жодна з поведінок не є мережевим збоєм: юніт описує час життя процесу, який не відповідає тому, що клієнт насправді робить. Клієнт може відгалузитися й вийти або налаштувати сеанс і одразу вийти.
Чому юніт стає неактивним через секунди після успішного запуску
systemd виводить стан із процесу, який сам запустив, тому Type= — це твердження про цей процес, а не документація. З Type=simple юніт вважається активним, поки команда працює, і стає неактивним, коли вона повертається. Клієнт, який передає з'єднання допоміжній програмі й виходить, тому виглядає як аварія, навіть коли тунель піднятий. Тоді журнал показує схему запуску й зупинки, яка читається як збійний бінарник.
Прочитайте тип юніта поряд із поведінкою клієнта, перш ніж торкатися мережевої конфігурації.
Виберіть тип, що відповідає клієнту
Дві схеми охоплюють більшість CLI постачальників: команда, яка налаштовує сеанс і виходить, і команда, яка перед поверненням відгалужує допоміжну програму. Кожна потребує іншої форми юніта.
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/bin/protonvpn-cli connect -f
ExecStop=/usr/bin/protonvpn-cli disconnectoneshot разом з RemainAfterExit=true залишає юніт активним після повернення команди, що відповідає схемі налаштуй і вийди, а команда зупинки дає службі чисте завершення. Клієнт, що відгалужується, зберігає ту саму форму, але потребує Type=forking, щоб systemd стежив за дочірнім процесом. Задайте Restart=on-failure, RestartSec=30 і скінченний StartLimitBurst, щоб збій постачальника не перетворився на цикл перезапусків, який ховає помилку.
Ніколи не дозволяйте керованому клієнту демонізуватися
Супровідники поза systemd упираються в ту саму стіну. Скрипт runit, який запускає демонізований клієнт, одразу повертається до супровідника, а той читає повернення як аварію й запускає ще одну копію. Кожен супровідник очікує володіти процесом переднього плану, як sshd -D залишається попереду. Приберіть прапорець демона для керованих команд і залиште фонову роботу супровіднику. Скрипти-обгортки, які повертаються раніше, ніж існує тунель, спричиняють таку саму плутанину.
Процес, який відокремлюється від самого себе, невидимий для всього, що мало за ним стежити.
Сеанс закінчується і забирає тунель із собою
Сеанс робочого столу володіє клієнтом, який запускає. Завершіть вхід, і шина сеансу зникає, забираючи тунель, що пояснює, чому з'єднання графічного клієнта часто обривається, коли закривається останнє вікно. Серверам варто використовувати системний юніт або профіль NetworkManager, який піднімається сам. Користувацький юніт має сенс лише тоді, коли тунель має завершуватися разом зі входом, тому прив'яжіть його до цілі графічного сеансу й зазначте це в описі.
Користувач служби — це друга половина тієї самої проблеми. Ключ, що належить root із режимом 0600, нечитабельний для юніта, який працює під іншим обліковим записом, хоч би чого досяг sudo у вашій оболонці.
systemctl cat openvpn-server@work
sudo chown -R openvpn:network /etc/openvpn/server
sudo find /etc/openvpn -type f -perm /077 -lsУпорядкуйте залежні служби після появи адреси
Коли демон прив'язується до адреси тунелю, якої ще не створено, він виходить із повідомленням Cannot assign requested address. Виправлення — явне впорядкування, а не цикл повторних спроб.
[Unit]
After=network.target [email protected]
Requires=sys-devices-virtual-net-wg0.deviceAfter= упорядковує завдання, а Requires= на юніті пристрою прив'язує залежного до існування інтерфейсу, що сильніше, ніж чекати лише на мережеву ціль. Перезавантажте менеджер після редагування й перезапустіть залежну службу, а потім прочитайте її журнал, замість того щоб вважати, що порядок спрацював. Спрямовуйте вивід клієнта до журналу через StandardOutput=journal або параметр логування, бо керований клієнт, який пише у файл, що його ніхто не відкриває, виглядає точно так само, як той, що так і не запустився.
Потім один раз перезавантажтеся й переконайтеся, що юніт активний після появи пристрою тунелю. Виправлення, перевірене лише через systemctl start, не перевірило порядок завантаження, який мало виправити.