It's similar to http://smorgasbord.gavagai.nl/2011/08/homemade-dynamic-dns-service/ except that it works only for home networks without the need for external domain name.
A home network of computers, connected by one wired/wireless home router (perhaps also acting as a modem for Internet access), which also acts as DHCP server for all computers in the network.
What you will need:
/etc/hosts
but instead read a
bunch of hosts-file-like configuration from a specified directory,
say, /tmp/hosts
. A file whose content looks like this:
192.168.201.15 my-machine
/tmp/hosts
,
one for each IP address/host.
domain-needed bogus-priv no-resolv server=208.67.222.222 server=208.67.220.220 no-hosts addn-hosts=/tmp/hosts
/tmp/hosts
. This can be anything; if you wish
you can run a samba server (an overkill, but works); or run ssh/dropbear
server, ftp server, web server with php/ruby/python/generic CGI, etc.
For this article, however, I will just use busybox' version of netcat
(nc
) to do the job - it will listen to a specified port and execute
a shell script when something connects to that port (=a poor man's inetd).
The script reads a line that contains an action, password, hostname and
IP address. If the password matches, the script will create/update/delete
a hostfile entry in /tmp/hosts
depending on the action.
/tmp/hosts
if
they change. You have to send SIGHUP to dnsmasq to tell it to re-load
its configuration files including re-reading /tmp/hosts
.
But that's not a problem, we can either setup a inotify watch
on the directory and sends SIGHUP to dnsmasq when it changes;
or you can immediately send SIGHUP from the script that nc
executes after it updates /tmp/hosts
(this is what I do).
All that the clients (ie the other computers) need to do is to watch for changes in its IP address (and hostname too, but hostname rarely changes so I don't even bother here); usually because it gets a new lease, but may be for other reasons too. As soon as it detects that the IP address has changed, contact the server to tell it of its new address.
For this article - matching the simple server - to do the update is very
simple as well: just use nc
again to contact the server's nc
to push
the details. In fact, if bash
is your shell, you don't even need nc
here - you can send the command just by echo
-ing to bash's virtual
/dev/tcp/host/port
.
To detect the IP address change, the easiest to use "ip monitor
" command,
available from iproute2 package (unfortunately busybox' ip
command has
not yet supported the "monitor" sub-command). But this package isn't included
in Fatdog64 or Puppy, so instead I've adapted a simple C client (ipmon.c)
that uses netlink to detect the changes and output the new IP address to
stdout. It should be straightforward to change the script to use
ip monitor
instead, if you wish.
To glue all these together, we need to instruct the DHCP server on the home router to hand out our dnsmasq server as the DNS IP address, instead of the original modem/router/ISP DNS IP address (that's the reason why the dnsmasq server IP address should be fixed). This can usually be done through the modem/router's configuration page.
If this is not possible, then we'll just have to modify the dhcp script which
updates /etc/resolv.conf
on the client machines to use our dnsmasq server
IP address instead of using one obtained from DHCP server.
If this is still too difficult, then one can use inotify to watch
/etc/resolv.conf
and as soon as the file is changed
(by DHCP client presumably), override it again with our dnsmasq server address.
/etc/resolv.conf
- the first one (which will have priority) is the dnsmasq
server; and the second one is a upstream DNS server (your modem's, your ISP's,
Google's, OpenDNS's, etc) which will be used if the first nameserver can't be
contacted.
This ensures that your network can still access the Internet even when your dnsmasq server is down for whatever reason.
The tarball contains dnsmasq configuration and scripts for server setup, scripts for client setup, ipmon.c, statically-compiled ipmon for x86-64 (Fatdog64) and ARMv6 (FatdogArm).
Get it here.
Note: If you choose not to use nc
as the update mechanism,
you can uncomment watch_hostdir in the server's init script so that
changes to /tmp/hosts
are automatically applied (this requires
busybox' inotifyd
).
Works, and works better than the method outlined here, but it requires a special DNS resolver (nss-mdns) and a daemon to respond to the mdns requests. The typical daemons are Bonjour and Avahi; both of these have larger scope and just doing DNS resolution (they also do for service advertisement and discovery). All machines must run one of these to participate.
With the method of the article, a machine which doesn't run the "client" setup can still participate - it can still contacts other machines by normal DNS resolution (this is especially true if the modem/router can be configured to hand out dnsmasq server IP address during DHCP negotiation); although it itself isn't contactable.
The idea is the same (in fact, the above site is where I get the inspiration from), only the implementation is different. The above site uses sheerdns as the DNS server (instead of dnsmasq), and uses Apache/Python/PHP for the 'client' setup to update the name server.
Sheerdns is an authoritative server, not a caching nameserver; so to run it you need a fully-qualified domain over which you have been delegated as its authority. It's good if the scope is the Internet (you can use it just like a proper dynamic DNS service like no-ip.org, dyndns.org, etc).
The idea of contacting an URL managed with a wildcard CNAME is clever (contacting the URL http://kitten.reg-a-record.tld/reg.php will create a DNS entry for "kitten" with the caller's IP address - no form filling is necessary), but it requires a heavier infrastructure (at least a web server with CGI). The benefit is, since it uses HTTP, it works with all sorts of clients, not only desktops (it also works smartphones, etc).
You can achieve the same thing with even less work if you disable your router's DHCP server altogether, and instead run dnsmasq as both your DHCP (and caching DNS) server.
Dnsmasq can provide DNS resolution to hostnames it receives through DHCP requests - so as soon as a machine in the network is started and it asks for an IP address (and declare its preferred hostname); dnsmasq will allocate the IP address for that machine and automagically map that hostname to this IP address for later DNS resolution requests. No other server/clients are necessary: dnsmasq is your server and your DHCP client is your client.
Security Notes
This, by its very mechanism, is not secure. The hostname is provided by the 'client' machine, the IP address is also provided by the 'client' machine, it is easy for a client machine to create multiple entries and spoof names of other client machines to point them to itself.
Use this only in a closed network where the participating machines are not hostile.