IPv6 - Set Up An IPv6 LAN with Linux

Setting up an IPv6 LAN with Linux? Ever wondered how to do that? For years we have heard the dire predictions about the impending doom of IPv4 and the imminent arrival of IPv6. As with any eschatological prediction you either choose to ignore it and hope for the best, or you prepare for the event as best one can. So far the former strategy has served many sys admins well and proved to be an effective strategy .

Get IPV6 Training
You know its coming!

If however, you have decided to gird your loins and face IPv6 head on, you probably quickly discovered, that, although there is a lot out there about the theory of IPv6, there is very little in the way of practical how tos when it comes to setting up an IPv6 LAN.

What makes understanding IPv6  troublesome is the complexity of working in a mixed environment of IPv4 and IPv6. This complexity becomes evident when one tries to connect to an external IPv6 network or the Internet which is still predominantly IPv4.

Steps to Set Up an IPv6 LAN

This blog posts break this down into two separate problems:

  1. A - Setting up  an IPv6 LAN network with Linux,
  2. B - Connecting your IPv6 network to the Internet

If you separate these two issues out its much easier to figure out what you need to do. Both of these steps have issues that need to be understood before the IPv6 "ah-hah" moment. Once that happens you will also have the "oh no" moment which might help you understand why there is such slow movement on IPv6 adoption.

In the first  part we will configure an Ubuntu 14.10 server to manage an  IPv6 LAN. In the 2nd part  we will deal with the myriad of options to connect an IPv6 network to the internet.

IPv6 Addressing - Some Theory

First we need to cover some theory on IPv6 addresses. There is a lot of article covering IPv6 addressing on the web, so I will just summarize what you need to know to proceed with setting up an IPv6 network. There are some nuances and subtleties we will brush over to provide you with a working conceptual model.

  • IPv6 addresses consist of 8 groups of 16 bit hexadecimal numbers to give a total address of 128 bits.  (See Global addresses below for explanation of the 2001:0db8::/32 address block.)
    • 2001:0db8:85a3:0000:0000:8a2e:0370:7334
    • 2001:db8:85a3:0:0:8a2e:370:7334 -> leading 0 are dropped & groups of zeros (0000) become 0,
    • 2001:db8:85a3::8a2e:370:7334 -> lastly consecutive zeros are  replaced with an empty double colon ::
  • The first 4 group of hexadecimal numbers of an address, 64 bits of the 128 bits,  is the network prefix (network mask). All IPv6 networks have a 64 bit network prefix,
  • The remaining 64 bits are the host identifier,

Sometime you will see an addresses listed with a prefix such as /48 or /56 etc. This does not mean that 16 (64-48) or 8 (64-56) bits of the 64 network prefix has been reserved for use by hosts as with IPv4 CIDR. The network address is always 64 bits long.

This notation refers to a block of networks. i.e all networks that begin with the first 48 or 56 bits set as specified. This is known as a routing prefix  and is used in routing rules, resulting in smaller routing tables. It is also used for when you are assigned a block of IPv6 networks.

The idea with IPv6 is that you should be assigned a block of networks by your ISP or IANA instead of a single host address or single IPv4 network as currently happens with IPv4.

The remaining bits of the network prefix 16 (64-48) or 8 (64-56) are called the subnet id. So the routing prefix +  subnet id make up the network prefix of an IPv6 address.  Dont' be confused by the use of the word subnet in subnet id.It is not an IPv4 subnet mask. It is simple the part of the network prefix you get to assign yourself as the administrator of that block of network addresses. 
So if you get an IPv6 address block with a 56 bit routing prefix it means you can have 255 (28)  networks each with  1.844674407×10¹⁹ (264) hosts!. Its up to you to determine how the subnet portion is used to create the network address. So if you are given a block of IPv6 network such as fdc8:282a:f54c::/48 it means you can have 216 networks. Your networks addresses are :

  • fdc8:282a:f54c:1::/64 
  • fdc8:282a:f54c:2:/64
  • ... 
  • fdc8:282a:f54c:ffff:/64

