More responsive web browsing on 3G/UMTS via dnsmasq on Ubuntu
One of the downsides to moving house is the complete loss of internet access for an extended period. Yes, technically, you can get it switched over seamlessly. In my case, though, the previous tenant hadn’t even cancelled his phone service, so it’s been a lot more long-winded and painful. I should have a phone line again by Wednesday (after 3 calls to BT, the last of which took 20 minutes). 48 hours after that, I’ll be able to order ADSL, the provision of which takes five working days.
But this is the UK, where former incumbent state operators still work on soviet bureaucracy timescales (c.f. Royal Mail).
I’d anticipated this cascade of incompetence, so I pre-emptively purchased a 3G UMTS dongle (a little Huawei USB device the size of a butane lighter) and bandwidth package. For £100, I got both the device and 12 GB to be used at any time over a period of 12 months. That’s a pretty reasonable offer that fits my expected usage pattern well. Also, £100 is small beer in the context of all the thieving bastards taking advantage of my change of address to screw me over.
So hurrah for modern technologies! Except … 3G is slow. Not in raw data transfer terms—it’s actually faster than the overly-contended ADSL connection was at my old place—but the latency is painful.
Web browsing entails lots of DNS queries to look up
(resolve) the address of a page—to say that
google.com
is 209.85.171.100
, for
example. Firefox, rightly, doesn’t cache this information. It
defers to the operating system. The operating system, also rightly,
defers to the local DNS server. Under normal circumstances, this is
close enough (in four dimensions) that you don’t notice the tiny
amount of extra time taken to resolve DNS queries.
On my 3G dongle, though, it can easily take up to a second to return a response.
There’s a second problem, too, in that 3’s DHCP service doesn’t
always seem to return DNS information. You can fix this by
appending known-good DNS servers to /etc/resolv.conf
,
but it’s a hassle.
To summarise: I need a local DNS server that always knows where
to look upstream. I took some information from
Local DNS Cache for Faster Browsing with the caveat that, at
least according to the dnsmasq community
documentation, dnsmasq
interferes with Network
Manager. Here’s my solution. I’ve used OpenDNS for this example, as
their DNS servers should work for anybody.
Install the dnsmasq-base
and
resolvconf
packages:
sudo apt-get install dnsmasq-base resolvconf
Edit /etc/dnsmasq.conf
to contain:
listen-address=127.0.01
and
resolv-file=/etc/resolv.conf.upstream
You can find commented-out lines with the left-hand values; uncomment them and add the right-hand side to each.
Create a file in /etc/resolv.conf.upstream
containing just:
nameserver 208.67.222.222 nameserver 208.67.220.220
Use other DNS servers if you prefer.
Finally, uncomment/modify one line in
/etc/dhcp3/dhclient.conf
:
prepend domain-name-servers 127.0.0.1;
Restart dnsmasq:
sudo /etc/init.d/dnsmasq restart
Reconnect to your internet connection, and try typing dig
google.com
into the terminal a few times. After the first
lookup, it should be very fast.
There’s one wrinkle: in 8.04,
NetworkManager ignores all DNS settings for 3G connections, and
sets resolv.conf
to whatver the DHCP server returned,
bypassing the local server. The best solution I’ve found so far is
to edit /etc/network/interfaces
and configure
ppp0
:
iface ppp0 dns-nameservers 127.0.0.1