One or more virtual or dedicated servers with root access, possibly located in the same data center. I'm running two Debian virtual machines (Lenny and Squeeze) but I assume you can adopt the recipe to work on any Linux box An account with tunnelbroker.net or similar service
All network configuration doesn't do any good if your web server software doesn't support IPv6 requests. For nginx this means compiling with the --with-ipv6 option. See my Human script for passenger w/ nginx for my favorite nginx compilation options.
| Hostname | IP --- | --- | --- Public IPv4 | fluffy.cloud.com | 69.150.210.40 Private IPv4 | fluffy.cloud.local | 192.168.170.200/17
| Hostname | IP --- | --- | --- Public IPv4 | cirrus.cloud.com | 69.150.210.41 Private IPv4 | cirrus.cloud.local | 192.168.170.201/17
| Client (my end of the tunnel) | Server (the other end of the tunnel) --- | --- | --- IPv4 Endpoint | 69.150.210.40 | 209.51.161.14 IPv6 Endpoint | 2001:470:1f04:f53::2/64 | 2001:470:1f04:f53::1/64 IPv6 Network | 2001:470:1f05:f53::/64 | -
I wanted both my servers to be on the same IPv6 network so I set up fluffy to handle my shiny new IPv6 network and do all the routing.
I requested two private IPs from my data center provider and set them up as virtual interfaces. Among other things this allows the two machines to communicate with each other without it counting towards my monthly bandwidth quota. Configuration is pretty straight forward. The snippets from /etc/network/interfaces
look something like this:
auto eth0 eth0:0
[...]
iface eth0:0 inet static
address 192.168.170.200
netmask 255.255.128.0
auto eth0 eth0:0
[...]
iface eth0:0 inet static
address 192.168.170.201
netmask 255.255.128.0
Next I hooked up fluffy to Hurricane Electric's IPv6 tunnel. Also fairly easy to setup in /etc/network/interfaces
, especially since they provide the necessary instructions:
iface he-ipv6 inet6 v4tunnel
address 2001:470:1f04:f53::2
netmask 64
endpoint 209.51.161.14
local 69.150.210.40
gateway 2001:470:1f04:f53::1
ttl 64
Now you should be able to reach any other public IPv6 host from fluffy.
Since you probably want to restrict access to a few services (HTTP, HTTPS, SSH etc.) its a good idea to get your paketfiler rules straight now. I read somewhere that the iptables people started integrating the IPv4 and IPv6 versions of their paket filter, which would allow you work with just one ruleset. For now however you have to live with administering the two separately.
Lets start with the IPv4 since this will be the first ruleset your tunnel traffic will run through since the IPv6 packets are encapsulated in IPv4 packets. You probably already knew that. Since iptables is pretty well covered in various tutorials an how-tos I'm just going to show you the one line that matters for our purposes:
I inserted this at the very to of my ruleset. It basically allow all IPv6 in from our tunnel:
-A INPUT -p ipv6 -s 209.51.161.14 -j ACCEPT
You probably also want unrestricted (private network) communication between your servers:
-A INPUT -s 192.168.170.201/17 -j ACCEPT
For an introduction and good standard web server ruleset I'd like to refer you to the Slicehost knowledge base (see further reading below for direct links).
Since now we're basically letting all IPv6 traffic you probably want to copy most of your IPv4 rules to your IPv6 config file. This time I'll post my full config:
*filter
# Allows all loopback (lo0) traffic
-A INPUT -i lo -j ACCEPT
**# Accepts all traffic from other nodes on YOUR IPv6 network (in my case just one)
-A INPUT -s 2001:470:1f05:f53::/64 -j ACCEPT**
# Accepts all established inbound connections
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Allows all outbound traffic
# You can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT
# Allow SSH since dyndns does not yet support IPv6
-A INPUT -p tcp --dport 22 -j ACCEPT
# Allows HTTP and HTTPS connections from anywhere (the normal ports for websites)
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
# Allow ICMP traffic
-A INPUT -p icmpv6 -j ACCEPT
**# Route any traffic to and from any node on my IPv6 network
-A FORWARD -s 2001:470:1f05:f53::/64 -j ACCEPT
-A FORWARD -d 2001:470:1f05:f53::/64 -j ACCEPT**
# log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
# Reject all other inbound - default deny unless explicitly allowed policy
-A INPUT -j DROP
-A FORWARD -j DROP
COMMIT
You can see that for the most this looks just your regular iptables ruleset, which really makes you wonder why on earth they made two separate engines for IPv4 and IPv6.
I'd like to point two rules (the ones in bold face):
- I allow unrestricted traffic on my IPv6 network (couldn't see why not)
- I also IPv6 packet forwarding to an from any node on my network. They all have their own packet filter with different rulesets so I'd say thats ok, too. This or a similar setting is required fluffy here is supposed the serve as the IPv6 router for my web hosts.
I don't think I need to show the iptables settings for cirrus here. In principle they look just the same only without the FORWARD ACCEPT and tunnel inlet rules.
Now for the somewhat tricky part. I need fluffy to assign an IPv6 address from my address space to cirrus and then do all the routing. Fluffy and cirrus can only talk IPv4 with one another since the data center internal traffic is IPv4 only. This calls for another tunnel only this time I didn't want to use static endpoints but rather have have fluffy use IPv6's RAD (router advertisement daemon) mechanism. The ISATAP protocol seemed perfect for the job.
Lets start with yet another virtual interface to allow IPv6 communication between the two hosts. Modify to whatever IPs you use but be sure to include the "5efe" part in that last line. You have to put it in between your IPv6 network and IPv4 address blocks. Otherwise ISATAP won't work.
ip tunnel add is0 mode isatap local 192.168.170.200 ttl 64
ip link set is0 up
ip addr add 2001:470:1f05:f53::5efe:192.168.170.200/64 dev is0
I put three lines into a little script and placed it in the /etc/network/if-up.d
folder for convenience reasons.
Next install the advertisement daemon, which should be available on any mainstream Linux distribution (aptitude install radvd on Debian). Create the config file, start your daemon and the router should be good to go:
interface is0 {
AdvSendAdvert on;
UnicastOnly on;
prefix 2001:470:1f05:f53::/64 {
AdvOnLink on;
AdvRouterAddr on;
};
};
Just replace the IPv6 network whatever your tunnelbroker provided you with. If you choose to fumble with the different configuration options just remember to keep the UnicastOnly option. It is required for ISATAP to work.
Hope I remember this correctly but I think I just had to install the isatapd daemon (aptitude install isatapd
on Debian). I'm using all the default settings so I didn't set up a separate config file. If you're using more custom options (e.g. for an interface name other than is0
) you'd have to create a config file at /etc/isatapd.conf?
I however had to go into the init.d file (/etc/init.d/isatapd
) and change line 29 to ISATAP_ROUTERS="fluffy"
and you most certainly will have to, too. Use the hostname corresponding with the router's private IP.
As for forward DNS you should be able to simply create AAAA records using your nameserver provider's administration console just like you would do with A records for IPv4 addresses. For each host name I have one IPv4 and one IPv6 address assigned.
DNS isn't really all that different. For reverse DNS I just use Hurricane Electric's free service. With a little bit of extra effort you can however ns3 or whatever daemon you prefer to do the job as well. There's actually a pretty good how-to on that.
I also set up bind as a DNS cache for Hurricane Electric's IPv6 server on my router instead of just adding their server to /etc/resolv.conf
. My configuration file (/etc/bind/named.conf.options
) looks like this:
acl cloud.local {
localhost;
192.168.128.0/17; // your LAN via IPv4
2001:470:1f05:f53::/64; // your tunnel IPv6 /64
2001:470:1f04:f53::/64; // your routed IPv6 /64
};
options {
directory "/var/cache/bind";
allow-query { cloud.local; };
forwarders {
2001:470:20::2;
[...]
};
auth-nxdomain no; # conform to RFC1035
listen-on-v6 { any; };
};
- [Basic web server setup in the Slicehost knowledge base (scroll down a bit for an introduction to iptables)] (http://articles.slicehost.com/2008/4/25/ubuntu-hardy-setup-page-1)
- ISTAP client for Linux homepage
- IPv6 DNS cache