We wil come to the host identifier portion later later. The IPv6 network address space has been "sliced up" into different blocks. What you need to know about these blocks is given below: (each address block is explained further later)

Special IPv6 Address Blocks
Name Prefix Explanation
Link Local fe80::/10 Although this routing prefix is only 10 bits leaving 54 bits for up to 254 networks only one subnet id has been allocated so far by the specification which is fe80:0:0:0 or  fe80::/64
Unique Local Addresses(ULA) fc00::/7 Although this routing prefix is only 7 bits, the 8th bit must always be 1 according to the spec. So what you will see in practice is fd00::/7. At some later point we may see fc00::/7. We will be using this address block in our setup.
Global Addresses  2001::/23  Global addresses will in fact be most of the address space of IPv6  So far the 2001::/23 block has been assinged and this is what you are likely to see in practice until further blocks are assigned to regional registrars. Within this some addresses have been reserved for a special purpose such as 2001:0db8::/32 which is reserved for documentation so if anyone copies it it won't actually route. To see what block have been assigned see the IANA site. 

For more information on the address blocks see the IANA site

A - Set Up an IPv6 Network

1) Set Up an Link Local Only IPv6 LAN with Linux

We will set up an IPv6 network incrementally. We will start with the simplest and most trivial IPv6 and add services as we go. This will help us arrive at a understanding of how the various services fit together. We will go from the simplest IPv6 network to one which has all the basic network services required of a business network.

Simplest IPv6 Network - Link Local Only

To setup the simplest IPv6 network you just have to boot up a host or two with a IPv6 enabled operating system such as Ubuntu. Open a terminal and type:

"ip -6 address list"

You should see output similar to the following:

1: lo:  mtu 65536 
inet6 ::1/128 scope host 
valid_lft forever preferred_lft forever 
2: eth0:  mtu 1500 
qlen 1000 inet6 fe80::922b:34ff:fe7b:6ff1/64 scope link 
valid_lft forever preferred_lft forever,multicast,up,lower_up>,up,lower_up>

IPv6 link local addresses have been assigned automatically to any interfaces that you have. The IPv6 localhost address (IPv4 127.0.0.1) is ::1/128. You can do the same on another host to gets it IPv6 link local address and then do a IPv6 ping with "ping6" - note the 6.

ping6 fe80::922b:34ff:fe7b:6ff1

The fe80::/64 network prefix is the link local network as explained in the table above. It should be the only IPv6 network address you will see across different physical networks. In fact every host on an IPv6 network must have an link local address (fe80::/64).

Host Identifier Generation

The host identifier portion of the link local address, the remaining 64 bits, is generated from the mac address with a algorithm applied to extend the 48 bit mac address to the 64 bit host address required for IPv6. See EUI64 for the algorithm used. The host identifier may also be manually assigned by the system administrator. This introduces the risk of duplicate IP addresses being assigned, so IPv6 has a duplicate address detection protocol that allows hosts to determine if there is a conflict before assigning itself an address.

In most cases you will let this be automatically generated. In IPv4 initially IP address had to be manually assigned or assigned via a DHCP server. Later the 169.254/16 address range was reserved for auto-configuration in IPv4 network. Unlike IPv4 your interfaces will always have an fe80::64 address, it is not used instead of a valid IPv6 address. In IPv6 your interfaces will typically have multiple IP addresses. 

Why do you need a Link Local Address?

IPv6 configuration is done using layer 3 (network layer) protocols and not layer 2 (media layer eg. Ethernet) as with IPv4; so a valid IPv6 address is required before any additional configuration can be done. Of couese it also allows for zero config simple networks.

Pros and Cons of Link Local Network

