Серверы не могут привязаться к адресам при загрузке
Я имею дело с известной проблемой в RHEL 7, из-за которой службы, которые указывают адрес для привязки, не будут запускаться правильно. Я нашел несколько подобных отчетов, многие говорят, что они были решены с помощью обновлений для systemd, но я все еще сталкиваюсь с этой проблемой. Это влияет на все сервисы на моем компьютере (sshd, sshd, vsftpd, nginx), которые не просто привязываются к 0.0.0.0.
Я нашел все возможные варианты обхода, но ни один из них не работает для меня постоянно. Взяв sshd в качестве примера, config выглядит так:
Port 22
ListenAddress 192.168.242.225
...
Вот что я пробовал, в одиночку и в комбинациях:
С https://bugzilla.redhat.com/show_bug.cgi?id=1352214 (я тоже пробовал sys-subsystem-net-devices-eth1.device
на месте network-online.target
но я подозреваю, что это не ждет, когда произойдет адресация.)
mkdir /etc/systemd/system/sshd.service.d
tee /etc/systemd/system/sshd.service.d/wait.conf << 'EOF'
[Unit]
After=network-online.target
EOF
С https://bugzilla.redhat.com/show_bug.cgi?id=1352214
mkdir /etc/systemd/system/sshd.service.d
tee /etc/systemd/system/sshd.service.d/wait.conf << 'EOF'
[Unit]
Wants=network-online.target
After=network-online.target
EOF
С https://bugzilla.redhat.com/show_bug.cgi?id=1438749
systemctl add-wants multi-user.target network.target
Откуда-то
mkdir /etc/systemd/system/sshd.service.requires
ln -s /usr/lib/systemd/system/network-online.target /etc/systemd/system/sshd.service.requires/
Независимо от того, что я пытаюсь, я обычно получаю сообщение "error: привязка к порту 22 на 192.168.242.125 завершилась неудачно: невозможно назначить запрошенный адрес". Иногда все начинается идеально, что, я думаю, связано с проблемой синхронизации.
Работает Scientific Linux (RHEL) 7.5 и включен сетевой менеджер, вся IP-адресация статическая. Если есть какие-либо другие детали, которые могут помочь, пожалуйста, дайте мне знать. Вот вывод journalctl
после неудачного запуска, с After=network-online.target
в файле модуля sshd. Соответствующие вещи начинаются примерно с линии 1700. Надеюсь, что кто-то сталкивался с этой проблемой и успешно ее решил!
2 ответа
Если вы используете NetworkManager, то для network-online.target
чтобы работать как положено, нужно включить сервис NetworkManager-wait-online.service
Это тот, который на самом деле ждет, пока сеть будет в сети, чтобы удовлетворить эту цель.
network-online.target
необходимо подключить к сетевому менеджеру (поскольку NetworkManager не единственная альтернатива, существует также systemd-networkd, который можно использовать для управления сетью.)
За network-online.target
чтобы работать с NetworkManager, вам нужно иметь символическую ссылку в /etc/systemd/system/network-online.target.wants/
указывая на /usr/lib/systemd/system/NetworkManager-wait-online.service
,
Что вы можете создать, включив эту услугу:
$ sudo systemctl enable NetworkManager-wait-online.service
Created symlink from /etc/systemd/system/network-online.target.wants/NetworkManager-wait-online.service to /usr/lib/systemd/system/NetworkManager-wait-online.service.
Как только это будет на месте, зависимости от network-online.target
должен начать работать, ожидая, пока NetworkManager не завершит работу со всеми интерфейсами, которые он должен вызывать при загрузке.
Чтобы помочь диагностировать любые проблемы с этой настройкой, вы можете посмотреть на вывод systemctl status network-online.target
а также systemctl status NetworkManager-wait-online.service
а также, поскольку они могут иметь больше подсказок о том, что происходит. (В частности, временные метки могут быть полезны, если демоны, которые зависят от network-online.target
начинают раньше NetworkManager-wait-online.service
закончено, тогда у вас может быть проблема с вашей конфигурацией.)
Из перечисленных вами решений я бы порекомендовал следующее:
# mkdir /etc/systemd/system/sshd.service.d
# tee /etc/systemd/system/sshd.service.d/wait.conf << 'EOF'
[Unit]
Wants=network-online.target
After=network-online.target
EOF
поскольку network-online.target
тот, который вы действительно хотите (чтобы убедиться, что все IP-адреса и т. д.) и в том числе Wants=
гарантирует, что его запуск будет запрошен.
Из других методов этот не будет работать: systemctl add-wants multi-user.target network.target
, поскольку он не создает никаких зависимостей между самими службами (демон SSH и т. д.) и сетью, которая работает полностью. Это просто говорит, что вы хотите, чтобы сеть была...
И тот, с участием /etc/systemd/system/sshd.service.requires/
в каталоге отсутствует After=
зависимость (что я считаю необходимым, а не подразумевается просто иметь .requires/
на нем.) Если вы думаете Requires=
лучше, чем Wants=
(это сильнее, вызывает сбой модуля, если зависимость не удается), то я бы рекомендовал просто использовать это в /etc/systemd/system/sshd.service.d/wait.conf
вместо этого файл переопределения определенно является более гибким способом управления этой конфигурацией.
Добавление зависимости от sys-subsystem-net-devices-eth1.device
тоже не помогает, так как это только указывает на то, что устройство существует (с точки зрения udev), что ничего не говорит о его настройке и настройке. Так что это тоже не вариант.
Возможно, лучше не настраивать системные службы для прослушивания определенных IP-адресов и контролировать доступ к ним через межсетевой экран хоста, если это необходимо.
Если вам действительно нужно иметь возможность привязываться к определенным IP-адресам до того, как они будут настроены на сетевом интерфейсе, вы можете обойти проблему синхронизации, установив sysctl net.ipv4.ip_nonlocal_bind
для IPv4 и sysctl net.ipv6.ip_nonlocal_bind
для IPv6. Затем службы могут связываться с IP-адресами, не настроенными ни на одном сетевом интерфейсе, но они не будут доступны, пока эти IP-адреса не настроены на интерфейсе.