Faking DNS with Ruby and Sinatra
I had an annoying problem, so I needed a hacky solution…
At work, we have a large number of boxes with dynamic IP addresses. Getting a static IP address is a complete pain, and keeping boxes running is bad for the planet.
IP addresses don’t *usually* change, but the do change often enough to be annoying - especially when you want to run a VMWare server to do something background-ish, and find that it’s IP address has changed and you have to open the console just to find the new address. Bleah.
I’m sure a DNS/DHCP trick could be done somewhere, somehow - probably setting up a special DNS server somewhere locally could be done. But I needed something quickly, so some ruby hackery was the solution…
Basically I set up a tiny web server running Sinatra, a really really simple web framework. It just listens to http posts containing mac addresses, host names, and IP addresses, and stores them (in a YAML text file on disk - this isn’t meant to be scalable!). It also serves up a general status page, plus a simple /etc/hosts file snippet containing all known hosts.
I then have a really tiny ruby script that I run on each other box, which posts that box’s IP address to the server whenever it changes. (Currently this means on Ubuntu boxes, it runs from /etc/network/if-up.d/, on RedHat it runs from a script called /sbin/ifup-local)
At any stage, a user can load the file served by the sinatra server at http://the_server:4567/hosts - this gives a snippet of text that can be pasted into an /etc/hosts file (or the Windows equivalent). I might automate this step eventually, but for now it’s a manual process; it’s usually pretty clear when your hosts file is wrong, and not that hard to update it.
The code is real simple. First, the script to post data from each machine - this basically runs ‘ipconfig’ and extracts useful fields, it would need fiddling to work on Windows or anywhere that had a different ipconfig command (or didn’t use ‘eth0′):
(note - file saved as text attachment to get around this blog’s limitations):
postip.rb
Next, the server. Sinatra does most of the work for me - but it’s documentation is kind of thin, so some bits took some fiddling. Still, it really doesn’t get much easier than this:
fakedns.rb
And that’s it!
Comment by Korny
March 7, 2008 @ 3:41 pm
oops, looks like wordpress didn’t like my inline html in the code. I might need to make these files into attachments…