With a link local address you can communicate with other IPv6 hosts on the local network segment or broadcast domain. i.e the same switch or shared media network. So for a home LAN not connected to the internet this is all that is required. You can connect to your printer, Smart TV, PlayStation etc automatically using protocols such as UPnP and multicast DNS (ZeroConf).  Connecting to the internet, or a network in a different physical network or logical network, will require a bit more work.

2) Set Up A Stateless Routable IPv6 Network

If this all there was too it then we could all go home. But if you start to think about it you will begin to have some doubts as to how useful a link local only IPv6 network is.

  • How do I assigned the same address to a host every time without doing it manually? (it is possible for a nodes host identifier to change between reboot if there is a conflict) 
  • What if I change the NIC and get a different IP address?
  • How do I configure the hosts for routes and other services such as DNS, NTP etc?
  • How do I communicate between two internal networks separated by a router or WAN link?

To address these issues you need to assign yourself a non-site local address. This can be a unique local address (ula) or a global address. For a global address you will need to get an IPv6 network block from your ISP or get one assigned to you by IANA. So we will make use of a ULA address which you can assign yourself.

What is the difference between a ULA and a Global address?  

By convention a ULA is not routed over the public internet. Routers on the public IPv6 network should refuse to route such traffic in a similar manner to private IPv4 addresses. Essentially there should be no routing entries in the routers responsible for internet traffic, making them unreachable from outside an organisation.

If you are going to start experimenting with IPv6 there are two reasons to use a ULA

  •  you should start with a ULA address to avoid any mis-configuration disasters.
  • It might be hard to get a global IPv6 address assigned to you. There are very few ISP handing out IPv6 network addresses currently so in some cases its the only choice available to you.

Unique Local Addresses

One feature of unique local addresses is that they should be different for every network you see. Unlike IPv4 where private addresses (196.128/16, 10/8 and 172.16/16) meant there are often networks with the same network mask - eg nearly every home and office has a  network with the network mask of 192.168.1.0/24 address or 10.0.0.0/24 range; you might never see a duplicate IPv6 ULA network address. This is because only the first 8 bits of the network prefix are fixed at "fd". The remaining 56 bits of the netowrk prefix, the subnet id, can be randomly selected. System administrators are meant to create the subnet id themselves. A handy way to generate the subnet id for the ULA is to use a site like unique-local-ipv6.com. From here you will get a /48 address range meaning you can have up to 65356 private networks!

Its generally a good idea to use a random subnet id rather than generate one like fd01:1:1:1::0/64 as this increase your chance of a conflict. Why would you be worried about a conflict if these are not routable? Have you ever had to merge two network that had the same IPv4 address range? Have you ever tried to setup a VPN between two network with the same IP network range?

Global Addresses

Global address will be assigned to you by an ISP unless you get your own block and tell your ISP to route it to you. So much like you get a public IP address from your ISP for IPv4 you will in future, get an IPv6 network address range when you dial up. Note: not a single IP address but a whole block of IPv6 addresses. Depending on your ISP you may get only one network or be assigned a block with multiple networks. In this case the router will received the network address prefix to use on your network. It will work the same as for the steps below except instead of a ULA network it will be a global address. Note you don't get assigned a full IPv6 address. You get the network prefix.

So to summarise. You will need at least two  IPv6 addresses for each interface if you want to do normal networkng tasks like route between network. A link local which is always present and at least one ULA or global address or perhaps all three!

For our exercise we will use ULA addresses to setup an IPv6 only LAN.

Set Up an ULA IPv6 Network in Linux

Note:You can setup the following IPv6 network on a network that is already configured for IPv4. You can run IPv6 in parallel with IPv4. This is known as a dual stack setup. Once done you can stop the IPv4 services and run the network on IPv6 only or keep it dual stack. One reason to test without IPv4 infrastructure running is to convince yourself that your network really is working over IPv6.

