With the last 5 /8 blocks of IP addresses being issued it is time to make your systems available through IPv6 if you haven’t done so yet. This short post shows how to configure a Centos or Red Hat Enterprise Linux (RHEL) system for IPv6.
Configuring your system consists of two distinct steps. First, you need to enable IPv6 on your network interface and second you need to configure your applications to bind to the right IPv6 addresses.
Before you begin
Like their IPv4 siblings the addresses in the IPv6 space are assigned to you. You cannot just make up your own IPv6 addresses and expect things to work. Check with your provider if they already support IPv6 and request an IPv6 subnet. Contrary to IPv4 you will not get a single IP address, but you will always get a subnet. Usually this will be a /64 subnet giving you the liberty to pick addresses within that space. If you have a significant number of addresses in use in your IPv4 space then it might be wise to consider the way you issue your IPv6 addresses. One way to do it could be to map the IPv4 address into the IPv6 address so you can easily see which addresses belong together.
Example network
In this document I use the official prefix for documentation purposes where-ever a network address is used. For IPv6 this is 2001:db8::/32, while for IPv4 I use the 192.0.2.0/24 network.
2001:db8:abc::/48 is my sample provider network with 2001:db8:abc::1/48 as it’s gateway. For our network I use 2001:db8:abc:1234::/64. I assume a pre-existing IPv4 network with the following addresses: 192.0.2.1/24 for the default gateway and 192.0.2.100/24 and 192.0.2.200/24 as two addresses assigned for us to use on the server.
The network
Network configuration for IPv6 is done through the same configuration files as the other networking configuration. The system-config-network-tui command does support IPv6 so you have to edit the files by hand.
First edit /etc/sysconfig/network and make sure that IPv6 networking is enabled by setting NETWORKING_IPV6 to yes:
NETWORKING=yes NETWORKING_IPV6=yes HOSTNAME=www.example.com GATEWAY=192.0.2.1 IPV6_DEFAULTGW="2001:db8:abc::1/48"
Here we have also setup the default IPv6 gateway with IPV6_DEFAULTGW.
Next step is to configure the network interface. In our example we have already two pre-existing IPv4 addresses configured on the eth0 interface and we want to map them to into our reserved IPv6 subnet. The first address we have is 192.0.2.100, which will map to 2001:db8:abc:1234::192.0.2.100 or 2001:db8:abc:1234::c000:264, the second address we have is 192.0.2.200, which maps to 2001:db8:abc:1234::192.0.2.200 or 2001:db8:abc:1234::c000:2c8. If you want to calculate your own IPv6 addresses you can easily do so with the following rule:
- Take your prefix (e.g. 2001:db8:abc:1234::)
- Add the IPv4 address (e.g. 192.0.2.100) after the double colon
- The resulting address is your IPv6 address, which you can convert with ipv6calc to the format using only the IPv6 notation with colons. (e.g. ipv6calc 2001:db8:abc:1234::192.0.2.100)
So, to configure the network interface we will edit the file /etc/sysconfig/network-scripts/ifcfg-eth0 and add the IPv6 configuration:
DEVICE=eth0 BOOTPROTO=static IPADDR=192.0.2.100 NETMASK=255.255.255.0 HWADDR=01:23:45:67:89:AB ONBOOT=yes IPV6INIT=yes IPV6ADDR="2001:db8:abc:1234::c000:264/48" IPV6ADDR_SECONDARIES="2001:db8:abc:1234::c000:2c8/48"
As you might have noticed instead of using the /etc/sysconfig/network-scripts/ifcfg-eth0:1 for the second address we can use the IPV6ADDR_SECONDARIES line to add as many secondary addresses to the interface as necessary.
With our basic networking ready we can restart the networking with the command service network restart or a reboot, but make sure that you have access to your server’s console in case you made a mistake and the network doesn’t come up again.
Once your network is up again you should be able to verify the configuration by pinging the gateway or an other IPv6 enabled host with the ping6 command.
Configuring services for IPv6
Many of the services will use IPv6 automatically if an IPv6 network is present at startup, some services require explicit configuration to enable IPv6. I will shortly mention those that I needed to configure on my own server.
Postfix
Postfix needs to be told to use IPv6 by adding inet_protocols = all to the /etc/postfix/main.cf, also if you have mynetwork_style = class or mynetwork_style = subnet configured you need to be aware that your entire IPv6 subnet will be considered part of the my network. If your server is not the relayhost or smarthost for other servers I would strongly suggest to keep the mynetwork_style = host or manually define the mynetwork.
Dovecot
To make Dovecot listen on IPv6 addresses it needs to have an explicit listen configuration added. To make it listen on all addresses add the line listen = *, [::].
Apache httpd
If your Apache httpd is configured with Listen *:80 and NameVirtualHost *:80 it will automatically listen on IPv6 addresses. However if you use IP based virtual hosts you will need to add the IPv6 IP addresses to the VirtualHost configurations. You will need to use the address within brackets to make a distinction between the colon used as separator between the sections in the address and the colon as separator between the address and port. You can use multiple addresses in a single VirtualHost configuration as in the following example:
<VirtualHost 192.0.2.100:443 [2001:db8:abc:1234::c000:264]:443> DocumentRoot /var/www/html ServerName www.example.com ServerAdmin webmaster@example.com … </VirtualHost>
Securing our IPv6 network
So far we haven’t looked at securing the network. The principles here are very much the same as with IPv4. The methods available are basically the same. You can use IPv6 addresses in the same way as IPv4 addresses in /etc/hosts.deny and /etc/hosts.allow as shown in the following example:
ALL: [2001:db8:abc:1234::]/64
NetFilter works pretty much the same for IPv6, but uses different tables. You use the command ip6tables instead of iptables to manipulate the IPv6 rules:
ip6tables -I INPUT -s 2001:db8:abc:1234::/64 -j ACCEPT
You use the command: service ip6tables start to start the firewall, and enable it at startup with: chkconfig ip6tables on.
N.B.: There is one caveat, it seems the 2.6.18 kernel modules do not support stateful inspection of IPv6 traffic.
N.B.: Be aware that IPv6 relies heavily on ICMPv6 for all kinds of traffic and route information, so it is not wise to drop this traffic.
The Apache httpd Allow and Deny options works with IPv6 as well, you specify the IPv6 address just as you would specify an IPv4 address like in the following example:
Order allow,deny Allow from 192.0.2.100 2001:db8:abc:1234::c000:264
And you can use networks as well as in the following example:
Order allow,deny Allow from 192.0.2.0/24 2001:db8:abc:1234::/64
Conclusions
Configuring IPv6 is not that hard, and gives you the benefit of having your own subnet with plenty of space for future growth. Support in Red Hat Enterprise Linux or CentOS 5 is pretty good, with only a small caveat with iptables. If your provider supports IPv6 there is no reason not to implement it at the moment. Even though providers in the western world may still have a decent supply of IPv4 addresses it is very clear that in the coming years there will be a major shift towards IPv6, because we now have really reached the end of the availability of IPv4 addresses.