PDNSD

Avoiding captive redirects on Libero/Wind/Infostrada

New chapter of my router project if you don’t care to follow it you probably don’t want to read this at all.

Libero – or Infostrada, Wind, how the heck do you want to call it today – is my provider. Like other providers in Italy, who have probably noticed their users using OpenDNS instead of the standard DNS they provide, they started providing “captive redirects” on failed urls: when you mistype an URL or you try to access an hostname that does not exist, they redirect to their own servers, using their own “search engine” (nowadays just a Google frontend!).

This breaks quite a few assumption, included the fact that the .local domains won’t resolve in the standard DNS servers, which in turn makes nss-mdns almost unusable.

Up to a couple of months ago, Libero only provided this service in the primary nameserver, and if you switched around primary and secondary servers, you sidestepped the issue (that was the actual advertised procedure by the Libero staff, on the public page that was linked from within the search results). Unfortunately this had other side effects, for instance the time needed for the update of records more than doubled, which was quite boring with dynamic DNS and with newly-created domains.

Luckily, pdnsd supports blocking particular IP returned by the results to avoid the fake records created for captive redirects, and the example configuration file itself provides an example for using that with OpenDNS to avoid falling into their redirected Google host (quite evil of them in my opinion). And in particular, at the time, there was only one host used for captive redirect, so the rule was quite simple.

Fast forwards to today, the rule have changed; first of all it seems like Libero now uses redirects on both servers (or the secondary fails so often that it always responds from the primary), and most importantly they increased the number of IPs the redirects respond from. After counting four different IPs I decided to go with something more drastic, and ended up blacklisting the whole /24 network that they belong to (which is assigned, in RIPE, to Tiscali France… which is quite strange). I’m not sure if I ended up blacklisting more than I should have; for now it blacklists just enough for me to keep on browsing the net without adverse effects that I can see, and it also no longer stop me from enjoying .local domains… and Firefox auto-search with Google when the hostname does not exist.

For those interested, the configuration section is this one:

server {
 label= “libero”;
 ip = 193.70.152.15, 193.70.152.25;
 proxy_only=on;
 timeout=4;
 reject = 195.210.87.131/32, 62.210.183.0/24;
}

The first IP (a single host) is the one that was used earlier, I keep it on the blacklist just to be on the safe side.

First startup of the router

Tonight I tried for the first time the router in its official capacity as my main home gateway. It wasn’t really a good start to be honest.

The first problem has been the noise: my mother complained that the fans were too loud, so I wanted to go with my backup plan (replacing the main CPU fan with a fanless heatsink. Unfortunately it didn’t work out at all: there’s a capacitor in the way where the heatsink should go. Minus my intervention in form of a powerdrill over the (quite expensive) copper heatsink, it will never fit; my intervention is scheduled for tomorrow.

Sidestepped that for a moment (“Sure mom, I’ll fix it, just give me tonight to test it out!”), the next problem waiting in line was with the startup: I made a mistake in the hurry of fixing up the init scripts to actually start, and I had to take the nullmodem cable again and fix up the boot with the serial console; unfortunately I wanted to do that with my newly fixed MacBook Pro running the newly updated Snow Leopard, but the nullmodem cable had the WCH314 serial converter rather than the PL2303 (the only one I have at home that works with OS X – note to self: order some more PL2303 converters), so I had to pick up the right one again.

Queued up to fix tomorrow I got: a very custom init script to convert the ethers file into a dhcpd-compatible list of known clients, and a fix to the pdnsd init script so that it will create the cache directory if it doesn’t exist (otherwise, the daemon will silently fail to work which is definitely not what you want!).

The final problem is with the DHCP protocol and the modem itself. The modem is actually a so-called modem/router, running Linux itself, as well. Unfortunately, it seems like the way it handles the DHCP requests is not fully compatible with either dhcpcd or dhclient; the former will try to validate the provided address and then times out (failing back to ipv4ll addresses, zeroconf), and the latter tries to renew the lease every 30 seconds, without actually setting up the routes for the Internet connections.

On the other hand, hostapd seems to work fine and seems to handle multiple clients just fine; thanks to the fact that I finally can handle this stuff just like I want it to, I created a single, open, wireless network (I live in the middle of nowhere, whoever comes near my wifi enough to connect would be in my garden!), where the authorized clients will sit in one subnet, and are allowed to talk to each other, and the unauthorized clients are left in a different subnet, able to talk between them but not to the authorized ones, and can still connect to the internet (but only passively). The latter is quite helpful so that I don’t have to register all the laptops I get to fix, or all the PSPs that connect at my home.

For all those who thought that the whole idea was moot and that using Gentoo in such a system is too difficult: the only ebuild I had to locally overlay was file, which is now fixed in Portage and even in the stable systems; the rest worked fine with some tweaks; of course there are a few more issues (for instance a lot of packages install Perl-based scripts that are absolutely not mandatory, and I’d like for those to have a perl USE flag in the future), but the whole idea is not bogus and it woks fine. Using simply emerge --configroot and some custom configuration files, the resulting system is 164MB big, and with the due fixes to device.map even setting up grub was quite painless.

I guess the absolute final step would be to create a Rails application to manage the router, akin to the web interface of most commercial solutions. Yes I know that dd-wrt and other opensource firmware for “classic” routers have interfaces already, but if I have to write something, I’m most certainly going for implementing it in Ruby, as silly as that might sound. And to make stuff worse, if I do, I’ll be using sudo to launch the commands, getting the password via net… okay I’m definitely overthinking something I’m most likely never going to do.

And for those of you who know me and my mania with Star Trek names (even my cellphones are called Danube and Delta Flyer), this one got a quite famous name: Deep Space 9. After all, it is somewhat of a base station to another quadrant of the net!

P.S.: Here I might as well ask some help to the lazyweb; I am planning on two things that I haven’t started even implementing yet: IPv6 support for my network and QoS for the VoIP connections (I got two in this network usually, my cellphone and the DECT phone). For the former, I did request registration with SIXXS but I missed the “no free mail providers” bit and registered with the GMail address, and was thus rejected, now waiting in the queue to see if the staff can rescue my request or not; in the mean time I have no idea how to set up IPv6 properly to avoid making myself open to the world; ideas?

For what concern QoS does anybody have some easy link that explains how to set it up? All the stuff I found skimming through seem to be trying to explain how it work more than how to make it work; and I really don’t care how it works as much as making sure that all the VoIP traffic can trump the P2P and HTTP traffic (so that if I’m downloading a new ISO of FreeBSD I can still make calls properly). Ideas?