Ok, now things start to get a bit more complicated. First we need some more theory :( We have already seen how a link local address is assigned. But how is the ULA  address assigned? The nodes will need some way to get the network prefix? For this IPv6 makes use of a router advertisement service that runs on the local network router. This is what they mean when they say SLAAC (Stateless Automatic Address Configuration) configuration. The process is as follows:

  • An link local address is generated by the host,
  • The host will  ask (solicit) any routers for configuration information.
  • The router response with a router advertisement. This advertisement contains the network prefix the host should use and the address of the router for the default route.
  • The router may also provide a DNS address
  • The node generates the host identifier portion of the IPv6 ULA address and assigns it to the interface. (Note: The router does not provide the entire IPv6 address)

So a node now has an ULA IPv6 address and a default gateway and all should be good. This is known as stateless address assignment. The router does not assign an address per se. It has no idea what IPv6 address the hosts ends up using, only that it is in the provided network. Hence the stateless in the term stateless automatic address configuration (SLAAC).

Steps to Configure the Router Advertisement Service 

The advertisement service can run on any Linux box, but that box will become the default route for IPv6 traffic. In future your ADSL router will provide router advertisement services. First assign the Linux box a static IPv6 address from the ULA network: (In the examples that follow I use the fd5f:12c9:2201::/48 ULA routing prefix and I have chosen fd5f:12c9:2201:1::/64 as the network prefix. (ie :1 is the subnet id).

Configure a static IPv6 on Ubuntu

 

sudo vi /etc/network/interfaces

 

auto eth0
iface eth0 inet6 static
  address fd5d:12c9:2201:1::1
  netmask 64
  autoconf 0
  dad-attempts 0
  accept_ra 0

Now we need to install the router advertisement service:

Router Advertisement Daemon Configuration

sudo apt-get install radvd

vi /etc/radvd.conf

interface eth0
{
    AdvSendAdvert on;
    prefix fd5d:12c9:2201:1::1/64 {
        AdvOnLink on;
        AdvAutonomous on;
    };
    #Send DNS Server setting - assumes there is a DNS server setup at the address below
    RDNSS fd5d:12c9:2201:1::2{
    };
};

Restart the service and then on a client restart the network. You should see two IPv6 address on your network card.

 

ip -6 address list

 

You can ping the router with the ping6 utility:

"ping6 fd5d:12c9:2201:1::1" if this doesn't work try "ping6 fd5d:12c9:2201:1::1 -I eth0" -> Use the interface with the assigned IPv6 address. We will cover DNS and IPv6 in the net section.

Congratulations you have an IPv6 network up and running! If your router is multi honed and has two interfaces with IPv6 addresses you will be able to route between the two networks. You will need to setup two static IPv6 addresses in /etc/network/interfaces.

3) Set Up a Stateful ULA IPV6 LAN with DHCP & DNS Services

After the initial excitement of getting a routable IPv6 network up and running you start to realise you need a few more services:

  • What if I want to send down other configuration information such as the NTP or SMTP server settings?
  • What if I want to make sure the same IPv6 address, not just the network prefix, always get assigned to a server like the NTP or SMTP server?
  • What if I want to track IP address assignment?
  • What if I want to provide dynamic updates to the local DNS server for local hosts? After all remembering all these 128 bit random addresses is going to be hard.
  • How do I assing a IPv6 address in the DNS server zone file?

Sadly the router advertisement service can only provide a network prefix, default route and dns server address and not much else.  To provide the required service we need to use a DHCP server.  To get the node to use a DHCP server we need to configure the radvd service to tell nodes to contact a DHCP server for additional configuration information.

You can configure radvd to tell the nodes to contact the DHCP server for

  • configuration info only (stateless) or
  • for configuration information and its IP address (stateful)

 So a DHCP server can be used in a stateless and stateful IPv6 setup. We will use DHCP to send configuration information such as DNS servers and to assign IP addresses since we want to assign fixed IP to well known hosts. 

Edit the /etc/radvd.conf file

interface eth0
{
     AdvSendAdvert on;
     prefix fd5d:12c9:2201:1::1/64 {
        AdvOnLink on;
        AdvAutonomous on;
        AdvManagedFlag on; # get a full IP address from the DHCP server
        AdvOtherConfigFlag on; # get other configuration info from the DHCP server
    };
};

Setting up DHCP6 is similar to DHCP for IPv4. We will use the isc-dhcpd-server:

"sudo apt-get install isc-dhcp-server"

Edit the /etc/dhcpd/dhcpd6.conf: (note comments removed for clarity)

ddns-update-style interim;
ddns-updates on;

update-conflict-detection false;
update-optimization false;

option domain-name "jumpingbean.co.za";
option dhcp6.name-servers fd5d:12c9:2201:1::2;

default-lease-time 600;
max-lease-time 7200;
include "/etc/dhcp/rndc.key";

log-facility local7;

zone jumpingbean.co.za. {
                          primary 127.0.0.1;
                          key rndc-key;
}


zone 1.0.0.0.1.0.2.2.c.9.2.1.d.5.d.f {
        primary 127.0.0.1;
        key rndc-key;
}

subnet6 fd5d:12c9:2201:1::/64 {
     range6 fd5d:12c9:2201:1::100 fd5d:12c9:2201:1::200;
}

A lot of the configuration for DHCPv6 is the same as DHCPv4 and I am assuming you are familiar with the configuraiton of DHCPv4 for dynamic DNS updates. Here we set up the DHCP server to

  • provide the DNS server
  • dynamically update the bind DNS server by specifying which Zone file should be updated
  • the domain name to use on nodes.
  • we could push additional routes, NTP server settings etc.

Note: To setup a fixed IPv6 address in DHCPv6 you make use of a DUID (Device Unique ID) which is not the mac address which is used for IPv4 DHCP. The DUID is assigned by the operating system and remains the same even if network cards change. The complete unique id is made up of the DUID and an IAID (interface assigned id) as you may have more than one interface on a node requesting IP addresses from the DHCP server. I.E Each interface has a unique ID.

Below is an example of a fixed assignment

host example {
  host-identifier option dhcp6.client-id 31:30:30:30:30:31:33;
  fixed-address6 fd5d:12c9:2201:1::101;
}

I am not aware of a way to get the DUID and IAD of a interface on a  node in Linux. You can look in the leases file on the DHCP server once an address is assigned but this is no ideal. A binary copy of the node's DUID can be found at /var/lib/dhcpv6/dhcp6s_duid but it cannot be simple cat'ed to stdout. If anyone knows how to read the unique id for an interface on a node please let the internet know :)

