Adding IPv6 to a FreeBSD Mail/Web Server

We’ve run out of IPv4 addresses. If you’re not already on IPv6, start hoarding gasoline and canned potted meat food product. Doomsday is here, film at eleven. Or, failing that, start running IPv6 on something so you can have a little familiarity with the new Internet protocol before you absolutely must. My personal FreeBSD 9 server (which hosts my email, this blog, web sites for my books, and a whole bunch of other equally trivial cruft) is now IPv6-enabled, even though the local site doesn’t have IPv6 connectivity. Here’s how I did it.

Establishing IPv6 connectivity to and from an IPv4-only server breaks requires:

  • Get an IPv6 tunnel from a tunnel provider
  • Configure a generic IPv4 tunnel to the tunnel provider
  • Assign IPv6 addresses to your IPv4 generic tunnel
  • Assign your IPv6 default route over the tunnel
  • Establish IPv6 DNS resolution
  • Configure services to run on IPv6
  • Offer IPv6 DNS records

    If you’re reading this , you probably don’t have IPv6 at your facility. You’ll need an IPv6 tunnel, offered for free by many providers. I used Hurricane Electric, but use any broker you like. Sign up for an account, respond to the verification mail, and request a tunnel. The Web interface will give you a bunch of details about your tunnel.

    The gif interface provides a generic IPv4 tunnel that can be used for many protocols. Configuring an IPv4 tunnel requires only the IP addresses on each end. ifconfig(8) creates a tunnel with just:

    # ifconfig gif0 tunnel 198.22.63.8 209.51.181.2

    You must be able to ping the tunnel’s remote address.

    Now assign IPv6 addresses to your gif0 tunnel.

    # ifconfig gif0 inet6 your-IPv6-address remote-IPv6-address prefixlen 128

    For example, my HE-assigned IPv6 tunnel endpoint is 2001:470:1f10:b9c::2. The he.net IPv6 address is 2001:470:1f10:b9c::1. I assign my IPv6 addresses as:

    # ifconfig gif0 inet6 2001:470:1f10:b9c::2 2001:470:1f10:b9c::1 prefixlen 128

    Verify that your IPv6 addresses are correctly configured by using ping6 to hit the far end. Remember, standard ping will not work — ping is specific to IPv4.

    # ping6 2001:470:1f10:b9c::1
    PING6(56=40+8+8 bytes) 2001:470:1f10:b9c::2 –> 2001:470:1f10:b9c::1
    16 bytes from 2001:470:1f10:b9c::1, icmp_seq=0 hlim=64 time=19.209 ms
    16 bytes from 2001:470:1f10:b9c::1, icmp_seq=1 hlim=64 time=21.661 ms

    At this point, you have IPv6. Now assign the IPv6 default route to the remote end of the tunnel.

    # route -n add -inet6 default 2001:470:1f10:b9c::1

    Your server will now send all IPv6 traffic across your IPv4 tunnel, while still routing IPv4 traffic as usual. Remember, IPv4 and IPv6 are different protocols.

    Some Internet sites, such as Google, have special requirements for accessing their IPv6 DNS. Your tunnel broker provides an IPv6-aware DNS server. Now that you have a default route, see if you can ping6 it. If you can ping the DNS server, edit /etc/resolv.conf. Remove your IPv4 nameservers. Add the IPv6 nameserver. Check DNS for IPv4 (A records) and IPv6 (AAAA records) with dig(1).

    # dig www.google.com A

    ;; ANSWER SECTION:
    www.google.com. 20478 IN CNAME www.l.google.com.
    www.l.google.com. 222 IN A 209.85.225.99
    www.l.google.com. 222 IN A 209.85.225.147
    www.l.google.com. 222 IN A 209.85.225.104
    www.l.google.com. 222 IN A 209.85.225.105
    www.l.google.com. 222 IN A 209.85.225.103
    www.l.google.com. 222 IN A 209.85.225.106

    This looks correct. Let’s try AAAA records.

    # dig www.google.com AAAA

    www.google.com. 20368 IN CNAME www.l.google.com.
    www.l.google.com. 180 IN AAAA 2001:4860:b007::63

    This is an IPv6 answer. Google has fewer IPv6 servers than IPv4 servers, but that’s to be expected these days.

    Now configure services on your server to listen on IPv6 addresses. Daemons included in FreeBSD listen to IPv6 by default. Run sockstat -6 to see what programs are listening to your new IPv6 address. In my case, Apache only listened to IPv4. At some point in the foggy past, I had turned off IPv6 when configuring the port. I rebuilt devel/apr1 and www/apache22 with IPv6 support, restarted Apache, and it listened to my IPv6 address without issue.

    Last, you must publish AAAA records for the hosts you want to offer over IPv6. By gradually adding AAAA records, you can slowly increase the amount of traffic you deliver over IPv6, letting your your IPv6 traffic grow slowly.

    www IN A 198.22.63.8
    www IN AAAA 2001:470:1f10:b9c::2

    Properly-configured hosts will attempt to connect to services on IPv6 first. If those connection attempts fail, they will try IPv4 instead.

    To make your FreeBSD changes permanent, use your addresses in the /etc/rc.conf entries below.

    gif_interfaces=”gif0″
    gifconfig_gif0=”198.22.63.8 209.51.181.2″
    ipv6_network_interfaces=”gif0 lo0″
    ifconfig_gif0_ipv6=”inet6 2001:470:1f10:b9c::2 2001:470:1f10:b9c::1 prefixlen 128″
    ipv6_defaultrouter=”2001:470:1f10:b9c::1″

    Lastly, tell your users that you have IPv6. Otherwise, nobody will notice. It’s that transparent.

  • One Reply to “Adding IPv6 to a FreeBSD Mail/Web Server”

    Comments are closed.