Simple DDNS Service

Because I could not find any free dynamic DNS service (and I need one to access my mom’s PC for maintenance) I thought of implementing a simple one on my own. I already have had a 24/7 running server at home (which is accesible via an exisiting dynamic DNS service ;-)) so with a few lines of CGI code written in bash it wasn’t a big problem to get this work.

The protection is done via apache’s mod_auth so you need a valid user/password to update the IP address, for safety the CGI is available via https only. The name of the host is passed to the CGI so it’s possible in theory that user A uses a name formally used by user B (which is beside that written as a comment to the hosts-file). So if you don’t trust your users that they won’t send hostnames others that you gave them for use you should add some kind of protection, e.g. write a mapping file users/hosts and check if the user is allowed to use that host it did sent. Since I trust my mom I won’t do such checks! 😉

#! /bin/bash

# could use trap here for cleaning lockfile

FILE=/tmp/hosts.ddns
DOMAIN_TO_APPEND=”.ddns.invalid”

# Convert POST to GET
if [ “$REQUEST_METHOD” = POST ]
then
QUERY_STRING=`dd bs=1 count=”$CONTENT_LENGTH” 2>/dev/null`
fi
QUERY_STRING=`echo “$QUERY_STRING” | awk ‘BEGIN {RS=”&”; FS=”=”} {print $0}’`

LINE=`echo “$QUERY_STRING” | grep -w name`
name=${LINE##*=}
name=`echo “$name” | sed ‘s/%3A/:/g’ | sed ‘s/%2F/\//g’`

basename=`basename “$0″`
lockfile=”/run/lock/apache2/$basename.lock”
lockfile -r10 “$lockfile”
grep -v ” $name$DOMAIN_TO_APPEND ” “$FILE” >”$FILE.tmp”
echo “$REMOTE_ADDR $name$DOMAIN_TO_APPEND # updated `date` by $REMOTE_USER” >>”$FILE.tmp”
mv “$FILE.tmp” “$FILE”
rm “$lockfile”

echo ‘Content-type: text/html’
echo
echo “<!DOCTYPE HTML PUBLIC \”-//W3C//DTD HTML 4.01 Transitional//EN\””
echo ”       \”http://www.w3.org/TR/html4/loose.dtd\”>”
echo “<html>”
echo “<head></head>”
echo “<body>”
echo “$name has been set to $REMOTE_ADDR”
echo “</body>”
echo “</html>”

exit 0

Additionally I tried to include the written file in my local DNS service. Since I’m running dnsmas this could be done easily by adding an additional host file in dnsmasq’s config-file (addn-hosts=<file>). Unfortunatelly dnsmasq reads this file statically when it is started only so changes to the file are not recognized by dnsmasq. To achieve that you would have to send a SIGHUP signal to dnsmasq which would have to be done via sudo since the script running under user apache is of course not allowed to send the signal to the process running under user dnsmasq.

The update on my mom’s PC is one via a simple single-line wget call executed by cron.

Advertisements
This entry was posted in Bash/Shell, Linux. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s