No, use *my* DNS. (aka Netflix vs tunnelbroker.net)

Google DNS is being hardcoded into a significant number of devices now. Which is nice, because it pretty much always works.

…except when you’re trying to use Netflix and you have a tunnelbroker IPv6 tunnel. Ugh.

So, this is a brief followup to Stupid OpenWRT tricks. Or maybe “Getting Netflix to work when your ISP doesn’t support IPv6 yet” is a better way to put it…

Anyways. In the previous post it I talked about how to use a local instance of bind to strip ipv6 addresses (AAAA records) from responses. (Again, I can’t take credit for that, though I like the way the person who came up with the idea thinks!) That solution works fabulously.

…unless your device decides it’s going to ignore your DNS servers, and go hit up 8.8.8.8 or 8.8.4.4 (or 2001:4860:4860::8888 or 2001:4860:4860::8844) directly. That’s going to fail. Ugh.

DNAT to the rescue! (Some NAT, like some cholesterol, moderate alcohol intake, and not staying up all night too often, is actually incredibly useful to downright fun. Particularly when staying up all night and the moderate alcohol intake are combined with writing ip6tables DNAT rules.)

The problem is that we have clients bypassing our DNS in favor of servers out on the public Internet. Our solution? Find anything that’s headed in through our lan interface (typically br-lan) and is headed to 53/udp, and DNAT it so that it’s headed to our router’s lan ip address. We don’t need to try to capture or reroute DNS traffic to 8.8.8.8 etc, because we don’t really want any of our clients doing direct DNS queries. (At least, I can’t think of a good reason.)

OpenWRT makes this pretty easy. While the Network->Firewall->Traffic Rules page doesn’t support DNAT, it’s easy enough to craft a custom rule and plug it in on the not very deceptively named “Custom Rules” page. OpenWRT also has a rather nice setup of iptables chains, including ones for user-defined rules, so you can add rules without their being trashed every time the firewall is reloaded.

For our purposes, this will do the trick:

iptables -t nat -A prerouting_lan_rule -p udp --dport 53 -j DNAT --to 192.168.1.1 -m comment --comment 'dns capture and redirect DNAT'

Note we’re using the user rule prerouting_lan_rule; this rule already only has packets coming in on br-lan, so we can omit the -i br-lan from our rule we’d otherwise need.

Once you’ve saved this, you either need to reboot or just ssh into your router and run the command directly, and you should be able to watch Netflix again. You can run host netflix.com 8.8.8.8 from a client box to see that no AAAA records are returned.

While we’re here, we should probably do this for IPv6 as well, just in case. First you’re going to need to install a couple additional packages: kmod-ipt-nat6, and if your lan interface is a bridge you’ll also need kmod-ebtables-ipv6. Then this rule should do it:

ip6tables -t nat -A PREROUTING -i br-lan -p udp --dport 53 -j DNAT --to 2001:470:XXXX:XXXX::1 -m comment --comment 'dns capture and redirect DNAT'

Note OpenWRT does not set up any chains in the IPv6 nat table, because you should never use NAT in IPv6.

Um, aside from this, naturally.

Enjoy!

Stupid OpenWRT ipv6 tricks

So, if you’re like me you find yourself wondering why your broadband provider has a /32 IPv6 prefix assigned, and yet chooses not to use it, forcing one to either be IPv4-only (how 20’th century) or use an IPv6-over-IPv4 tunnel solution.

Fortunately there is a simple and free solution out there, courtesy of Hurricane Electric’s rather fabulous tunnelbroker service. Obtaining an IPv6 prefix and setting up the tunnel is covered, extensively, so I won’t go into it. It’s also rather easy to set the tunnel up on an OpenWRT based router, like mine. The default setup is rather nice, but there are some changes you can make to your router configuration that will make it even nicer.

Remove the “ULA Prefix”

