Что мы имеем на начало установки:
- Установленный и работающий сервер BIND9 в связке с Samba DC.
- Samba собрана из исходников и установлена в /usr/local/samba/
- В DNS создана обратная зона для нашей сети.
- Все работы на сервере производятся от имени "root".
- Все работы проводятся на ОС Rosa Combalt (или CentOs7, RedHat 7 и других сборках, основанных на RedHat)
- Сервер DHCP устанавливается на одном из контроллеров домена.
Описание имеющейся сети:
- Домен: EXAMPLE.LOC
- Подсеть: 192.168.20.0
- Маска сети: 255.255.255.0
- Широковещательный адрес: 192.168.20.255
- Шлюз по умолчанию: 192.168.20.1
- Имя домена: example.loc
- DNS сервера: 192.168.20.2, 192.168,20,3
- NETBIOS сервера: 192.168.20.3, 192.168.20.2
- Сервера времени: 192.168.20.2, 192.168.20.3
- Диапазон арендуемых IP адресов: 192.168.20.50 - 192.168.20.229
Установка сервера DHCP
yum install dhcp*
Данная команда установит все пакеты, относящиеся к серверу DHCP
Создаем пользователя, от имени которого будут производится обновления DNS записей
samba-tool user create dhcpduser --description="Непривелигерованный пользователь для обновления TSIG-GSSAPI DNS через DHCP сервер" --random-password
Устанавливем срок действия пароля (безсрочный) для созданного пользователя и добавляем его в группу DnsAdmins
samba-tool user setexpiry dhcpduser --noexpiry samba-tool group addmembers DnsAdmins dhcpduser
Теперь экспортируем файл keytab, требующийся для выполнения обновлений.
samba-tool domain exportkeytab --principal=Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в вашем браузере должен быть включен Javascript. /etc/dhcp/dhcpduser.keytab
chown dhcpd:dhcpd /etc/dhcp/dhcpduser.keytab
chmod 400 /etc/dhcp/dhcpduser.keytab
Параметр dhcpd:dhcpd указывает пользователя, от имени которого работает сервер DHCP. Если он другой, то требуется указать его.
Создаем скрипт, для выполнения обновлений.
Создаем новую директорию и правим права доступа:
mkdir -p /etc/dhcp/bin chown -R /etc/dhcp/bin chmod 755 /etc/dhcp
Далее копируем следующий скрипт в файл /etc/dhcp/bin/dhcp-dyndns.sh
#!/bin/bash # /etc/dhcp/bin/dhcp-dyndns.sh # Скрипт для обновления DDNS в режиме secure на Samba 4 # Версия: 0.8.8 # DNS domain domain=$(hostname -d) if [ -z ${domain} ]; then echo "Невозможно определить имя домена, DNS настроен правильно?" echo "Невозможно продолжить... Выход." logger "Cannot obtain domain name, is DNS set up correctly?" logger "Cannot continue... Exiting." exit 1 fi # Samba 4 realm REALM=$(echo ${domain^^}) # Дополнительный флаг nsupdate (-g уже установлен), т.е. "-d" для отладки #NSUPDFLAGS="-d" # krbcc ticket cache export KRB5CCNAME="/tmp/dhcp-dyndns.cc" # Kerberos principal SETPRINCIPAL="dhcpduser@${REALM}" # Kerberos keytab # /etc/dhcp/dhcpduser.keytab # krbcc ticket cache # /tmp/dhcp-dyndns.cc TESTUSER=$(/usr/local/samba/bin/wbinfo -u | grep dhcpduser) if [ -z "${TESTUSER}" ]; then echo "Нет пользователя AD dhcp , требуется сначало его создать... Выход." echo "Вы должны выполнить следующие команды" echo "kinit Administrator@${REALM}" echo "samba-tool user create dhcpduser --random-password --description=\"Непривелигерованный пользователь для обновления DNS через DHCP сервер\"" echo "samba-tool user setexpiry dhcpduser --noexpiry" echo "samba-tool group addmembers DnsAdmins dhcpduser" exit 1 fi # Check for Kerberos keytab if [ ! -f /etc/dhcp/dhcpduser.keytab ]; then echo "Требуемый файл /etc/dhcpduser.keytab не найден, его необходимо создать." echo "Выполните следующие команды от пользователя root" echo "samba-tool domain exportkeytab --principal=${SETPRINCIPAL} /etc/dhcp/dhcpduser.keytab" echo "chown XXXX:XXXX /etc/dhcp/dhcpduser.keytab" echo "Замените 'XXXX:XXXX' на пользователя и группу, от имени которого выполняется сервер DHCP" echo "chmod 400 /etc/dhcp/dhcpduser.keytab" exit 1 fi # Переменные, предоставленные dhcpd.conf action=$1 ip=$2 DHCID=$3 name=${4%%.*} usage() { echo "USAGE:" echo " `basename $0` add ip-address dhcid|mac-address hostname" echo " `basename $0` delete ip-address dhcid|mac-address" } _KERBEROS () { # берем текущее время в цифровом формате test=$(date +%d'-'%m'-'%y' '%H':'%M':'%S) # Примечание: были проблемы с этим # проверьте, что 'date' возвращает что-то вроде # 04-10-17 10:23:15 # Check for valid kerberos ticket #logger "${test} [dyndns] : Running check for valid kerberos ticket" klist -c /tmp/dhcp-dyndns.cc -s if [ "$?" != "0" ]; then logger "${test} [dyndns] : Getting new ticket, old one has expired" kinit -F -k -t /etc/dhcp/dhcpduser.keytab -c /tmp/dhcp-dyndns.cc "${SETPRINCIPAL}" if [ "$?" != "0" ]; then logger "${test} [dyndns] : dhcpd kinit for dynamic DNS failed" exit 1; fi fi } # Выход, если нет ip адреса или mac-адреса if [ -z "${ip}" ] || [ -z "${DHCID}" ]; then usage exit 1 fi # Выйдите, если не указано имя компьютера, и если действие не является 'delete' if [ "${name}" = "" ]; then if [ "${action}" = "delete" ]; then name=$(host -t PTR "${ip}" | awk '{print $NF}' | awk -F '.' '{print $1}') else usage exit 1; fi fi # Установить PTR адрес ptr=$(echo ${ip} | awk -F '.' '{print $4"."$3"."$2"."$1".in-addr.arpa"}') ## nsupdate ## case "${action}" in add) _KERBEROS nsupdate -g ${NSUPDFLAGS} < UPDATE server 127.0.0.1 realm ${REALM} update delete ${name}.${domain} 3600 A update add ${name}.${domain} 3600 A ${ip} send UPDATE result1=$? nsupdate -g ${NSUPDFLAGS} UPDATE server 127.0.0.1 realm ${REALM} update delete ${ptr} 3600 PTR update add ${ptr} 3600 PTR ${name}.${domain} send UPDATE result2=$? ;; delete) _KERBEROS nupdate -g ${NSUPDFLAGS} UPDATE server 127.0.0.1 realm ${REALM} update delete ${name}.${domain} 3600 A send UPDATE result1=$? nsupdate -g ${NSUPDFLAGS} UPDATE server 127.0.0.1 realm ${REALM} update delete ${ptr}3600 PTR send UPDATE result2=$? ;; *) echo "Invalid action speciied" exit 103 ;; esac result="${result1}${result2}" if [ "${result}" != "00" ]; then logger "DHCP-DNS Update failed: ${result}" else logger "DHCP-DNS Update succeeded" fi exit ${result}
Установить права доступа на этот скрипт:
chmod 755 /etc/dhcp/bin/dhcp-dyndns.sh chown dhcpd:dhcpd /etc/dhcp/bin/dhcp-dyndns.sh
Изменяем файл конфигурации DHCP сервера dhcpd.conf
Прежде всего сохраним оригинальный файл
cp /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.orig
Теперь отредактируйте файл /etc/dhcp/dhcpd.conf и сделайте его похожим на приведенный ниже.
authoritative; ddns-update-style none; subnet 192.168.20.0 netmask 255.255.255.0 { option subnet-mask 255.255.255.0; option broadcast-address 192.168.20.255; option time-offset 0; option routers 192.168.20.1; option domain-name "example.loc"; option domain-name-servers 192.168.20.2, 192.168.20.3; option netbios-name-servers 192.168.20.3, 192.168.20.2; option ntp-servers 192.168.20.2, 192.168.20.3; pool { max-lease-time 1800; # 30 минут range 192.168.20.50 192.168.20.229; } } on commit { set noname = concat("dhcp-", binary-to-ascii(10, 8, "-", leased-address)); set ClientIP = binary-to-ascii(10, 8, ".", leased-address); set ClientDHCID = binary-to-ascii(16, 8, ":", hardware); set ClientName = pick-first-value(option host-name, config-option-host-name, client-name, noname); log(concat("Commit: IP: ", ClientIP, " DHCID: ", ClientDHCID, " Name: ", ClientName)); execute("/etc/dhcp/bin/dhcp-dyndns.sh", "add", ClientIP, ClientDHCID, ClientName); } on release { set ClientIP = binary-to-ascii(10, 8, ".", leased-address); set ClientDHCID = binary-to-ascii(16, 8, ":", hardware); log(concat("Release: IP: ", ClientIP)); execute("/etc/dhcp/bin/dhcp-dyndns.sh", "delete", ClientIP, ClientDHCID); } on expiry { set ClientIP = binary-to-ascii(10, 8, ".", leased-address); # cannot get a ClientMac here, apparently this only works when actually receiving a packet log(concat("Expired: IP: ", ClientIP)); # cannot get a ClientName here, for some reason that always fails execute("/etc/dhcp/bin/dhcp-dyndns.sh", "delete", ClientIP, "", "0"); }
Теперь запускаем dhcp сервер и смотрим, что происходит.
Добавляем отказоустойчивости.
Добавляем следующие строчки в файл /etc/dhcp/dhcpd.conf на "мастер-сервере":
failover peer "dhcp-failover" { primary; address dc1.example.loc; peer address dc2.example.loc; max-response-delay 60; max-unacked-updates 10; mclt 3600; split 128; load balance max seconds 3; auto-partner-down 86400; }
Устанавливаем DHCP сервер на другой контроллер домена и дополняем его файл dhcpd.conf строками:
failover peer "dhcp-failover" { secondary; address dc2.samdom.example.com; peer address dc1.samdom.example.com; max-response-delay 60; max-unacked-updates 10; load balance max seconds 3; auto-partner-down 86400; }
Важно: Убедитесь, что вы добавили раздел перехода на другой ресурс выше раздела «subnet».
Необходимо добавить ссылки для subnet/pool которые будут выполнять переход на другой сервер.
subnet 192.168.20.0 netmask 255.255.255.0 { option subnet-mask 255.255.255.0; option broadcast-address 192.168.20.255; option time-offset 0; option routers 192.168.20.1; option domain-name "samdom.example.com"; option domain-name-servers 192.168.20.2, 192.168.20.3; option ntp-servers 192.168.20.3, 192.168.20.5; pool { failover peer "dhcp-failover"; max-lease-time 1800; # 30 minutes range 192.168.20.50 192.168.20.229; } }
Настраиваем OMAPI и задаем секретный ключ
Создаем секретный ключ OMAPI на "мастер-сервере", используя утилиту dnssec-keygen, распространяемую вместе с BIND.
dnssec‐keygen ‐a HMAC‐MD5 ‐b 512 ‐n USER DHCP_OMAPI
Извлекаем полученный ключ:
cat Kdhcp_omapi.+*.private |grep ^Key|cut -d ' ' -f2-
Добавляем следующие строки в dhcpd.conf на обоих серверах:
omapi-port 7911; omapi-key omapi_key; key omapi_key { algorithm hmac-md5; secret "ПОМЕСТИТЬ_ПОЛУЧЕННЫЙ_СЕКРЕТНЫЙ_КЛЮЧ_СЮДА"; }
Необходимо заменить "ПОМЕСТИТЬ_ПОЛУЧЕННЫЙ_СЕКРЕТНЫЙ_КЛЮЧ_СЮДА" на ключ, извлеченный на предыдущем шаге.
Перезагружаем оба сервера для применения изменений:
systemctl restart dhcpd
В системных логах на обоих серверах должны появится записи похожие на эти:
Feb 28 17:34:39 dc1 dhcpd: failover peer dhcp-failover: peer moves from recover-done to normal Feb 28 17:34:39 dc1 dhcpd: failover peer dhcp-failover: Both servers normal
Если OMAPI работает правильно, можено проверить переход на другой ресурс, остановив основной сервер.
Также в файерволе необходимо открыть TCP порты 647 и 7911 на обоих серверах:
firewall-cmd --permanent --add-port=647/tcp firewall-cmd --permanent --add-port=2911/tcp firewall-cmd --reload
Значение «Split» «128» на «primary» сервере, делит ответственность для клиентов между двумя серверами по отказоустойчивости.
В итоге мы имеем в сети два DHCP сервера, работающие в режиме отказоустойчивости.
Для полного счастья нам необходимо заставить наш сервер раздавать адреса в разных VLAN (не ставить же в каждом VLAN свой DHCP сервер).
Настройка DHCP для разных VLAN.
В первую очередь на сервере DNS создаем обратные зоны для всех используемых подсетей.
На ядровом коммутаторе настраиваем (коммутаторе, функцией которого является маршрутизация внутренних сетей) для каждого VLAN параметр dhcp-relay. Описание как именно настраивать этот параметр не входит в рамки этой статьи. У каждого бренда есть свои тонкости данной настройки.
Далее в файл dhcp.conf вносим необходимые изменения:
# Логгинг информации, если запрос пришел от 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 ................... ................... ................... # Дополнительные файлы конфигурации для VLAN'ов include "/etc/dhcp/dhcpd.d/vlan10.conf"; include "/etc/dhcp/dhcpd.d/vlan11.conf";
Далее для каждого VLAN создаем свой конфиг:
# Объявление зон для безболезненного динамического обновления zone 10.1.10.in-addr.arpa. { primary 192.168.20.2; secondary 192.168.20.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; } }
Аналогичные изменения делаем на втором DHCP сервере.