Implementing IPv6 Part 2

We are quickly running out of IPv4 addresses. Are you ready for World IPv6 Day on June 8th, 2011? I have prepared my configuration on OpenWRT and Ubuntu. This includes configuring DNS using bind, email using Exim, and a Squid web proxy.

Having verified that I could establish IPv6 connectivity, I chose to improve my connectivity. This started with getting a tunnel from Hurricane Electric and updating my configuration. I then updated my bind server and Exim mail server support IPv6 addresses. This posting updates and continues from my post on Implementing IPv6 6to4 on OpenWRT.   Review it for information on creating a tunnel and running radvd on OpenWRT.

Replacing the Tunnel

When I registered with Hurricane Electric, I got the configuration information for the new static tunnel.  This included:

  • the remote IPv4 address for the tunnel;
  • local and remote IPv6 addresses for an IPv6 point-to-point link; and
  • the address of a delegated IPv6 /64 block.  For most home users this should be all they need.

First I shutdown the existing tunnel. The I used the new values to  updated my /etc/config/6tunnel configuration file.  I included a change to the tunnel’s interface name.

config 6tunnel
    # Tunnel parameters
    option tnlifname        'he-ipv6'
    option localip4         '192.0.2.10'
    option remoteip4        '198.51.100.2'
    option localip6         '2001:db8:1f20:bcd::2/64'
    option remoteip6        '2001:db8:1f20:bcd::1'
    option delegatedip6     '2001:db8:1f21:bcd::/64'

    # Standard values
    option mtu              '1480'
    option ttl              '64'

I restarted the tunnel and tested as I had before.

Once this was working I updated /etc/config/radvd configuration with the new address.  After restarting radvd and shorewall6-lite, I verified the addresses and connectivity of my clients.

In my case I had multiple local subnets.  To support this I requested a IPv6 /48 delegation from Hurricane Electric.  I replaced the DMZ block with the originally delegated /64 block.  For the rest of my blocks I replaced the previous /48 prefix with the newly delegated prefix.  This provides a cleaner separation of the DMZ from the LAN.  Nothing should be allowed from the Internet to the /48 block.  My shorewall6 configuration was updated and the firewall rebuilt.  Various network configuration files, including another radvd configuration was updated and implemented.

Updating Bind

Adding addresses to bind is quite simple.   IPv6 addresses are handled by AAAA records.  For initial testing your may want to configure an ipv6 sub-domain in which to publish your IPv6 addresses.   Due to the lack of NAT security you should carefully consider what information you wish to publish about hosts on your LAN.

IPv6 provides a significant improvement for maintaining reverse DNS configuration.  Along with the delegation of a network block, the reverse DNS zone can be delegated.  This allows you to maintain both forward and reverse DNS zones.  This should improve the quality of this data.

Configuring an IPv6 Reverse zone.

Adding a reverse zone for a /64 block consists of creating a new zone file and adding a zone specification to the bind configuration.  My zones are in an include file /etc/bind/named.conf.zones.  The new zone definition is a reverse order nibble encoded entry like the following:

// We are the master server for 2001:db8:1f21:bcd::/64>
zone "d.c.b.0.1.2.f.1.08b.d.0.1.0.0.2.ip6.arpa" {
    type master;
    file "/etc/bind/db.2001_0db8_1f21_0bcd";
    allow-query { any; };
    allow-transfer { xfer; };
};

The new zone file needs to be reverse order nibble encoded.  In case your prefixes change, you should avoid specifying the origin.  The following is a sample for a couple of addresses differentiated by the last nibble.

$TTL 12H
@       IN      SOA     example.com. hostmaster.example.com.  (
                        2011011501      3H    2H     2W    4H    )
        IN      NS      ns1.example.com.
        IN      NS      ns2.ipv6.example.com.

1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN      PTR     gateway.ipv6.example.com.
5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN      PTR     mail.example.com.
;; EOF

It you have a larger zone you may want to configure the reverse entries in /64 zone files and delegate from your larger zone.  The following zone file delegates the :1234/64 subnet from a /48 reverse delegation file.

$TTL 12H
@       IN      SOA     example.com. hostmaster.example.com.  (
                        2011011501      3H    2H     2W    4H    )
                IN      NS      ns1.example.com.
                IN      NS      ns2.ipv6.example.com.

4.3.2.1         IN      NS      ns1.example.com.
IN      NS      ns2.ipv6.example.com.
;; EOF

Enabling IPv6 in Exim

Ubuntu distributes Exim with IPv6 enabled.  I had previously disabled IPv6 due to problems with my ISP’s DNS servers.   Enabling IPv6 mainly consisted of undoing those changes.  I also updated the logging and greylist databases to support the longer IPv6 addresses.

I found and commented out this block of options in the Exim4 configuration.  This re-enabled IPv6.

## Disable IPV6 name lookups
#dns_ipv4_lookup = *
#disable_ipv6 = true

Updating Databases

I use the Exim4 heavy package which accesses a MySQL database.  The database contains tables for greylisting, spamassassin’s automatic whitelisting,  and tracking data used for research.  Two tables contained columns listing IP addresses in text format.  The column width needed to be expanded to 40 characters for raw ip addresses, and 44 characters for IP addresses with a mask suffix.  It is also impossible to convert an IPv6 address to an integer type.  For IPv6, I used 0 for the integer value of the IP address.

For the greylisting database, I decided to use a 48 bit mask.  On further study, I found this can be done by using a substring function on the address.   This allowed me to retain the original 20 character field size for the IP address.   The masking code was changed in two places from

    '${quote_mysql:${mask:$sender_host_address/24}}'

to

    '${if isip4{$sender_host_address} \
        {${mask:$sender_host_address/24}} \
        {${substr_0_14:$sender_host_address}}}'

Updating SPF

My SPF records needed updating because I was using ip4: specifications.  I changed the records so they will follow the server definitions. This will limit future maintenance requirements.  Because my MX is also handles all outgoing mail, I am able use two simple SPF records for mail enabled addresses. My new SPF records are:

  • “v=spf1 a -all” for MXs (and outgoing mail servers);
  • “v=spf1 mx -all” for all email sending domains using an MX; and
  • “v=spf1 -all” for all other domains and hosts.

I publish both SPF records as TXT and SPF records.

Enabling IPv6 on Squid

Neither of the Squid packages for the Ubuntu Lucid support IPv6.  Squid 3.1 which does support IPv6 is currently in being tested for backports. To use it I created the file /etc/apt/sources.list.d/backports.list containing the lines:

# Backports for main only
deb http://ca.archive.ubuntu.com/ubuntu/ lucid-backports main
# Backport in testing
deb http://ppa.launchpad.net/ubuntu-backports-testers/ppa/ubuntu lucid main

I also added the PGP key using the command:

apt-key adv --keyserver keyserver.ubuntu.com --recv-keys AAC7706F

There are minor changes to the squid.conf file to support IPv6 addresses. I extracted my local changes and reapplied them to the new squid.conf file. I also added my delegated network blocks to the localnet definition.

  • Save the existing /etc/squid.conf file.  Identify the changes in it from the default configuration
  • Use aptitude to upgrade squid3 and squid3-cgi.
  • Reapply the local changes to the squid.conf file.  Add the delegate IPv6 range(s) to localnet src definition.
  • Restart the squid3 server and test.

The Test your IPv6 website rates my laptop using the squid cache at 10/10 for IPv4 and 9/10 for IPv6. The missing point is for a timeout on an upstream DNS server.  Otherwise, I have a full working IPv4 / IPv6 dual stack implementation.