Вы настроили сервис так, чтобы он запускался после network.target, но он всё равно стартует до полной готовности сети? Разберёмся, почему так происходит и как это исправить.
Почему «сеть готова» — понятие неоднозначное
В скриптах LSB (Linux Standard Base) используется понятие $network — условный маркер готовности сети. Однако его трактовка крайне расплывчата. Разные системы могут считать «готовность сети» выполненной при следующих условиях:
- запущен софт для управления сетью;
- все настроенные сетевые интерфейсы активны и имеют IP‑адреса;
- доступен DNS‑сервер;
- доступен определённый сервер (специфичный для конкретной инфраструктуры);
- есть выход в Интернет;
- настроен хотя бы один глобальный IPv4‑ или IPv6‑адрес и т. д.
Из‑за такой неоднозначности $network не может служить универсальным критерием.
Динамичность современных сетей
Современные сетевые среды крайне динамичны:
- устройства перемещаются между сетями;
- конфигурация сети меняется;
- добавляется и удаляется оборудование;
- создаются и удаляются виртуальные сети.
Поэтому ПО должно уметь работать с изменяющейся конфигурацией:
- реагировать на изменения настроек сети;
- повторять попытки подключения при временных сбоях;
- корректно обрабатывать потерю соединения.
Хорошо написанное ПО стартует в любое время и адаптируется к текущим условиям.
Как работает сеть в systemd: три ключевых target
В systemd роль $network выполняют три целевых юнита:
network.target
- Суть: сигнализирует, что стек управления сетью запущен.
- Важно: не гарантирует, что интерфейсы настроены и имеют IP‑адреса.
- Назначение: упорядочивание остановки сервисов при выключении системы. Сервисы с After=network.target останавливаются до отключения сети, что позволяет корректно завершить соединения.
- Особенности: пассивный юнит — его нельзя запустить напрямую. Сервисы должны указывать After=network.target, но не Wants= или Requires=.
network-online.target
- Суть: активно ждёт, пока сеть не будет «готова» (определение «готовности» зависит от ПО управления сетью, обычно это наличие настроенного маршрутизируемого IP‑адреса).
- Назначение: задержка активации сервисов до полной настройки сети.
- Особенности: активный юнит — может быть вызван сервисами, которым нужна готовая сеть. По умолчанию его используют удалённые монтирования из
/etc/fstab. Не рекомендуется для серверного ПО, которое может работать с локальными подключениями. - Таймаут: 90 секунд.
network-pre.target
- Суть: позволяет запускать сервисы до настройки сетевых интерфейсов.
- Назначение: используется, например, для фаерволов, которые нужно настроить до активации интерфейсов.
- Особенности: пассивный юнит. Сервисы, которые должны стартовать до настройки сети, указывают Before=network-pre.target и Wants=network-pre.target.
Как заставить сервис стартовать после полной готовности сети
Чтобы сервис запускался только после того, как сеть полностью настроена, добавьте в его .service-файл следующие строки:
After=network-online.target
Wants=network-online.target
Это гарантирует, что все настроенные сетевые устройства активны и имеют IP‑адреса до старта сервиса.
Важно: также нужно активировать соответствующий «ожидающий» сервис:
- NetworkManager-wait-online.service — если используется NetworkManager;
- systemd-networkd-wait-online.service — если используется systemd-networkd.
Проверить активацию можно командой:
# systemctl is-enabled NetworkManager-wait-online.service systemd-networkd-wait-online.service
Рекомендации для разработчиков
Вместо того чтобы полагаться на network.target, лучше сделать ваше ПО устойчивым к динамическим изменениям сети. Это:
- повысит удовлетворённость пользователей;
- сократит количество отчётов об ошибках;
- ускорит загрузку системы.
Возможные подходы:
- Отслеживать изменения сети через rtnetlink. Это наиболее элегантное, но не всегда простое решение.
- Для серверного ПО: слушать псевдоадреса
[::],[::1],0.0.0.0и127.0.0.1. Они всегда доступны, поэтому код не нужно адаптировать под изменения сети. - Использовать
IP_FREEBIND. Этот механизм ядра Linux позволяет привязываться к адресу, даже если он ещё не настроен локально. Это делает код устойчивым к изменениям конфигурации сети.
Вывод
В современных динамических сетях лучше писать ПО, которое адаптируется к изменениям, а не ждёт фиксированного состояния «сеть готова». Если же требуется явная задержка старта сервиса, используйте network-online.target с соответствующим «ожидающим» сервисом.