OpenWRT creates, by default, a ULA prefix — a deprecated “site-local” prefix. While these are perfectly valid, I’ve found that non-globally routable IPv6 addresses tends to confuse the heck out of Android-based phones, resulting in certain operations taking forever while various network operations time out, and are then retried with globally routable addresses. They’re also pointless, as we don’t do IPv6 NAT (don’t even think it), so just remove it. Your phone will thank you.

A note about firewalls

It’s worth repeating: we don’t do IPv6 NAT. Assuming you’ve removed the ULA prefix, every non-link-local IPv6 address assigned will be globally routable, meaning, among other things, that you can’t just rely on NAT to be your firewall, you’ll actually have to use your router as a firewall as well.

This is also well documented, and left as an exercise for the reader. …one I rather suspect you’ve already completed, as, well, you’re using OpenWRT, aren’t you?

More than one network? Get a /48!

By default, HE will give you a /64 routed prefix: this is the pool of addresses your LAN-connected devices will draw from. If you ask — that is, hit the “assign /48” button on your tunnel’s configuration page — HE will also give you a /48. Why would you do this? Well, while you can subdivide your /64 up and route it however you want, most IPv6 tech presumes the smallest network it will ever encounter is a /64. If you choose to, say, make your wired and wireless networks distinct and route rather than bridge between the two the canonical approach is to use one /64 for the wired network, and a second, different /64 for your wireless. (The same logic applies if you wish to also delegate prefixes to hosts on your network — say a /64 to some box you have running a bunch of VM’s or docker containers on.)

But how to set this up easily? Remember that “ULA prefix” option, above? Just put the /48 prefix HE assigned you in there, and everything will Just Work. Delegating specific /64’s to interfaces can be done with “hints” in the interface configuration, and each internal interface will receive a /64 from your /48 automatically.

Yes, this means at least one of your internal networks will have two /64 prefixes addresses can be assigned/chosen from. Don’t sweat it: your device should pick up an address from each /64, and things will Just Work.

Hostnames!

OpenWRT uses dnsmasq to provide DNS, and because of this we can do some neat things. If you edit your /etc/dnsmasq.conf appropriately, you can get:

Hostnames for the ips assigned to our interfaces, automatically

# hostnames for our interface ips!
interface-name=wan.router,eth0
interface-name=wan.router,6in4-henet
interface-name=lan.router,br-lan

…yielding:

$ host lan.router
lan.router has address 192.168.1.1
lan.router has IPv6 address 2001:470:XXXX:1::1
lan.router has IPv6 address 2001:470:1f11:XXXX::1

“Synthetic” hostnames

That is, a deterministic hostname for every ip on a given subnet that dnsmasq doesn’t already know a hostname for.

synth-domain=ip.lan,192.168.1.0/24
synth-domain=ip.lan,2001:470:1f11:XXXX::/64
# Apparently /48 breaks dnsmasq more than a bit
#synth-domain=ip.lan,2001:470:XXXX::/48
synth-domain=ip.lan,2001:470:XXXX:1::/64

…yielding:

$ host 2001:470:1f11:XXX::2
2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.X.X.X.X.1.1.f.1.0.7.4.0.1.0.0.2.ip6.arpa domain name pointer 2001-470-1f11-XXXX--2.ip.lan.

Note this “synthetic hostname” will only be returned if dnsmasq lacks a better name, e.g.:

$ host 2001:470:1f11:XXX::1
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.X.X.X.X.1.1.f.1.0.7.4.0.1.0.0.2.ip6.arpa domain name pointer lan.router.

AAAA records

While OpenWRT does not use dnsmasq for router advertisements, we can still use it’s rather nifty “match info from DHCPv4 requests against the DID/MAC the device would use for SLAAC” functionality to enable it to return both A (IPv4) and AAAA (IPv6) records when asked for an internal hostname:

$ host mfc.lan
mfc.lan has address 192.168.1.78
mfc.lan has IPv6 address 2001:470:...
$ ping6 mfc.lan
PING mfc.lan(mfc.lan) 56 data bytes
64 bytes from mfc.lan: icmp_seq=1 ttl=64 time=0.490 ms
64 bytes from mfc.lan: icmp_seq=2 ttl=64 time=46.5 ms
...

Enable with the somewhat cryptic:

# serve AAAA records based off DID/MAC and DHCPv4 requests
dhcp-range=::,constructor:br-lan,ra-names

…or some permutation thereof, if you’ve altered the topology of your internal network.

Strip AAAA records for Netflix

Sigh. Yes, apparently we need to do this. Lame. Basically, Netflix thinks it doesn’t know where you are located, so will refuse to serve content to any address that HE has delegated to you via tunnelbroker (e.g. your /64, /48). Fortunately, this is a problem others have already elegantly resolved: OpenWRT workaround against Netflix blocking IPv6 requests from tunnel brokers.

Basically, the solution is to build and install a bind package that supports the strip-aaaa option, then have dnsmasq delegate any lookups for *.netflix.com to the bind server. Clean, simple, and easily extensible to any other service that may choose to do the same thing in the future.

With this hack in place, without impacting any other domain your netflix.com lookups will go from this:

$ host netflix.com 8.8.8.8
Using domain server:
Name: 8.8.8.8
Address: 8.8.8.8#53
Aliases: 

netflix.com has address 52.45.218.113
netflix.com has address 52.23.189.13
netflix.com has address 52.207.111.144
netflix.com has address 52.206.68.176
netflix.com has address 52.205.89.26
netflix.com has address 52.54.2.184
netflix.com has address 52.7.207.34
netflix.com has address 52.71.64.222
netflix.com has IPv6 address 2406:da00:ff00::34cf:6f90
netflix.com has IPv6 address 2406:da00:ff00::34ca:21dd
netflix.com has IPv6 address 2406:da00:ff00::34c8:ef2b
netflix.com has IPv6 address 2406:da00:ff00::36a4:da76
netflix.com has IPv6 address 2406:da00:ff00::34ce:44b0
netflix.com has IPv6 address 2406:da00:ff00::3655:55f6
netflix.com has IPv6 address 2406:da00:ff00::34cb:53f8
netflix.com has IPv6 address 2406:da00:ff00::34cd:591a

…to this:

$ host netflix.com 
netflix.com has address 52.54.2.184
netflix.com has address 52.71.64.222
netflix.com has address 52.205.89.26
netflix.com has address 52.207.111.144
netflix.com has address 52.206.68.176
netflix.com has address 52.7.207.34
netflix.com has address 52.45.218.113
netflix.com has address 52.23.189.13

These are little things, yes (hence the “stupid … tricks” appellation), but every little bit helps when trying to figure out a problem.

…or, you know, appease Netflix 🙂

Enjoy!

Currying patterns

One of the most dangerous books I’ve ever even partially read is MJD’s Higher Order Perl. In particular, its description of subroutine currying — that is, building more specific functions out of more general purpose ones — is a pattern I find incredibly useful.

The other day I found myself writing a number of routines that were surprisingly similar… kinda. They all implemented a common pattern, but across routines that were rather… different. I found myself wistfully longing for the familiar pattern of currying, and then realized — I’m working in PERL, DAMNIT.

This is part of recent work of mine, extending Test::Moose::More to use subtests where they make sense. Here I was able to curry one function — _validate_subtest_wrapper() — by passing it a reference to another function, that it then invokes.

Excellent. Life is easier, as it should be.

easy command-line compiz settings import and export

One thing I dislike about setting up any new machine is how many places I have to poke compiz to get it to behave in the manner to which I am accustomed (e.g. widget layer enabled; sloppy focus (the One True Focus); viewport grid with names and quick-jump hotkeys; etc, etc). One can use compiz-settings-manager to do a manual import of settings (that one has hopefully exported — also manually — from another machine setup the way one likes it), but that gets… tedious.

