Настройка DHCP-сервера

DHCP (Dynamic Host Configuration Protocol) автоматически выдаёт клиентам IP-адрес, маску, шлюз, DNS-серверы, домен поиска и другие сетевые параметры.

Основные серверы в Linux:

Названия пакетов и служб могут отличаться в разных дистрибутивах.

Содержание


Основы DHCP

Как работает DHCP

Типичный обмен DHCPv4 называется DORA:

  1. DHCPDISCOVER — клиент ищет сервер широковещательным запросом.
  2. DHCPOFFER — сервер предлагает адрес и параметры.
  3. DHCPREQUEST — клиент выбирает предложение.
  4. DHCPACK — сервер подтверждает аренду.

DHCPv4 использует 67/udp на сервере и 68/udp на клиенте. Выданный адрес является арендой (lease) с ограниченным сроком действия.

Широковещательный запрос обычно не проходит через маршрутизатор. Для обслуживания удалённых подсетей и VLAN нужен DHCP relay.


Планирование

До настройки определите:

Пример:

Подсеть:           192.168.50.0/24
DHCP-сервер:       192.168.50.2
Шлюз:              192.168.50.1
Пул:               192.168.50.100–192.168.50.200
DNS:               192.168.50.2, 1.1.1.1
Домен поиска:      office.example
Срок аренды:       12 часов

Адрес сервера, шлюза, DNS и сетевого оборудования не должен попадать в динамический пул.


Kea DHCP

Установка

Debian/Ubuntu:

sudo apt update
sudo apt install kea-dhcp4-server

RHEL-подобные системы:

sudo dnf install kea

Arch Linux:

sudo pacman -S kea

Типичный файл DHCPv4:

/etc/kea/kea-dhcp4.conf

Проверить фактические имена службы и пути:

systemctl list-unit-files | grep -i kea
systemctl cat kea-dhcp4-server

Базовая конфигурация Kea

{
  "Dhcp4": {
    "interfaces-config": {
      "interfaces": ["enp1s0"]
    },
    "lease-database": {
      "type": "memfile",
      "persist": true,
      "name": "/var/lib/kea/kea-leases4.csv"
    },
    "valid-lifetime": 43200,
    "renew-timer": 21600,
    "rebind-timer": 37800,
    "subnet4": [
      {
        "id": 1,
        "subnet": "192.168.50.0/24",
        "pools": [
          { "pool": "192.168.50.100 - 192.168.50.200" }
        ],
        "option-data": [
          { "name": "routers", "data": "192.168.50.1" },
          { "name": "domain-name-servers", "data": "192.168.50.2, 1.1.1.1" },
          { "name": "domain-name", "data": "office.example" },
          { "name": "domain-search", "data": "office.example" }
        ],
        "reservations": [
          {
            "hw-address": "52:54:00:12:34:56",
            "ip-address": "192.168.50.20",
            "hostname": "printer01"
          }
        ]
      }
    ],
    "loggers": [
      {
        "name": "kea-dhcp4",
        "output-options": [{ "output": "stdout" }],
        "severity": "INFO"
      }
    ]
  }
}

Проверка, запуск и просмотр логов:

sudo kea-dhcp4 -t /etc/kea/kea-dhcp4.conf
sudo systemctl enable --now kea-dhcp4-server
sudo systemctl status kea-dhcp4-server
sudo journalctl -u kea-dhcp4-server -f

В некоторых системах служба называется kea-dhcp4. Перед перезапуском всегда проверяйте конфигурацию:

sudo kea-dhcp4 -t /etc/kea/kea-dhcp4.conf && \
sudo systemctl restart kea-dhcp4-server

Резервации желательно размещать вне динамического пула. Для небольшой сети достаточно базы memfile; Kea также поддерживает PostgreSQL и MySQL.

Несколько подсетей

"subnet4": [
  {
    "id": 10,
    "subnet": "192.168.10.0/24",
    "pools": [{ "pool": "192.168.10.100 - 192.168.10.200" }],
    "option-data": [
      { "name": "routers", "data": "192.168.10.1" },
      { "name": "domain-name-servers", "data": "192.168.100.53" }
    ]
  },
  {
    "id": 20,
    "subnet": "192.168.20.0/24",
    "pools": [{ "pool": "192.168.20.100 - 192.168.20.200" }],
    "option-data": [
      { "name": "routers", "data": "192.168.20.1" },
      { "name": "domain-name-servers", "data": "192.168.100.53" }
    ]
  }
]

Для удалённых подсетей сервер выбирает пул по адресу relay-agent в поле giaddr.


ISC DHCP Server (dhcpd)

dhcpd широко используется в старых установках. Для новых проектов обычно выбирают Kea.

Установка

Debian/Ubuntu:

sudo apt install isc-dhcp-server

RHEL-подобные системы, если пакет доступен:

sudo dnf install dhcp-server

Основные файлы:

/etc/dhcp/dhcpd.conf
/var/lib/dhcp/dhcpd.leases

На Debian/Ubuntu интерфейс часто задаётся в /etc/default/isc-dhcp-server:

