For a while now, I’ve been monkeying about with using OpenDNS as my DNS service provider rather than rather than using my ISP‘s name servers in order to take advantage of some of the great additional features offered by OpenDNS. In a simple scenario, configuring OpenDNS name server support is easy – just tell your network or machine to use their name servers and go on about your day. Easy. Except that my network architecture isn’t that simple. The other night I decided to put in the time to get myself sorted out and commit to OpenDNS.
In a nutshell, here’s what my home network architecture and usage looks like:
- I connect to the internet via DSL service.
- I do not have a static IP. It would make life easier (see problem #3 below), but I’m not willing to pay the premium.
- Behind a couple of firewalls, I run a LAN.
- I have an internal name server for resolving the IP addresses of other machines on the LAN.
- I have a DHCP server that broadcasts the name servers to be used by the other machines on the LAN in addition to assigning their IP addresses.
- I have an account with DynDNS that allows me to connect to my home network by name even though it has a dynamic IP that changes with some frequency.
- I often have to connect to work through a VPN to access corporate resources.
In the course of configuring OpenDNS for use in my environment, I bumped into a number of problems that I needed to solve.
Problem #1 : Resolving Internal and External Machine Names
In order to use OpenDNS, you can only use their name servers. Mix in another name server and all of the additional features aren’t available because OpenDNS no longer has full control over name resolution. Because I need internal machine names resolved, I originally had my DCHP server broadcasting my internal name server as the primary name server and the OpenDNS servers as the secondary and tertiary name servers. Both internal and external machine names were being resolved, but I couldn’t use any of the OpenDNS service features.
To solve the problem, I told my DHCP server to broadcast only the IP address of my internal name server. On the name server itself I defined a forwarder in my /etc/resolv.conf file (this is a Linux box, of course). Any domain name requested that is not known to the internal server will be sent to the name servers listed in that file. My resolv.conf file includes these entries:
Those are the OpenDNS name servers. If my internal name server doesn’t know how to direct a request, it’ll hand the request off to OpenDNS.
Problem #2 : VPN Connections
Some time last night, after solving the first problem, I noticed that, while VPN’d into the corporate network, the office Exchange server wasn’t available. I didn’t think much of it at the time and just assumed that our MIS guys were doing some maintenance or that maybe the server was down. When I couldn’t get in this morning, though, I got to thinking…what if I’m the problem? I was (of course).
I’m not a sys admin, so I the best I can offer is an educated guess as to what was happening. My company laptop was plugged into my home network which meant that the machine itself was using the name servers broadcast by my DHCP server as detailed above. When I connected to the VPN, that connection included the corporate name servers. I assumed that the name servers assigned to the VPN connection would override those assigned to the client machine itself. Not so, it would seem.
It seems that even while connected to the VPN, my home network name servers were taking precedence. That means that when requesting a corporate resource like, say, exchangeserver.corp.mycompany.com, my internal name server didn’t know what to do with the request and handed it off to OpenDNS. OpenDNS, of course, didn’t know what to do with it either.
I think (and take this for what it’s worth, please) that OpenDNS was engaging one of those nifty features I mentioned – typo correction. If OpenDNS doesn’t recognize the name as it was typed it tries to correct any spelling errors. If it can’t, maybe OpenDNS doesn’t hand off unknown requests to another name server or maybe it can’t. Whatever the case, the request for my internal resource was dying at OpenDNS’ name servers.
Since the problem was OpenDNS’ typo correction feature, then fixing it meant avoiding the correction. Fortunately, it’s not an all or nothing feature. A corollary feature, typo exceptions, is also provided. In my Settings > Type Exceptions interface, I just added corp.mycompany.com.
Problem #3 : Dynamic DNS Updates
The last problem I had was due to my lack of a static IP address. In order to use OpenDNS features like typo correction (and the exceptions I just configured), I needed to ensure that the network I defined in OpenDNS – the one that identifies me by my public IP address – would get updated when my ISP changed my IP.
My router firmware handles dynamic IP updates with DynDNS, but not with OpenDNS. Even though I only had one problem (managing OpenDNS), I really wanted my solution to solve both in order to keep everything under one umbrella, so to speak. OpenDNS provides another service, DNS-O-Matic, that does just that. Sure, it’s a cheesy name, but it works. You tell DNS-O-Matic about any other dynamic DNS services (including your OpenDNS network) and it takes on the responsibility of broadcasting any changes. All I have to do is let it know when a change occurs.
There’s a lot of software out there to monitor and push changes, but the service is a simple REST API so all it takes to tell DNS-O-Matic about my IP change is a simple HTTP request. Why do I need to install additional software for that?
The API documentation is pretty clear, so instead I opted to use cURL to do the dirty work. I wrote a quickie shell script that uses curl to retrieve my current IP address and then makes another curl request to the DNS-O-Matic web service passing that address.
#!/bin/bash # # Retrieve the current public URI # ip=`curl -s -m 5 http://myip.dnsomatic.com/` # # Send the new IP to DNS-O-Matic. # The URI (including the query string) in the curl command below # must be on one line. It is split here because of space limitations. # curl -m 60 -k -u mydnsomaticusername:mydnsomaticpassword \ https://updates.dnsomatic.com/nic/update?hostname=all.dnsomatic.com&myip=$ip&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG exit 0
Nothing tricky there right? DNS-O-Matic receives the request and kicks off similar requests to the services I’ve asked it to update. How convenient is that?
There is one caveat that I’ll offer because I spent hours trying to track it down. If you get a badauth error, look at your service passwords. I had a “<” in one of mine and it errored out. I assume that the other services offer similar REST web services and the HTTP request didn’t encode the symbol. Make sure that your passwords don’t contain characters that are illegal in URI strings.