Управление ISC DHCPd 4.x из скриптов

Понадобилось реализовать управление выдачей IP в сети одного провайдера, увязав его с системой учёта и прочими «фишками». В качестве DHCP сервера стоял ISC DHCP 4.x на 9-м Ubuntu Server’е.

Для DHCPd нужно было реализовать:

  1. добавление новой статичной резервации (по маку либо порту свитча — опция 82),
  2. «привязка» юзера с IP выданным динамически (то есть из пула свободных IP) в статичную резервацию
  3. удаление статичной резервации
  4. удаление динамической лизы до истечения срока резервации
  5. Различные отчёты по подсетям, мак-адресам, свободным и занятым аресам

Хочу поделиться информацией, собранной в процессе реализации, на какие подводные камни наткнулся, как обходил, что так и не обошёл. Возможно кому-то сэкономит несколько часов времени.

  1. ISC DHCPd не поддерживает и в обозримом будущем не будет поддерживать обновление конфига по SIGHUP или какому-то ещё сигналу. По их заверениям это «требует слишком серьёзной работы, на которую у них нет и не предвидится времени»
  2. Вся статичная конфинурация хранится в dhcpd.conf, вся динамическая dhcpd.leases. При чём сначала пишется lease, делается flush на диск, и только после этого посылается ответ клиенту. Вместе эти два файла содержат всю необходимую информацию, чтобы при рестарте сервер вернулся точно в то же состояние, в каком он был до этого.
  3. Если dhcpd делает что-то, что прописано в конфиге и не предполагает никаких вариаций, конфликтов (например статические резервации IP по MAC’у) — в dhcpd.leases ничего не пишется.
  4. Как следствие — единственный способ проследить когда последний раз выдавался некий IP статично привязанный к MAC’у — анализ логов: dhcpd.leases этой информации не содержит, в конфиг сервер тоже ничего не пишет.
  5. dhcpd имеет свой API через который теоретически можно управлять сервером в real-time. А так же command-line утилитку omshell, использующую этот API. Через неё теоретически можно управлять сервером без даун-тайма. К тому же она поддерживает возможность подать последовательность команд на STDIN, что делает её довольно удобным инструментом для многих задач. Все данные пишутся в dhcp.leases, конфиг не трогают.
  6. В omshell нет возможности получить списки чего-либо. Вся работа идёт с 1 уникальным объектом. Для получения списков придётся парсить файлы конфига/leases.
  7. omshell не поддерживает удаление имеющейся lease, говорит «not implemented». Кроме того во время одного из тестов поломался файл dhcp.leases (появился какой-то странный мусор внутри) и dhcpd из-за этого не перезапускался. Воспроизвести ситуацию не удалось, но решил не рисковать и оставил omshell в покое.
  8. В 4-й версии нет возможности контроллировать порядок динамической выдачи адресов из нескольких подсетей shared-network’а. Вариант типа выдавать публичные адреса для всех клиентов из основной сети и приватные с NAT-ом из другой только, если в основной сети в данный момент свободных не осталось больше не работает. Будет выдаваться из обеих в порядке, удобном dhcpd.
  9. Привязка ip-mac значит только, что этому маку будет выдан этот IP, если он попросит и IP будет свободен. Но при этом этот IP может быть выдан ещё кому-то, если на данный момент свободен, находится в pool’e где разрешено выдавать IP не прописанным статически клиентам и свободных адресов недостаточно.
  10. Мне не удалось найти ни одного готового внятно работающего инструмента, способного управлять isc dhcd 4.x из под web’a и мало-мальски расширяемого. Всё что есть более менее работоспособного — сделано под 3-ю версию.
  11. Я не нашёл ни одного реализованного в полной мере проекта подключения SQL как бекенда для хранения dhcpd.conf и dhcpd.leases. Все виденные мною проекты пересоздают конфиг, читают и пишут dhcpd.leases и перезапускают dhcpd

Далее, как я решил некоторые подзадачи в моём случае:

  • Удаление уже выданной lease решил посредством дописывания в конец dhcpd.leases копии требуемой лизы, заменив в ней «binding state active» на «bindng state free» и рестартом dhcpd. Сервер читает dhcpd.leases по порядку и записи встречающиеся позже оверрайдят предыдущие.
  • Данные хранил в MySQL, при изменениях перегенерил конфиг и перезапускал dhcpd.
  • Занятые на данный момент адреса получал прочитав dhcpd.leases (как упоминалось выше, его содержимое всегда актуально, файл легко разбирается регекспами) + из базы: всё чего нет ни в файле в статусе ‘active’, ни в базе — считается свободным.
  • Привязку IP к порту свича комбинацией класса и pool’a как в этом примере:
    ... класс задается по IP cвича и номеру порта ...
    class "172.16.16.227:4" {
    match if concat(
    binary-to-ascii(10,8,".",packet(24,4)),":",binary-to-ascii(10,8,"",suffix(option agent.circuit-id,1))) = "172.16.16.227:4";
    }
    ...
    subnet 192.168.1.0 netmask 255.255.255.0 {
    option routers 192.168.1.1;
    ... другие опции...
    pool { range 192.168.1.3; allow members of "172.16.16.227:4"; } # bind ip to port
    pool { #static bindings
    range 192.168.1.2; range 192.168.1.4; range 192.168.1.5;
    .... тут продолжается список занятых под разные нужды IP в этой сети, КРОМЕ тех что на портах свичей ...
    deny unknown-clients;
    }
    pool { #free IPs
    range 192.168.1.6; range 192.168.1.8; range 192.168.1.15;
    .... тут продолжается список cвободных IP в этой сети ...
    allow unknown-clients;
    }
    }

Leave a comment

Your comment