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. |