RFC 6225 Geolocation configuration generator tool

While mobile devices (especially those with a GPS) have made people more aware of geolocation/geotagging, you don’t need a GPS in a device to make it location-aware, nor do you need to resort to IP-based reverse lookups. Location information can be made available on any network that has a DHCP server using the Location Configuration Information DHCP Option defined in RFC 3825 and RFC 6225. It makes sense: for most wired or wireless networks, the engineer responsible for setting up the DHCP server will know at the least where the server or AP is located, and maybe even static information about the locations of each terminal of a wired port.

The Option has a somewhat unorthodox binary format with non-power-of-2-width fixed point reals. To make generating the DHCP configuration statements easier, I developed a web-based RFC 6225 location configuration generation tool. It’s all client-side and even has a Google Maps preview of the location!

Copy the configuration to your local DHCP server, grab an appropriate geolocation library, and you’re ready to go! The tool generates a DHCP LCI Option for both dnsmasq and ISC’s dhcpd.

The lack of fixed point integers in Javascript made the implementation a little trickier than it would have been in, say, C.

Other lessons: Google Maps is not highly accurate.

Update 2019-06-01: updated the tool from RFC 3825 to support RFC 6225 and the GeoLoc option.
Update 2023-04-24: fixed a bug with the dhcpd/dnsmasq config lines missing the leading payload bytes (that existed since 2019 :( )

dudders and reliable DNS zone updates

I’ve released a new version of dudders, 1.04, and finally submitted it as a package to OpenWRT. The focus of this release was on making the update more robust to network failure as the result of an email correspondence with Peter Holik. I am of the opinion that DNS UPDATE is a strong candidate for being TCP by default (along with zone-transfers).

In RFC 1123 it is stipulated that:

a DNS resolver or server that is sending a non-zone-transfer query MUST send a UDP query first.

However, if you are doing a DNS UPDATE you really want the reliability that TCP offers, even if you don’t expect truncation to be an issue. The update is sent to the relevant authority server, so the arguments about load on root servers in the RFC aren’t applicable.

I’ve made the UDP implementation retry by default, but I think if you need more than 2 retries, you should be considering using TCP with its (much more advanced) retransmission algorithms.

Peter also found a bug in glibc’s res_send (actually in their send_dg function) whereby the resolver interprets the lack of the DNS “recursion available” flag in the header as an error. However, that flag isn’t even meaningful for DNS UPDATE responses; according to RFC 2136, those bits:

Should be zero (0) in all requests and responses. A non-zero Z field should be ignored by implementations of this specification.

As a result, glibc was setting errno to ECONNREFUSED or ETIMEDOUT even when the update was successful. I’ve hacked dudders to double-check after res_send, but it’s making me question the wisdom of using res_send at all, given that I’m constantly working around it.

Update: submitted glibc bug report #11950

To get dudders-1.04 on OpenWRT, simply update the official package feed and select dudders from the Net > DNS > dudders menu in the buildroot config. For systems other than OpenWRT, you can grab the source from sourceforge, or even github.

dudders: Dynamically Updating DNS Duly Embracing RSA SIG(0)

For those of us with dynamic IP addresses at home (assigned via IPCP/PPP/ADSL) it’s nice to have a stable host name for remote access. My previous solution was to use dyndns, which uses an HTTP-based protocol to update a subdomain of one of dyndns’s domains. However, I preferred to use my own domain.

As I try to use cool crypto wherever possible, the public-key based SIG(0) from RFC2931 seemed like a nifty protocol to use. The usual tool for generating keys is dnssec-keygen, and for performing updates it’s nsupdate, both part of ISC’s BIND. I set this up and tested it from my MacBook Pro, where it worked fine.

However, since a WRT54GL router running OpenWRT controls my PPP connection, and thus knows when my IP address changes, the logical place to be running nsupdate was on this router. Unfortunately OpenWRT’s nsupdate (packaged as bind-client) is relatively large at 439186 octects; add to this libopenssl and bind-libs, and I’d run out of room on my JFFS2 partition. If you have the room, it’ll work for TSIGs: Ignace Mouzannar describes how to do it. However, even when I got it installed, I couldn’t make it sign a SIG(0) request. Chip Rosenthal has also noticed problems, and came up with an HTTP-based solution to get another host to run nsupdate, called web-nsupdate.

My solution? Write my own client in C, that can read the “dnssec-keygen“ key files. Presenting dudders: my lightweight DNS UPDATE client. It even comes as an OpenWRT ipkg. It still needs a crypto library, but it can use libgcrypt which (even after dependencies) still weighs in lighter than libopenssl.