DHCP Complexities

Before moving on to configuring the name server there are some issues to note about the DHCP server.

  • You can run an IPv4 and IPv6 DHCP server in parallel on the same network as they listen on different ports. So you can have a dual stack DHCP IPv6 and IPv4 network but it does require two running instances of the DHCP server.
  • To start the isc-dhcp-server in IPv6 mode you need to provide it with the option "-6". You can set this in /etc/defaults/isc-dhcpd-server via "OPTIONS="-6" on Ubuntu. BUT! on Ubuntu 14.10 this is ignored and the init v script will stubbornly start in IPv4 mode. To get the dhcp server to start in DHCPv6 mode add this to the /etc/rc.local file as a temporary solution and disable the init system from starting up the DHCP server.

sudo update-rc.d dhcpd disable

dhcpd -6  -cf /etc/dhcp/dhcpd6.conf -lf /var/lib/dhcp/dhcpd6.leases eth0

If you going to run dual stack you will nee to add this for the IPv4 mode of the DHCP server

dhcpd -4  -cf /etc/dhcp/dhcpd4.conf -lf /var/lib/dhcp/dhcpd4.leases eth0

You might also have apparmour prevent writing to the lease file if you try and write it to a different location. You can either stop apparmor or configure the dhcp server to write the lease file to location that its profile supports writing to.

