Cover V14, i11
nov2005.tar

An IPv6-to-IPv4 Web Proxy

Matt Ganis

As new technologies get introduced to the Internet, the rate of adoption seems to be tied to the ease at which they can be implemented. This seems to be the case with IP version 6, the next generation of the Internet Protocol. This article will attempt to help ease the transition to IPv6 by showing how to attach to the version 6 network and provide access to your company's existing Web site via a simple IPv6-to-IPv4 proxy. Using industry-standard tunneling, "free" IPv6 tunnel brokers, and the power of Linux, I will show how a company can easily have its Web site accessible on the traditional IPv4 network as well as the IPv6 network. The net result is a low-cost method for creating a presence on this new networking standard.

Background

Last summer, I was asked to enable our Web site for IPv6 access. I spent several days looking at solutions ranging from obtaining direct IPv6 routing so I could run a dual-stack machine supporting both traditional IPv4 and IPv6, to duplicating our Web site (hardware and software) and running two separate (yet identical) sites. Neither of these options was appealing from a cost perspective or a Web site maintenance perspective.

I chose a fairly simple solution, which was to build a proxy from the IPv6 network to the IPv4 site. Users connecting to the IPv6 site would have their pages served via a proxy to the original IPv4 site (see Figure 1). Although I would have to install one new piece of hardware for the proxy, I could serve two sites from one source (albeit from different locations). The problem then became where to find a cheap, reliable IPv6-to-IPv4 Web proxy, and the answer was simple -- use Linux!

IPv6 Connectivity

IPv6 is a new generation of the Internet Protocol that is beginning to be adopted by the Internet community. The most visible difference between today's commonly used version of IP (IPv4) and IPv6 is the larger address space supported by IPv6. The new protocol supports 128-bit Internet addresses, compared to the 32-bit Internet address supported by IP version 4. Thus, IPv6 is especially well suited for the next wave of Internet devices, such as mobile phones and appliances with potential addresses numbering in the trillions!

There are several ways to obtain connectivity to the IPv6 network. I chose a tunnel broker for my connectivity, but let's look at some other options as well. The most expensive solution is to route IPv6 traffic natively to the IPv6 Internet -- in other words, route the TCP/IP traffic just like you do today. This requires a new IPv6 router as well as additional connectivity with an ISP that actually routes native traffic. This is actually a good solution from the perspective that your IPv6 network and traffic can be kept separate from each other (important when you're just experimenting), but a poor solution from a cost perspective.

Most connectivity for IPv6 is done by IPv6-over-IPv4 tunneling. In this method, the existing IPv4 network is used to exchange IPv6 packets. To use IPv6-over-IPv4 tunneling, your site or hosting center will need to support an IPv4/IPv6 dual router that supports IPv6-over-IPv4 tunneling. The IPv6 packets from your network are encapsulated in IPv4 packets at your outbound router; the tunnel is terminated at your ISP where the packets are sent to the IPv6 Internet. This requires that your router support 6-to-4 translation. Vendors like Cisco already have this support, but, since this was an experimental activity, production hosting teams are cautious about configuring this kind of support into routers.

The 6-to-4 approach was designed to allow isolated IPv6 sites (more than one host) to easily connect to each other without having to wait for native IPv6 support from their ISP. The tunnel broker is designed for small, isolated IPv6 sites or hosts that are on the IPv4 network yet require access to the IPv6 network. There are several "for free" IPv6 tunnel brokers in the Internet including Hurricane Electric, SixXS, and BTExact. By far the easiest and most reliable tunnel broker I found was BTExact at:

https://tb.ipv6.btexact.com/
Note, I am not affiliated with BTExact; I just liked their service.

Tunneling

Tunneling one protocol inside another is not a new phenomenon on the Internet. In this case, we simply define the IPv4 tunnel endpoints (my server is one end and the tunnel broker is the other), and all IPv6 traffic that is sent to or from my machine travels the regular Internet with the IPv6 packets stuffed inside of an IPv4 packet (see Figure 2).

Once registered with your tunnel broker of choice, it's time to set up your tunnel. In the case of BTexact, they will conveniently send you a script to run to configure your tunnel endpoint. Currently, they support script generation for Linux, Solaris, Cisco, FreeBSD, and Windows.

To check whether your server is enabled for IPv6, you can either:

cat /proc/net/if_inet6
or issue:

/sbin/ifconfig -a
and you should have devices sit0 and sit1 defined. SIT stands for Simple Internet Transition and will define the IPv6 tunnel for your server. If you don't see any sitx devices defined, try running modprobe ipv6 to load the kernel support.

Here's an example of the script I use to enable my tunnel (courtesy of BTexact), which I call from /etc/rc.d/rc3.d/S99local at startup:

#!/bin/sh
if ! [ -f /proc/net/if_inet6 ]
then echo "IPv6 is not installed!" 1>&2; exit 1; fi
ifconfig sit0 up \
&& ifconfig sit0 inet6 tunnel ::213.121.24.85 \
&& ifconfig sit1 inet6 add 2001:618:400::cc92:e045/128 \
&& route -A inet6 add ::/0 gw fe80::d579:1855 dev sit1 \
&& echo "IPv6 configuration completed" || \
{ echo "IPv6 configuration failed!" 1>&2; exit 1; }
The address 213.121.24.85 is the IP address of the tunnel server at BTexact, and the IPv6 address of my server is 2001:618:400::cc92:e045. Note that for tunneling you need to allow IP packets that specify a protocol number of 41 through your firewall destined to the IP address of your tunnel endpoint. Remember this is not a port; it's a protocol number (like 6 for TCP or 17 for UDP). Refer to /etc/protocols for a complete list.

To test the newly defined tunnel, try to ping a remote host with the ping6 command:

[root@sixgun root]# ping6 -n www.kame.net

PING www.kame.net(2001:200:0:8002:203:47ff:fea5:3085) 56 data bytes
64 bytes from 2001:200:0:8002:203:47ff:fea5:3085: icmp_seq=1 \
  ttl=54 time=483 ms
64 bytes from 2001:200:0:8002:203:47ff:fea5:3085: icmp_seq=2 \
  ttl=54 time=483 ms
64 bytes from 2001:200:0:8002:203:47ff:fea5:3085: icmp_seq=3 \
  ttl=54 time=483 ms
Note that certain commands for IPv6 use have the 6 appended to them (i.e., ping6 or traceroute6); others like netstat require you to specify additional parameters. For example, to see your routing table, use:

netstat -rn -A inet6
To check your server from another node in the network, check out the site:

http://www.ipv6tools.com/
where you can interactively ping or traceroute to your site.

Setting up a DNS record on the site is straightforward (and doesn't necessarily require IPv6 on the server). I created a new test subdomain for this effort called ipv6-test.ibm.com and then defined a record for www like so:

www     IN      AAAA    2001:618:400::cc92:e045
Configuring the Web Proxy

Once the server is operational as an IPv6 node, it's time to configure the Web proxy. I used Apache2 for my proxy (for reasons I'll describe a bit later). Building Apache2 is relatively simple. To run a proxy, you must enable the mod_proxy module in your server. After untarring the source, I ran the configure command with the following parameters (in this case, I wanted all of the modules built into my httpd so I could easily configure new features). I'm not sure why I had to specify --enable-proxy to build mod_proxy when I specified --enable-modules=all, but it didn't work unless I did:

./configure --enable-proxy --enable-modules=all
In your httpd.conf, you need to add or modify the following directives:

# Listen on Port 80 for IPv6
Listen [::]:80 

ExtFilterDefine fixtext-ipv6 mode=output intype=text/html \
  cmd="/bin/sed s/www.ibm.com/www.ipv6-test.ibm.com/g"
SetOutputFilter fixtext-ipv6
#
#
ProxyPass        /  http://www.ibm.com/
ProxyPassReverse /  http://www.ibm.com/
The Listen, ProxyPass, and ProxyPassReverse are also relatively straightforward. The ProxyPass directive allows a remote server to be mapped into the space of the local server; the local server does not act as a proxy in the conventional sense, but appears to be a mirror of the remote server (in this case, it appears to be a mirror of http://www.ibm.com). The ProxyPassReverse directive lets Apache adjust the URL in the Location header on HTTP redirect responses. This is essential when Apache is used as a reverse proxy to avoid bypassing the reverse proxy due to HTTP redirects on the backend servers.

The ExtFilterDefine and setOutputFilter are interesting (and important) for the operation of this proxy. The SetOutputFilter directive sets the filters (defined by ExtFilterDefine) that will process responses from the server before they are returned to the client. The ExtFilterDefine directive defines the characteristics of an external filter, including the program to run and its arguments. In this case, I apply the simple sed command (to change all occurrences of www.ibm.com to www.ipv6-test.ibm.com) for any page accessed by the proxy before it's returned to the client. By doing this, I change all links on the page to point not to the original IPv4 site but to the IPv6 proxy instead (see Figure 3).

To test your Web site proxy, you need a browser that is IPv6 capable. To be honest, I've lost track of which browsers do and don't support IPv6, but I use Opera on Linux, which works quite well. If you don't have a DNS entry setup, you can specify the IP address. Note, however, that it's not like IPv4; you have to include the host address in square brackets, like so:

http://[ 2001:618:400::cc92:e045]
Conclusion

This proxy has proved to be quite simple to set up and has provided us with an almost instant presence on the IPv6 networks. I'm not claiming that I would use this for heavy amounts of traffic, but for an experimental setup, it can't be beat.

Matt Ganis is a Senior Technical Staff Member at IBM where he is also part of the ibm.com webmaster team. In his spare time, he teaches astronomy and computer science at Pace University in Westchester, New York. He can be reached at: ganis@us.ibm.com.