Enter this nifty little question and answer! Note that there are two scripts: one for export and one for import.

http://askubuntu.com/questions/244333/compiz-profile-settings-export-and-import-using-command-line

Using these scripts to set up a cron-driven auto backup is left as an exercise for the reader. 🙂

Intel 7260AC Bluetooth [8087:07dc], Ubuntu, and the Thinkpad T440p

This requires a little magic, unfortunately; either the driver, system, hardware itself, or some combination thereof do not operate well with autosuspend enabled. Disabling autosuspend for this device does appear to resolve dropped / corrupted / weird bluetooth issues.

Based on my googling, I do not believe this to be Thinkpad-specific, rather something the Intel 7260AC firmware isn’t handling properly at the moment. FWIW, I’m running Ubuntu 13.10 (saucy) on the thinkpad in question, and 12.04LTS (precise) on my destop, with the same card sold by Intel in a PCI-e mount.

Based on one posting in particular, the following solution presents itself:

This isn’t ideal — as it should Just Work — but it works, and is certainly less drastic than turning off USB autosuspend globally. In retrospect, having the bluetooth device drop out shortly after boot/resume, but always be available after resuming, was a big clue.

docker without password prompting

Just a little snippet.  This should be pretty obvious to those familiar with how sudo functions, but it’s easy to run docker commands with sudo without being prompted for your password by configuring sudo to not ask for it.

Note that the normal warnings and red flags apply here.

If you install the above as /etc/sudoers.d/docker, then the user rsrchboy (line 1) and any user in the docker group (line 2) will not be asked for a password when running “sudo docker …”.

Again, the normal warnings and red flags apply here.

Useful git defaults — systemwide

Sometimes it’s necessary to — for one’s sanity, if nothing else — to establish a set of generally non-controversial, sane, system-wide git configuration defaults. This is largely helpful when multiple people are using the same system who may not have a standard ~/.gitconfig they carry around with them.

To do this, we can leverage the little-used system-wide git config file at /etc/gitconfig. Remember that by default git looks at three files to determine its configuration: /etc/gitconfig (system), ~/.gitconfig (user aka global), and .git/config (configuration for the current repository); settings closer to the user win. This allows us to set defaults in the system configuration file without interfering with people who prefer different settings: their global config at ~/.gitconfig will win.

This config sets a couple safer defaults for pushing, makes git merge/diff/rebase a little more DWIM, causes the committer, as well as the author, information to be displayed by default, as well as allowing for an easy way to override the system config on a per-system basis. (In case, say, you’re using puppet or the like to distribute this configuration across multiple hosts.)

And… As with all things “generally non-controversial”, remember that these are the sorts of things likely to touch off religious wars. The goal here is for a sane set of defaults for all users, not The One True Way To Do GIT. That’s what user global configs are for 🙂

screen, vim, tabs, and C-PgUp/C-PgDn mappings

I use screen with vim. One of the things I like about vim is that, much like unix itself, I’m always discovering useful new features, even after years of use.

Recently, I’ve been using tabs in vim to complement window regions. I’ve found it pretty useful, as there are times I’d want to keep certain tasks on one tab but not another. e.g. different source files open in windows on one tab; a test file + vim-pipe buffer showing the rest.

While I’m not using screen to change between multiple vim sessions in the same project anymore, I still use it pretty much everywhere: it’s there, and sometimes a wireless network isn’t. (Or you’re working one place and need to pack up and move to another place.) screen preserves your working sessions, so you don’t have to get everything “just right” again.

Unfortunately, screen seems to mangle the C-PgUp and C-PgDn commands vim gives as default (right?) shortcuts to switch between tabs. Leaving out that these key sequences are also used at the windowing level to switch tabs, it turns out that screen was mangling them on the way through to vim, so vim didn’t see C-PgUp, for instance, it saw some other sequence.

Adding this to your ~/.vimrc will cause vim to recognize the sequence it sees when running under screen:

Reboot!