Web and Mail Servers with IPv6

If you run a web server and a mail server and anticipate that users from Asia will access your system, it’s time to get it ready for IPv6.

Migrating the company’s local network to IPv6 will not make much sense in the next few years. The situation is different for leased dedicated servers, or ones that have a genuine IPv4 address and are thus part of the Internet. If you have customers from Asia who use native IPv6 to surf the Internet, it definitely makes sense to prepare the services that you provide on IPv4 for IPv6. It is primarily the 4,000,000,000 inhabitants of this continent who are affected by the scarcity of IPv4 addresses – and who are thus the earliest adopters of IPv6. This situation will mainly relate to your web offerings, possibly followed by your mail server.

In this article, I’ll describe a useful strategy step-by-step – and there are many pitfalls to watch out for. The first step is to ask yourself how many addresses you need and how big your IPv6 network is going to be. If your mail server and web server only have IPv4 addresses, and you just want to make sure they have IPv6 addresses, you will be fine with just one address, or a /64 network.

To test whether your configuration actually works, you also will need a local machine that speaks IPv6. If your ISP doesn’t support IPv6, you can resort to a tunnel broker such as SixXs.net . Alternatively, you can build an IPv6-in-IPv4 tunnel to the server you want to configure, which is possible within an OpenVPN connection. To allow this to happen, you need to ask your provider to give you an IPv6 network of the right size, which you then segment into smaller /64 networks, before configuring one of them for the tunnel.

Preparing DNS

Before you start to configure your new IPv6 addresses on the server, you need to make a few preparations, including creating valid DNS reverse entries for the IPv6 addresses you will be using (Figure 1).

Figure 1: Create DNS reverse entries for your IPv6 addresses at an early stage – the example shows the web hoster Strato, whose customers can create DNS entries themselves or delegate the zone on their own name server.

Because Linux systems prefer IPv6 for outgoing connections, as soon as an IPv6 address is configured locally, your forward and reverse resolution should produce the same results. You should start with lab-friendly, separate DNS names, such as ipv6.Domainname.com.

Consistent DNS records are also mandatory if you will be using SMTP to send mail to some other IPv6 entity that checks the consistency of the DNS record against the transmitting server to prevent spam. Many mail servers are configured to discard mail if the DNS record does not exist or is inconsistent.

Firewall Issues

Once you assign an IPv6 address to your server, the machine is totally exposed in the middle of the web. The reason for this is that the Linux firewall isn’t typically configured for IPv6, which means that the kernel just accepts any connection. The following command line

netstat -anp | grep ":::" | grep LISTEN

shows you which active applications would react to incoming IPv4 and thus automatically to IPv6 connections. You can identify these applications by the three colons (:::) in the IP address, followed by the program name.

Some hard work now lies ahead: all the firewall rules that you created in IPv4 need to be modified for IPv6. Otherwise, you run the risk of internal services being accessible from the web via IPv6. You also need to pay attention to your Linux version. Kernels in older enterprise distributions, in particular, will not have IP6tables support for things like connection tracking. A kernel or distribution upgrade is definitely necessary here.

When you write the rules, make sure that ICMPv6 communication is allowed on the local IP addresses that the system autonomously generates (fe80::/​10) to ensure that neighbor solicitation and neighbor advertisement (a kind of IPv6 ARP) still work properly. Without ICMPv6, there can be no IPv6 data traffic. It is important for the firewall setup on the Linux server that the server accept the router advertisements from the local address of the router (fe80::/​10). The router sends the advertisements to an IPv6 multicast address (ff02::1).

You might find it useful to initially reject all incoming connections. After you have performed tests to make sure that the corresponding application configuration is okay, you can open the required ports on the firewall one by one. In particular, you should add an ACCEPT rule that classifies all the incoming connections from your lab machine’s source address as benevolent, before you add the reject rule. Otherwise you will not be able to use this machine to test your server’s IPv6 functionality.

Configuring an IPv6 Address

Once the firewall is in place, you can configure the IPv6 addresses on your Linux server. Although you could ask your provider to assign the IPv6 address using DHCPv6, this approach is not typical. You will probably need to configure the address yourself. However, this means that choosing an address is a conscious decision on your part. You can configure the address in the normal way using your distribution’s setup tool (which may even be GUI-based), or by modifying the configuration files in /etc.