DNS Set Up Bind9

​First you will need to install bind9. DNS differs from DHCP in that only one instance of the DNS server needs to be running to service both IPv4 and IPv6 requests. It simple need to bind to both IPv4 and IPv6 addresses. A DNS server will provide answers to queries for an IPv4 or IPv6 address no matter what the source address of the query. i.e it doesn't look at whether the query came from an IPv4 or IPv6 address it just looks at what it was asked to lookup - the record type.

sudo apt-get install bind9

​Next we need to edit the bind configuration to setup our zones and tell bind to listen on IPv6 or IPv6 and IPv4 interfaces. Most of this is standard bind9 setup as for IPv4. The only real change at this point is the AAAA records in the zone file and the awful reverse zone name that is a mission to type without making a mistake.


/etc/bind/named.conf.options

options {
          directory "/var/cache/bind";
          forwarders {
                        8.8.8.8;
          };
          dnssec-validation auto;

          auth-nxdomain no; # conform to RFC1035
          listen-on-v6 { any; };
};


/etc/named/named.conf.local

zone "jumpingbean.co.za" {
        type master;
        allow-update { key rndc-key; };
        file "/var/lib/bind/jumpingbean.co.za";
};

zone "1.0.0.0.1.0.2.2.9.c.2.1.d.5.d.f.ip6.arpa" {
        type master;
        file "/var/lib/bind/fd5d:129c:2201:1";
        allow-update { key rndc-key; };
};

The zone files below already contain some dynamically updated IPv6 address from the DHCP server. Those are the ones annotated with the TXT entries. You will only make entries for the static IPv6 addresses and let DHCP handle the dynamic address entries.

Zone files

/var/lib/bind/jumpingbean.co.za

$ORIGIN .

$TTL 604800     ; 1 week
jumpingbean.co.za           IN SOA  ns.jumpingbean.co.za. no.jumpingbean.co.za. (
                                182        ; serial
                                604800     ; refresh (1 week)
                                86400      ; retry (1 day)
                                2419200    ; expire (4 weeks)
                                604800     ; minimum (1 week)
                                )
                        NS      ns.jumpingbean.co.za.
                        A       127.0.0.1
                        AAAA    ::1
$TTL 300        ; 5 minutes
android-a74e95670198fd6a A      10.0.10.4
                        TXT     "0002ec64161ce51591018b9eb0a01ae6b9"
$TTL 604800     ; 1 week
gateway                 AAAA    fd5d:12c9:2201:1::2
ns                      AAAA    fd5d:12c9:2201:1::2
$TTL 300        ; 5 minutes
trinity                 A       10.0.10.3
$TTL 187        ; 3 minutes 7 seconds
    
                    TXT     "025c83d7b0b5ca62d26381f057fbeed483"


/var/lib/bind/fd5d:129c:2201:1

$ORIGIN .
$TTL 604800     ; 1 week
jumpingbean.co.za           IN SOA  jumpingbean.co.za. no.jumpingbean.co.za. (
                                182        ; serial
                                604800     ; refresh (1 week)
                                86400      ; retry (1 day)
                                2419200    ; expire (4 weeks)
                                604800     ; minimum (1 week)
                                )
                        NS      ns.jumpingbean.co.za.
                        A       127.0.0.1
                        AAAA    ::1
$ORIGIN jumpingbean.co.za.
$TTL 300        ; 5 minutes
android-a74e95670198fd6a A      10.0.10.4
                        TXT     "0002ec64161ce51591018b9eb0a01ae6b9"
$TTL 604800     ; 1 week
gateway                 AAAA    fd5d:12c9:2201:1::2
ns                      AAAA    fd5d:12c9:2201:1::2
$TTL 300        ; 5 minutes
trinity                 A       10.0.10.3
$TTL 187        ; 3 minutes 7 seconds
                        TXT     "025c83d7b0b5ca62d26381f057fbeed483"

