Настройка DHCP-сервера и диагностика сетевых проблем в дата-центре на 500 серверов

Ситуация клиента

Дата-центр «ДатаРу» эксплуатировал 500 bare-metal серверов в трёх залах. DHCP работал на одном сервере с конфигурацией, которую написали 5 лет назад. Проблемы: серверы иногда не получали IP при загрузке PXE, DHCP-сервер периодически падал без логов, а при замене сетевого оборудования половина серверов теряла связь на 10-15 минут.

Команда itfresh.ru провела аудит и перестроила DHCP-инфраструктуру: два DHCP-сервера в режиме failover, relay agents на каждом коммутаторе, статические привязки для всех серверов, интеграция с PXE для автоматической установки ОС.

Как работает DHCP: процесс DORA

Прежде чем чинить — нужно понять, как DHCP работает на уровне пакетов. Протокол использует 4 сообщения (DORA):

  1. Discover — клиент без IP отправляет broadcast (255.255.255.255) на UDP порт 67: «Кто здесь DHCP-сервер?»
  2. Offer — сервер отвечает unicast или broadcast на порт 68: «Вот тебе IP 10.0.1.42, маска /24, gateway 10.0.1.1, DNS 8.8.8.8, lease 3600 сек»
  3. Request — клиент подтверждает broadcast-ом: «Беру 10.0.1.42 от сервера 10.0.0.5»
  4. ACK — сервер финализирует: «Подтверждено, 10.0.1.42 твой на 1 час»

Ключевая особенность: на этапе Discover у клиента ещё нет IP-адреса. Поэтому dhclient открывает raw socket (AF_PACKET, SOCK_RAW), минуя стандартный сетевой стек ядра. Это означает, что iptables не может заблокировать DHCP-трафик — пакеты обрабатываются ниже уровня netfilter:

# Проверяем, как dhclient работает с raw sockets
strace -e trace=network dhclient -v eth0 2>&1 | head -20
# socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) = 5
# setsockopt(5, SOL_SOCKET, SO_ATTACH_FILTER, ...) = 0

# iptables НЕ блокирует DHCP:
iptables -A INPUT -p udp --dport 68 -j DROP
# Правило матчит (счётчик растёт), но dhclient продолжает получать ответы!

# Единственный способ заблокировать — XDP (eXpress Data Path):
# Программа eBPF, работающая до сетевого стека ядра

dhclient vs NetworkManager vs systemd-networkd

В Linux существует три основных DHCP-клиента. Выбор зависит от сценария использования:

Параметрdhclient (ISC)NetworkManagersystemd-networkd
НазначениеСерверы, минимализмДесктопы, Wi-FiСерверы, контейнеры
Raw socketsДа (AF_PACKET)Внутренний DHCP-клиентВнутренний DHCP-клиент
Конфигурация/etc/dhcp/dhclient.confnmcli / GUI/etc/systemd/network/*.network
Скрипты хуков/etc/dhcp/dhclient-exit-hooks.d/dispatcher.d/Нет (networkctl)
IPv6 (DHCPv6)dhclient -6ВстроеноВстроено
СтатусEnd-of-life (2022)Активная разработкаАктивная разработка

Важный нюанс: ISC объявил dhclient deprecated в 2022 году. Для новых серверов рекомендуется systemd-networkd. Но в «ДатаРу» половина серверов работала на CentOS 7 с dhclient, а вторая на Ubuntu 22.04 с systemd-networkd. Конфигурация для systemd-networkd:

# /etc/systemd/network/10-eth0.network
[Match]
Name=eth0

[Network]
DHCP=ipv4

[DHCPv4]
UseDNS=yes
UseNTP=yes
UseDomains=yes
RouteMetric=100
SendHostname=yes
# Запрашиваем конкретные опции
RequestOptions=1 3 6 15 42 119
# Не принимаем маршруты от DHCP
UseRoutes=false

Настройка ISC DHCP Server с failover

Для отказоустойчивости мы развернули два ISC DHCP сервера в режиме failover. Каждый сервер обслуживает свой диапазон адресов, но при падении партнёра забирает его пул.

Конфигурация основного (primary) сервера:

# /etc/dhcp/dhcpd.conf — Primary DHCP Server (10.0.0.5)

authoritative;
default-lease-time 3600;
max-lease-time 7200;
log-facility local7;

# Failover конфигурация
failover peer "dhcp-failover" {
    primary;
    address 10.0.0.5;
    port 647;
    peer address 10.0.0.6;
    peer port 647;
    max-response-delay 60;
    max-unacked-updates 10;
    mclt 3600;  # Maximum Client Lead Time
    split 128;  # 50/50 split
    load balance max seconds 3;
}

# Подсеть серверного зала 1
subnet 10.0.1.0 netmask 255.255.255.0 {
    option routers 10.0.1.1;
    option domain-name-servers 10.0.0.10, 10.0.0.11;
    option domain-name "dc1.dataru.local";
    option ntp-servers 10.0.0.10;

    pool {
        failover peer "dhcp-failover";
        range 10.0.1.50 10.0.1.250;
    }
}

# Серверный зал 2
subnet 10.0.2.0 netmask 255.255.255.0 {
    option routers 10.0.2.1;
    option domain-name-servers 10.0.0.10, 10.0.0.11;
    option domain-name "dc2.dataru.local";

    pool {
        failover peer "dhcp-failover";
        range 10.0.2.50 10.0.2.250;
    }
}

# Серверный зал 3
subnet 10.0.3.0 netmask 255.255.255.0 {
    option routers 10.0.3.1;
    option domain-name-servers 10.0.0.10, 10.0.0.11;
    option domain-name "dc3.dataru.local";

    pool {
        failover peer "dhcp-failover";
        range 10.0.3.50 10.0.3.250;
    }
}

Конфигурация secondary-сервера отличается тремя строками:

# Фрагмент /etc/dhcp/dhcpd.conf — Secondary (10.0.0.6)
failover peer "dhcp-failover" {
    secondary;  # <-- вместо primary
    address 10.0.0.6;
    port 647;
    peer address 10.0.0.5;
    peer port 647;
    max-response-delay 60;
    max-unacked-updates 10;
    load balance max seconds 3;
}

После запуска серверы синхронизируют базу leases и начинают работать в паре. Проверка статуса:

# Проверка failover-статуса
dhcpd -t -cf /etc/dhcp/dhcpd.conf  # проверка синтаксиса
systemctl restart isc-dhcp-server

# Просмотр leases
cat /var/lib/dhcp/dhcpd.leases | grep -A5 "^lease"

# Мониторинг failover-состояния
omshell << 'EOF'
server 127.0.0.1
port 7911
connect
new failover-state
set name = "dhcp-failover"
open
EOF

Статические привязки и PXE Boot

Для 500 серверов дата-центра критично иметь фиксированные IP-адреса. Мы создали статические привязки по MAC-адресам и интегрировали с PXE для автоматической установки ОС.

# Статические привязки в dhcpd.conf

# Группа для серверов зала 1
group {
    option domain-name "dc1.dataru.local";
    next-server 10.0.0.20;  # TFTP сервер для PXE
    filename "pxelinux.0";  # PXE bootloader

    host srv-dc1-001 {
        hardware ethernet 00:1a:2b:3c:4d:01;
        fixed-address 10.0.1.101;
        option host-name "srv-dc1-001";
    }
    host srv-dc1-002 {
        hardware ethernet 00:1a:2b:3c:4d:02;
        fixed-address 10.0.1.102;
        option host-name "srv-dc1-002";
    }
    # ... 160 серверов в зале 1
}

# Группа для PXE-установки (UEFI)
class "pxe-uefi" {
    match if substring(option vendor-class-identifier, 0, 9) = "PXEClient";
    filename "grubx64.efi";  # UEFI bootloader
    next-server 10.0.0.20;
}

# Группа для PXE-установки (BIOS)
class "pxe-bios" {
    match if substring(option vendor-class-identifier, 0, 9) = "PXEClient"
        and not substring(option vendor-class-identifier, 0, 20) = "PXEClient:Arch:00007";
    filename "pxelinux.0";
    next-server 10.0.0.20;
}

Для генерации 500 host-записей мы написали скрипт, который читал инвентарь из CSV:

#!/bin/bash
# generate_dhcp_hosts.sh — генерация host-записей из CSV
# CSV: hostname,mac,ip,room

while IFS=',' read -r hostname mac ip room; do
    cat << EOF
    host ${hostname} {
        hardware ethernet ${mac};
        fixed-address ${ip};
        option host-name "${hostname}";
    }
EOF
done < servers_inventory.csv > /etc/dhcp/hosts.conf

# Подключаем в основной конфиг:
# include "/etc/dhcp/hosts.conf";

DHCP Relay Agents

DHCP Discover — broadcast-пакет, который не проходит через роутеры. В дата-центре с тремя залами и отдельными VLAN-ами нужен DHCP relay agent на каждом L3-коммутаторе.

Настройка relay на коммутаторе (Cisco IOS):

! Конфигурация DHCP relay на Cisco
interface Vlan10
  description "Серверный зал 1"
  ip address 10.0.1.1 255.255.255.0
  ip helper-address 10.0.0.5   ! Primary DHCP
  ip helper-address 10.0.0.6   ! Secondary DHCP

interface Vlan20
  description "Серверный зал 2"
  ip address 10.0.2.1 255.255.255.0
  ip helper-address 10.0.0.5
  ip helper-address 10.0.0.6

interface Vlan30
  description "Серверный зал 3"
  ip address 10.0.3.1 255.255.255.0
  ip helper-address 10.0.0.5
  ip helper-address 10.0.0.6

Если коммутатор Linux-based (Open vSwitch или Cumulus), используется dhcrelay:

# Установка и запуск dhcrelay на Linux-коммутаторе
apt install isc-dhcp-relay

# /etc/default/isc-dhcp-relay
SERVERS="10.0.0.5 10.0.0.6"
INTERFACES="vlan10 vlan20 vlan30"
OPTIONS="-id vlan10 -id vlan20 -id vlan30 -iu eth0"

systemctl enable isc-dhcp-relay
systemctl start isc-dhcp-relay

# Проверка работы relay
tcpdump -i eth0 -n port 67 or port 68

Relay agent добавляет в DHCP-пакет опцию 82 (Agent Information), содержащую идентификатор VLAN и порта коммутатора. DHCP-сервер использует эту информацию для выбора правильной подсети.

Отладка DHCP через tcpdump

Когда серверы «ДатаРу» не получали IP, нужно было определить: пакеты не доходят до DHCP-сервера, или сервер не отвечает, или ответ не доходит обратно? Tcpdump — основной инструмент диагностики.

# Перехват DHCP-трафика на сервере
tcpdump -i eth0 -n -vv port 67 or port 68

# Пример нормального DORA-обмена:
# 10:15:01 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP Request
#   DHCP-Message: Discover
#   Client-Ethernet: 00:1a:2b:3c:4d:01
#
# 10:15:01 10.0.0.5.67 > 10.0.1.101.68: BOOTP/DHCP Reply
#   DHCP-Message: Offer
#   Your-IP: 10.0.1.101
#   Server-ID: 10.0.0.5
#
# 10:15:01 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP Request
#   DHCP-Message: Request
#   Requested-IP: 10.0.1.101
#   Server-ID: 10.0.0.5
#
# 10:15:01 10.0.0.5.67 > 10.0.1.101.68: BOOTP/DHCP Reply
#   DHCP-Message: ACK
#   Lease-Time: 3600

# Фильтр только Discover (для диагностики "не получает IP")
tcpdump -i eth0 -n 'udp and port 67 and udp[247:1] = 0x01'

# Запись в файл для анализа в Wireshark
tcpdump -i eth0 -n -w /tmp/dhcp_debug.pcap port 67 or port 68

Типичные проблемы, которые мы нашли при аудите:

  • Discover приходит, Offer нет: IP-пул исчерпан или конфликт подсетей в конфиге
  • Discover не приходит на сервер: relay agent не настроен или VLAN не прописан
  • ACK приходит, но IP не применяется: баг в dhclient-script или конфликт с NetworkManager
  • Двойные Offer: два DHCP-сервера без failover — гонка за lease

Результаты и рекомендации

После перестройки DHCP-инфраструктуры «ДатаРу»:

  • Время получения IP при PXE-загрузке: стабильно 1-2 секунды (было 5-30 секунд с таймаутами)
  • Отказоустойчивость: при выключении primary-сервера secondary подхватывает за 3 секунды
  • Управляемость: 500 статических привязок генерируются из CSV-инвентаря за секунду
  • Диагностика: любая проблема локализуется за 5 минут через tcpdump + логи

Рекомендации:

  • ISC DHCP Server deprecated — для новых инсталляций рассмотрите Kea DHCP (от тех же ISC, но на C++ с REST API)
  • Всегда используйте failover — один DHCP-сервер = single point of failure
  • Статические привязки для серверов, динамические пулы только для PXE-установки и временных устройств
  • DHCPv6 проще в диагностике — Link-Local адрес всегда есть, и стандартный firewall работает

Нужна помощь с DHCP или сетевой инфраструктурой дата-центра? Обращайтесь в itfresh.ru — настроим отказоустойчивый DHCP, PXE и автоматизируем управление IP-адресами.

Часто задаваемые вопросы

Потому что dhclient использует raw sockets (AF_PACKET), которые работают ниже уровня netfilter. Пакеты читаются напрямую с сетевого интерфейса через BPF-фильтр, минуя весь сетевой стек ядра. Заблокировать входящий DHCP можно только через XDP (eBPF на уровне драйвера) или отключив dhclient.
Kea — это следующее поколение от ISC. Написана на C++ (ISC DHCP на C), имеет REST API для управления, поддерживает хранение leases в PostgreSQL/MySQL, горячую перезагрузку конфигурации без перезапуска, встроенные hooks для расширения. ISC DHCP объявлен end-of-life в 2022 году.
Отслеживайте: количество свободных адресов в каждом пуле (dhcp-lease-count exporter для Prometheus), состояние failover-пары, время ответа на Discover. Критичный алерт — когда свободных адресов в пуле менее 10%. Логи dhcpd писать через syslog в отдельный файл для анализа.
Нет, если DHCP-сервер и клиенты в одном broadcast-домене — relay не нужен. Но в дата-центрах серверы обычно разнесены по VLAN-ам для изоляции трафика, и broadcast из одного VLAN не попадает в другой. В этом случае relay обязателен на L3-коммутаторе.
Создайте конфигурацию systemd-networkd заранее, затем в maintenance window: остановите NetworkManager/dhclient, включите systemd-networkd. Сетевой интерфейс сохранит текущий IP до истечения lease. При следующем DHCP renew systemd-networkd подхватит управление. Откат — обратное переключение.

Нужна помощь с проектом?

Специалисты АйТи Фреш помогут с архитектурой, DevOps, безопасностью и разработкой — 15+ лет опыта

📞 Связаться с нами
#dhcp#isc dhcp server#dhclient#networkmanager#pxe boot#relay agent#failover#tcpdump
Комментарии 0

Оставить комментарий

загрузка...