The IPv6 default gateway is often an issue. Many networks use router advertisements that automatically assign the default gateway. Other providers require you to configure the gateway manually.

This setup is typically preferable on network segments where the network operator does not know whether all servers on the network segment will run without issues if router advertisements are distributed on the network segment once you add a gateway to the routing table. You can now try to ping the server to which you assigned an IPv6 address. Start with ping6 Defaultgateway; you can find the address by typing ip  6 route show if you are unsure (Figure 2).

Figure 2: ip -6 addr show and ip -6 route show parse the IPv6 configuration. To ping a local address in the fe80::/​64 range, specify the network interface because the network is available on all interfaces.

Then try a hostname with an AAAA (IPv6) record, such as ipv6.google.com. If one of these pings doesn’t work, check the server setup, including the default gateway and firewall configuration.

If you are unable to troubleshoot your network problems quickly, you can temporarily disable the IPv6 address. The Linux system will prefer IPv6 as soon as it has an IPv6 address and a gateway. If the stack isn’t working properly, the programs need to time out before they fall back and try IPv4, which can severely impair the usability of production systems.

The European IP coordination center, RIPE , offers a test page where you can test your dual-stack connectivity (Figure 3).

Figure 3: The Dual Stack Connectivity Chart offered by RIPE NCC [1] tells you if your IP configuration is okay and lists which major servers you can access.

The test shows you clearly, and in real time, whether you can access a number of dual-stack test servers. If all of this works, you can start to concentrate on the applications themselves.

First Connections

From now on, the released services on your server will be accessible externally via IPv6. The first application – if the firewall doesn’t object – is the typically correctly preconfigured SSH daemon. If your admin PC has native IPv6 access or you turn to a tunnel broker as a workaround, you can get started right away. If you run your own tunnel, you need to configure IPv6 forwarding and the firewall on the server to match. On the client PC, set the IPv6 default route to point to the IPv6 address of the server’s tunnel interface.

Apache with Dual Stack

In regard to the web server, if you have used an Apache standard configuration without virtual hosts thus far, typically no further settings are required. But, the situation is different if you work with virtual hosts. In this case, you need to look at the NameVirtualHost directive, which binds multiple virtual hosts to an IP address. The directive is suitable for IPv4 and IPv6 alike:

# Standard for IPv4
NameVirtualHost 85.214.7.192
# For an IPv6 address
NameVirtualHost [2a01:238:10b:3000::1]
# For all usable addresses
# incl. IPv4 and IPv6
NameVirtualHost *

Brackets are essential for the IPv6 addresses because NameVirtualHost expects a colon to separate the IP address and the port number, but the IPv6 addresses also use colons. Depending on how the virtual hosts are configured on Apache, you may need to create a duplicate of the VirtualHost sections. As a general rule, if the VirtualHost directive specifies a domain name, this is sufficient to reach the virtual host via IPv4 and IPv6 .

If the Apache configuration for virtual hosts is based on IP addresses, you need to have a section for each. You can copy the existing IPv4 configuration and replace the IPv4 addresses with IPv6 addresses in the copy (Listing 1). If multiple virtual hosts share an IP address, the corresponding NameVirtualHost entry is mandatory. If you use multiple VirtualHost entries, you might want to write errors to different error logfiles to speed the process of locating IPv6-related errors.

Listing 1: Multiple Virtual Hosts
01 
02     ServerName domain1.de
03     ServerAlias www.domain1.de
04 [...]
05 
06 
07     ServerName domain1.de
08     ServerAlias www.domain1.de
09 [...]
10 

Virtual Domains

If the IPv6 assignment means that you have at least a /64 IPv6 network, you can now assign a separate IPv6 address to each virtual host. After doing so, the virtual web servers no longer need to share IPv6 addresses and the NameVirtualHost is redundant. With this method, each virtual host can use its own SSL certificate. This approach is useful in practical terms if you do the same thing for IPv4, because the overwhelming majority of users will use IPv4 clients to surf your site. If you use multi-domain or wildcard certificates, you don’t need to worry. It will always assign the same SSL key and the same SSL certificate to the VirtualHost.

Testing the Web Server