Now we have a fully functional IPv6 LAN. You may have IPv4 running at the same time and a interface can have a IPv4 and IPv6 address. To test DNS try the following (you can try it on public DNS servers too)

dig @DNS-IP www.google.com A

dig @DNS-IP www.google.com AAAA

You can query the local DNS server you just setup as well for an address you assigned.

So now you have a fully functioning IPv6 network. You can disable the IPv4 network and see that you can still reach all machines and services. On the client side you will not have to do any explicit configuration changes. Everything will be fine until you try and access the internet. The following will fail:

"ping6 www.google.com"

"ping www.google.com"

The first ping to google IPv6 address will fail unless you have global address. If you have an fd00::/7 address you won't get a response. The second will fail because you are trying to access an IPv4 host from an IPv6 network. And this leads to the second issue we need to deal with to understand IPv6.

B: Connecting to the Internet from an IPv6 Network

This is the most troublesome part of the IPv6 protocol. There are a myriad of "transition mechanism" designed to ease the transition form IPv4 to IPv6. None of them are ideal as far as I can tell and most have requirements which place them outside of the reach of small and medium businesses until IPv6 becomes more widespread.

At the time of writing this article the most common occurrence is for an ISP to assign a single IPv4 address to your router. As IPv6 becomes more widely adopted this will change and the step below may not be that relevant. The issue is that IPv6 services cannot be access via an IPv4 address and IPv4 services cannot be natively connected from an IPv6 only host. We are going to look at two solutions:

  • NAT64,
  • Using a tunnel broker 

NAT64 Transition Mechanism

For the sake of simplicity we will assume an IPv4 address on the router. The advantage of NAT64 is that you can use IPv6 internally and still use your ISP public IPv4 address. Another advatnage is you can keep using your IPTables IPv4 firewall rules. The disadvantage is that  you will only need to connect to IPv4 hosts on the internet. So it kind of defeats the purpose of setting up an IPv6 network other than to experiment with its features.

NAT64 protocol nats all outgoing IPv6 addresses to a pool of IPv4 addresses and then routes the request to the ISP. This means there will be double natting. Once for NAT64 and then again for your router to the ISP.  To setup NAT64 install tayga.

"sudo apt-get install tagya"

edit /etc/tagya.conf

tun-device nat64 # the interface to create to perform the natting
ipv4-addr 192.168.255.1 # the ipv4 address for the tayg interface from the pool below.
ipv6-addr fd5d:12c9:2201:1::3 # the IPv6 address to assign to the tun-device nat64 above
prefix fd5d:12c9:2201:1:1:1::/96 # see explanation below
dynamic-pool 192.168.255.0/24 # the pool of IPv4 addresses to assign to each IPv6 address
data-dir /var/spool/tayga

So NAT64 creates a interface to listen on. The interface gets an IPv6 and IPv4 address. Any request from an IPv6 source for an IPv4 address will get routed to the nat64 interface. To do this we need to add a route for IPv6 addresses:

"sudo ip route add fd5d:12c9:2201:1:1:1::/96 dev nat64"

All that remains is to explain where the network prefix d5d:12c9:2201:1:1:1::/96 used above and in tagya.conf file come from. This is a network from your ULA block which you set aside for IPv4 to IPv6 address translation. You need to configure the bind DNS server to automatically convert any IPv4 addresses to IPv6 using the prefix above. This way you won't get an error when you try and ping an IPv4 host from an IPv6 address.

/etc/bind/named.conf.options file and add the items in bold below:

options {
        directory "/var/cache/bind";

         forwarders {
                8.8.8.8;
         };

        dns64 fd5d:12c9:2201:1:1:1::/96 {
                clients {
                        any;
                };

                exclude {
                        any;
                };
        };

        dnssec-validation auto;

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };

};

