Найти тему
Андрей Ага

Настройка DHCP на Альт-Линукс

В общем-то, если у вас сеть без домена и создаете вы ее с нуля, то тут все просто: заходите на сервер в ЦУС по адресу https://ip_адрес_сервера:8080, там сначала настраиваете DHCP, а затем DNS. В итоге у вас получится настроенная связка DHCP+DNS, комп-ы и другие устройства(например, сетевые принтеры) будут получать адреса по DHCP, который будет вносить изменения в прямую и обратную зоны DNS-сервера. Кстати, после того, как вы все настроите- посмотрите в файл /etc/dhcp/dhcpd.conf - там должны быть строки с названиями зон(они содержат слово zone). Если нет, зайдите снова в ЦУС в DHCP, уберите галку с Включить DHCP, нажмите Применить, подождите несколько секунд, поставьте галку на место и снова нажмите Применить.

Рассмотрим случай, когда мы собираемся создавать домен на Альте, плюс делать мы это будем в сети, где уже есть виндовые DHCP, DNS и домен. Через ЦУС такое не настроить, так что идем в терминал. Ставим apt-get dhcp. На всякий случай удаляем apt-get remove alterator-dhcp, чтобы исключить возможность перезаписи /etc/dhcp/dhcpd.conf этим самым альтератором(он может это сделать).

Идем в /etc/dhcp/dhcpd.conf, удаляем там все и вставляем вот это:

ddns-update-style none;

authoritative;

option space altlinux;
option altlinux.keydata code 2 = string;
vendor-option-space altlinux;

deny unknown-clients;
shared-network xz
{
subnet 192.168.0.1 netmask 255.255.255.0
{
pool
{
max-lease-time 86400;
range 192.168.0.3 192.168.0.254;
deny unknown-clients;

host a1 { hardware ethernet 52:54:00:6f:06:8b; }

option routers 192.168.0.1;
option domain-name-servers 192.168.0.2;
option domain-name "xz.local";
default-lease-time 3600;
max-lease-time 3600;
}
}
}

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/d.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/d.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));
execute("/etc/dhcp/d.sh", "delete", ClientIP, "", "0");
}

Думаю, тут все понятно. Самое главное- строка deny unknown-clients; - она нужна, чтобы никто не мог получить ip-адрес с нашего сервера, кроме тех, кто явно прописан строкой вида host a1 { hardware ethernet 52:54:00:6f:06:8b; } (вместо a1 можно писать все, что угодно, лишь бы названия эти не повторялись). Кстати, на виндовом DHCP для этих мак-адресов нужно поставить запрет, чтобы они гарантированно получали адрес только с Альтовского сервера(это делается в Фильтрах). После того, как вы переведете все компы в новый домен- эту строку можно убрать.

Строки "on commit" и т.д. запускают обработчик, который обновляет информацию об ip-адресах в DNS, установку которого я опишу в следующий раз.

Для работы этого самого обработчика нужно кое-что сделать:

samba-tool user create dhcpduser --description="for_dhcp"
samba-tool user setexpiry dhcpduser --noexpiry
samba-tool group addmembers DnsAdmins dhcpduser
samba-tool domain exportkeytab --principal=dhcpduser@XZ.LOCAL /etc/dhcp/dhcpduser.keytab
chown dhcpd:dhcp /etc/dhcp/dhcpduser.keytab

Т.е. создать пользователя в Самбе и сгенерировать dhcpduser.keytab. Перед этим у вас должна быть установлен домен на Самбе. Как его создать- напишу в другой раз.

Важное замечание: из-за особенностей альтовского dhcpd запускаться d.sh не будет- будет писать, что не может найти файл и/или ошибку execute: d.sh exit status 32512. Как это исправить- описано здесь

Текст файла d.sh:

#!/bin/bash
domain=$(hostname -d)
#domain=xz.local
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="/etc/dhcp/dhcp-dyndns.cc"

# Kerberos principal
SETPRINCIPAL="dhcpduser@${REALM}"
# Kerberos keytab
# /etc/dhcp/dhcpduser.keytab
# krbcc ticket cache
# /tmp/dhcp-dyndns.cc

TESTUSER=$(/usr/bin/wbinfo -u | grep dhcpduser)
if [ -z "${TESTUSER}" ]; then
echo "Нет пользователя AD dhcp , требуется сначала его создать... Выход."
exit 1
fi

# Check for Kerberos keytab
if [ ! -f /etc/dhcp/dhcpduser.keytab ]; then
echo "Требуемый файл /etc/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 /etc/dhcp/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 /etc/dhcp/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

echo REALM: ${REALM}
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
echo ===1===
result1=$?

echo realm=${REALM}, ptr=${ptr}, name=${name}, domain=${domain}
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
echo ===2===
result2=$?
;;
delete)
_KERBEROS

nsupdate -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}

После всего включаем все это дело командой systemctl enable dhcpd

Запускаем командой systemctl start dhcpd

И убеждаемся, что он работает командой systemctl status dhcpd

Если пишет, что не запущен- запускаем dhcpd -t -cf /etc/dhcp/dhcpd.conf и смотрим- что ему там не нравится.