INTERFACESv4="enp1s0"
INTERFACESv6=""

Базовая конфигурация

authoritative;
default-lease-time 43200;
max-lease-time 86400;

option domain-name "office.example";
option domain-name-servers 192.168.50.2, 1.1.1.1;

subnet 192.168.50.0 netmask 255.255.255.0 {
    range 192.168.50.100 192.168.50.200;
    option routers 192.168.50.1;
    option subnet-mask 255.255.255.0;
    option broadcast-address 192.168.50.255;
}

host printer01 {
    hardware ethernet 52:54:00:12:34:56;
    fixed-address 192.168.50.20;
    option host-name "printer01";
}

authoritative применяйте только на сервере, действительно отвечающем за указанные подсети.

Проверка и запуск:

sudo dhcpd -t -cf /etc/dhcp/dhcpd.conf
sudo systemctl enable --now isc-dhcp-server
sudo systemctl status isc-dhcp-server

На RHEL-подобной системе служба обычно называется dhcpd.


dnsmasq

dnsmasq подходит для домашней сети, лаборатории, точки доступа, виртуальных машин и PXE.

Установка

# Debian/Ubuntu
sudo apt install dnsmasq

# RHEL-подобные системы
sudo dnf install dnsmasq

# Arch Linux
sudo pacman -S dnsmasq

Пример /etc/dnsmasq.d/lan.conf:

interface=enp1s0
bind-interfaces
port=0

dhcp-authoritative
dhcp-range=192.168.50.100,192.168.50.200,255.255.255.0,12h
dhcp-option=option:router,192.168.50.1
dhcp-option=option:dns-server,192.168.50.2,1.1.1.1
dhcp-option=option:domain-name,office.example

dhcp-host=52:54:00:12:34:56,printer01,192.168.50.20,infinite
log-dhcp

port=0 отключает DNS-функцию dnsmasq. Удалите эту строку, если dnsmasq должен также обслуживать DNS.

Проверка и запуск:

sudo dnsmasq --test
sudo systemctl enable --now dnsmasq
sudo journalctl -u dnsmasq -f

Файл аренд обычно расположен в /var/lib/misc/dnsmasq.leases, но путь зависит от дистрибутива.


systemd-networkd

Для небольшого изолированного сегмента можно использовать встроенный сервер. Пример /etc/systemd/network/20-lab.network:

[Match]
Name=br-lab

[Network]
Address=10.20.0.1/24
DHCPServer=yes
IPMasquerade=ipv4

[DHCPServer]
PoolOffset=100
PoolSize=100
DefaultLeaseTimeSec=12h
MaxLeaseTimeSec=1d
EmitDNS=yes
DNS=10.20.0.1
EmitRouter=yes

Применение:

sudo systemctl enable --now systemd-networkd
sudo networkctl reload
sudo networkctl reconfigure br-lab

Доступные параметры зависят от версии systemd:

man systemd.network

DHCP relay и VLAN

Если сервер не находится в клиентском L2-сегменте, broadcast нужно переслать через relay:

VLAN 10 ─┐
         ├─ маршрутизатор / DHCP relay ─ DHCP-сервер
VLAN 20 ─┘

На сетевом оборудовании функция может называться DHCP relay, IP helper или helper-address.

Relay в Linux:

sudo apt install isc-dhcp-relay
sudo dhcrelay -i vlan10 -i vlan20 192.168.100.10

В этом примере vlan10 и vlan20 — клиентские интерфейсы, а 192.168.100.10 — DHCP-сервер. Для постоянной работы используйте конфигурацию пакета или unit systemd.

Пример временного создания локального VLAN-интерфейса:

sudo ip link add link enp1s0 name enp1s0.20 type vlan id 20
sudo ip address add 192.168.20.1/24 dev enp1s0.20
sudo ip link set enp1s0.20 up

Для постоянной конфигурации применяйте NetworkManager, Netplan или systemd-networkd.


DHCP-опции

Опция Назначение
subnet-mask Маска подсети
routers Шлюз по умолчанию
domain-name-servers DNS-серверы
domain-name Домен клиента
domain-search Список доменов поиска
ntp-servers NTP-серверы
classless-static-routes Статические маршруты, option 121
tftp-server-name TFTP-сервер
boot-file-name Файл сетевой загрузки

Не все клиенты одинаково поддерживают дополнительные опции. Статические маршруты через option 121 необходимо проверять на целевых ОС.


Интеграция с DNS

DHCP сообщает клиенту адрес DNS, но сам по себе не создаёт записи в зоне BIND.

Возможные варианты:

Для безопасного DDNS с BIND применяют TSIG. Не разрешайте неаутентифицированное обновление зон. Нужно согласовать прямую и обратную зоны, создание A/AAAA и PTR, правила имён и удаление записей после окончания аренды.


DHCPv6

DHCPv6 использует 546/udp на клиенте и 547/udp на сервере. В IPv6 шлюз по умолчанию обычно передаётся через Router Advertisement, а не DHCPv6.

Основные варианты:

RA и DHCPv6 нужно проектировать совместно. Поведение зависит от флагов RA и поддержки клиентской ОС.


