DHCP отлично подходит для рабочих станций, но для сервера — это лотерея: адрес может смениться после перезагрузки коммутатора или истечения аренды, и все зависящие сервисы, файрвол-правила и DNS-записи разом окажутся неактуальны. Серверу нужен постоянный, предсказуемый адрес, который не меняется годами. В этой статье разберём, как настроить статический IP в современном Ubuntu через netplan, а заодно — как читать и менять таблицу маршрутизации, когда сервер должен видеть несколько сетей одновременно.

Возьмём для примера два узла лаборатории itpages.lab.local: сервер srv-db01 с адресом 192.168.10.12 в сети 192.168.10.0/24, и маршрутизатор rtr-edge01 с адресом 192.168.10.1, который смотрит наружу и по совместительству связывает основную сеть со служебным сегментом 192.168.20.0/24, где живут системы мониторинга.

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

Определяем сетевой интерфейс

Прежде чем что-либо конфигурировать, нужно понять, как называется интерфейс в системе. В современных дистрибутивах имена вида eth0 уступили место предсказуемым именам вида enp0s3 или ens160 — конкретное имя зависит от драйвера и шины устройства:

ip link show
ip a

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

Настройка статического адреса через netplan

Найди файл конфигурации в /etc/netplan/ — обычно это 00-installer-config.yaml или 50-cloud-init.yaml — и приведи его к следующему виду:

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: no
      addresses:
        - 192.168.10.12/24
      routes:
        - to: default
          via: 192.168.10.1
      nameservers:
        addresses: [192.168.10.5, 1.1.1.1]
        search: [itpages.lab.local]

Секция routes с ключом to: default задаёт маршрут по умолчанию — это современный синтаксис netplan, который пришёл на смену устаревшему параметру gateway4. Если в старой документации или в чужих конфигурациях встречается gateway4: 192.168.10.1, знай, что это тот же самый результат, просто записанный по-старому — netplan версии 2 всё ещё понимает оба варианта, но новый синтаксис гибче и позволяет задавать несколько маршрутов сразу.

Обрати внимание на права доступа к файлу — netplan откажется применять конфигурацию, если права слишком открытые:

sudo chmod 600 /etc/netplan/50-cloud-init.yaml

Проверь синтаксис перед применением:

sudo netplan generate
sudo netplan try

netplan try покажет предпросмотр и подождёт подтверждения 120 секунд — если сеть после применения отвалится, конфигурация автоматически откатится, и ты не потеряешь доступ к серверу даже при опечатке в адресе шлюза.

Настройка нескольких адресов на одном интерфейсе

Иногда серверу нужно несколько IP на одном физическом интерфейсе — например, для нескольких виртуальных хостов с раздельными SSL-сертификатами или для миграции сервиса со старого адреса на новый без простоя. Это делается простым добавлением второго адреса в список:

network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
      addresses:
        - 192.168.10.12/24
        - 192.168.10.13/24

После netplan apply оба адреса появятся на одном интерфейсе, и можно будет проверить это командой ip a — второй адрес отобразится как secondary, а приложения смогут слушать конкретный адрес через bind.

Второй сетевой интерфейс и раздельная маршрутизация

Если у srv-db01 два сетевых адаптера — один для пользовательского трафика, второй для сети репликации 192.168.30.0/24, — конфигурация netplan описывает оба интерфейса отдельно, и важно не задавать маршрут по умолчанию на обоих сразу, иначе система будет непредсказуемо выбирать, через какой интерфейс отправлять внешний трафик:

network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
      addresses: [192.168.10.12/24]
      routes:
        - to: default
          via: 192.168.10.1
    eth1:
      dhcp4: no
      addresses: [192.168.30.12/24]

На eth1 маршрут по умолчанию не указан — трафик в подсеть 192.168.30.0/24 пойдёт напрямую, а весь остальной трафик по-прежнему будет уходить через eth0 и rtr-edge01.

Работа с таблицей маршрутизации

Посмотреть текущие маршруты можно командой:

ip route show

Типичный вывод для srv-db01 покажет маршрут по умолчанию через rtr-edge01 и маршрут для локальной подсети:

default via 192.168.10.1 dev eth0 proto static
192.168.10.0/24 dev eth0 proto kernel scope link src 192.168.10.12
192.168.30.0/24 dev eth1 proto kernel scope link src 192.168.30.12

Если серверу нужен доступ к сегменту мониторинга 192.168.20.0/24 через отдельный маршрутизатор в той же сети, а не через основной шлюз, добавляем маршрут вручную и временно, для проверки:

sudo ip route add 192.168.20.0/24 via 192.168.10.254 dev eth0

Такой маршрут исчезнет после перезагрузки — это нормально для тестирования. Чтобы закрепить его постоянно, добавь секцию routes в netplan-конфигурацию нужного интерфейса:

routes:
  - to: 192.168.20.0/24
    via: 192.168.10.254

Настройка DNS отдельно от netplan

Ubuntu Server использует systemd-resolved для резолвинга имён. Проверить, какие DNS-серверы реально используются, можно командой:

resolvectl status

Если нужно временно поменять DNS без правки netplan (например, для отладки), это делается через resolvectl напрямую:

sudo resolvectl dns eth0 192.168.10.5
sudo resolvectl domain eth0 itpages.lab.local

Но такие изменения не переживут перезагрузку — постоянная настройка всегда должна идти через netplan, иначе конфигурация разъедется между файлом и реальным состоянием системы, и через полгода никто не вспомнит, откуда взялся текущий DNS-сервер и почему он отличается от документации.

Включение маршрутизации между сетями (IP forwarding)

