Два DHCP сервера на Centos7 с failover, dhcp-relay и динамическим обновлением зон

в 8:58, , рубрики: dhcp, dhcp failover, dhcp-relay, отказоустойчивость, Сетевые технологии, системное администрирование

Приветствую всех читательов. Мой первый опыт написания статей на Хабре, так что любая конструктивная критика приветствуется. Написать решил только лишь потому, что недавно столкнулся с задачей, решения которой «в лоб» не нашел.

Суть задачи в том, что в большой организации нужен был отказоустойчивый DHCP-сервер, с dhcp-relay и возможностью быстро синхронизировать конфигурацию. Основной момент, что в большинстве найденных мной руководствах рассматривается либо вариант failover, либо dhcp-relay и нигде оба варианта не рассматривались вместе да ещё и с удобным методом синхронизации конфигурации. Вдруг кому моя статья немного поможет?

Суть задачи в следующем: есть большое предприятие, сеть на >1000 компов, единственный vlan, 2 контроллера домена, в сети dhcp отсутствует(!). Предыдущие админы умели только так, но это отдельный рассказ и не для Хабра.

Понятно, что первой же задачей стала модернизация сети, а именно сегментация на vlan и внедрение dhcp. При анализе задачи были выработаны следующие требования:

  • Отказоустойчивость — независимость от какого-либо железа
  • Учитывая планы по сегментации сети — необходимо, чтоб сервер знал, в какой vlan какую адресацию отдавать
  • «Репликация» — учитывая, что планируется широко использовать dhcp «привязки» по MAC, нужно чтоб эти «привязки» работали всегда (например, сетевые принтеры)
  • Автоматическое ведение обратных DNS зон

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

  • Две виртуальные машины на двух разных гипервизорах
  • На машинах стоит centos7 и isc-dhcpd
  • На dhcp настроены failover, динамическое обновление зон и распознавание option 82
  • Option 82 меткой того VLAN, из которого пришел запрос, серверу отдают центральные коммутаторы L3+, на которых все VLAN и разруливаются
  • Так как большинство админов плохо ориентируются в linux и vim, нужна автоматизация процесса добавления статических привязок и механизм репликации конфига

Схема сети:

image

Имеем:

  • DC0 и DC1 с настроенными DNS серверами, 10.1.2.2 и 10.1.2.3
  • DHCP0 и DHCP1, 10.1.2.4 и 10.1.2.14
  • VLAN'ы пользователей: 10, 11, 20, 21
  • Домен corp.example.ru
  • Дополнительную DNS зону (для linux серверов) — example.lan
  • Маршрутизаторы на базе L3 коммутаторов с поддержкой dhcp option 82. Во всех VLAN'ах они имеют 1-й IP адрес, связаны через OSPF

