18 October, 2012
mifi vs ipv6
23 July, 2012
autogenerating reverse DNS for ipv6
I was getting annoyed by manually configuring an IPv6 reverse domain.
For reverse DNS, you need to break the IP address up into pieces (bytes for IPv4, nibbles for IPv6), reverse them, put dots between pieces, to get a domain name. Then at that domain name, you put a reference to the hostname for that IP.
So an IP address like 2001:8b0:7c:1:216:76ff:fe16:755a
turns into a domain name a.5.5.7.6.1.e.f.f.f.6.7.6.1.2.0.1.0.0.0.c.7.0.0.0.b.8.0.1.0.0.2.ip6.arpa.
, and there you can find a PTR record pointing to the hostname dildano.hawaga.org.uk
Forming those long domain names was/is quite awkward, and its a task well suited to automation. All of the hosts already have forward DNS entries, so there's not even much additional information needed to generate the reverse zone.
I wrote a tool (in an unholy alliance of Haskell and dig) which queries a bunch of forward zones and outputs the appropriate reverse DNS records ready for pasting into a zone file.
You specify zones (and appropriate servers) that will be asked for AAAA records; then all of the AAAA records which refer to IPv6 addresses on the specified network will be converted into PTR records and sent to stdout, ready to paste into a zone file.
$ dnsrz hawaga.org.uk@dildano.hawaga.org.uk clifford.ac@malander.clifford.ac charlottevrinten.org@dildano.hawaga.org.uk mrsclifford.eu@malander.clifford.ac --prefix=200108b0007c0001 3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 PTR clifford.ac. 3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 PTR malander.clifford.ac. 3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 PTR malander.mrsclifford.eu. 4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 PTR fecolith.clifford.ac. 4.1.2.0.0.f.e.f.f.f.3.9.d.0.2.0 PTR pomade.clifford.ac. a.5.5.7.6.1.e.f.f.f.6.7.6.1.2.0 PTR dildano.hawaga.org.uk. c.0.2.a.4.c.e.f.f.f.3.6.b.1.2.0 PTR newsnowdrop.mrsclifford.eu. 0.a.0.c.b.a.e.f.f.f.3.6.1.2.2.0 PTR tenesmus.clifford.ac. 7.2.f.0.1.9.e.f.f.f.b.4.5.2.2.0 PTR coprolith.clifford.ac. c.2.5.d.b.f.e.f.f.f.b.e.7.2.a.b PTR pygar.hawaga.org.uk. c.2.5.d.b.f.e.f.f.f.b.e.7.2.a.b PTR pygar-6.hawaga.org.uk. b.6.5.8.2.f.e.f.f.f.8.c.c.b.a.c PTR laptop.hawaga.org.uk.
I wanted to use the Haskell dns package which I've used a bit before; but it didn't have enough features: no zone transfer capability, for a start... so I invoke dig
and parse that out.
The commandline syntax is: <zonename>@<DNS server> where zonename is a forward zone, and the specified server will answer AXFRs for that zone. Thats quite icky but it gets around needing a full Haskell DNS implementation.
The code is on github under benclifford/dnsrz.
(later: as fits my tradition of writing a tool and then finding someone has done something similar first, bind comes with a toolarpaname
which will convert an IP address into a reverse name, though it doesn't do all the other stuff above, but does work for ipv4 too: http://ftp.isc.org/isc/bind9/cur/9.9/doc/arm/man.arpaname.html
06 June, 2012
3ffe:1900:4545:3:200:f8ff:fe21:67cf
happy ipv6 launch day! the world is different now.
some of us noticed 3ffe:1900:4545:3:200:f8ff:fe21:67cf referred to in a BBC article; that address is "clearly" an old 6bone IP from the dawn of the century, which seemed strange to see in an article published this week.
I typed it into google and its used in a lot of places as an example IP address: IBM documentation, an XKCD discussion thread, software unit tests, youtube comments about minecraft....
But nothing appeared to give an original source.
Did someone just make it up years ago as an example and everyone else just copied it off each other?
Who was it originally allocated to on the 6bone?
Answers on an ipv6-enabled postcard...
08 June, 2011
June 8th is world IPv6 day!
On 8 June, 2011, Google, Facebook, Yahoo!, Akamai and Limelight Networks will be amongst some of the major organisations that will offer their content over IPv6 for a 24-hour “test flight”. The goal of the Test Flight Day is to motivate organizations across the industry – Internet service providers, hardware makers, operating system vendors and web companies – to prepare their services for IPv6 to ensure a successful transition as IPv4 addresses run out.
Some of us have been trying to do that for years ;)
Anyway, some things you can do:
- Read all the ipv6 related posts on this blog
- Make sure you are using IPv6 certified cable
- Play loops of zen, an ipv6-only browser tile-puzzle
- If your ISP does not provide IPv6 and you want easy IPv6 access for a single workstation, I recommend the teredo protocol (its built into windows, and you can
apt-get miredo
on debian. For a server or network installation, take a look at Hurricane Electric's tunnel broker which will give you a /48 prefix routed over your normal internet connection. - If you're on ipv6 already and you're feeling hardcore you can use NAT64 and DNS64 to get rid of all your local ipv4 traffic, instead routing it all through a NAT gateway at (for example) Andrews and Arnold.
29 May, 2011
Panickers guide to world ipv6 day
What I'm going to tell you about here will get basic IPv6 access to your site. It won't do it in a particularly pretty way, and its probably not the long term way to do it. Also I just hammered this out this afternoon (though its based on years of IPv6 use). (I hope) it should work.
First some DOs and DONTs:
* DON'T deploy IPv6 on your production servers. If you don't know much about IPv6, then blindly sticking it on your real production resources is probably a good way to put even your IPv4 (read: the real IP that everyone actually uses) connectivity at risk (for various reasons that you'll understand when you understand...)
* DO deploy a http proxy server on its own machine, and have that proxy your IPv6 traffic. You shouldn't need to modify *anything* on your production machines.
* DON'T put the IPv6 address record (AAAA, as opposed to the IPv4 A record) in your normal DNS. If you do, then users who have both IPv4 and IPv6 will usually try to connect over IPv6. You don't know how well this is going to scale, or how good your IPv6 connectivity is going to be (or even how good your users ipv6 connectivity is going to be, if everyone is going to be fucking around that day)
* DO put a DNS name (eg www.6.example.com, if your main site is on www.example.com) with the AAAA record. That way, users can choose to try using IPv6, and if its broken can easily get back to your main site. You'll need to publicise this, though, because its not going to get users connecting via IPv6 automatically, and at the same time you should provide some feedback: for example, an email address or a forum.
So what do you need to do:
* Get a dedicated server (either a physical hardware server, or a VPS) running a recent version of Linux. (Ubuntu 10.x would be enough)
* Connect that server to the ipv6 internet. If its on a network with native IPv6, then your host will probably give you connection details. If not, then use Hurricane Electric's free tunnel broker which will connect you over a regular internet connection.
* However you connect, you'll end up with an IPv6 address for your machine. It will be a string something like this
2001:470:1f09:1288::2
that you can get out of ifconfig
(specifically, if you have a choice, choose the one that begins with a 2, not the one that begins with an f). Put that IPv6 address into an AAAA record in DNS (better hope your DNS hosting provider does AAAA records - the good ones do...) under a new DNS name. Don't put IPv4 addresses in there too. In my example, I'm going to configure:blog.6.hawaga.org.uk AAAA 2001:470:1f09:1288::2
* Put apache httpd on your server,
apt-get install apache2
* Now you'll need a client machine with IPv6 to try connecting to your new server. If you have a windows PC, you can probably turn on Teredo in the network configuration - it comes built in. On OS X, Linux or BSD, you can install miredo which is a Teredo client. Or you can set up another Hurricane Electric tunnel for your client machine. You can use test-ipv6.com to get a score for how well your new client machine is connected to the ipv6 internet.
* You should now be able to use a web browser to reach the hostname you configured in DNS back there - you should see apache's welcome/default page.
* Now, configure apache to forward all requests it receives onwards to your production website over IPv4. In the following example, my production IPv4 website is the one you are reading right now,
benctechnicalblog.blogspot.com
. Enable mod_proxy
and mod_proxy_http
, and then set up a virtual host directive like this (or put it in the base of your server config, seeing as this a host dedicated to forwarding ipv6 traffic):<virtualHost *:80> ServerName blog.6.hawaga.org.uk ProxyPass / http://benctechnicalblog.blogspot.com/ <Proxy http://benctechnicalblog.blogspot.com/> Allow from All </Proxy> </virtualhost>
Once you've done that, visiting your ipv6 hostname (eg blog.6.hawaga.org.uk) should serve you the content of your real production website website.
Now publish the new hostname in a news item and make it seem like you know what you're doing...
Some stuff will not work, for sure: if you have anything that does things based on IPv4 address of client, that's all going to be based on the address of the proxy machine, not the real client IPv6 address. Things that might affect are localisation (eg language), and rate/load limiting based on ip address.
So, please ask questions in the comments and I'll see about answering them...
06 February, 2011
Using mrtg and iptables to record IPv4 vs IPv6 traffic
iptables on Linux counts bytes that pass through it, even if there are no iptables rules:
$ iptables -L -v -x Chain INPUT (policy ACCEPT 6079694 packets, 2474020715 bytes) [...]
That counts ipv4 packets. The ipv6 equivalent is ip6tables.
So without needing to add any iptables rules at all, I can feed this output to mrtg with a script as follows, which outputs IPv4 traffic (for all three categories) as the first (input) variable, and IPv6 as the second(output) variable.
#!/bin/bash A=0 IP4=$(/sbin/iptables -L -x -v | grep -e ^Chain | sed 's/.* \([0-9]*\) bytes)$/\1/' | ( while read n ; do A=$(( $A + $n )) ; done ; echo $A)) A=0 IP6=$(/sbin/ip6tables -L -x -v | grep -e ^Chain | sed 's/.* \([0-9]*\) bytes)$/\1/' | ( while read n ; do A=$(( $A + $n )) ; done ; echo $A)) echo $IP4 echo $IP6 echo 0 echo unknown
On one host, there really is hardly any ipv6 traffic (2 bytes/sec!) so I turned on the log scale plot option in MRTG to show the ipv6 a bit more (though to be honest its still pretty invisible).
Here's the config I used in MRTG to call the above script:
Target[ip46]: `/home/benc/bin/iptables-to-mrtg` Target[ip46]: `curl http://dildano.hawaga.org.uk/mrtg-iptables.txt` options[ip46]: growright,logscale MaxBytes[ip46]: 1000000000000 Title[ip46]: IPv4 vs IPv6 YLegend[ip46]: bytes/sec LegendI[ip46]: IPv4 LegendO[ip46]: IPv6
and here's an example graph (live, click for historical data):
Caveats:
I'm summing the all three iptables chains: input, output, and forwarded, for all interfaces. So some traffic here can be counted unexpectedly: A forwarded packet traverses all three chains (I think) so this is not a good way to count traffic if your linux box is a router; The lo interface will also be counted, so traffic to localhost (127.0.0.1 or ::1) will be counted in this graph. This might be useful to remove.
When there's a tunnel endpoint on the machine, then traffic to that tunnel will be counted twice: one as it passes the tunnel interface, and once as the encapsulated form passes the physical ethernet interface.
These are not insurmountable, I think: by setting specific iptables rules that address these concerns and counting traffic from those instead of the main chain counters.
14 January, 2011
IPv6 in Amazon EC2
Amazon declares that IPv6 is unsupported on EC2 (the Elastic Compute Cloud), but I wanted it anyway.
I tried two ways, one which worked well, and one which did not.
The first way I tried, which did not work well, was using 6to4; the way which did work was a tunnel from Hurricane Electric.
I did everything below on one of the free Linux micro-instances supplied by Amazon, with an elastic IP address attached so that I'd have a permanent address.
The first approach I tried was using 6to4. This is a protocol which automatically gives a large range of IPv6 addresses to anyone with a single static IPv4, through a decentralised network of protocol gateways.
In another blog post, I described how to get 6to4 running on Linux in 5 command lines. I ran those commands on my EC2 instance and end up with my own IPv6 address configured.
But having an IPv6 address configured is not the same as having an IPv6 address reachable from the internet. There were severe reachability problems. The problems boil down to two causes:
- The decentralised management of 6to4 leads to lots of gateways being broken in a way that makes them act of blackholes; and the protocol makes it hard to discover which those gateways are to fix them. This is a problem for any host, not just for EC2 instances.
- Even with the EC2 firewall turned off as much as possible (i.e. no firewall rules at all), EC2 doesn't cleanly deliver IP traffic to instances. For most traffic, this is not a problem; but it interacts with 6to4 in a terrible way:
your instance can only receive traffic from any particular 6to4 gateway if it has recently sent at least one packet to that gateway; there is a global network of 6to4 gateways, any of which can send traffic to you; when you send 6to4 traffic, you send it only to your closest 6to4 gateway. As a result, basically no 6to4 gateways can ever send traffic to you.
That second bullet point was especially hard to debug before I figured out what the EC2 firewall was doing - because certain pings and probes to test reachability caused the firewall to open up, at which point IPv6 traffic would flow between some sets of hosts until a few minutes later when it would mysteriously stop working again.
6to4 is basically useless on ec2.
The second method I tried, with much greater success [to the extent that, a year later, I regard this as production quality] is a manually configured tunnel via Hurricane Electric. HE have been around a long time; have a good reputation; and I used them before years ago.
The configuration at their end is a set of fairly straightforward web forms. I was allocated a /64 prefix, but they have options for more.
That web form also gives example configuration instructions for a variety of platforms. The Linux-net-tools
instructions are the ones I used. I pasted the 4 given commands literally into a root prompt on my EC2 machine, and those configured the interface correctly (at least until reboot).
I get similar "stateful firewall" behaviour from EC2 as I mentioned above, but the difference here is that that the connection is only between me and the HE tunnel endpoint, rather than to arbitrary 6to4 gateways around the network. As long as *anything* goes over the tunnel every few minutes, then connectivity with the entire IPv6 world stays up. Compared to 6to4, when that tunnel is up, the connectivity from machines D and P seem *much* better. I can ping both ways without any mysterious losses. I need a ping to the tunnel endpoint (or anywhere on the IPv6 internet, really) every minute or so. That's no big deal - I have MRTG set up to measure some ipv6 latencies anyway, and that is generating this traffic as a side-effect.
So HE is a little bit (a few web forms) more effort to set up. But the connectivity is much much better. I recommend HE over 6to4 for this.
Other links: aco wrote about getting IPv6 on EC2 using sixxs, and if you're interested in getting a shell account on this machine (barwen.ch) to try for yourself: www.barwen.ch
. I found this this online ping tool useful during testing.
Modified: 2011-04-19 Rephrasing a bit based on ongoing experience, and some more hyperlinks
Modified: 2012-05-05 Rephrasing some more.
6 to 4 in 5
My present configuration uses 6to4. This is a very straightforward mechanism to configure on linux, without needing any setup outside of my own machine. On the downside, it gives very little control of routing which can lead to strange connectivity problems that are hard to debug.
I followed the
Linux IPv6 HOWTO howto pretty faithfully.
I needed these 5 steps:
$ ipv4="174.143.245.7"; printf "2002:%02x%02x:%02x%02x::1" `echo $ipv4 | tr "." " "`
This tells me that my prefix is:
2002:ae8f:f507::/48
I get a 16-bit (4 hex-digit) subnet number to pick my own networks (I'll pick 2 in this case, fairly arbitrarily), and then the remaining 64 bits go towards identifying the host on the network (which I'll pick 0123:4567:89ab:cdef. Another good choice would be ::1)
So I end up choosing the IP address: 2002:ae8f:f507:2:0123:4567:89ab:cdef
Next:
modprobe sit (it was compiled but not loaded) ifconfig sit0 add 2002:ae8f:f507:2:0123:4567:89ab:cdef/16 up /sbin/route -A inet6 add 2000::/3 gw ::192.88.99.1 dev sit0
and now I can ping my own machine:
benc@paella:~$ ping6 dildano.hawaga.org.uk PING dildano.hawaga.org.uk(dildano.hawaga.org.uk) 56 data bytes 64 bytes from dildano.hawaga.org.uk: icmp_seq=1 ttl=62 time=136 ms 64 bytes from dildano.hawaga.org.uk: icmp_seq=2 ttl=62 time=132 ms 64 bytes from dildano.hawaga.org.uk: icmp_seq=3 ttl=62 time=132 ms --- dildano.hawaga.org.uk ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2000ms rtt min/avg/max/mdev = 132.002/133.335/136.002/1.931 ms
easy peasy. shame it's quite unreliable.