PXE-загрузка

Пример для dhcpd:

next-server 192.168.50.2;
filename "pxelinux.0";

Пример для dnsmasq:

enable-tftp
tftp-root=/srv/tftp
dhcp-boot=pxelinux.0

Для UEFI обычно используется отдельный файл, например bootx64.efi. В смешанной среде загрузчик выбирают по архитектуре клиента. TFTP не обеспечивает шифрование, поэтому PXE-сегмент следует ограничивать.


Межсетевой экран

UFW:

sudo ufw allow in on enp1s0 to any port 67 proto udp

firewalld:

sudo firewall-cmd --permanent --add-service=dhcp
sudo firewall-cmd --reload

nftables:

udp dport 67 iifname "enp1s0" accept
udp dport 547 iifname "enp1s0" accept

Разрешайте DHCP только на нужных внутренних интерфейсах. При relay необходимо разрешить обмен между relay-agent и сервером.


Логи и аренды

sudo journalctl -u kea-dhcp4-server -f
sudo journalctl -u isc-dhcp-server -f
sudo journalctl -u dhcpd -f
sudo journalctl -u dnsmasq -f

Типичные базы аренд:

/var/lib/kea/kea-leases4.csv
/var/lib/dhcp/dhcpd.leases
/var/lib/misc/dnsmasq.leases

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


Диагностика

Проверка интерфейсов и портов:

ip -br link
ip -br address
ip route
sudo ss -lunp | grep -E ':(67|547)\b'

Захват DHCPv4:

sudo tcpdump -nvvv -i enp1s0 'udp port 67 or udp port 68'

DHCPv6:

sudo tcpdump -nvvv -i enp1s0 'udp port 546 or udp port 547'

Интерпретация:

Нет DISCOVER       → клиент, VLAN, Wi-Fi или коммутатор
Есть DISCOVER,
но нет OFFER       → сервер, пул, firewall, интерфейс или relay
Есть OFFER,
но нет REQUEST     → ответ не доходит или отвергнут клиентом
Есть REQUEST,
но нет ACK         → сервер не подтверждает аренду

Обновление аренды на клиенте:

sudo dhclient -r enp1s0
sudo dhclient -v enp1s0

Для systemd-networkd:

sudo networkctl renew enp1s0

Проверка результата:

ip address show dev enp1s0
ip route
resolvectl status enp1s0

Типичные проблемы

Клиент не получает адрес

Проверьте службу, интерфейс прослушивания, свободные адреса, синтаксис, firewall, VLAN, relay, SELinux/AppArmor и соответствие пула подсети клиента.

Выдаётся адрес из неправильной подсети

Причинами бывают ошибочная VLAN-конфигурация, неправильный giaddr, объединение L2-сегментов или посторонний DHCP-сервер. Найти все предложения:

sudo tcpdump -eni enp1s0 'udp port 67 or udp port 68'

Сравните адреса и MAC отправителей DHCPOFFER.

Адрес есть, интернета нет

Проверьте шлюз, маршрутизацию, forwarding и NAT:

ip route
ping -c 3 192.168.50.1
ping -c 3 1.1.1.1

IP работает, DNS — нет

resolvectl status
cat /etc/resolv.conf
dig example.com

Проверьте DHCP-опцию DNS и доступность 53/udp и 53/tcp.

Пул исчерпан

Проверьте количество активных аренд. При необходимости расширьте пул или подсеть, либо сократите lease time для гостевой сети. Не удаляйте файл аренд вслепую.


Безопасность и отказоустойчивость

DHCP обычно не аутентифицирует сервер. Rogue DHCP может выдать вредоносный шлюз или DNS.

Рекомендуется:

Для отказоустойчивости используйте HA Kea, штатный failover существующей установки dhcpd либо split-scope с непересекающимися диапазонами:

Сервер A: 192.168.50.100–149
Сервер B: 192.168.50.150–200

Split-scope не синхронизирует аренды и уступает полноценному HA.


Резервное копирование

Сохраняйте:

Пример для Kea:

sudo systemctl stop kea-dhcp4-server
sudo tar -czf dhcp-$(date +%F).tar.gz /etc/kea /var/lib/kea
sudo systemctl start kea-dhcp4-server

Для SQL-базы используйте штатные средства резервного копирования СУБД. После восстановления проверьте конфигурацию до запуска службы.


Краткая памятка

Kea:

sudo kea-dhcp4 -t /etc/kea/kea-dhcp4.conf
sudo systemctl restart kea-dhcp4-server
sudo journalctl -u kea-dhcp4-server -f

ISC DHCP:

sudo dhcpd -t -cf /etc/dhcp/dhcpd.conf
sudo systemctl restart isc-dhcp-server
sudo journalctl -u isc-dhcp-server -f

dnsmasq:

sudo dnsmasq --test
sudo systemctl restart dnsmasq
sudo journalctl -u dnsmasq -f

Диагностика:

ip -br address
sudo ss -lunp | grep -E ':(67|547)\b'
sudo tcpdump -nvvv -i enp1s0 'udp port 67 or udp port 68'