Серверу нужен постоянный адрес: к нему привязаны записи DNS, правила сетевого экрана, списки доступа и конфигурации мониторинга, и смена адреса после перезагрузки ломает всё сразу. Динамическое получение адреса удобно для рабочих станций и неудобно для служб. Разбираем, как задать постоянный адрес в RHEL-подобных системах через NetworkManager, как устроены файлы конфигурации и как устранить ошибку недоступности узла.
Почему серверу не подходит динамический адрес
Клиент DHCP получает адрес на срок аренды и запрашивает продление. При недоступности сервера в момент продления адрес возвращается в пул и может быть выдан другой машине. После перезагрузки устройство способно получить другой адрес из пула, и для сервера это означает недоступность служб.
Вторая причина связана с резервированием. Профиль с постоянным адресом позволяет заранее подготовить вторую машину и переключить её, не меняя записи DNS и правила доступа. Привязка адреса к MAC-адресу на стороне DHCP-сервера решает часть проблемы, но оставляет зависимость от внешнего сервиса: при его отказе машина остаётся без сети. Третий случай, когда на одном интерфейсе нужно несколько адресов или адрес из другой подсети, динамическая настройка не покрывает вовсе.
Постоянный адрес не означает ручную правку при каждом изменении. NetworkManager хранит профиль соединения, правка которого применяется одной командой. Профиль привязан к устройству по имени или по MAC-адресу, и это различие становится источником ошибок, о которых сказано ниже.
Как устроено управление сетью в RHEL-подобных системах
NetworkManager различает устройство и соединение. Устройство это сетевой интерфейс, соединение это набор параметров, который к нему применяется. Одно устройство может иметь несколько профилей, например для домашней и рабочей сети, а активным в каждый момент является один.
Профили хранятся в каталоге /etc/NetworkManager/system-connections в формате keyfile, по одному файлу на соединение. В RHEL 8 и более ранних выпусках основным был формат ifcfg в каталоге /etc/sysconfig/network-scripts, и чтение таких файлов поддерживал отдельный модуль. В RHEL 9 формат keyfile стал единственным, а файлы ifcfg при обновлении преобразуются автоматически.
Служба network.service с набором скриптов в RHEL 8 объявлена устаревшей, а в RHEL 9 удалена. Поэтому правка файлов ifcfg в свежем выпуске без запущенного NetworkManager ничего не даёт: конфиг прочитан не будет. Перед работой стоит убедиться, что служба запущена.
systemctl status NetworkManager
nmcli device status
nmcli connection show
Первая команда показывает состояние устройств, вторая список профилей. У устройства в столбце STATE должно стоять connected, у профиля присутствуют имя и имя устройства.
Назначение постоянного адреса через nmcli
Правка профиля выполняется одной командой: метод ipv4.method переводится в значение manual, адрес задаётся с длиной префикса, шлюз и DNS перечисляются отдельно.
nmcli device status
nmcli connection modify "System eth0" \
ipv4.method manual \
ipv4.addresses 192.168.10.20/24 \
ipv4.gateway 192.168.10.1 \
ipv4.dns "192.168.10.1 1.1.1.1" \
ipv4.dns-search example.local
nmcli connection up "System eth0"
Команда up перечитывает профиль и применяет его к устройству. При правке по сети через тот же интерфейс соединение прервётся, поэтому операцию безопаснее выполнять с консоли или через второй канал управления.
Профиль создают заново, если существующий привязан к другому устройству.
nmcli connection add type ethernet ifname eth0 con-name static-lan \
ipv4.method manual ipv4.addresses 192.168.10.20/24 \
ipv4.gateway 192.168.10.1 ipv4.dns 192.168.10.1 \
connection.autoconnect yes
Несколько адресов на интерфейсе задают перечислением через запятую, каждая запись со своей длиной префикса.
nmcli connection modify static-lan +ipv4.addresses 192.168.10.21/24
nmcli connection modify static-lan -ipv4.addresses 192.168.10.21/24
Знак плюс добавляет значение к списку, знак минус убирает. Такая форма удобнее перезаписи, поскольку не требует перечислять уже заданные адреса.
Стоит упомянуть два частных случая. При нескольких интерфейсах маршрут по умолчанию задают только для одного, иначе направление выбирается по метрике и зависит от порядка активации профилей. Метрику задают параметром ipv4.route-metric, меньшее значение означает приоритетный маршрут.
Отключение IPv6 выполняется переводом ipv6.method в значение disabled. Это оправдано, если сеть не поддерживает шестую версию, а служба при запуске ждёт адрес. Обратная ситуация настраивается симметрично: ipv4.method переводят в disabled, а адрес задают в ipv6.addresses.
Проверка результата выполняется тремя командами: профиль, адрес устройства и таблица маршрутов.
nmcli connection show static-lan | grep -E 'ipv4\.(method|addresses|gateway|dns)'
ip -4 addr show dev eth0
ip route show
Формат keyfile и правка конфигурации руками
Файл профиля это текстовый документ с разделами. Правка руками допустима, но требует перечитывания конфигурации службой, иначе изменения не применятся до перезагрузки.
# /etc/NetworkManager/system-connections/static-lan.nmconnection
[connection]
id=static-lan
uuid=6f1c6d3a-1a2b-4c3d-9e8f-0a1b2c3d4e5f
type=ethernet
interface-name=eth0
autoconnect=true
[ipv4]
method=manual
addresses=192.168.10.20/24
gateway=192.168.10.1
dns=192.168.10.1;1.1.1.1;
dns-search=example.local
[ipv6]
method=auto
[ethernet]
mac-address=52:54:00:11:22:33
Поле uuid обязано быть уникальным, и при копировании файла его меняют. Привязка возможна через interface-name по имени устройства или через mac-address по аппаратному адресу. Второй способ устойчив к переименованию интерфейсов после обновления ядра.
Права на файл задают доступ только для владельца, поскольку в профиле хранится пароль.
sudo chmod 600 /etc/NetworkManager/system-connections/static-lan.nmconnection
sudo nmcli connection reload
sudo nmcli connection up static-lan
journalctl -u NetworkManager -n 50 --no-pager
Команда reload перечитывает каталог профилей. Журнал службы показывает причину отказа: неверный формат строки, конфликт адресов, отсутствие устройства с указанным именем.
Старые файлы преобразует утилита из пакета NetworkManager, после чего исходные ifcfg переносят в резервный каталог, чтобы они не читались одновременно с keyfile. Двойное описание устройства приводит к тому, что применяется последний активированный профиль.
Формат ifcfg для CentOS 7 и прежних выпусков
На старых системах конфигурация лежит в каталоге /etc/sysconfig/network-scripts и называется по имени устройства. Ошибки в ней дают те же симптомы, что и в новом формате.
# /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=none
ONBOOT=yes
IPADDR=192.168.10.20
PREFIX=24
GATEWAY=192.168.10.1
DNS1=192.168.10.1
DNS2=1.1.1.1
DOMAIN=example.local
NM_CONTROLLED=yes
Значение BOOTPROTO=none означает отказ от DHCP, вариант static даёт тот же результат. Параметр ONBOOT=yes включает интерфейс при загрузке, и без него после перезагрузки сеть не поднимается, хотя ручная активация работает. Длина префикса задаётся параметром PREFIX либо маской NETMASK.
Дополнительные адреса того же интерфейса описывают отдельным файлом с суффиксом в имени, например ifcfg-eth0:0, и тем же набором параметров. Применение выполняется перезапуском службы или перечитыванием профиля через nmcli.
sudo systemctl restart network
sudo nmcli connection reload && sudo nmcli connection up "System eth0"
ip -4 addr show
Отдельная деталь касается порядка применения настроек. При нескольких профилях на одном устройстве активным становится последний применённый, а параметр connection.autoconnect-priority задаёт явный приоритет.
На новом выпуске такие файлы читаются только модулем совместимости. Откладывать преобразование не стоит: после удаления модуля конфиги перестанут читаться, и сеть поднимется с параметрами по умолчанию.
Причины ошибки Destination Host Unreachable после правки
Сообщение о недоступности узла означает, что система не определила, куда отправить пакет. В локальной сети это почти всегда сбой разрешения адреса, в маршрутизируемой сети отсутствие подходящего маршрута. Типовых причин шесть:
- Неверная длина префикса, из-за которой адрес получателя считается удалённым и пакет уходит на шлюз, которого нет в этой сети;
- Шлюз не указан или указан адрес из другой подсети, и маршрут по умолчанию отсутствует;
- Адрес уже занят другой машиной, и на запрос отвечает не тот узел;
- Профиль привязан к имени устройства, которого в системе нет, поэтому настройки не применились;
- Служба NetworkManager не запущена, а профиль активирован не был;
- Кабель не подключён, порт коммутатора выключен или машина оказалась в другой VLAN.
ip -4 addr show
ip route show
ping -c 3 192.168.10.1
ip neigh show
arping -I eth0 -c 3 192.168.10.20
journalctl -u NetworkManager -b --no-pager | grep -i -E 'error|fail'
Первые две команды показывают адрес и маршруты. Отсутствие строки default через ожидаемый шлюз означает, что параметр gateway не задан или задан неверно. Записи соседей в состоянии FAILED говорят, что устройство не отвечает на запросы, и причину стоит искать на уровне кабеля или коммутатора.
Полезно различать два сообщения. Недоступность узла чаще указывает на проблему разрешения адреса в локальном сегменте, отсутствие маршрута до узла на таблицу маршрутов или фильтрацию. Первое проверяют через ip neigh и arping, второе через ip route и ip rule.
Проверка с другой машины дополняет картину: если сосед видит адрес в таблице соседей, но не получает ответов, пакеты отбрасывает фильтр на самой машине.
sudo nft list ruleset | grep -i -E 'drop|reject' | head -n 20
Ещё один сценарий связан с виртуализацией: адрес назначается дважды, настройками гостевой системы и настройками виртуальной сети гипервизора. Результат выглядит как произвольная смена адреса после перезагрузки. Лечится это отказом от одного из источников.
Отдельно проверяют, не осталось ли двух профилей для одного устройства.
nmcli -f NAME,DEVICE,TYPE connection show
Как не потерять доступ при удалённой настройке
Правка адреса по сети через тот же интерфейс связана с риском: после применения профиля соединение разрывается, и при ошибке вернуться к машине не получится. Риск снижают несколькими приёмами.
Первый приём, проверка с автоматическим откатом. Команда подтверждает применение изменений, и если подтверждение не отправить, настройки возвращаются к прежним.
sudo nmcli connection modify static-lan ipv4.addresses 192.168.10.20/24
sudo nmcli --ask connection up static-lan
Второй приём, резервная перезагрузка. Планировщик перезагружает машину через несколько минут, отменить его можно сразу после проверки. Если доступ пропал, система вернётся в прежнее состояние сама.
sudo shutdown -r +5
sudo shutdown -c
Третий приём, работа через второй канал: консоль виртуальной машины, последовательный порт или интерфейс удалённого управления сервером.
До правки стоит сделать копию каталога профилей, чтобы восстановление сводилось к возврату файлов.
sudo cp -a /etc/NetworkManager/system-connections ~/nm-backup-$(date +%F)
После успешной правки прогоняют короткий набор проверок: доступность шлюза, работа DNS, ответ собственной службы по новому адресу и отсутствие ошибок в журнале за последнюю загрузку.
ping -c 3 192.168.10.1
getent hosts example.local
ss -tlnp | head -n 20
journalctl -b -p err --no-pager | tail -n 20
Завершает работу фиксация изменений. Конфигурацию сети удобно держать в системе контроля версий вместе с остальными настройками: файл профиля небольшой и текстовый, а его история позволяет вернуть рабочее состояние за минуту. Без системы контроля версий достаточно копии каталога профилей с датой в имени.
Отдельное правило касается имени интерфейса. Переименование устройства меняет привязку профилей, и машина может загрузиться без сети. Если имя нужно поменять, профиль одновременно переводят на привязку по MAC-адресу.