At this point your IPv6 network can live happily in a sea of public IPv4 addresses. Unfortunately you won't be able to access an IPv6 host with a global address just yet :(

Using Tunnel Brokers

Alternatively you can keep a dual stack and then setup a IPv6 tunnel at one of the well known tunnel brokers such as Hurricane Electric or setup a Teredo tunnel. Both have draw backs. The Hurricane Electric service requires you to setup a SIT tunnel to one of their points-of-presence. This requires a static IPv4 address or you will need to constantly update the configuration on their site when your ip changes. A Teredo tunnel requires a IPv6 address.

The advantages of a SIT tunnel is that you get a routable global IPv6 address at the POP and you can access IPv6 nodes natively. The disadvantage is your traffic needs to be proxied or tunneled over the IPv4 internet increasing latency. If you get a SIT tunnel you only have one global IP address for the host the tunnel is created on so you will need to setup a tunnel per node or have an IPv4 network and nat it through the SIT tunnel.

Risk of Using IPv6

​One point to bear in mind when using IPv6 is that it will bypass all your IPv4 security measures. If you have an IPTables ruleset for IPv4 you will need to re-implement that for IPv6 with IP6tables. There is no natting in IP6tables currently. One thing to remember, if you in a co-location data centre and geting IPv6 auto-generated link-local addresses, any machine in the same centre can connect to your server via IPv6, potentially by passing any IPv4 ruleset you have setup! Some data-cenre might be assigning you global ipv6 addresses without you knowing! So check your co-location servers and make sure you don't have any back-doors due to mis-configuration. At least one data centre we have server at had helpfully given us an gobal IPv6.

Conclusion

The transition mechanisms are a mess. One just has to look at the acronym soup on Wikipedia transition mechanism page dealing with the myriad of ways to inter operate between IPv4 and IPv6. We have only tried two!  We are still experimenting with the tunneling mechanisms above to see if they work properly as they promise the most benefits, being able to reach servers in different locations over the public internet with routable IPv6 addresses. So far we have met with limited success. No doubt we got to learn a bit more. But this also points to the biggest reason IPv6 is not being adopted. There is no real way for the two protocols to inter operate. A painful time will come when 50% of the world is on IPv6 and the rest on IPv4. 

At least you can get some experience setting up internal IPv6 networks in the meantime.

Comments

 

Nice blog post.

 

The transition mechanisms are in pretty good shape now with the recent publication of the LW4over6 & MAP RFCs.

These taken with knowing which transition mechanisms should fade away (anything that tunnels over IPv4) brings more clarity to the situation. The latest mechanisms assume native IPv6 and provide IPv4 as a service on top. This has become practical by fixed and mobile access providers starting to deploying IPv6. 

There are two main sets of RFCs. As a foundation to all there is RFC 6145 IP/ICMP translation algorithm and RFC 6346 The A + P Approach.

Some mobile operators are deploying 464XLAT (RFC6877) which builds on RFC6145 and RFC 6146 and RFC 6147.

Then there are the latest MAP RFCs which improve on 464XLAT by pushing state out to the client device away from central Large-scale NAT boxes. 

RFCs7596, 7597, 7598, & 7599.

These are more attractive to fixed ISPs as their data volumes are much higher than mobile operators. They also allow the customer router to directly share a public IPv4 making port forwarding easier. OpenWRT has an implementaton of it, as that and the stateless Border Router capability becomes more widely supported there will be highly scalable tools for managing the transition. 

Mark Clarke's picture

Thanks for the additional information on the transition mechanisms. Will put them on my reading list.

Thanks for your guidance greatly. It helps me save lots of time to comprehend.
BTW, In "Set Up a Stateful ULA IPV6 LAN with DHCP & DNS Services", "AdvManagedFlag" and "AdvOtherConfigFlag" are interface specific options instead of prefix options, the file "radvd.conf" shows above can't be used to startup radvd.