Do you know? It seems to me that one of the obstacles which bar the development of the Internet as a real distributed network are the objections that access providers pose to offering public, static IP addresses to their home clients, who must deal with dynamic addresses, private networks and NAT. A pity, since making everyone's machines reachable via the Internet would allow anyone to offer their own services, empowering individuals and levelling their position against big content providers, as it happens right now in free (as in freedom), neutral networks like guifi.net. In contrast with mass media, the Internet doesn't tell emitters apart from receivers.
IPv4 address scarcity is a (very debatable) reason wielded by providers for keeping the current statu quo. IPv6, for a change, offers real address abundance for everyone and, though it may seem, it's already usable whatever our way of accessing the Internet is. Moreover, connecting to the Internet of the future is quite fun, so let's jump in!
To move one step at a time, this article describes how to provide a stable IPv6 connection to a Debian machine having a fixed IPv4 address, using 6to4, with no need for a tunnel broker subscription and performing a really minimal configuration.
6to4 configuration
In the first place, we need to make sure
that we already have access to a 6to4 router
through the anycast address 192.88.99.1
:
$ ping -c 4 192.88.99.1 PING 192.88.99.1 (192.88.99.1) 56(84) bytes of data. 64 bytes from 192.88.99.1: icmp_seq=1 ttl=249 time=2.00 ms 64 bytes from 192.88.99.1: icmp_seq=2 ttl=249 time=2.09 ms 64 bytes from 192.88.99.1: icmp_seq=3 ttl=249 time=1.85 ms 64 bytes from 192.88.99.1: icmp_seq=4 ttl=249 time=2.04 ms --- 192.88.99.1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3000ms rtt min/avg/max/mdev = 1.854/1.996/2.091/0.099 ms
We can also run mtr 192.88.99.1
to
check how far away the router is.
Of course, the nearer the better.
To create a 6to4 configuration for the machine's IPv4 public address,
the simplest way is to use the IPv6 6to4 config generator for Debian.
For instance, running the generator on the IPv4 address 1.2.3.4
we'd get the following fragment:
# IPv6 using a 6to4 tunnel to the internet (from 1.2.3.4) # Generated at http://debian6to4.gielen.name/ auto tun6to4 iface tun6to4 inet6 v4tunnel pre-up modprobe ipv6 address 2002:0102:0304::1 netmask 16 gateway ::192.88.99.1 endpoint any local 1.2.3.4 # If you have an IPv6-capable firewall (and you really should have one), # it can be enabled by using an "up" rule, such as the example below. # up /usr/local/sbin/ipv6firewall.sh tun6to4
We simply include the previous fragment in /etc/network/interfaces
and bring the interface up with:
# ifup tun6to4
We can check the new IPv6 address by pinging some machine in the IPv6 network, for instance:
# ping6 -I tun6to4 -c 4 www.whatismyv6.com PING www.whatismyv6.com(www.whatismyv6.com) from 2002:102:304::1 tun6to4: 56 data bytes 64 bytes from www.whatismyv6.com: icmp_seq=1 ttl=59 time=9.10 ms 64 bytes from www.whatismyv6.com: icmp_seq=2 ttl=59 time=10.3 ms 64 bytes from www.whatismyv6.com: icmp_seq=3 ttl=59 time=10.3 ms 64 bytes from www.whatismyv6.com: icmp_seq=4 ttl=59 time=10.1 ms --- www.whatismyv6.com ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3005ms rtt min/avg/max/mdev = 9.107/9.980/10.333/0.518 ms
If this didn't work and the machine runs a firewall, we may need to tell it to let IPv4 packets with protocol IPv6 pass, with the following command or the equivalent one in our firewall configuration system:
# iptables -t filter -A INPUT -p ipv6 -j ACCEPT
Once pings work, we can
check web access via IPv6.
The simplest way to do it is visiting www.whatismyv6.com
using w3m:
$ w3m -6 www.whatismyv6.com
If the page displays an IPv6 source address, we're done. Yes, really, that's it. Welcome to the wonderful world of IPv6!
Additional addresses
Well, we already have our IPv6 address,
but we really have much more than that:
6to4 allocates 216 subnets of 264 IPv6 addresses
(that's one quadrillion (1024) addresses, now that's total abundance!)
for each IPv4 address
to let us build our own IPv6 network.
Moreover, assigning additional IPv6 addresses to our machine
is as easy as adding one up
and one down
option
per extra address to the previous tun6to4
configuration block.
For instance:
up ip -6 addr add 2002:0102:0304::2/16 dev $IFACE preferred_lft 0 down ip -6 addr del 2002:0102:0304::2/16 dev $IFACE
The option preferred_lft 0
avoids using the last added address
as the default source address for outgoing connections.
See this article
for a more detailed description of this mechanism
(thanks Axel!).
If our machine had several IPv4 public addresses,
we could add a similar tun6to4
block for each one of them.
However, a single one provides us with plenty of addresses,
and we thus simplify network configuration
while keeping things easier
if we later want to set up reverse name resolution.
If you want to know how to set up an IPv6 network behind your machine, please have a look at this section of Madduck's guide to IPv6.
Firewall configuration
Now that the machine is publicly accessible via IPv6,
it's recommended to set up a firewall with ip6tables
(e.g. using local-iptables
).
Rules should be similar to IPv4 ones.
For instance, to allow local traffic,
incoming SSH and SMTP connections,
and outgoing connections:
# ip6tables -t filter -N in-new # ip6tables -t filter -A INPUT -i lo -j ACCEPT # ip6tables -t filter -A INPUT -p ipv6-icmp -j ACCEPT # ip6tables -t filter -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # ip6tables -t filter -A INPUT -m state --state INVALID -j DROP # ip6tables -t filter -A INPUT -m state --state NEW -j in-new # ip6tables -t filter -A in-new -p tcp -m tcp ! --syn -j RETURN # ip6tables -t filter -A in-new -p tcp -m tcp --dport 22 -j ACCEPT # ip6tables -t filter -A in-new -p tcp -m tcp --dport 25 -j ACCEPT # ip6tables -t filter -A INPUT -m limit --limit 3/min --limit-burst 10 \ -j LOG --log-prefix "[INPUT6]: " # ip6tables -t filter -A INPUT -j REJECT
Versions prior to 2.6.20 of the Linux kernel fail to handle connection tracking properly. The following configuration is similar to the previous one, but doesn't take connection state into consideration (unfortunately, it neither allows UDP traffic over IPv6 without explicit rules):
# ip6tables -t filter -A INPUT -i lo -j ACCEPT # ip6tables -t filter -A INPUT -p ipv6-icmp -j ACCEPT # ip6tables -t filter -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT # ip6tables -t filter -A INPUT -p tcp -m tcp --dport 25 -j ACCEPT # ip6tables -t filter -A INPUT -p tcp -m tcp --dport 1024:65535 \ ! --syn -j ACCEPT # ip6tables -t filter -A INPUT -m limit --limit 3/min --limit-burst 10 \ -j LOG --log-prefix "[INPUT6]: " # ip6tables -t filter -A INPUT -j REJECT
Name resolution
IPv6 addresses are hard-to-remember, lengthy numbers.
If we want to associate names to addresses using DNS,
we'll have to include new AAAA
-type entries
in the proper name servers.
In the previous example, the following entry would assign
the name test6to4
to the IPv6 address:
test6to4 IN AAAA 2002:102:304::1
Once the changes to DNS are done,
we can use dig
(dnsutils
package) to
check that direct resolution works as expected in our DNS server.
In our example:
$ dig -t AAAA test6to4.example.net @SERVIDOR_DE_DNS +short 2002:102:304::1
If we want reverse resolution to work, we'll have to suffer a little more, since we need a DNS server where we can create new domains, and we need to request that the resolution of IPv6 addresses starting with the prefix associated with our IPv4 address is delegated to us. Fortunately, this last step is automatic.
Here we're trying to make the IPv6 address in our example, which is fully written as:
2002:0102:0304:0000:0000:0000:0000:0001
or in DNS terms (take breath):
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.4.0.3.0.2.0.1.0.2.0.0.2.ip6.arpa
(that is, the complete address reversed, with dot-separated digits)
be resolved to a name like test6to4.example.net
.
We'll start by visiting 6to4.nro.net
using IPv6
from the very machine we're configuring:
$ w3m -6 http://6to4.nro.net/
The domain displayed as reverse will be
the one that we'll create in our DNS server
(its installation and configuration is left as an exercise to the reader,
but this page can be useful).
In our example, the reverse domain would be 4.0.3.0.2.0.1.0.2.0.0.2.ip6.arpa
,
and the full zone file would be similar to this one:
@ IN SOA 4.0.3.0.2.0.1.0.2.0.0.2.ip6.arpa. hostmaster.example.net. ( 2009122102 ; Serial number (YYYYMMDDnn) 3h ; Refresh time 1h ; Retry time 7d ; Expire time 3h ; Default TTL ) ; Nameservers IN NS ns1.example.net. IN NS ns2.example.net. ; IPv6 pointers $ORIGIN 4.0.3.0.2.0.1.0.2.0.0.2.ip6.arpa. 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR test6to4.example.net.
Once the changes to DNS are done,
we use dig
(dnsutils
package) to
check that reverse resolution works as expected on our DNS server.
In our example:
$ dig -x 2002:102:304::1 @DNS_SERVER +short test6to4.example.net.
To end it all, we shall request delegation by visiting 6to4.nro.net
using IPv6 from the very machine we're configuring:
$ w3m -6 http://6to4.nro.net/
We enter into the form the administrator's e-mail address (hostmaster@example.net
)
and the names of at least two name servers (ns1.example.net
and ns2.example.net
) for the reverse domain,
a password to keep anyone in our machine from changing the data,
and press Submit
.
That's it.
When changes in DNS have propagated (which may take hours),
you should see the right reverse resolution
e.g. in the output of ping6
(between parenthesis):
$ ping6 -c 4 test6to4.example.net PING test6to4.example.net(test6to4.example.net) 56 data bytes 64 bytes from 2002:102:304::1 icmp_seq=1 ttl=64 time=0.033 ms 64 bytes from 2002:102:304::1 icmp_seq=2 ttl=64 time=0.053 ms 64 bytes from 2002:102:304::1 icmp_seq=3 ttl=64 time=0.052 ms 64 bytes from 2002:102:304::1 icmp_seq=4 ttl=64 time=0.049 ms --- test6to4.example.net ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 2999ms rtt min/avg/max/mdev = 0.033/0.046/0.053/0.011 ms
More, more, more!
Now that we know how to equip our server with a fully fledged IPv6 connection, it'd be nice to set up our home computer to access the Internet via IPv6. In some future post I'll describe how to give IPv6 connectivity to a machine behind a NAT-performing router with almost no headaches, using Teredo. However, this provides a temporary IPv6 address which may change to the will of our access provider or router.
So, the next step would be to configure our home network to form an IPv6 network which is fully accessible from the outside, e.g. usingSixXS tunnel broker. Fortunately, our pal Madduck has already described the full procedure with full detail in his page about IPv6 with Debian. There's even a howto on setting up an IPv6 tunnel and network using OpenWRT, though there seem to be some problems with processor overload. I'll tell you if I make up my mind.
See you on the next IPv6 trip!