View difference between Paste ID: cNeVQdh3 and Aa10va7y
SHOW: | | - or go back to the newest paste.
1
#!/bin/sh
2
3
# This script is for secure DDNS updates using GSS/TSIG
4
# Version: 0.1
5
6
## CONFIGURATION ##
7
# Kerberos realm
8
realm="DOMAIN.LAN"
9
# Kerberos principal
10
principal="dhcpduser@$realm"
11
# Kerberos keytab
12
keytab="/etc/dhcp/dhcpd.keytab"
13
# Kerberos credentials cache
14
krb5cc="/run/dhcp-server/dhcpd.krb5cc"
15
# Use MIT kerberos args instead of heimdal.
16
#KRB5MIT="YES"
17
18
# Domain appended to hostname
19
domain="domain.lan"
20
# Space separated list of DNS servers for sending updates to
21
NSRVS="ns1.domain.lan ns2.domain.lan"
22
# Default DNS resource records TTL
23
RRTTL="3600"
24
# Do not use TXT RRs (rfc4701)
25
NOTXTRRS="YES"
26
27
# Additional nsupdate flags (-g already applied), e.g. "-d" for debug
28
#NSUPDFLAGS="-d"
29
# Run in the foreground (for manual run only!!!), it's better to use "-d" as script's first argument
30
#DEBUG="YES"
31
32
######################################################
33
34
## VARIABLES ##
35
[ "$1" = "-d" ] && DEBUG="YES" && shift
36
action=$1
37
ip=$2
38
DHCID=$3
39
name=${4%%.*}
40
[ -n "$5" ] && RRTTL="$5"
41
42
_usage() {
43
echo "Usage:"
44
echo "	`basename $0` [-d] add ip-address dhcid|mac-address hostname [dns-ttl]"
45
echo "	`basename $0` [-d] delete ip-address dhcid|mac-address"
46
}
47
48
_kerberos() {
49
export KRB5_KTNAME="$keytab"
50
export KRB5CCNAME="$krb5cc"
51
52
if [ "$KRB5MIT" = "YES" ]; then
53
    KLISTARG="-s"
54
else
55
    KLISTARG="-t"
56
fi
57
58
klist $KLISTARG || kinit -k -t "$keytab" -c "$krb5cc" "$principal" || { echo "DDNS: kinit failed"; exit 1; }
59
}
60
61
_main() {
62
umask 77
63
64
if [ -z "$ip" ] || [ -z "$DHCID" ]; then
65
    _usage
66
    exit 1
67
fi
68
69
70
## NSUPDATE ##
71
case "$action" in
72
    add)
73
        RRPTR="$name.$domain"
74
	if [ "$NOTXTRRS" != "YES" ]; then
75
	    NOTXTRRS=""
76
	    RRAOLD=`host $RRPTR | awk '/has address/ {print $4}'`
77
	    if [ -n "$RRAOLD" ]; then
78
		RRTXTOLD=`host -t txt "$RRPTR" | sed -n '/descriptive text/s/^.*[[:space:]]descriptive text[[:space:]]*"\(.*\)"$/\1/p'`
79
		[ -z "$RRTXTOLD" ] && echo "DDNS: adding records for $ip ($RRPTR) FAILED: has A record but no DHCID, not mine" && exit 1
80
81
		RRTXT=`echo "$DHCID$RRPTR" | sha256sum`
82
		RRTXT="000101${RRTXT%% *}"
83
		[ "$RRTXT" != "$RRTXTOLD" ] && echo "DDNS: adding records for $ip ($RRPTR) FAILED: has A record but DHCID is wrong" && exit 1
84
	    else
85
		RRTXT=`echo "$DHCID$RRPTR" | sha256sum`
86
		RRTXT="000101${RRTXT%% *}"
87
	    fi
88
	else
89
	    NOTXTRRS=";"
90
	fi
91
	
92
	RRPTRNAME=`echo $ip | awk -F '.' '{print $4"."$3"."$2"."$1".in-addr.arpa"}'`
93
94
	_kerberos
95
96
	for NSRV in $NSRVS; do
97
	    nsupdate -g $NSUPDFLAGS << UPDATE
98
server $NSRV
99
realm $realm
100
update delete $RRPTR. $RRTTL A
101
${NOTXTRRS}update delete $RRPTR. $RRTTL TXT
102
${NOTXTRRS}update add $RRPTR. $RRTTL TXT $RRTXT
103
update add $RRPTR. $RRTTL A $ip
104
send
105
update delete $RRPTRNAME. $RRTTL PTR
106
update add $RRPTRNAME. $RRTTL PTR $name.$domain.
107
send
108
UPDATE
109
	    result=$?
110
	    [ "$result" -eq "0" ] && echo "DDNS: adding records for $ip ($RRPTR) succeeded" && exit 0
111
	done
112
113
	[ "$result" != "0" ] && echo "DDNS: adding records for $ip ($RRPTR) FAILED: nsupdate status $result" && exit "$result"
114
    ;;
115
    delete)
116
	RRPTR=`host $ip | awk '/domain name pointer/ { sub(/\.$/, "", $5); print $5}'`
117
	if [ "$NOTXTRRS" != "YES" ]; then
118
	    NOTXTRRS=""
119
	    if [ -n "$RRPTR" ]; then
120
		RRTXTOLD=`host -t txt "$RRPTR" | sed -n '/descriptive text/s/^.*[[:space:]]descriptive text[[:space:]]*"\(.*\)"$/\1/p'`
121
		[ -z "$RRTXTOLD" ] && echo "DDNS: removing records for $ip ($RRPTR) FAILED: has A record but no DHCID, not mine" && exit 1
122
123
		RRTXT=`echo "$DHCID$RRPTR" | sha256sum`
124
		RRTXT="000101${RRTXT%% *}"
125
		[ "$RRTXT" != "$RRTXTOLD" ] && echo "DDNS: removing records for $ip ($RRPTR) FAILED: has A record but DHCID is wrong" && exit 1
126
	    else
127
		echo "DDNS: removing records for $ip FAILED: has no PTR, can not determine A record" && exit 1
128
	    fi
129
	else
130
	    NOTXTRRS=";"
131
	fi
132
	
133
	RRPTRNAME=`echo $ip | awk -F '.' '{print $4"."$3"."$2"."$1".in-addr.arpa"}'`
134
135
	_kerberos
136
137
	for NSRV in $NSRVS; do
138
	    nsupdate -g $NSUPDFLAGS << UPDATE
139
server $NSRV
140
realm $realm
141
update delete $RRPTR. $RRTTL A
142
${NOTXTRRS}update delete $RRPTR. $RRTTL TXT
143
send
144
update delete $RRPTRNAME. $RRTTL PTR
145
send
146
UPDATE
147
	    result=$?
148
	    [ "$result" -eq "0" ] && echo "DDNS: removing records for $ip ($RRPTR) succeeded" && exit 0
149
	done
150
151
	[ "$result" != "0" ] && echo "DDNS: removing records for $ip ($RRPTR) FAILED: nsupdate status $result" && exit "$result"
152
    ;;
153
    *)
154
	_usage && exit 1
155
    ;;
156
esac
157
}
158
159
if [ "$DEBUG" = "YES" ]; then
160
    _main
161
else
162
    :
163
    _main | logger -s -t dhcpd &
164
fi