Если сервер сам должен работать как маршрутизатор между двумя подсетями — например, промежуточный узел между сетью 192.168.10.0/24 и служебным VLAN, — нужно включить форвардинг пакетов на уровне ядра:

echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Без этой настройки Linux по умолчанию не пересылает пакеты между интерфейсами, даже если оба адреса настроены правильно и физически связаны с нужными сетями — трафик будет доходить до сервера и там же теряться.

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

Диагностика сетевых проблем

Когда после смены конфигурации сеть работает не так, как ожидалось, полезный набор команд для быстрой диагностики:

ip a
ip route
ping -c 4 192.168.10.1
traceroute 8.8.8.8
ss -tulnp

ss -tulnp покажет, какие порты реально слушаются и какой процесс их держит — это часто спасает, когда сервис вроде бы настроен, но снаружи недоступен: может выясниться, что демон слушает только 127.0.0.1 вместо 0.0.0.0 или конкретного адреса из внешней сети.

Ещё один полезный инструмент — networkctl, который показывает состояние всех интерфейсов, управляемых systemd-networkd:

networkctl list
networkctl status eth0

Команда покажет не только текущий адрес, но и статус линка (carrier detected или no carrier), что удобно для диагностики физических проблем — оборванный кабель, отключённый порт коммутатора, неправильный VLAN на access-порту.

Policy-based routing: несколько шлюзов и таблицы маршрутов

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

sudo ip route add default via 192.168.10.1 table 100
sudo ip rule add from 192.168.10.13 table 100
ip rule show
ip route show table 100

Таблица 100 в этом примере содержит альтернативный маршрут по умолчанию, а правило ip rule указывает ядру: пакеты с адресом источника 192.168.10.13 нужно маршрутизировать по этой таблице, а не по основной. Это удобный инструмент, но он усложняет диагностику — если через полгода забыть, что настроено policy-based routing, поведение сервера будет казаться необъяснимым. Обязательно документируй такие правила отдельно, вне самой конфигурации.

Настройка VLAN на сетевом интерфейсе

Если коммутатор настроен на передачу нескольких VLAN через один физический порт (trunk), сервер может получить доступ сразу к нескольким логическим сетям через один сетевой кабель, не требуя дополнительного интерфейса на каждую сеть. Например, на srv-db01 может понадобиться отдельный VLAN 20 для трафика резервного копирования поверх того же физического порта, где уже работает основная сеть 192.168.10.0/24. netplan описывает VLAN отдельной секцией, привязанной к родительскому интерфейсу:

network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
      addresses: [192.168.10.12/24]
      routes:
        - to: default
          via: 192.168.10.1
  vlans:
    eth0.20:
      id: 20
      link: eth0
      addresses: [192.168.20.12/24]

Параметр id: 20 задаёт тег VLAN, а link: eth0 указывает, через какой физический интерфейс проходит этот тегированный трафик. После применения конфигурации в системе появится виртуальный интерфейс eth0.20 с собственным IP-адресом — трафик с этим тегом коммутатор направит в отдельный широковещательный домен, полностью изолированный от основной сети, хотя физически оба идут по одному кабелю.

sudo netplan apply
ip -d link show eth0.20

Флаг -d в команде ip link show выводит дополнительные детали интерфейса, включая номер VLAN и имя родительского устройства — удобно для проверки, что тег настроен именно тот, что ожидался, особенно если на коммутаторе таких VLAN настроено несколько и легко перепутать номер при копировании конфигурации между серверами.

Важно, чтобы порт коммутатора со стороны сервера был настроен как trunk с разрешёнными нужными VLAN, а не как access-порт с одним VLAN по умолчанию — если сетевой инженер не согласовал эту настройку заранее, тегированные пакеты с сервера будут просто отброшены коммутатором, и создастся впечатление, что проблема на стороне Linux, хотя конфигурация netplan абсолютно верна.

Итоговая проверка конфигурации

После любых изменений в сети полезно пройтись по короткому списку проверок, прежде чем считать задачу закрытой:

  • ip a показывает ожидаемый адрес на нужном интерфейсе и статус UP.
  • ip route show содержит ровно один маршрут по умолчанию, если только сознательно не настроено policy-based routing.
  • ping до шлюза rtr-edge01 и до внешнего адреса проходит без потерь пакетов.
  • resolvectl status подтверждает, что DNS-серверы и домен поиска соответствуют ожидаемым.
  • конфигурация в /etc/netplan/ сохранена, права на файл ограничены (600), а изменения переживают перезагрузку — это стоит проверить явным образом хотя бы один раз после настройки.

Частые ошибки и как их избежать

  • Опечатка в отступах YAML. netplan крайне чувствителен к отступам — файл использует пробелы, а не табуляцию, и одна лишняя буква ломает всю конфигурацию с невнятной ошибкой парсинга. Всегда проверяй через netplan generate перед apply и используй редактор с подсветкой YAML.
  • Забыли про netplan try и потеряли доступ к серверу. Прямой netplan apply с ошибочным адресом шлюза мгновенно обрывает SSH-сессию без возможности вернуться удалённо. Для серверов без прямого доступа к консоли netplan try — не опция, а обязательная привычка.
  • Маршрут по умолчанию задан сразу на двух интерфейсах. Система в этом случае выбирает маршрут по метрике, и поведение становится непредсказуемым — трафик может внезапно пойти через резервный интерфейс с меньшей пропускной способностью. Задавай default route только на одном интерфейсе, который реально смотрит наружу.

Что дальше

Эта настройка почти всегда идёт в связке с соседними задачами администрирования Linux: