Попередження про кілька скриптів звучить як скарга на планування, тому очевидне виправлення — переставляти рядки, доки воно не зникне. Але це не скарга на планування. Пізніше визначення --up замінює команду, уже збережену для цього етапу, і аналізатор так і повідомляє, а отже, з двох ваших скриптів колись виконувався рівно один. Другий не стоїть у черзі за ним; він зник.

Тому попередження варте уваги, навіть якщо воно не фатальне: воно передбачає оновлення DNS або зміну маршруту, які тихо перестали відбуватися.

Попередження не про порядок

OpenVPN зберігає одну команду користувацького скрипту для етапу up. Коли аналізатор зустрічає інше визначення — з профілю, включеного файлу або командного рядка, — він замінює вже збережене і видає попередження. Нічого не об’єднується, ніщо не виконується двічі, і питання порядку не існує. Виживає та команда, яку аналізатор побачив останньою, тому переміщення рядка може змінити переможця, а інший скрипт залишиться мертвим.

Той самий принцип діє й для інших етапів скриптів: по одній команді на кожен. Якщо дві роботи мають відбутися обидві, їм потрібна єдина точка входу, а не дві директиви, схожі на список.

Знайдіть обидва визначення в реальному запуску

Почніть з того, що демон справді отримав, а не з профілю, який ви редагували. ps -ef і ExecStart юніта показують командний рядок, до якого можуть додати --up з точки входу контейнера або обгортки; init-файл дистрибутива може зробити те саме. systemctl cat openvpn-server@server показує, що додає сама служба, а рекурсивний grep у каталозі конфігурації знаходить визначення на рівні файлів. Дублікати зазвичай походять з різних шарів, і саме тому редагування одного файлу нічого не змінює.

Копіювання скрипту в інший каталог або перейменування також не видаляє директиву. Аналізатор рахує визначення, а не файли.

Нехай один hook володіє роботою

Довготривале рішення — один диспетчер, який виконує обидві дії в продуманому порядку. Короткий shell-скрипт з set -eu, який викликає потрібну інтеграцію, потім локальну дію і передає "$@", щоб межі аргументів збереглися, тримає поведінку в одному місці, яке можна перевірити. Передача аргументів лише зберігає їх; вона не доводить, що два помічники очікують однаковий інтерфейс, тому прочитайте контракт кожного. Вирішіть, що має робити помилка і чи потрібно відкочувати часткові зміни.

Якщо завантажувач пропонує підтримуваний hook розширення, віддайте йому перевагу перед саморобним ланцюгом. Образ контейнера або пакет постачальника часто має документоване місце для додаткової роботи, і його використання не дає оновленню перезаписати ваш диспетчер.

Очищення належить відповідному етапу down. Дія up, яка переписує DNS або додає маршрути, потребує документованого відкату, а диспетчер, який займається лише запуском, — це половина проєкту.

Підтвердьте інтеграцію, а не лише тишу

Прибрати попередження про дублікат — проста частина; інтеграція все одно має працювати. Перевірте стан резолвера після підключення за допомогою resolvectl status або прочитавши /etc/resolv.conf, і підтвердьте маршрути за допомогою ip route. Потім від’єднайтеся й під’єднайтеся знову, бо поспіхом з’єднаний hook зазвичай залишає щось від попереднього сеансу. journalctl -u openvpn-server@server -b показує, чи запускався ваш диспетчер і що він вивів.

Тримайте привілеї hook там, де їм місце. Підвищення script-security або запуск демона з більшими правами — не рішення для заміненого hook; це розширює те, що може робити кожен майбутній скрипт, зокрема той, який назве зловмисник.

Ознака справжнього виправлення — не тиша в журналі. Це відповідь DNS, запис маршруту й очищення, які працюють після двох перепідключень.

Схожі статті