The setup work is nearly done at this point. The next step is to configure the DNS name you created previously ipv6.Domainname.com as VirtualHost. The DocumentRoot should point to a directory in which you already have a content management system or static web content in place. This setup lets you test your web application for IPv6 capability on the fly.

To check the web server’s IPv6 capabilities, you can surf to http://ipv6.Domainname.com in your client’s browser. You should see the web content that you put in DocumentRoot. Because DNS only has one IPv6 address for ipv6.Domainname.com, this can only be an IPv6 TCP/​IP connection.

If you use a failover setup that relies on heartbeats or some other method, you’ll need to look for one IPv6-specific quirk: experience shows that a short time can elapse on a Linux system before an Apache server binds to a previously configured IPv6 address. If needed, add a short wait to your heartbeat scripts. A wait of just a few seconds will be sufficient to allow your Apache to bind to the IPv6 address.

The dual-stack Apache, which is now correctly configured, shouldn’t cause you any trouble. Web statistics, as gathered by Webalizer, for example (Figure 4), will not typically worry about the IPv6 addresses.

Figure 4: Apache logfile tools like Webalizer are not typically fazed by interpreting IPv6 connections and will work in dual-stack mode without complaint.

The Mail Server in Dual Stack Mode

You will probably want to get your mail server ready for the new Internet, too. Be prepared for the typical issues in representing the IPv6 addresses in the configuration file. Exim, which I will use as an example in this article, uses a colon to separate IP addresses in its configuration. That means you need to define a different separator – the new separator follows the option with the angled brackets:

hostlist relay_from_hosts = <; 85.214.7.0/24; 2a01:238:10b::/56

If you are configuring multiple IPv6 addresses at the same time on a system, you must define which service uses which IPv6 address. For Exim, you can define the configured IPv6 address that the mail server uses for outgoing connections in the corresponding SMTP transport. Again, you need to use a different separator for the IPv6 addresses:

driver = smtp
interface = <; 85.214.7.192;2a01:238:10b:3310::11

Without the explicitly defined IP address for outgoing connections (IPv4/IPv6), the kernel will choose one of the existing IP addresses for outgoing connections – typically, the last configured IP. A static configuration is preferable if you assign specific IP addresses to specific services, or if you want to use a specific IP address for external communication.

ACLs, Graylisting, Proxies

ACLs that define which IP networks accept mails without authentication (relaying) or that refuse mail are common pitfalls. Add your own IPv6 network to the relaying settings first, to make sure messages that reach the system via IPv6 get through. If you implemented graylisting with a MySQL back end in your mail configuration, make sure the fields are long enough for the IPv6 addresses.

Again, test everything related to IPv6. To do so, set up the IPv6 address, or the IPv6 test host name temporarily as your mail server in your mail client. If this doesn’t work, check the mail server configuration and the client.

Many proxy daemons such as anti-virus or PGP encryption are not IPv6 compatible. You might want to disable the proxy services while you experiment. A permanent solution is a static IPv4 address on the mail client, or you could create a particular hostname such as ipv4.mail.Domainname.com with the suitable IPv4 addresses only.

Joining Forces

After completing these tests, the plan is to enable the host and domain names for parallel IPv4 and IPv6 support.

To do so, add suitable AAAA records to the corresponding DNS settings for IPv6 in your DNS. Choose a very low TTL for the DNS record, if possible. Doing so will help you quickly disable the IPv6 address without the DNS cache keeping the last status for too long.

After adding IPv6 records to your DNS settings, you can try out the new names. Before you do, however, restart the Apache service, especially if you use DNS-based virtual hosts. If everything works, change the DNS reverse records to the correct names and remove the test domain ipv6.Domainname.com.

Enforcing IPv4 Where Necessary

In some cases, you need to force clients to keep using IPv4 to access a service. You will typically need to do so if the application isn’t configured for IPv6, or just isn’t compatible. To allow this to happen, add the following rule on your firewall:

ip6tables -A INPUT -j REJECT -p tcp-dport 25 --reject-with tcp-reset

This setup acknowledges IPv6 connections to the SMTP port 25 with a TCP reset, thus forcing a failback to IPv4 if the domain name is defined as an IPv4 and an IPv6 address.

If you just configured a drop or reject on the firewall, the client application might have some difficulty, and the responses from the server might be delayed. n

The Author

Michael Prohm is the head of development and administration in the dedicated and virtual server division of Strato AG.