Скрипты подготовки, которые сообщают об ошибке и продолжают работу, хуже скриптов, которые никогда не запускаются. Настройка клиента затрагивает защищённые ключи, идентичность на шлюзе и службу, которая, возможно, уже обслуживает трафик. Каждому из этого нужно условие остановки, а скрипт должен знать, какого этапа он достиг, когда остановился.

Рассматривайте всё как одну транзакцию с пятью контрольными точками и заставьте каждую контрольную точку самостоятельно отказываться от продолжения.

Исправьте входные данные, прежде чем трогать файловую систему

Начните с явного договора: одна идентичность, один источник профиля, один предполагаемый владелец службы. Проверьте, что профиль существует, что сертификат и ключ, на которые он ссылается, читаемы, и что целевой каталог принадлежит ожидаемому пакету. Разрешающийся путь не является доказательством того, что материал за ним полон.

Отклоняйте пустые переменные сразу. Неустановленная $DEVICE, которая разворачивается в ничто, превращает install -m 400 $KEY /etc/openvpn/client/ в копию, нацеленную на каталог, и сбой приходит позже как служба, которая не может прочитать свой ключ.

Соберите набор профилей в подготовительном каталоге

Сначала постройте полный набор в закрытом месте: профиль, CA, клиентский сертификат, ключ и любой помощник, который вызывает профиль. Копируйте через install -m 400 -o root -g root, чтобы права задавались при создании, а не после. Затем проверьте ссылки внутри профиля, потому что относительная строка ca или key разрешается относительно рабочего каталога юнита, как только служба запускается. В живой каталог не должно быть записано ничего, пока весь набор не пройдёт проверку.

Запишите несекретный отпечаток того, что произвёл этот запуск, например sha256sum office.conf, сохранённый рядом с маркером версии. Именно это единственное значение позволяет повторному запуску отличить обновление от бездействия.

Заменяйте атомарно и сохраняйте предыдущий набор

Переместите подготовленный набор на место одной операцией там, где это позволяет файловая система, и сохраните проверенный предыдущий набор под именем с отметкой времени. Частичная копия, оставляющая новый профиль рядом со старым ключом, создаёт службу, которая аутентифицируется с неверной идентичностью и не записывает ничего полезного о причине. Если замена не может быть атомарной, упорядочьте перемещения так, чтобы профиль оказался последним.

Когда цель уже существует, явно решите, является ли этот запуск обновлением, идентичным повтором или конфликтом с профилем другого устройства. Тихо перезаписать профиль, принадлежащий другой идентичности, — это путь, которым две машины начинают делить один сертификат. Вместо этого откажитесь от запуска и назовите конфликтующего владельца.

Активируйте одного владельца и докажите это

Выберите один путь активации — экземпляр systemd или NetworkManager — и используйте его последовательно. Запуск неуправляемого процесса openvpn рядом с включённым юнитом даёт два туннеля, конкурирующие обновления DNS и никакого ясного ответа на вопрос, к какому из них обращена команда остановки. После активации проверьте systemctl is-active openvpn-client@office, затем маршрут к удалённому префиксу, затем resolvectl status для преобразователя, установленного туннелем. Завершите, достигнув одного ресурса, ради которого туннель существует.

Работающий процесс и зелёный значок в трее — это факты процесса, а не доказательство того, что идентичность и политика трафика пережили передачу.

Повторный запуск и вывод из эксплуатации — разные рабочие процессы

Второй запуск должен сходиться к тем же проверенным файлам и тому же владельцу, а не создавать вторую учётную запись или второй демон. Вывод из эксплуатации — это собственная процедура: остановите точного владельца, заархивируйте или удалите локальный профиль согласно политике и отзовите идентичность на шлюзе. Удаление локального файла ключа не отзывает копию, которая уже покинула машину.

Сохраняйте путь восстановления, не зависящий от туннеля, например доступ к консоли или второй маршрут управления. Изменение подготовки, которое запирает вас снаружи машины, — это неудачное изменение, даже когда каждый этап сообщил об успехе.

Скрипт, который стоит сохранить, — это транзакция вокруг владения и доказательств. Короткий список привилегированных команд копирования — не то же самое.

Похожие статьи