Что мы имеем на начало установки:
- Установленный и работающий сервер 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 сервере.
