ГлавнаяСтатьиПроект YvixSlideCraft

yvix-dhcp-server: выдача IP через REST API

yvix-dhcp-server — DHCP-сервер на Go, собранный на базе CoreDHCP. От классических DHCP-серверов он отличается тем, что решение «какой адрес выдать клиенту» принимает не статичный конфиг с пулом, а внешний REST API. Плюс есть файловый кеш выданных адресов — чтобы сеть продолжала работать, если API на время отвалится.

Из чего состоит

Сервер собирается из плагинов: в конфиге перечисляется список, и входящий запрос проходит по ним по очереди. Порядок важен.

Собственные плагины:

Встроенные плагины из CoreDHCP: dns, lease_time, mtu, searchdomains, server_id, netmask, router, staticroute, range (динамический пул), file (статические привязки), autoconfigure, prefix (для DHCPv6).

Конфигурация

Конфиг — YAML. Вот рабочий пример: выдача через API плюс кеш и пара стандартных опций.

server4:
  listen:
    - "0.0.0.0%enp3s0:67"
  plugins:
    - yvix:
        - https://your-domain.com
        - 0aaaaaaaaaaaaaaaabbbbbbbbbbbbbcccccccccc
        - if:enp3s0.123(123,124,125)
        - ip:10.153.0.1(130,131)
    - cacheplugin:
        - /var/lib/yvix-dhcpd/cache.bin
        - 86400
    - dns: 10.12.1.9
    - ntp4: 10.12.1.9
    - lease_time: 7200s
    - searchdomains: example.com
    - server_id: 192.168.12.1

Как сервер спрашивает у API

Плагин yvix принимает три обязательных параметра: базовый URL, секретный токен и карты if:/ip: (о них ниже). Из URL формируются два эндпоинта:

Запрос уходит как JSON с заголовком Authorization: Token <токен>. Таймаут — 15 секунд, проверка TLS-сертификата отключена, поэтому работают и самоподписанные сертификаты.

Запрос на выдачу:

{
  "clientMac": "18:c0:4d:95:d0:30",
  "hostname": "PCName",
  "circuitId": "0x...",
  "remoteId": "0x...",
  "seconds": 1800,
  "yourIpAddr": "0.0.0.0",
  "gatewayIp": "10.153.0.1",
  "clientId": "",
  "poolId": 101
}

Ответ API:

{
  "yourIpAddr": "10.153.0.50",
  "mask": "255.255.255.0",
  "router": "10.153.0.1",
  "leaseTime": 7200
}

Сервер применяет из ответа yourIpAddr, mask и router. Время аренды в DHCP-ответе задаёт отдельный плагин lease_time, а не поле leaseTime.

При DHCPRELEASE уходит короткий запрос:

{
  "clientMac": "18:c0:4d:95:d0:30",
  "ipAddr": "10.153.0.50"
}

Как выбирается пул

У API нет «одного пула на всё» — в запросе передаётся poolId, по которому ваш бэкенд понимает, в какой сети искать адрес. poolId — это uint16, и в текущей реализации это фактически VLAN ID, но семантически это «что угодно, что уникально привязано к сети и позволяет выбрать нужную подсеть».

Сопоставление задаётся прямо в конфиге плагина:

То есть при прямой выдаче смотрится интерфейс, а за relay — IP-адрес источника пакета.

Кеш

cacheplugin хранит пары MAC → IP в бинарном файле. Логика простая:

Поэтому, когда API лежит, клиенты продолжают получать свои прежние адреса, и сеть не встаёт. Срок жизни записи задаётся вторым аргументом плагина в секундах. Посмотреть содержимое кеша можно так:

yvix_dhcpd -S /var/lib/yvix-dhcpd/cache.bin

Что можно реализовать в API

Раз решение принимает ваш код, сценарии ограничены только фантазией:

Итог

yvix-dhcp-server превращает выдачу IP из «настройки конфига» в «вызов вашего кода». С одной стороны это максимальная гибкость и интеграция с бэкендом, с другой — зависимость от доступности API, которую закрывает кеш: если API отвалился, клиенты продолжают получать прежние адреса, и сеть не встаёт.