- Register an account at go6.net. (There are several
ipv6 tunnel brokers out there that will give you a free ip or netblock,
but I chose to use go6.net and this Mini-HOWTO is based on that assumption.)
There was no rocket science in my choice for go6.net over, for example,
sixxs.net. It was simply the first one I stumbled upon when I Googled
for ipv6 broker. They all seem to be equal in terms of what they offer,
differing only slightly in how they go about offering it to you.
- Decide which machine is going to be the gateway machine. There are
some very specific requirements. First, it must have a fairly recent
kernel and iptables. At one location I'm using a Gentoo box with kernel 2.6.23 and
iptables 1.4.0. At another location I'm using a Mandriva box with kernel 2.6.22 and
iptables 1.3.7. It should also work with the latest Fedora Core
release, as well as the latest CentOS 5 or RedHat EL 5 release. This
machine will need to have ipv6 support enabled and ipv6
autoconfiguration enabled. In the case of my Ubuntu box, this results
in an eth0 interface that looks like this:
# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:90:27:E0:0A:00
inet addr:192.168.0.50 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::290:27ff:fee0:a00/64 Scope:Link
The "Scope:Link" address is an automatically generated ipv6 address that
is designed to work ONLY on the local LAN. (network fe80::/16) Step 14
shows what the ethernet IPs will look like once this procedure is
finished.
- Install the radvd package. For Gentoo, 'emerge radvd'. For CentOS,
configure and enable the DAG repo and 'yum install radvd'. For Mandriva, it takes
a few extra steps.
Mandriva:
useradd radvd
mkdir /var/run/radvd
chown radvd:radvd /var/run/radvd
- Download the source for gw6c from go6.net (aka freenet6.net). At the
time of this writing (Jan 2008), the current version of gw6c is 5.1.
gw6c is an abbreviation for Gateway 6 Client, the name of the software
we'll be using. Gentoo users can 'emerge freenet6' if you choose, but
you'll have to know where your config files are because they'll be
different than what I describe here.
- When you extract gw6c tarball, it will extract into the current
directory, so force it to extract into a subdirectory to keep the
current directory clean:
mkdir gw6c
tar -zxvf gw6c*tar.gz -C gw6c/
- Compile and install the source:
cd gw6c/tspc-advanced
make target=linux
make target=linux install installdir=/usr/local/gw6c
- Get the configuration in a place suitable for configs:
cd /usr/local/gw6c
mkdir logs
mkdir etc
mv bin/gw6c.conf* etc/
- Edit the configuration. Leave the defaults unchanged except for:
userid -> the user you registered at go6.net
passwd -> and the password for that user
server=broker.freenet6.net
auth_method=any
host_type=router
if_prefix -> the ethernet interface facing your local LAN
log_file=2
log_filename=/usr/local/gw6c/logs/gw6c.log
- Create an init script for the gw6c service in /etc/init.d/gw6c or use
one of the following init scripts (current as of Jan 2008). These init
scripts take into account that the radvd service will be started by
gw6c, and shuts it down. You do *NOT* want to start the radvd service
from the init script nor at boot time automatically. The gw6c will
handle starting radvd if you have gw6c configured to get a network
(instead of a single IP) from go6.net.
- Enable the service to start at boot.
RedHat/CentOS and Mandriva:
chkconfig gw6c --add
chkconfig gw6c on # should be on by default, but just in case
chkconfig radvd off # again, just in case
Gentoo:
# Assuming "default" is your default boot category
rc-update add gw6c default
- Configure the machine to forward packets across interfaces:
echo "net.ipv6.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
- At this point, you can start the gw6c service and test to see if it
works. If it doesn't start properly, the next step discusses a couple of things to
check. But how do you know if it works?
a. Starting says OK:
/etc/init.d/gw6c start
If it doesn't say OK, then go look in /usr/local/gw6c/logs/gw6c.log and read the
next step.
b. There is a process running named gw6c.
c. There is a process running named radvd (if host_type=router).
d. There is a new ivp6 address on your ethernet interfaces, such as:
ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:90:27:E0:0A:00
inet addr:192.168.0.50 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: 2001:9999:8888::1/64 Scope:Global
inet6 addr: fe80::290:27ff:fee0:a00/64 Scope:Link
Note the new address with the 2001::/16 prefix. That is the new
ipv6 address that has been automatically created on the
interface using the 2001:9999:8888::/64 network which was
assigned to us by the gw6c client. Per convention, 2001:9999:8888::/64
is shorthand for 2001:9999:8888:0000::/64. Additionally, much
like an ipv4 network where people typically put 192.168.0.1 as
the default gateway for the 192.168.0.0/24 network, the gw6c
client automatically assigns 2001:9999:8888::1/128 to the gateway
interface (if_prefix=eth0). I have not seen this convention in
any RFC, but this is the way gw6c does it.
- If you configured your machine as 'host_type=router', then gw6c
did a second step for you as it started. It created a temporary config file for radvd
at /usr/local/gw6c/radvd-gw6c.cfg. If for some reason it cannot start radvd, then the
gw6c startup will fail. So if gw6c fails to start, one of the things to check is if
radvd has some kind of error condition that causes it to fail its startup. In my
tests where radvd failed to start, gw6c logged a message saying that it started up ok
and assigned an ip, but then radvd logged an error (at that point both daemons died
with no further logging). What's misleading is the init script said that it started ok.
You must pay attention to the previous step for the sequence to verify that everything
started up properly.
- Test the connection by pinging some known good ipv6 site.
ping6 www.mrball.net
PING www.mrball.net(2001:5c0:8fff:fffe::7a55) 56 data bytes
64 bytes from 2001:5c0:8fff:fffe::7a55: icmp_seq=1 ttl=62 time=192 ms
64 bytes from 2001:5c0:8fff:fffe::7a55: icmp_seq=2 ttl=62 time=218 ms
- Turn off the service because currently it's not firewalled and
anybody can ping/ssh to your machine, even if you're behind an ipv6 NAT
gateway. Why? Because you're tunnelling to go6.net and getting
globally reachable IP addresses. The next step will take care of that.
/etc/init.d/gw6c stop
- Make sure you have ipv6 iptables support, called ip6tables.
CentOS/RedHat:
yum install iptables-ipv6
Mandriva:
urpmi iptables-ipv6
Gentoo:
vi /etc/make.conf # make sure that you have ipv6 in USE flags
emerge iptables # will build ipv6 support in
# Make sure you have required kernel modules enabled. You can
# either compile as a loadable module or into the kernel, your
# choice. The following are required:
# CONFIG_TUN
# CONFIG_INET_TUNNEL
# CONFIG_IPV6
# CONFIG_IPV6_PRIVACY
# CONFIG_IPV6_SIT (used if you're not behind a NAT)
# CONFIG_NETFILTER
# CONFIG_NETFILTER_XTABLES
# CONFIG_NETFILTER_XT_MATCH_STATE
# CONFIG_NF_CONNTRACK_IPV6
# CONFIG_IP6_NF_IPTABLES
# CONFIG_IP6_NF_MATCH_OPTS
# CONFIG_IP6_NF_FILTER
# CONFIG_IP6_NF_TARGET_REJECT
# CONFIG_IP6_NF_TARGET_LOG
# I hope I didn't miss any.
# On my Gentoo box, I made everything ipv6 related a module, and
# ended up loading these for proper operation:
lsmod
Module Size Used by
tun 8096 1
ip6t_REJECT 4064 1
nf_conntrack_ipv6 14780 2
xt_state 1888 2
nf_conntrack 50376 2 nf_conntrack_ipv6,xt_state
ip6table_filter 2016 1
ip6_tables 11148 1 ip6table_filter
x_tables 11332 3 ip6t_REJECT,xt_state,ip6_tables
ipv6 242724 16 ip6t_REJECT,nf_conntrack_ipv6
- Set up a simple firewall for ipv6. For CentOS/RedHat and Mandriva
the following will be in /etc/sysconfig/iptables. For Gentoo, the following will be in
/var/lib/ip6tables/rules-save:
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:IPV6-INPUT - [0:0]
[0:0] -A INPUT -j IPV6-INPUT
[0:0] -A FORWARD -j IPV6-INPUT
[0:0] -A IPV6-INPUT -i lo -j ACCEPT
# [0:0] -A IPV6-INPUT -p ipv6-icmp -j ACCEPT
[0:0] -A IPV6-INPUT -p esp -j ACCEPT
[0:0] -A IPV6-INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# The following line uses my internal LAN facing interface
[0:0] -A IPV6-INPUT -i eth0 -m state --state NEW -j ACCEPT
[0:0] -A IPV6-INPUT -j REJECT --reject-with icmp6-adm-prohibited
COMMIT
You can uncomment the line with ipv6-icmp if you choose. This line
allows all ping6 and tracepath6/traceroute6 tests to work both inbound
and outbound. If commented, ping6 and tracepath6/traceroute6 only work
from the inside. PAY ATTENTION: People can ping your
internal hosts from the outside with that line enabled. They can't ssh
or browse to it, but they'll be able to ping it, so they will know
things like when employees are at work (when not to try to break in to
some machine or when they're not at home) and other social engineering
type things like that.
WARNING: IPv6 stateful filtering was broken until kernel 2.6.20. CentOS 5
uses 2.6.18, so the --state rules above won't work.
- Load the firewall with:
/etc/init.d/ip6tables start
- Look at the firewall rules to make sure it loaded properly:
# ip6tables --list -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
IPV6-INPUT all ::/0 ::/0
Chain FORWARD (policy ACCEPT)
target prot opt source destination
IPV6-INPUT all ::/0 ::/0
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain IPV6-INPUT (2 references)
target prot opt source destination
ACCEPT all ::/0 ::/0
ACCEPT icmpv6 ::/0 ::/0
ACCEPT esp ::/0 ::/0
ACCEPT all ::/0 ::/0 state RELATED,ESTABLISHED
ACCEPT all ::/0 ::/0 state NEW
REJECT all ::/0 ::/0 reject-with icmp6-adm-prohibited
- Now start the gw6c process back up:
/etc/init.d/gw6c start
- Stateless autoconfiguration is the end goal of this
whole procedure. The gist of stateless autoconfiguration is that the
radvd process advertises a /64 network (the first 64 bits). The ipv6
enabled host will see this advertisement and the host generates the
last 64 bits of the host address. Here's how to make sure that your
host is ipv6 enabled.
CentOS: If you didn't specifically disable ipv6 during the installation
or at any time during the gui/ncurses configuration step, ipv6 should be
enabled. Here's how to check:
# in /etc/sysconfig/network
NETWORKING_IPV6=yes
# in /etc/sysconfig/network-scripts/ifcfg-eth0 (or whichever device needs to be ipv6 enabled)
IPV6INIT=yes
IPV6_AUTOCONF=yes
# IPV6_PRIVACY="rfc3041"
* For me, privacy extensions didn't work properly, but that may be because
the machine I was testing it on was a wifi card so init scripts didn't
quite work.
Mandriva: If you didn't specifically disable ipv6 during any part of the
gui/ncurses configuration step, ipv6 should be enabled.
- Go look at any host that has ipv6 and ipv6 autoconfiguration enabled
and look to see if it has created the new address:
~$ /sbin/ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:1D:09:76:F5:58
inet addr:192.168.0.166 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: 2001:9999:8888:0:21d:9ff:fe76:f558/64 Scope:Global
inet6 addr: fe80::21d:9ff:fe76:f558/64 Scope:Link
Again, this is stateless autoconfiguration at work.
Your server is advertising 2001:9999:8888::/64 as a valid network, but
where did the second 64 bits of address come from? (the
21d:9ff:fe76:f558 portion). It is automatically generated using what's
called EUI-64. It's based upon your 48 bit MAC address. Look at the
MAC above and compare to the last 64 bits of the ipv6 address you'll see
that it is very similar. The exact generation formula is described in
Appendix A of RFC 4291.
- Test to see if you can ping6 www.kame.net or some other known ipv6
site. It should all be working now.
ping6 www.mrball.net
PING www.mrball.net(2001:5c0:8fff:fffe::7a55) 56 data bytes
64 bytes from 2001:5c0:8fff:fffe::7a55: icmp_seq=1 ttl=62 time=192 ms
64 bytes from 2001:5c0:8fff:fffe::7a55: icmp_seq=2 ttl=62 time=218 ms
- Add a little bit of resiliency by making a quick
cronjob that will test if the daemon is still running and restart it
if it is not. Like any service which is tunnelled, occassional
disconnects happen and this is a simple way of correcting it. I
achieve this using this:
~$ crontab -l -u root | grep gw6c
0 * * * * /sbin/pidof gw6c >/dev/null || /etc/init.d/gw6c restart
- Test from somewhere outside and make sure that your
hosts are not reachable from the outside (several webbased ipv6
testers are available if you google for it). Note that if you allowed
icmpv6 in the firewall by uncommenting that icmpv6 line, you'll be able
to ping the host, but you won't be able to connect to anything via tcp
or udp. If you specifically blocked icmpv6 by leaving that line
commented, then you won't be able to ping the host either. In this
example, I allowed ping:
ping6 2001:9999:8888:0:21d:9ff:fe76:f558
PING 2001:9999:8888:0:21d:9ff:fe76:f558(2001:9999:8888:0:21d:9ff:fe76:f558) 56 data bytes
64 bytes from 2001:9999:8888:0:21d:9ff:fe76:f558: icmp_seq=1 ttl=62 time=188 ms
64 bytes from 2001:9999:8888:0:21d:9ff:fe76:f558: icmp_seq=2 ttl=62 time=186 ms
--- 2001:9999:8888:0:21d:9ff:fe76:f558 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 186.161/187.506/188.852/1.413 ms
telnet 2001:9999:8888:0:21d:9ff:fe76:f558 80
Trying 2001:9999:8888:0:21d:9ff:fe76:f558...
telnet: Unable to connect to remote host: Permission denied
- RFC's are technical documents that pertain to implementing things on
computers. The following page lists ipv6 specific RFC's:
http://wiki.go6.net/index.php?title=IPv6_Requests_for_Comment.
The ones of particular interest are:
Also interesting is 4193
if you choose to implement a local subnet that you manually create,
do dns for, and maintain (it can still generate automatically the
second 64 bits of space, same as is done here.) There is a webbased
form that will do the autogeneration of your own unique local subnet
that is supposed to be globally unique, but since it's not a routable
prefix, it is relatively safe (think 192.168.*.* or 10.*.*.* in the
ipv4 world but without NAT capability, you'd use your globally unique
public routable IP instead and rely on the firewall to keep anything
you don't want from penetrating to your box).
- I try to keep up with everything that's happening in the
ipv6 world. See what things I have been reading when it comes to ipv6 on my
Del.icio.us bookmark page.
Todd A. Lyons
Rev 2 - 2/26/2009
Rev 1 - 6/03/2008
Rev 0 - 1/24/2008