- Добавляем в /etc/portage/package.use/custom такие строчки
`#net-proxy/squid kerberos
net-proxy/squid kerberos (если требуется)
dev-libs/cyrus-sasl kerberos (если требуется)
net-misc/dhcp ldap (если требуется)
net-dns/bind-tools gssapi
- Редактируем /etc/krb5.conf
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
dns_lookup_kdc = no
dns_lookup_realm = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
rdns = false
#Для Windows 2003 добавить:
#default_tgs_enctypes = rc4-hmac des-cbc-crc des-cbc-md5
#default_tkt_enctypes = rc4-hmac des-cbc-crc des-cbc-md5
#permitted_enctypes = rc4-hmac des-cbc-crc des-cbc-md5
default_realm = DIB5.LOCAL
#default_ccache_name = KEYRING:persistent:%{uid}
default_keytab_name = /etc/squid/proxy.keytab
[realms]
DIB5.LOCAL = {
kdc = dc1.dib5.local
#kdc = srvasdc2.domen.local
#admin_server = dc1.dib5.local
}
- Редактиуем /etc/dhcp/dhcpd.conf
# DHCP Server Configuration file.
# see /usr/share/doc/dhcp*/dhcpd.conf.sample
# see 'man 5 dhcpd.conf'
#ddns-domainname "dib5.local"; # Имя нашего домена
local-address 192.168.1.200; # Адрес сервера
#option tftp-server-name "calculate.dib5.local";
#next-server 192.168.200.71;
#option tftp-server-name "wds-win.dib5.local";
#next-server 192.168.200.77;
#option bootfile-name "boot\\x86\\wdsnbp.com";
#option bootfile-name "boot\\x64\\wdsnbp.com";
#filename "lpxelinux.0";
#filename "pxelinux.0";
#option root-path
ddns-update-style interim;
ddns-updates on;
#ddns-update-style standard;
update-static-leases on;
ignore client-updates;
update-conflict-detection off;
do-forward-updates on;
update-optimization off;
allow unknown-clients;
#use-host-decl-names on;
ddns-domainname "dib5.local.";
ddns-rev-domainname "in-addr.arpa.";
#authoritative;
# Логгинг информации, если запрос пришел от 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));
#}
# Настройка времени аренды
default-lease-time 60;
max-lease-time 60;
# default netmask /24
#option subnet-mask 255.255.255.0;
include "/etc/dhcp/conf/192.168.1.subnet";
- создаем и редактируем /etc/dhcp/conf/192.168.1.subnet
# Vlan200
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.217 192.168.1.245;
option domain-name-servers 192.168.1.111;
option netbios-name-servers 192.168.1.111;
option netbios-node-type 8;
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.1.255;
option domain-name "dib5.local.";
option routers 192.168.1.1;
option ntp-servers 192.168.1.111;
on commit {
set noname = concat("dhcp-", binary-to-ascii(10, 8, "-", leased-address));
set ClientName = pick-first-value(option host-name, config-option-host-name, client-name, noname);
set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
#set ClientDHCID = binary-to-ascii(16, 8, ":", hardware);
set ClientDHCID = concat (
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,1,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,2,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,3,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,4,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,5,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,6,1))),2)
);
log(concat("Commit: IP: ", ClientIP, " DHCID: ", ClientDHCID, " Name: ", ClientName));
#execute("/etc/dhcp/dns-krbnsupdate.sh", "add", ClientIP, "-h", ClientName, "-m", ClientMac);
execute("/etc/dhcp/dns-krbnsupdate.sh", "add", ClientIP, "-h", ClientName, "-m", ClientDHCID);
}
on release {
set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
#set ClientDHCID = binary-to-ascii(16, 8, ":", hardware);
set ClientDHCID = concat (
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,1,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,2,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,3,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,4,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,5,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,6,1))),2)
);
set ClientName = pick-first-value(option host-name, config-option-host-name, client-name, noname);
log(concat("Release: IP: ", ClientIP));
#execute("/etc/dhcp/dns-krbnsupdate.sh", "delete", ClientIP, "-m", ClientMac);
execute("/etc/dhcp/dns-krbnsupdate.sh", "delete", ClientIP);
}
on expiry {
set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
set ClientName = pick-first-value(option host-name, config-option-host-name, client-name, noname);
# 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/dns-krbnsupdate.sh", "delete", ClientIP);
}
}
- создаем, редактируем и даем нужные права на скрипт /etc/dhcp/dns-krbnsupdate.sh
#!/bin/bash
# This script is for secure DDNS updates using GSS/TSIG
# Version: 0.1
## CONFIGURATION ##
# Kerberos realm
REALM="DIB5.LOCAL"
# Kerberos principal
PRINCIPAL="dnsupdater@${REALM}"
# Kerberos keytab
KEYTAB="/etc/dhcp/dnsupdater.keytab"
# Kerberos credentials cache
KRB5CC="/tmp/krb5cc_0"
# Use MIT kerberos args instead of heimdal.
KRB5MIT="YES"
# Domain appended to hostname
DOMAIN="dib5.local"
# Space separated list of DNS servers for sending updates to
NSRVS="192.168.1.111"
# Default DNS resource records TTL
RRTTL="60"
# Do not use TXT RRs (rfc4701)
NOTXTRRS="YES"
# Default to IPv4
PROTO="IPv4"
# Additional nsupdate flags (-g already applied), e.g. "-d" for debug
#NSUPDFLAGS="-d"
# Run in the foreground (for manual run only!!!), it's better to use "-d" as script's first argument
#DEBUG="YES"
######################################################
_usage() {
if [ "${NOTXTRRS}" == "YES" ]
then
echo "Usage:"
echo "`basename ${0}` add ip-address -h hostname [-m dhcid|mac-address] [-p IP version | --ipv4 | --ipv6] [-t dns-ttl] [-d]"
echo "`basename ${0}` delete ip-address [-m dhcid|mac-address] [-p IP version | --ipv4 | --ipv6]"
else
echo "Usage:"
echo "`basename ${0}` add ip-address -h hostname -m dhcid|mac-address [-p IP version | --ipv4 | --ipv6] [-t dns-ttl] [-d]"
echo "`basename ${0}` delete ip-address -m dhcid|mac-address [-p IP version | --ipv4 | --ipv6]"
fi
}
## VARIABLES ##
ACTION=${1}
IP=${2}
shift && shift
while [ ! -z ${1} ]
do
case "${1}" in
"-d")
DEBUG="YES"
shift
;;
"-m")
DHCID=${2}
shift && shift
;;
"-h")
NAME=${2%%.*}
shift && shift
;;
"-t")
RRTTL="${2}"
shift && shift
;;
"-p")
PROTO=${2}
shift && shift
;;
"--ipv4")
PROTO="IPv4"
shift
;;
"--ipv6")
PROTO="IPv6"
shift
;;
"--help")
_usage
exit 0
;;
*)
echo "Unknown option: ${1}"
_usage
exit 1
esac
done
_kerberos() {
export KRB5_KTNAME="${KEYTAB}"
export KRB5CCNAME="${KRB5CC}"
if [ "${KRB5MIT}" = "YES" ]; then
KLISTARG="-s"
else
KLISTARG="-t"
fi
klist ${KLISTARG} || kinit -k -t "${KEYTAB}" -c "${KRB5CC}" "${PRINCIPAL}" || { echo "DDNS: kinit failed"; exit 1; }
}
_expandv6() {
# Adapted from https://github.com/mutax/IPv6-Address-checks by
# Florian Streibelt <florian@f-streibelt.de>
local __revipv6=${2}
local INPUT="${1}"
local O=""
while [ "${O}" != "${INPUT}" ]; do
O="${INPUT}"
# fill all words with zeroes
INPUT="$( sed 's|:\([0-9a-f]\{3\}\):|:0\1:|g' <<< "${INPUT}" )"
INPUT="$( sed 's|:\([0-9a-f]\{3\}\)$|:0\1|g' <<< "${INPUT}")"
INPUT="$( sed 's|^\([0-9a-f]\{3\}\):|0\1:|g' <<< "${INPUT}" )"
INPUT="$( sed 's|:\([0-9a-f]\{2\}\):|:00\1:|g' <<< "${INPUT}")"
INPUT="$( sed 's|:\([0-9a-f]\{2\}\)$|:00\1|g' <<< "${INPUT}")"
INPUT="$( sed 's|^\([0-9a-f]\{2\}\):|00\1:|g' <<< "${INPUT}")"
INPUT="$( sed 's|:\([0-9a-f]\):|:000\1:|g' <<< "${INPUT}")"
INPUT="$( sed 's|:\([0-9a-f]\)$|:000\1|g' <<< "${INPUT}")"
INPUT="$( sed 's|^\([0-9a-f]\):|000\1:|g' <<< "${INPUT}")"
done
# now expand the ::
grep -qs "::" <<< "${INPUT}"
if [ "$?" -eq 0 ]; then
GRPS="$(sed 's|[0-9a-f]||g' <<< "${INPUT}" | wc -m)"
((GRPS--)) # carriage return
((MISSING=8-GRPS))
for ((i=0;i<$MISSING;i++)); do
ZEROES="$ZEROES:0000"
done
# be careful where to place the :
INPUT="$( sed 's|\(.\)::\(.\)|\1'$ZEROES':\2|g' <<< "${INPUT}")"
INPUT="$( sed 's|\(.\)::$|\1'$ZEROES':0000|g' <<< "${INPUT}")"
INPUT="$( sed 's|^::\(.\)|'$ZEROES':0000:\1|g;s|^:||g' <<< "${INPUT}")"
fi
# an expanded address has 39 chars + CR
if [ $(echo ${INPUT} | wc -m) != 40 ]; then
echo "Invalid IPv6 Address"
exit 1
fi
LEN=${#INPUT}
for ((i=LEN-1;i>=0;i--))
do
[ ${INPUT:i:1} != ":" ] && TMPSTR=${TMPSTR}"."${INPUT:i:1}
done
INPUT=${TMPSTR:1}".ip6.arpa"
# echo the fully expanded version of the address
eval ${__revipv6}="'${INPUT}'"
}
_main() {
umask 77
if [ -z "${IP}" ]
then
_usage
exit 1
fi
if [ "${NOTXTRRS}" != "YES" ] && [ -z "${DHCID}" ]
then
_usage
exit 1
fi
## NSUPDATE ##
case "${ACTION}" in
add)
if [ -z "${NAME}" ]
then
_usage
exit 1
fi
RRPTR="${NAME}.${DOMAIN}"
if [ "${NOTXTRRS}" != "YES" ]; then
NOTXTRRS=""
RRAOLD=`host ${RRPTR} | awk '/has address/ {print $4}'`
if [ -n "${RRAOLD}" ]; then
RRTXTOLD=`host -t txt "${RRPTR}" | sed -n '/descriptive text/s/^.*[[:space:]]descriptive text[[:space:]]*"\(.*\)"$/\1/p'`
[ -z "${RRTXTOLD}" ] && echo "DDNS: adding records for $ip (${RRPTR}) FAILED: has A record but no DHCID, not mine" && exit 1
RRTXT=`echo "${DHCID}${RRPTR}" | sha256sum`
RRTXT="000101${RRTXT%% *}"
[ "${RRTXT}" != "${RRTXTOLD}" ] && echo "DDNS: adding records for $ip (${RRPTR}) FAILED: has A record but DHCID is wrong" && exit 1
else
RRTXT=`echo "${DHCID}${RRPTR}" | sha256sum`
RRTXT="000101${RRTXT%% *}"
fi
else
NOTXTRRS=";"
fi
echo "${PROTO}!"
case "${PROTO}" in
"IPv4")
RRPTRNAME=`echo ${IP} | awk -F '.' '{print $4"."$3"."$2"."$1".in-addr.arpa"}'`
RECNAME="A"
;;
"IPv6")
_expandv6 ${IP} RRPTRNAME
RECNAME="AAAA"
;;
*)
echo "Unknown IP version: ${PROTO}"
exit 1
esac
_kerberos
for NSRV in ${NSRVS}; do
nsupdate -g ${NSUPDFLAGS} << UPDATE
server ${NSRV}
realm ${REALM}
update delete ${RRPTR}. ${RRTTL} ${RECNAME}
${NOTXTRRS}update delete ${RRPTR}. ${RRTTL} TXT
${NOTXTRRS}update add ${RRPTR}. ${RRTTL} TXT ${RRTXT}
update add ${RRPTR}. ${RRTTL} ${RECNAME} ${IP}
send
update delete ${RRPTRNAME}. ${RRTTL} PTR
update add ${RRPTRNAME}. ${RRTTL} PTR ${NAME}.${DOMAIN}.
send
UPDATE
RESULT=${?}
[ "${RESULT}" -eq "0" ] && echo "DDNS: adding records for ${IP} (${RRPTR}) succeeded" && exit 0
done
[ "${RESULT}" != "0" ] && echo "DDNS: adding records for ${IP} (${RRPTR}) FAILED: nsupdate status ${RESULT}" && exit "${RESULT}"
;;
delete)
RRPTR=`host ${IP} | awk '/domain name pointer/ { sub(/\.$/, "", $5); print $5}'`
if [ "${NOTXTRRS}" != "YES" ]; then
NOTXTRRS=""
if [ -n "${RRPTR}" ]; then
RRTXTOLD=`host -t txt "${RRPTR}" | sed -n '/descriptive text/s/^.*[[:space:]]descriptive text[[:space:]]*"\(.*\)"$/\1/p'`
[ -z "${RRTXTOLD}" ] && echo "DDNS: removing records for $ip (${RRPTR}) FAILED: has A record but no DHCID, not mine" && exit 1
RRTXT=`echo "${DHCID}${RRPTR}" | sha256sum`
RRTXT="000101${RRTXT%% *}"
[ "${RRTXT}" != "${RRTXTOLD}" ] && echo "DDNS: removing records for ${IP} (${RRPTR}) FAILED: has A record but DHCID is wrong" && exit 1
else
echo "DDNS: removing records for ${IP} FAILED: has no PTR, can not determine A record" && exit 1
fi
else
NOTXTRRS=";"
fi
case "${PROTO}" in
"IPv4")
RRPTRNAME=`echo ${IP} | awk -F '.' '{print $4"."$3"."$2"."$1".in-addr.arpa"}'`
RECNAME="A"
;;
"IPv6")
_expandv6 ${IP} RRPTRNAME
RECNAME="AAAA"
;;
*)
echo "Unknown IP version: ${PROTO}"
exit 1
esac
_kerberos
for NSRV in ${NSRVS}; do
nsupdate -g ${NSUPDFLAGS} << UPDATE
server ${NSRV}
realm ${REALM}
update delete ${RRPTR}. ${RRTTL} ${RECNAME}
${NOTXTRRS}update delete ${RRPTR}. ${RRTTL} TXT
send
update delete ${RRPTRNAME}. ${RRTTL} PTR
send
UPDATE
RESULT=${?}
[ "${RESULT}" -eq "0" ] && echo "DDNS: removing records for ${IP} (${RRPTR}) succeeded" && exit 0
done
[ "${RESULT}" != "0" ] && echo "DDNS: removing records for ${IP} (${RRPTR}) FAILED: nsupdate status ${RESULT}" && exit "${RESULT}"
;;
*)
_usage && exit 1
;;
esac
}
if [ "$DEBUG" = "YES" ]; then
_main
else
:
_main | logger -s -t dhcpd &
fi
- На КД создаем пользователя например dnsupdater и добавляем в группу DnsUpdateProxy
- В останстке DNS добавляем разделе безопасность пользователя dnsupdater или группу DnsUpdateProxy. Можно сделать на все дочернии обьекты чтобы этот пользователь смог обновить действующие записи.
- На КД, запускаем cmd от администратора, и выполняем команду
ktpass /princ dnsupdater@DIB5.LOCAL /mapuser dnsupdater@DIB5.LOCAL /crypto ALL /ptype KRB5_NT_PRINCIPAL /pass "12345" /out C:\dnsupdater.keytab
- файл копируем на сервер calculate с dhcp и выставляем нужные права.
- редактируем файл /etc/dhcp/dns-krbnsupdate.sh, указываем значения ниже
# This script is for secure DDNS updates using GSS/TSIG
# Version: 0.1
## CONFIGURATION ##
# Kerberos realm
REALM="DIB5.LOCAL"
# Kerberos principal
PRINCIPAL="dnsupdater@${REALM}"
# Kerberos keytab
KEYTAB="/etc/dhcp/dnsupdater.keytab"
# Kerberos credentials cache
KRB5CC="/tmp/krb5cc_0"
# Use MIT kerberos args instead of heimdal.
KRB5MIT="YES"
# Domain appended to hostname
DOMAIN="dib5.local"
# Space separated list of DNS servers for sending updates to
NSRVS="192.168.1.111"
# Default DNS resource records TTL
RRTTL="60"
# Do not use TXT RRs (rfc4701)
NOTXTRRS="YES"
# Default to IPv4
PROTO="IPv4"
# Additional nsupdate flags (-g already applied), e.g. "-d" for debug
#NSUPDFLAGS="-d"
# Run in the foreground (for manual run only!!!), it's better to use "-d" as script's first argument
#DEBUG="YES"
- Создаем групповую полититку, или меняем политику Default Domain Policy: В раздлеле Конфигурация компьютера -> Административные шаблоны -> Сеть DNS включаем эти значения Динамическое обновление - отключено, Регистрация PTR записи отлючено.
- Теперь DHCP сервер сможет обновлять А записи, PTR запись почему то не обновляется, а появляется новая запись с новым айпи.
- На windows клиентах выполняем команду ipconfig /realese *, ipconfig /renew * для получения нового ip.
- На dhcp сервер если запускать ручками скрипт /etc/dhcp/dns-krbnsupdate.sh delete <указать ip> то запись удаляется. Также если выполнить /etc/dhcp/dns-krbnsupdate.sh add <указать ip> -h hostname [-m dhcid|mac-address]
dns-krbnsupdate.sh add ip-address -h hostname [-m dhcid|mac-address] [-p IP version | --ipv4 | --ipv6] [-t dns-ttl] [-d]
dns-krbnsupdate.sh delete ip-address [-m dhcid|mac-address] [-p IP version | --ipv4 | --ipv6]