Так как некоторые вещи достаточно тривиальны и описаны в интернете не раз, подробно их расписывать не буду.

  1. Для начала в Windows DNS создаем все обратные зоны для всех VLAN'ов, разрешаем зонам небезопасные обновления.
  2. Устанавливаем на виртуальные машины минимальный centos 7, устанавливаем пакет dhcp.
  3. Настраиваем DHCP-relay на интерфейсах управляемых коммутаторов. При этом в качестве circuit-id приходит строка «VLAN10» и т.п.
  4. Редактируем /etc/dhcp/dhcpd.conf
    # DHCP Server Configuration file.
    #   see /usr/share/doc/dhcp*/dhcpd.conf.example
    #   see dhcpd.conf(5) man page
    #
    #
    ddns-update-style interim;			# Тип обновлений
    ddns-domainname "corp.example.ru";		# Имя нашего домена
    update-static-leases on;			# На всякий случай
    
    local-address 10.1.2.4;				# Адрес сервера
     
    # Логгинг информации, если запрос пришел от DHCP-relay
    if exists agent.circuit-id {
    	log ( info, concat( " Accepted DHCP RELAY request for ",
    		binary-to-ascii (10, 8, ".", leased-address),
    		" Network segment: ",
    		option agent.circuit-id,
    		" DHCP Agent: ",
    		option agent.remote-id));
    }
     
    # this DHCP server to be declared valid
    authoritative;
     
    # Настройка безотказности
    failover peer "dhcp-failover" {
    	primary;			# Этот сервер главный
    	address 10.1.2.4;		# Его адрес
    	port 519;			# Его порт
    	peer address 10.1.2.14;		# Адрес второго DHCP
    	peer port 520;			# Порт второго DHCP
    	# Дополнительные параметры настройки
    	max-response-delay 30;
    	max-unacked-updates 10;
    	load balance max seconds 3;
    	mclt 1800;
    	split 128;
    }
    
    # Сообщаем этот суффикс всем клиентам
    option domain-name 		"corp.example.ru";
    # DNS-сервера
    option domain-name-servers	10.1.2.2, 10.1.2.3;
    # Дополнительные DNS-суффиксы. Не работает для Windows-клиентов
    option domain-search		"example.lan corp.example.ru";
    # Настройка времени аренды
    default-lease-time		604800;		# 7 days
    max-lease-time			2419200;	# 4 weeks
     
    # default netmask /24
    option subnet-mask 255.255.255.0;
    
    # Servers vlan - без DHCP
    subnet 10.1.2.0 netmask 255.255.255.0 {
    }
     
    # Дополнительные файлы конфигурации для VLAN'ов
    include "/etc/dhcp/dhcpd.d/vlan10.conf";
    include "/etc/dhcp/dhcpd.d/vlan11.conf";
    include "/etc/dhcp/dhcpd.d/vlan20.conf";
    include "/etc/dhcp/dhcpd.d/vlan21.conf";

  5. Теперь добавляем файл конфигурации для каждого VLAN (на примере /etc/dhcp/dhcpd.d/vlan10.conf)
    # Объявление зон для безболезненного динамического обновления
    zone 10.1.10.in-addr.arpa. {
     	primary 10.1.2.2;
    	secondary 10.1.2.3;
    }
     
    # Описываем класс для фильтрации запросов от DHCP-relay
    class "VLAN10" {
    	match if option agent.circuit-id = "VLAN10";
    }
     
    # Объявляем саму нашу сеть
    subnet 10.1.10.0 netmask 255.255.255.0 {
    	option routers  10.1.10.1;
    	pool {
    		failover peer "dhcp-failover";	# Указание на то, какой failover использовать
    		range 10.1.10.51 10.2.56.254;	# Диапазон
    		allow members of "VLAN10";	# Привязка к классу
    	}
    
    	# === Static hosts
    	# Admin
    	host admin {
    		hardware ethernet 01:23:45:67:89:ab;
    		fixed-address 10.1.10.20;
    	}
    	# Admin's printer
    	host admin {
    		hardware ethernet cd:ef:01:23:45:67;
    		fixed-address 10.1.10.21;
    	}
    	# Строчка ниже используется самописным скриптом как маркер того,
    	# что ниже нужно вставить текст для статической привязки очередного устройства
    	# Insert automatic text above this
    }
    

  6. Для второго DHCP сервера создаем аналогичные конфиги, только исправляем в основном файле:
    failover peer "dhcp-failover" {
    	secondary;			# Этот сервер запасной
    	address 10.1.2.14;		# Его адрес
    	port 520;			# Его порт
    	peer address 10.1.2.4;		# Адрес главного DHCP
    	peer port 519;			# Порт главного DHCP
    	# Дополнительные параметры настройки
    	max-response-delay 30;
    	max-unacked-updates 10;
    	load balance max seconds 3;
    }

Получились у нас 2 dhcp сервера, в случае отключения одного из них его функции подхватывает второй, при этом оба отвечают на запросы от dhcp relay agent и на основании установленной в dhcp option 82 circuit-id строки (в нашем случае имя VLAN) выдает каждому сегменту его диапазон.

Для репликации серверов достаточно написать скрипт, который синхронизирует файлы в каталоге "/etc/dhcp/dhcpd.d/" и перезапускает dhcp-демон после этого. Сам скрипт приводить не буду из-за очень «костыльного» кода, который писался на коленке и на очень скорую руку. Возможно синхронизировать конфиги с помощью утилиты типа csync2 или rsync.

Для добавления статических привязок также был написан отдельный скрипт, который мне стыдно приводить тут по тем же причинам. Каждый может порезвиться с этим сам либо добавлять статические привязки «ручками».

Единственное «но» — при добавлении нового VLAN основной файл конфигурации "/etc/dhcp/dhcpd.conf" придется править ручками, так как у меня не получилось сделать include на весь каталог, только на конкретные файлы.

Возможно это можно обойти двойным include: сначала в основном файле на вспомогательный, а во вспомогательном уже на конкретные файлы VLAN, а затем синхронизировать и вспомогательный, но я заморачиваться не стал.

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

Автор: a_putsev

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js