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 |