A spike is when you play around with something and then throw it away for the purposes of learning. So, let’s play around with IPv6. I had read a little bit about it but essentially my working experience with IPv6 was nothing except for disabling it. Let’s learn some stuff!
I’m going to skip over all the history of IPv6 and assume that you agree with me and think that this is important and relevant to the future of the Internet.
Setup
First, build 4 Ubuntu VMs. I’m using 13.04 but any current Linux distro should work, just the packages and paths will change. I found the best way is to build a simple VM and then clone it 3 more times (in Fusion this is copy/paste and resetting the MAC address). You’ll need four machines to simulate a local network. You won’t need any network hardware and VMware will be able to simulate everything we need. You can actually do this whole experiment on one real box (cool stuff)!
The goal of this spike is:
- Build 4 VMs
- Make a router, a web server, a dns server and a client
- Hit a web page between two network boundaries over IPv6 only
Super practical IPv6 primer
Addressing is WEIRD. That’s really what I wanted to spike on. Getting comfortable with the addressing length, hexadecimal and understanding the addressing layout.
In IPv4, a network segment might look like this: ` 10.0.0.0/24
So a box with an IP on that network might be this:
ip: 10.0.0.136 netmask:255.255.255.0`
IPv6 is a lot different. Private addresses don’t start with 192.168., 172. or 10. Private addresses start with fc00 (from what I’ve read). So I made up two network segments called
fc00:deed:d34d:b33f
fc00:deee:deee:deee
But that’s only 4 sets of hex. IPv6 addresses have 8 sets of 4 hex bytes like this:
nnnn:nnnn:nnnn:nnnn:hhhh:hhhh:hhhh:hhhh (where n's are the network parts and h's are the host parts in a /64)
So let’s configure a box with an ip. Our boxes are named after onomatopoeias (boing, wap, rawr and piff). Boing’s address is “dot” 10.
boing: fc00:deed:d34d:b33f::10/64
So there’s a box that’s configured with an IP. Notice the double colons. That just means it fills in the zeros between. It’s shorthand. The /64 is the network segment. Like in ipv4 192.168.0.1/24 is a common private ip. The /24 is out of 32. So it means X.X.X.Y where Y is the host part and X.X.X is the network part. So 192.168.0.* is the network and .1 is the host. In IPv6 it’s /64 out of a total /128.
So my private address space is just like an IPv4 private range. I’m assigning this IPv6 space and I have 18 trillion private address for my ONE SUBNET. For a router to work, I need two subnets. So now I have 36 TRILLION free private addresses. O_o
Address Configuration
I’m using ipv4 just for remote admin and installing things through apt. So you’ll have to add another ip to your vm’s network card. Ubuntu does this in the file /etc/network/interfaces. Here’s an example.
boing - dns (10.0.0.137) /etc/network/interfaces iface eth0 inet6 static address fc00:deed:d34d:b33f::10 netmask 64 gateway fc00:deed:d34d:b33f::1
If you type ifconfig or ip addr
you will see that it has two IPs now. One IPv4 and one IPv6 address. We’re not quite done. I drew a picture of the network layout and you’ll have to configure all the VMs like this.
Router Configuration
This is really easy. You just need the Rawr box to forward IPv6 packets like a router but not like a firewall. So Linux can do that will a simple kernel switch. But first, you’ll need to add a second network card in VMWare. So:
- Shutdown rawr
- Add a second network card
- Boot rawr
- Edit /etc/sysctl.conf, change net.ipv6.conf.all.forwarding = 1
- Run sysctl -p
Routing through rawr should work at this point. For example, from piff, you should be able to ping boing through ipv6 even though they aren’t on the same network segment. Use ping6 and traceroute6 to sanity check.
DNS Configuration
Boing is our DNS server so let’s make some changes. First, apt-get install bind9. Then edit these files below. I configured a temporary subdomain on squarism.com called ipv6.squarism.com but this can be anything you want.
Notice that the reverse zone (ip6.arpa) is super annoying to type out. It needs to be the reverse bytes (afaik).
Here we’re using the AAAA records for IPv6. In IPv4 these would be A records. Bind has supported AAAA records for a long time. CNAME records don’t change. Notice that you could easily run a DNS server that serves both stacks.
I used a reverse zone generator at rdns6.com for this last time. It’s amazingly annoying to type out. I’m not sure if there’s a more convenient form that could be used.
Restart bind: sudo services bind9 restart
Check the logs in /var/log/syslog for any named:
errors. I had a few typos I had to chase down. DNS can be tricky to set up so take your time.
See DNS working
Ok, let’s take a quick break from this infinite configuration and see how we are doing so far. At this point we should have routing and DNS working. So that means that Piff should be able to ping a DNS name and it should work.
But first, we need to tell Piff and all the other boxes to use our new dns server. Edit /etc/network/interfaces
again and add
For example, your eth0 block will look like this
Restart networking. Even if your VMs are running DHCP (they are by default), we’re just adding a DNS server to the static IPv6 address. In other Linux distros, this file will be different (sry).
Ok great. DNS and routing are working. Now we are ready for the final part.
Web Server Configuration
Get dependencies installed on Wap (the web server).
aptitude install zlib1g-dev libssl-dev libpcre3-dev
We need ipv6 support built in and I’m not sure if the OS packages are going to come with it out of the box. Installing nginx is easy. So let’s download nginx, configure, compile.
Start nginx:
/opt/nginx/sbin/nginx -c /opt/nginx/conf/nginx.conf
Normally, I’d write a init.d script here but whatever. You can stop nginx like this:
sudo /opt/nginx/sbin/nginx -s stop
Sanity check:
netstat -nlp | grep nginx
tcp6 0 0 :::80 :::* LISTEN 24618/nginx.conf
Let’s create a dummy web page on Wap (the nginx box). We’ll test this page in the next section.
End to end test
Ok, everything is set up. So let’s see it work end to end. Our goal was to hit an IPv6 web server through DNS and a router.
Here you can see I’m pinging the webserver from the web client (piff -> wap).
IPv4 is routable directly because of vmware. But IPv6 traffic is split, the client isn’t on the same IPv6 segment as the web server. So I can ping directly with IPv4. So that’s our IPv4 sanity test but not why we did all this.
You can see when I try to hit that ipv6.html test page we created earlier it won’t work.
It actually says connection refused and this makes sense if you look at the netstat information from Wap. It’s not listening on 0.0.0.0:80, it’s listening on :::80. Crazy!
If I use ipv6 (curl needs some special settings for the URL)
And ipv6 DNS is working.
You can see it’s going through a router:
Wget works too
Ssh has no special flags, it just works.
Victory Lap
Even firefox works.
Just to prove that this isn’t IPv4, let’s use the weird numerical URL format for the IP.
Well this was a fun spike and I feel like I understand IPv6 a whole lot more and it doesn’t strike fear into my heart to think about big scary addressing. I think the key is to actually use DNS instead of fudging it with typing manual addresses or managing crazy hosts files. It should be interesting to see when ISPs and cloud providers start offering serious options for IPv6.