Серверы не могут привязаться к адресам при загрузке

Я имею дело с известной проблемой в 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-адреса не настроены на интерфейсе.

Другие вопросы по тегам