source: dyndns/dyndns.sh@ 187

Last change on this file since 187 was 187, checked in by Rick van der Zwet, 14 years ago

CGI details included

  • Property svn:executable set to *
  • Property svn:keywords set to Id
File size: 3.4 KB
Line 
1#!/bin/sh -
2#
3# KISS Dynamic DNS service (no locking (hint lockf wrapper), no advanced checking)
4# 'ping' is based on ssh call or CGI call
5#
6# = INSTALL - SSH =
7# 1) Make sure to allow rndc reload in your sudoers file
8# ssh_user ALL=(ALL) NOPASSWD: /usr/sbin/rndc reload
9# 2) prefix your ssh authorized key to allow only this script
10# command="/home/ssh_user/dyndns/dyndns.sh"
11# 3) Call for the remote host from crontab:
12# ssh -a -p 1022 -i id_rsa dnsserver.example.net `hostname -s`
13#
14# = INSTALL - CGI =
15# 1) Put your secret password in ``.cgi_secret''
16# 2) Alter your apache configuration to allow executing the script
17# ScriptAlias /dyndns /path/to/dyndns/dyndns.sh
18# 1) Make sure to allow rndc reload in your sudoers file
19# www_user ALL=(ALL) NOPASSWD: /usr/sbin/rndc reload
20# 3) Call from the remote host from crontab:
21# fetch -q -o - "http://dnsserver.example.net/dyndns/`hostname -s`/SECRET/"
22#
23# = USAGE =
24# Make sure your DNS entries has zones like this to allow remote updating
25# example 60 IN A 192.0.32.10
26# example 60 IN TXT "dyndns"
27#
28# Rick van der Zwet <info@rickvanderzwet.nl>
29#
30ZONE='vanderzwet.net'
31ZONEFILE="/etc/namedb/master/$ZONE"
32CGI_SECRET_FILE="`dirname $0`/.cgi_secret"
33
34### NO USER EDITABLE PARTS BELOW HERE ###
35exec 2>&1
36if [ -n "$SSH_ORIGINAL_COMMAND" ]; then
37 # SSH specific details
38 HOSTNAME=`echo $SSH_ORIGINAL_COMMAND | tr -c -d '[a-zA-Z0-9\-_\.]' | cut -d ' ' -f 1 | cut -d '.' -f 1`
39 REMOTEIP=`echo $SSH_CLIENT | cut -d ' ' -f 1`
40else
41 # CGI specific details
42 HOSTNAME=`echo $REQUEST_URI | tr -c -d '[a-zA-Z0-9\-_\./]' | awk -F/ '{print $3}'`
43 SECRET=`echo $REQUEST_URI | tr -c -d '[a-zA-Z0-9\-_\./\!_]' | awk -F/ '{print $4}'`
44 REMOTEIP=$REMOTE_ADDR
45 echo "Content-Type: text/plain"
46 echo ""
47 CGI_SECRET=`cat $CGI_SECRET_FILE`
48 if [ -z "$CGI_SECRET" ]; then
49 echo "Secret not readable from $CGI_SECRET_FILE"
50 exit 1
51 fi
52 if [ "$SECRET" != "$CGI_SECRET" ]; then
53 echo "Secret invalid"
54 exit 1
55 fi
56fi
57
58# Tmpfile creation for editing 'in between'
59TMPFILE=`mktemp -t $(basename $0 .sh).XXX`
60trap "rm -f $TMPFILE; exit 1" 0 1 2 15
61cp $ZONEFILE $TMPFILE || exit 1
62
63
64# See whether there exists a dynamic entry for it, like this
65# example 60 IN A 192.0.32.10
66# example 60 IN TXT "dyndns"
67LINENR=`awk -v host=$HOSTNAME '{if ($1 == host) { if ($4 == "A") { line=NR } else if($5 ~ /dyndns/) {print line; exit} }}' $TMPFILE`
68if [ -z "$LINENR" ]; then
69 echo "$HOSTNAME does not exists or is not marked as dynamic"
70 exit 1
71fi
72
73# Do we need to update the entry
74OLDIP=`awk -v linenr=$LINENR 'NR==linenr {print $5}' $TMPFILE`
75if [ "$OLDIP" = "$REMOTEIP" ]; then
76 echo "No changes"
77 exit 0
78fi
79
80# Update the entry
81sed -i '' "${LINENR}s/$OLDIP/$REMOTEIP/" $TMPFILE || exit 1
82
83# Update serial of zone name
84# YYYYMMDDNN where NN is from 00 till 99
85TODAY=`date "+%Y%m%d"`
86OLDSERIAL=`sed -n '1,10s/.*\([0-9]\{10\}\).*/\1/p' $TMPFILE`
87if [ -z "$OLDSERIAL" ]; then
88 echo "Error Unable to find SERIAL of zone"
89 exit 1
90fi
91if `echo $OLDSERIAL | grep -q "^$TODAY"`; then
92 if `echo $OLDSERIAL | grep -q '99$'`; then
93 echo "Sorry domain update limit reached no more updates for today"
94 exit 1
95 fi
96 NEWSERIAL=`expr $OLDSERIAL + 1`
97else
98 NEWSERIAL="${TODAY}00"
99fi
100sed -i '' "1,10s/$OLDSERIAL/$NEWSERIAL/g" $TMPFILE || exit 1
101
102# Install and activate
103if `/usr/sbin/named-checkzone -q $TMPFILE $ZONE`; then
104 echo "New zone failed to validate"
105 exit 1
106fi
107cp $TMPFILE $ZONEFILE || exit 1
108sudo /usr/sbin/rndc reload || exit 1
109echo "Entry updated"
Note: See TracBrowser for help on using the repository browser.