Martin F. Krafft: IPv6 with Debian
Even though I ve dealt with IPv6 for almost a decade,
have delivered presentations, and given multi-day courses on IPv6
security aspects, I ve never actually added IPv6 to my own
server/home network infrastructure because it seemed that Linux
and/or Debian just weren t ready for it. This seems to have changed
(although there are still a number of problems) and in less than a
day, I put a few of my machines online. In the following, I d like
to share with you how I did it.
Kernel versions and stateful connection tracking
Unfortunately, I have to start off with some bad news: even
though Debian etch, our current
stable release, which uses a Linux kernel version 2.6.18, speaks
IPv6, I cannot recommend it for deployment, as the 2.6.18 kernel
does
not support proper stateful connection tracking for IPv6, and
thus makes it impossible to firewall hosts in a sensible manner (I
always add local packet filters to all my hosts, and if only to
guard against the situation when a user installs a malicious
programme to listen on a high port). Of course, it is
possible to configure a packet filter statelessly in an acceptable
manner once you know the use case, so do with this information what
you wish; I prefer to stay general for now.
For me, a remedy is almost around the corner: the 2.6.24 kernel
seems to support stateful connection tracking for IPv6, and it s
even available for etch as it will be included in the upcoming
etch-and-a-half
release. I simply ended up using the kernel packages pre-release,
and so far have not had a problem with it.
To do so, add the following line to your
/etc/apt/sources.list, making sure to use a close
archive mirror:
deb http://ftp.xx.debian.org/debian etch-proposed-updates main
I then just upgraded the system and pulled in all proposed
updates. As that may have let in software that won t be part of
etch-and-a-half, or even lenny, you may want to pin the archive and
only upgrade the kernel packages, by adding to
/etc/apt/preferences (replacing amd64
with your architecture):
Package: *
Pin: release a=proposed-updates
Pin-Priority: -1
Package: linux-image-2.6.24-etchnhalf.1-amd64
Pin: release a=proposed-updates
Pin-Priority: 600
Alternatively, you could use the 2.6.24 linux kernel packages on
backports.org.
Xen and IPv6
One drawback of switching to 2.6.24 is that you cannot run a
dom0 on that machine any longer, so by practical
extension, you cannot connect it to the IPv6 network with a packet
filter in place. Supposedly, running 2.6.24 instances on a 2.6.18
dom0 is reported to work, however.
Configuring the packet filter
The first thing I did was to configure the packet filter on each
host appropriately. Unfortunately, this is harder than it should
be, because to quote one of the netfilter developers when ip6tables
was conceived, someone had a big bad brainfart : rather than adding
IPv6 rules to your existing iptables ruleset, you have
to create a new ruleset, duplicate all chains, networks, hosts, and
individual rules, and maintain the two in parallel. Even though
there are efforts of unification on the way, I speculate it ll take
another couple of years until PF_INET6 will be fused
into PF_INET and one will be able to do sensible
cross-address-family packet filtering with Linux. Since I ve
recently started to look (again) at pyroman, maybe the most
logical way forward would be to extend it to write both, IPv4 and
IPv6 rulesets from its knowledge about the hosts and networks you
configured.
Anyway, we want to get stuff working now! Thus, let s configure
ourselves a packet filter. (Almost) all IPv6-related filtering must
be configured via ip6tables (read on further down
about IPv6 in IPv4 tunneling, the reason I said almost ). The
following is a simple default ruleset to start with, which I put
into /etc/network/ip6tables to load with
ip6tables-restore:
*filter
:INPUT REJECT [0:0]
:FORWARD REJECT [0:0]
:OUTPUT ACCEPT [0:0]
:in-new - [0:0]
### INPUT chain
# allow all loopback traffic
-A INPUT -i lo -j ACCEPT
# RT0 processing is disabled since 2.6.20.9
#-A INPUT -m rt --rt-type 0 -j REJECT
# allow all ICMP traffic
-A INPUT -p icmpv6 -j ACCEPT
# packets belonging to an establish connection or related to one can pass
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# packets that are out-of-sequence are silently dropped
-A INPUT -m state --state INVALID -j DROP
# new connections unknown to the kernel are handled in a separate chain
-A INPUT -m state --state NEW -j in-new
# pass SYN packets for SSH
-A in-new -p tcp -m tcp --dport 22 --syn -j ACCEPT
# log everything else
-A INPUT -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[INPUT6]: "
### OUTPUT chain
# RT0 processing is disabled since 2.6.20.9
#-A OUTPUT -m rt --rt-type 0 -j REJECT
# allow outgoing traffic, explicitly (despite chain policy)
-A OUTPUT -j ACCEPT
### FORWARD chain
# RT0 processing is disabled since 2.6.20.9
#-A FORWARD -m rt --rt-type 0 -j REJECT
# disallow forwarded traffic, explicitly (despite chain policy)
-A FORWARD -j REJECT
COMMIT
Note that this recipe is pretty much unusable on pre-2.6.20
kernels due to their broken implementation of stateful connection
tracking.
The ruleset should be fairly obvious, but you might wonder about
my use of REJECT and allowing all ICMP after all, you ve
heard for the past 30 years that ICMP is a bad hacker
protocol , and Internet security is no domain for being nice to
people, so to prevent any information disclosure, you should
DROP connections, not let people know that they re
simply not allowed.
Well, to hell with all that! I don t see a single reason or
attack vector that is foiled by DROP or disallowing
ICMP. In fact, it s just security by obscurity, and
might inconvenient at the same time. ICMP is also much
more important with IPv6 than with IPv4 (it replaces ARP,
for instance), and it s actually useful to be able to
ping hosts, or get back informational messages on why
something failed. Finally, rejecting traffic rather than dropping
it doesn t suggest to a hacker that something s hidden here.
Then there is RFC
4890, which almost made
me puke. This document is part of the reason why I say: let s
fix problems in the kernel, rather than shielding them with
unreadable and unmanageable rulesets!
Getting connected
If you already have an IPv6 address, you re basically ready to
go, but may want to read further down on how to connect your local
network to the IPv6 Internet as well. If you are searching for a
provider, have a look at the list of
providers with native IPv6 connectivity over at sixxs.net.
If you are reading up to here, I assume you are connected to the
Net with IPv4. There are two ways for you to move towards IPv6:
6to4 or by way of a
tunnel provider. A Kiwi website explains how to setting up 6to4
connectivity, and thus I will concentrate only on the tunnel
approach. Even though everyone can set up
6to4 in a breeze without any accounts or waiting,
there are a number of security considerations,
it s pretty ugly to debug (due in part to asymmetric routing), and
makes your life unnecessarily difficult when all you have is a
dynamic IP that changes from time to time. If you are stuck behind
a NAT gateway, you cannot use 6to4 either. Thus, I
prefer the tunnel approach.
With the tunnel approach, IPv6 packets are wrapped up in IPv4
packets on your host, and sent to the IPv4 address of your tunnel
provider, who has native IPv6 connectivity. The tunnel provider
unwraps your packet and shoves the contained IPv6 packet onto the
backbone. The IPv6 address you used as source address is routed to
the tunnel provider, so any replies arrive at their machines, where
they re again wrapped into IPv4 packets and sent to your
(publicly-accessible) IPv4 address. Those IPv4 packets specify
payload type 41 ( ipv6 ), which is why we need those -p ipv6
-j ACCEPT rules in the iptables ruleset.
There are a few tunnel providers out there. I chose SixXS and have not regretted my choice. I
shall thus assume that you do the same: sign up for an account right
now, so that you have it by the time you finished reading this
document! SixXS works on a credit
system: tunnels and subnets cost credits, which you can
accumulate by maintaining your tunnels properly. This ensures that
everyone can play around, but to do more advanced stuff, you need
to first display competence with the basic concepts.
Your first step with SixXS will be to request a tunnel. SixXS
offers three types of tunnels:
- static tunnels, for those with static IPs,
- heartbeat tunnels, for those with dynamic IPs, and
- AYIYA tunnels,
for those behind NAT gateways.
Each of these tunnels have advantages and disadvantages, as
everything does: the first two types of tunnels use IP protocol 41
packets to encapsulate the IPv6 packets. As such, there are
security considerations involving the impersonation by spoofing,
and all upstream firewalls must let protocol 41 pass.
AYIYA addresses these problems by using signed
packets, but that solution comes with extra computation overhead
and smaller MTUs.
I suggest to use the first type of tunnel that fits your
situation. Debian s aiccu package can take care
of heartbeat and AYIYA tunnels for you, and it can
even set up static ones.
During registration, you will also need to choose a PoP , which
stands for Point of Presence . If your country only has a single
PoP, that s the one you will end up using (unless you have a good
reason for another one), but if there are more options, I strongly
suggest that you go through the list of PoPs and select the
one with the best roundtrip time and lowest latency from your
location! Note that you must answer ping requests
(ICMP echo-request) from the PoP you
chose, or else the tunnel will not be created.
Once your tunnel request gets approved, you ll get a
/64 prefix, in which you only use two addresses: the
PoP will configure the :1 address and you need to
configure your host to use the :2 address on the
tunnel interface. You ll also be told the IPv4 address of your PoP
endpoint .
Joey Hess taught me that aiccu can set up the
interface for you, using the data it queries from the SixXS
registration (TIC) server. I tried it, and it works. However, I
prefer the pure ifupdown approach, as it
makes things explicit and allows me to use the hooks for stuff like
loading the packet filter. So in my
/etc/network/interfaces, you can find:
auto sixxs
iface sixxs inet6 v4tunnel
endpoint 194.1.163.40
address 2001:41e0:ff00:3b::2
netmask 64
gateway 2001:41e0:ff00:3b::1
ttl 64
pre-up ip6tables-restore < /etc/network/ip6tables
up ip link set mtu 1480 dev $IFACE
up invoke-rc.d aiccu start
down invoke-rc.d aiccu stop
Make sure to read about MTU values of the
tunnel and adjust the 1480 value in the above to your tunnel
settings and ISP connectivity.
Also set ipv6_interface sixxs in
/etc/aiccu.conf, if you are using aiccu,
or else aiccu will bring up a duplicate/additional
interface. If you tell it to use the same interface, it will
actually execute all the same commands (which will fail), but won t
report any errors. A future version will have a switch to prevent
it from configuring the interface.
Unfortunately, this will probably not work. The reason is that
your regular IP packet filter (iptables, without the
6) doesn t let those encapsulating IPv4 packets pass, unless we
tell it to; we probably want to do this early on in the chain, and
also limit it to our tunnel peer, so:
iptables -I INPUT -p ipv6 -s 194.1.163.40/32 -j ACCEPT
For AYIYA, you need to open port 5072, either for UDP, TCP, or
SCTP, depending on how you configured it. Also have a look at this
FAQ
entry on what a firewall needs to pass. If it still doesn t
work, you have an upstream packet filter that needs some of those
holes poked. Good luck.
In most situations, the FORWARD chain does not get
such a rule, since the tunnel terminates at the gateway, which
routes to a native IPv6 network, or another tunnel. Allowing
tunnels through a gateway is almost always a bad thing, as it would
allow undetected and untraceable traffic from compromised boxes in
the local network. The OUTPUT chain also does not need
such a rule, if you have configured stateful filtering
properly.
Now bring up the interface and verify the connection:
# ifup sixxs
# ping6 -nc1 2001:41e0:ff00:3b::1
PING 2001:41e0:ff00:3b::1(2001:41e0:ff00:3b::1) 56 data bytes
64 bytes from 2001:41e0:ff00:3b::1: icmp_seq=1 ttl=64 time=74.0 ms
[...]
# ping6 -nc1 ipv6.aerasec.de
PING ipv6.aerasec.de(2001:a60:9002:1::184:1) 56 data bytes
64 bytes from 2001:a60:9002:1::184:1: icmp_seq=1 ttl=55 time=91.5 ms
[...]
Welcome to the Internet of the future!
Setting up an IPv6-capable gateway
Your IPv6 connection works, but it s limited to a single
address, and you do not get to specify the reverse DNS
PTR record for it. Since the concept of NAT is mostly
absent from IPv6 (thanks! thanks! thanks!), you will not be able to
connect any other hosts to the IPv6 network. If your local network
has a few hosts behind a gateway, you will need to request a subnet
from SixXS and configure your gateway (which has the tunnel
connection) appropriately. Don t worry, this is not really very
difficult.
First, request a subnet for your tunnel from your PoP via your
SixXS homepage. Once approved, you will get a /48
prefix for your own use: 2^80 1.2 heptillion addresses which are
yours to assign to every dust particle in your office or
home, if you so desire.
The way I set it up is to add the first of these addresses to
your internal interface on the gateway, by adding the following two
lines to the interface s stanza in
/etc/network/interfaces; you will need the iproute package installed
(which you should be using for everything network-related
anyway):
up ip -6 addr add 2001:41e0:ff12::1/64 dev $IFACE
down ip -6 addr del 2001:41e0:ff12::1/64 dev $IFACE
Instead of bringing the interface down and up, just run ip
-6 addr add 2001:41e0:ff12::1/64 dev eth0. Note the use of
the /64 prefix instead of the /48 that
got assigned, leaving only 20 pentillion addresses. Oh no! The
reason for this is buried in the specs: basically, /48
is a site prefix, but individual networks should not be larger than
/64, which is the prefix length of links in the IPv6
domain.
Now is also a good time to enable IPv6 forwarding, e.g. like
so:
# echo net.ipv6.conf.all.forwarding = 1 >> /etc/sysctl.conf
# sysctl -p /etc/sysctl.conf
Obviously, you will also need to change the policy on the
ip6tables FORWARD chain. For now, let s
just set it to accept. You should later create a proper ruleset,
though!
# ip6tables -I FORWARD -j ACCEPT
Bringing IPv6 to your local network
The final step is to spread the love to your local network.
Refrain from selecting addresses from your subnet and assigning
them to the local hosts, or wondering how to configure the DHCP server, because IPv6
does it differently: your gateway will advertise its routes (which
includes a default route) to your network, and each host will pick
an address based on its MAC address
(unless it already has an EUI-64 address
assigned. This all happens automagically, at least with current
Debian and Windows machines.
On the gateway, you need to install radvd and simply tell it
which prefix to use on which interface. My /etc/radvd
looks like this, and I won t explain it:
interface eth0
AdvSendAdvert on;
prefix 2001:41e0:ff12::/64
;
;
Note again how we advertise a /64 network rather
than the /48 we own . You cannot advertise smaller
networks if you want automatic configuration to work, and you
should not use networks larger than /64 in any case.
If 2^64 addresses are not enough for you, I trust you ll be able to
figure out how to advertise another of your 65536 /64
prefixes in the /48 subnet to appropriate hosts.
Restart radvd and run over to another host to
witness how it automagically gets connected to the IPv6 network by
scanning /var/log/kern.log and watching the output of
ip -6 addr and ip -6 route. Try
ping6ing from there! Find the dancing turtle! It should all work.
If you don t like the automagic aspect of this, look into
stateful configuration, using DHCPv6, as provided by
dibbler-server
and ?wide-dhcpv6-server.
Resolving names
Take note of the IPv6 address of each host. There s a way to
determine it given the host s MAC address, but this is easier
(ipv6calc is also
useful). You might want to let your local DNS server know by adding
AAAA records in parallel to the existing
A records, and possibly even adding PTR
entries.
If you re serious about IPv6, you can tell SixXS to delegate
reverse lookups for the IPv6 addresses to your DNS servers, but you
ought to refrain from polluting the DNS
namespace.
Note that bind9-host provides
an improved host tool, which fetches all kinds of
information about names, not just the one single information
configured as default:
% host pulse.madduck.net
pulse.madduck.net has address 130.60.75.74
pulse.madduck.net has IPv6 address 2001:41e0:ff1a::1
pulse.madduck.net mail is handled by 99 b.mx.madduck.net.
pulse.madduck.net mail is handled by 10 a.mx.madduck.net.
% host 2001:41e0:ff1a::1
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.a.1.f.f.0.e.1.4.1.0.0.2.ip6.arpa
domain name pointer pulse.madduck.net.
Oh, and if you re really that curious about how IPv6 addresses
are computed from MAC addresses, read RFC 2464. Basically,
given a prefix 2001:41e0:ff1a:: and a MAC address
aa:bb:cc:dd:ee:ff, the resulting IPv6 address is
obtained by:
- inserting
ff:fe into the middle of the MAC address
to yield aa:bb:cc:ff:fe:dd:ee:ff;
- flipping the second lowest bit of the first octet to yield
a8:bb:cc:ff:fe:dd:ee:ff;
- removing the odd colons to yield
a8bb:ccff:fedd:eeff, the EUI-64;
- concatenating the prefix and this result to get
2001:41e0:ff1a::a8bb:ccff:fedd:eeff.
If you find your (Windows) IPv6 addresses changing all the time,
you might be faced by privacy
features .
Remaining issues
Even though my IPv6 connectivity works, I have two remaining
issues.
Sending larger amounts of data to the network
I am experiencing a curious issue where outgoing ssh IPv6
connections time out and outgoing data transfers hiccup. I have
yet to find out what s going on.
Mapping names to laptops
Laptops generally have two interfaces, one with a cable, and the
other wireless. Both of these interfaces will have separate MAC
addresses, and by extension, the laptop will have different IPv6
addresses depending on how it is connected to the local
network.
I want to be able to connect to laptops without knowing the
medium they use to connect to the network. Unfortunately, there
seems to be no feasible way. The solutions I see are:
- override the MAC address of one interface with that of the
other, which is going to cause bgi problems in the case when the
laptop (accidentally) gets connected to the same network
twice;
- add both IPv6 addresses as
AAAA records to the
laptop s DNS name, which will cause random delays when connecting
as the resolver may return the currently inactive address
first;
- set up mobile IPv6, e.g.
by following this Mobile IPv6
how-to, which would allow accessing the laptop uniformly, no
matter where in the world it is. Unfortunately, Debian s support
for Mobile IPv6 is severly lacking at time of writing. Also,
Yves-Alexis Perez notes that this how-to is horribly outdated and
promised to tend to it Real Soon Now .
The second solution works for me for now, but I am interested in
the third.
In response to this document, Andreas Henriksson has suggested
the replace the stateless configuration (radvd) with
stateful configuration, using DHCPv6. I have yet to
investigate this option.
Jeroen Massar suggests to unite cable and wireless into a
bridged interface, which seems like a very good idea.
Credits
Thanks to Bernhard Schmidt, William Boughton, and Jeroen Massar,
and everyone on #ipv6/irc.freenode.org
for their help over the past few weeks, and all those who fed back
comments in response to this document!
deb http://ftp.xx.debian.org/debian etch-proposed-updates main
Package: *
Pin: release a=proposed-updates
Pin-Priority: -1
Package: linux-image-2.6.24-etchnhalf.1-amd64
Pin: release a=proposed-updates
Pin-Priority: 600
dom0 on that machine any longer, so by practical
extension, you cannot connect it to the IPv6 network with a packet
filter in place. Supposedly, running 2.6.24 instances on a 2.6.18
dom0 is reported to work, however.
Configuring the packet filter
The first thing I did was to configure the packet filter on each
host appropriately. Unfortunately, this is harder than it should
be, because to quote one of the netfilter developers when ip6tables
was conceived, someone had a big bad brainfart : rather than adding
IPv6 rules to your existing iptables ruleset, you have
to create a new ruleset, duplicate all chains, networks, hosts, and
individual rules, and maintain the two in parallel. Even though
there are efforts of unification on the way, I speculate it ll take
another couple of years until PF_INET6 will be fused
into PF_INET and one will be able to do sensible
cross-address-family packet filtering with Linux. Since I ve
recently started to look (again) at pyroman, maybe the most
logical way forward would be to extend it to write both, IPv4 and
IPv6 rulesets from its knowledge about the hosts and networks you
configured.
Anyway, we want to get stuff working now! Thus, let s configure
ourselves a packet filter. (Almost) all IPv6-related filtering must
be configured via ip6tables (read on further down
about IPv6 in IPv4 tunneling, the reason I said almost ). The
following is a simple default ruleset to start with, which I put
into /etc/network/ip6tables to load with
ip6tables-restore:
*filter
:INPUT REJECT [0:0]
:FORWARD REJECT [0:0]
:OUTPUT ACCEPT [0:0]
:in-new - [0:0]
### INPUT chain
# allow all loopback traffic
-A INPUT -i lo -j ACCEPT
# RT0 processing is disabled since 2.6.20.9
#-A INPUT -m rt --rt-type 0 -j REJECT
# allow all ICMP traffic
-A INPUT -p icmpv6 -j ACCEPT
# packets belonging to an establish connection or related to one can pass
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# packets that are out-of-sequence are silently dropped
-A INPUT -m state --state INVALID -j DROP
# new connections unknown to the kernel are handled in a separate chain
-A INPUT -m state --state NEW -j in-new
# pass SYN packets for SSH
-A in-new -p tcp -m tcp --dport 22 --syn -j ACCEPT
# log everything else
-A INPUT -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[INPUT6]: "
### OUTPUT chain
# RT0 processing is disabled since 2.6.20.9
#-A OUTPUT -m rt --rt-type 0 -j REJECT
# allow outgoing traffic, explicitly (despite chain policy)
-A OUTPUT -j ACCEPT
### FORWARD chain
# RT0 processing is disabled since 2.6.20.9
#-A FORWARD -m rt --rt-type 0 -j REJECT
# disallow forwarded traffic, explicitly (despite chain policy)
-A FORWARD -j REJECT
COMMIT
Note that this recipe is pretty much unusable on pre-2.6.20
kernels due to their broken implementation of stateful connection
tracking.
The ruleset should be fairly obvious, but you might wonder about
my use of REJECT and allowing all ICMP after all, you ve
heard for the past 30 years that ICMP is a bad hacker
protocol , and Internet security is no domain for being nice to
people, so to prevent any information disclosure, you should
DROP connections, not let people know that they re
simply not allowed.
Well, to hell with all that! I don t see a single reason or
attack vector that is foiled by DROP or disallowing
ICMP. In fact, it s just security by obscurity, and
might inconvenient at the same time. ICMP is also much
more important with IPv6 than with IPv4 (it replaces ARP,
for instance), and it s actually useful to be able to
ping hosts, or get back informational messages on why
something failed. Finally, rejecting traffic rather than dropping
it doesn t suggest to a hacker that something s hidden here.
Then there is RFC
4890, which almost made
me puke. This document is part of the reason why I say: let s
fix problems in the kernel, rather than shielding them with
unreadable and unmanageable rulesets!
Getting connected
If you already have an IPv6 address, you re basically ready to
go, but may want to read further down on how to connect your local
network to the IPv6 Internet as well. If you are searching for a
provider, have a look at the list of
providers with native IPv6 connectivity over at sixxs.net.
If you are reading up to here, I assume you are connected to the
Net with IPv4. There are two ways for you to move towards IPv6:
6to4 or by way of a
tunnel provider. A Kiwi website explains how to setting up 6to4
connectivity, and thus I will concentrate only on the tunnel
approach. Even though everyone can set up
6to4 in a breeze without any accounts or waiting,
there are a number of security considerations,
it s pretty ugly to debug (due in part to asymmetric routing), and
makes your life unnecessarily difficult when all you have is a
dynamic IP that changes from time to time. If you are stuck behind
a NAT gateway, you cannot use 6to4 either. Thus, I
prefer the tunnel approach.
With the tunnel approach, IPv6 packets are wrapped up in IPv4
packets on your host, and sent to the IPv4 address of your tunnel
provider, who has native IPv6 connectivity. The tunnel provider
unwraps your packet and shoves the contained IPv6 packet onto the
backbone. The IPv6 address you used as source address is routed to
the tunnel provider, so any replies arrive at their machines, where
they re again wrapped into IPv4 packets and sent to your
(publicly-accessible) IPv4 address. Those IPv4 packets specify
payload type 41 ( ipv6 ), which is why we need those -p ipv6
-j ACCEPT rules in the iptables ruleset.
There are a few tunnel providers out there. I chose SixXS and have not regretted my choice. I
shall thus assume that you do the same: sign up for an account right
now, so that you have it by the time you finished reading this
document! SixXS works on a credit
system: tunnels and subnets cost credits, which you can
accumulate by maintaining your tunnels properly. This ensures that
everyone can play around, but to do more advanced stuff, you need
to first display competence with the basic concepts.
Your first step with SixXS will be to request a tunnel. SixXS
offers three types of tunnels:
- static tunnels, for those with static IPs,
- heartbeat tunnels, for those with dynamic IPs, and
- AYIYA tunnels,
for those behind NAT gateways.
Each of these tunnels have advantages and disadvantages, as
everything does: the first two types of tunnels use IP protocol 41
packets to encapsulate the IPv6 packets. As such, there are
security considerations involving the impersonation by spoofing,
and all upstream firewalls must let protocol 41 pass.
AYIYA addresses these problems by using signed
packets, but that solution comes with extra computation overhead
and smaller MTUs.
I suggest to use the first type of tunnel that fits your
situation. Debian s aiccu package can take care
of heartbeat and AYIYA tunnels for you, and it can
even set up static ones.
During registration, you will also need to choose a PoP , which
stands for Point of Presence . If your country only has a single
PoP, that s the one you will end up using (unless you have a good
reason for another one), but if there are more options, I strongly
suggest that you go through the list of PoPs and select the
one with the best roundtrip time and lowest latency from your
location! Note that you must answer ping requests
(ICMP echo-request) from the PoP you
chose, or else the tunnel will not be created.
Once your tunnel request gets approved, you ll get a
/64 prefix, in which you only use two addresses: the
PoP will configure the :1 address and you need to
configure your host to use the :2 address on the
tunnel interface. You ll also be told the IPv4 address of your PoP
endpoint .
Joey Hess taught me that aiccu can set up the
interface for you, using the data it queries from the SixXS
registration (TIC) server. I tried it, and it works. However, I
prefer the pure ifupdown approach, as it
makes things explicit and allows me to use the hooks for stuff like
loading the packet filter. So in my
/etc/network/interfaces, you can find:
auto sixxs
iface sixxs inet6 v4tunnel
endpoint 194.1.163.40
address 2001:41e0:ff00:3b::2
netmask 64
gateway 2001:41e0:ff00:3b::1
ttl 64
pre-up ip6tables-restore < /etc/network/ip6tables
up ip link set mtu 1480 dev $IFACE
up invoke-rc.d aiccu start
down invoke-rc.d aiccu stop
Make sure to read about MTU values of the
tunnel and adjust the 1480 value in the above to your tunnel
settings and ISP connectivity.
Also set ipv6_interface sixxs in
/etc/aiccu.conf, if you are using aiccu,
or else aiccu will bring up a duplicate/additional
interface. If you tell it to use the same interface, it will
actually execute all the same commands (which will fail), but won t
report any errors. A future version will have a switch to prevent
it from configuring the interface.
Unfortunately, this will probably not work. The reason is that
your regular IP packet filter (iptables, without the
6) doesn t let those encapsulating IPv4 packets pass, unless we
tell it to; we probably want to do this early on in the chain, and
also limit it to our tunnel peer, so:
iptables -I INPUT -p ipv6 -s 194.1.163.40/32 -j ACCEPT
For AYIYA, you need to open port 5072, either for UDP, TCP, or
SCTP, depending on how you configured it. Also have a look at this
FAQ
entry on what a firewall needs to pass. If it still doesn t
work, you have an upstream packet filter that needs some of those
holes poked. Good luck.
In most situations, the FORWARD chain does not get
such a rule, since the tunnel terminates at the gateway, which
routes to a native IPv6 network, or another tunnel. Allowing
tunnels through a gateway is almost always a bad thing, as it would
allow undetected and untraceable traffic from compromised boxes in
the local network. The OUTPUT chain also does not need
such a rule, if you have configured stateful filtering
properly.
Now bring up the interface and verify the connection:
# ifup sixxs
# ping6 -nc1 2001:41e0:ff00:3b::1
PING 2001:41e0:ff00:3b::1(2001:41e0:ff00:3b::1) 56 data bytes
64 bytes from 2001:41e0:ff00:3b::1: icmp_seq=1 ttl=64 time=74.0 ms
[...]
# ping6 -nc1 ipv6.aerasec.de
PING ipv6.aerasec.de(2001:a60:9002:1::184:1) 56 data bytes
64 bytes from 2001:a60:9002:1::184:1: icmp_seq=1 ttl=55 time=91.5 ms
[...]
Welcome to the Internet of the future!
Setting up an IPv6-capable gateway
Your IPv6 connection works, but it s limited to a single
address, and you do not get to specify the reverse DNS
PTR record for it. Since the concept of NAT is mostly
absent from IPv6 (thanks! thanks! thanks!), you will not be able to
connect any other hosts to the IPv6 network. If your local network
has a few hosts behind a gateway, you will need to request a subnet
from SixXS and configure your gateway (which has the tunnel
connection) appropriately. Don t worry, this is not really very
difficult.
First, request a subnet for your tunnel from your PoP via your
SixXS homepage. Once approved, you will get a /48
prefix for your own use: 2^80 1.2 heptillion addresses which are
yours to assign to every dust particle in your office or
home, if you so desire.
The way I set it up is to add the first of these addresses to
your internal interface on the gateway, by adding the following two
lines to the interface s stanza in
/etc/network/interfaces; you will need the iproute package installed
(which you should be using for everything network-related
anyway):
up ip -6 addr add 2001:41e0:ff12::1/64 dev $IFACE
down ip -6 addr del 2001:41e0:ff12::1/64 dev $IFACE
Instead of bringing the interface down and up, just run ip
-6 addr add 2001:41e0:ff12::1/64 dev eth0. Note the use of
the /64 prefix instead of the /48 that
got assigned, leaving only 20 pentillion addresses. Oh no! The
reason for this is buried in the specs: basically, /48
is a site prefix, but individual networks should not be larger than
/64, which is the prefix length of links in the IPv6
domain.
Now is also a good time to enable IPv6 forwarding, e.g. like
so:
# echo net.ipv6.conf.all.forwarding = 1 >> /etc/sysctl.conf
# sysctl -p /etc/sysctl.conf
Obviously, you will also need to change the policy on the
ip6tables FORWARD chain. For now, let s
just set it to accept. You should later create a proper ruleset,
though!
# ip6tables -I FORWARD -j ACCEPT
Bringing IPv6 to your local network
The final step is to spread the love to your local network.
Refrain from selecting addresses from your subnet and assigning
them to the local hosts, or wondering how to configure the DHCP server, because IPv6
does it differently: your gateway will advertise its routes (which
includes a default route) to your network, and each host will pick
an address based on its MAC address
(unless it already has an EUI-64 address
assigned. This all happens automagically, at least with current
Debian and Windows machines.
On the gateway, you need to install radvd and simply tell it
which prefix to use on which interface. My /etc/radvd
looks like this, and I won t explain it:
interface eth0
AdvSendAdvert on;
prefix 2001:41e0:ff12::/64
;
;
Note again how we advertise a /64 network rather
than the /48 we own . You cannot advertise smaller
networks if you want automatic configuration to work, and you
should not use networks larger than /64 in any case.
If 2^64 addresses are not enough for you, I trust you ll be able to
figure out how to advertise another of your 65536 /64
prefixes in the /48 subnet to appropriate hosts.
Restart radvd and run over to another host to
witness how it automagically gets connected to the IPv6 network by
scanning /var/log/kern.log and watching the output of
ip -6 addr and ip -6 route. Try
ping6ing from there! Find the dancing turtle! It should all work.
If you don t like the automagic aspect of this, look into
stateful configuration, using DHCPv6, as provided by
dibbler-server
and ?wide-dhcpv6-server.
Resolving names
Take note of the IPv6 address of each host. There s a way to
determine it given the host s MAC address, but this is easier
(ipv6calc is also
useful). You might want to let your local DNS server know by adding
AAAA records in parallel to the existing
A records, and possibly even adding PTR
entries.
If you re serious about IPv6, you can tell SixXS to delegate
reverse lookups for the IPv6 addresses to your DNS servers, but you
ought to refrain from polluting the DNS
namespace.
Note that bind9-host provides
an improved host tool, which fetches all kinds of
information about names, not just the one single information
configured as default:
% host pulse.madduck.net
pulse.madduck.net has address 130.60.75.74
pulse.madduck.net has IPv6 address 2001:41e0:ff1a::1
pulse.madduck.net mail is handled by 99 b.mx.madduck.net.
pulse.madduck.net mail is handled by 10 a.mx.madduck.net.
% host 2001:41e0:ff1a::1
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.a.1.f.f.0.e.1.4.1.0.0.2.ip6.arpa
domain name pointer pulse.madduck.net.
Oh, and if you re really that curious about how IPv6 addresses
are computed from MAC addresses, read RFC 2464. Basically,
given a prefix 2001:41e0:ff1a:: and a MAC address
aa:bb:cc:dd:ee:ff, the resulting IPv6 address is
obtained by:
- inserting
ff:fe into the middle of the MAC address
to yield aa:bb:cc:ff:fe:dd:ee:ff;
- flipping the second lowest bit of the first octet to yield
a8:bb:cc:ff:fe:dd:ee:ff;
- removing the odd colons to yield
a8bb:ccff:fedd:eeff, the EUI-64;
- concatenating the prefix and this result to get
2001:41e0:ff1a::a8bb:ccff:fedd:eeff.
If you find your (Windows) IPv6 addresses changing all the time,
you might be faced by privacy
features .
Remaining issues
Even though my IPv6 connectivity works, I have two remaining
issues.
Sending larger amounts of data to the network
I am experiencing a curious issue where outgoing ssh IPv6
connections time out and outgoing data transfers hiccup. I have
yet to find out what s going on.
Mapping names to laptops
Laptops generally have two interfaces, one with a cable, and the
other wireless. Both of these interfaces will have separate MAC
addresses, and by extension, the laptop will have different IPv6
addresses depending on how it is connected to the local
network.
I want to be able to connect to laptops without knowing the
medium they use to connect to the network. Unfortunately, there
seems to be no feasible way. The solutions I see are:
- override the MAC address of one interface with that of the
other, which is going to cause bgi problems in the case when the
laptop (accidentally) gets connected to the same network
twice;
- add both IPv6 addresses as
AAAA records to the
laptop s DNS name, which will cause random delays when connecting
as the resolver may return the currently inactive address
first;
- set up mobile IPv6, e.g.
by following this Mobile IPv6
how-to, which would allow accessing the laptop uniformly, no
matter where in the world it is. Unfortunately, Debian s support
for Mobile IPv6 is severly lacking at time of writing. Also,
Yves-Alexis Perez notes that this how-to is horribly outdated and
promised to tend to it Real Soon Now .
The second solution works for me for now, but I am interested in
the third.
In response to this document, Andreas Henriksson has suggested
the replace the stateless configuration (radvd) with
stateful configuration, using DHCPv6. I have yet to
investigate this option.
Jeroen Massar suggests to unite cable and wireless into a
bridged interface, which seems like a very good idea.
Credits
Thanks to Bernhard Schmidt, William Boughton, and Jeroen Massar,
and everyone on #ipv6/irc.freenode.org
for their help over the past few weeks, and all those who fed back
comments in response to this document!
*filter
:INPUT REJECT [0:0]
:FORWARD REJECT [0:0]
:OUTPUT ACCEPT [0:0]
:in-new - [0:0]
### INPUT chain
# allow all loopback traffic
-A INPUT -i lo -j ACCEPT
# RT0 processing is disabled since 2.6.20.9
#-A INPUT -m rt --rt-type 0 -j REJECT
# allow all ICMP traffic
-A INPUT -p icmpv6 -j ACCEPT
# packets belonging to an establish connection or related to one can pass
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# packets that are out-of-sequence are silently dropped
-A INPUT -m state --state INVALID -j DROP
# new connections unknown to the kernel are handled in a separate chain
-A INPUT -m state --state NEW -j in-new
# pass SYN packets for SSH
-A in-new -p tcp -m tcp --dport 22 --syn -j ACCEPT
# log everything else
-A INPUT -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[INPUT6]: "
### OUTPUT chain
# RT0 processing is disabled since 2.6.20.9
#-A OUTPUT -m rt --rt-type 0 -j REJECT
# allow outgoing traffic, explicitly (despite chain policy)
-A OUTPUT -j ACCEPT
### FORWARD chain
# RT0 processing is disabled since 2.6.20.9
#-A FORWARD -m rt --rt-type 0 -j REJECT
# disallow forwarded traffic, explicitly (despite chain policy)
-A FORWARD -j REJECT
COMMIT
6to4 in a breeze without any accounts or waiting,
there are a number of security considerations,
it s pretty ugly to debug (due in part to asymmetric routing), and
makes your life unnecessarily difficult when all you have is a
dynamic IP that changes from time to time. If you are stuck behind
a NAT gateway, you cannot use 6to4 either. Thus, I
prefer the tunnel approach.
With the tunnel approach, IPv6 packets are wrapped up in IPv4
packets on your host, and sent to the IPv4 address of your tunnel
provider, who has native IPv6 connectivity. The tunnel provider
unwraps your packet and shoves the contained IPv6 packet onto the
backbone. The IPv6 address you used as source address is routed to
the tunnel provider, so any replies arrive at their machines, where
they re again wrapped into IPv4 packets and sent to your
(publicly-accessible) IPv4 address. Those IPv4 packets specify
payload type 41 ( ipv6 ), which is why we need those -p ipv6
-j ACCEPT rules in the iptables ruleset.
There are a few tunnel providers out there. I chose SixXS and have not regretted my choice. I
shall thus assume that you do the same: sign up for an account right
now, so that you have it by the time you finished reading this
document! SixXS works on a credit
system: tunnels and subnets cost credits, which you can
accumulate by maintaining your tunnels properly. This ensures that
everyone can play around, but to do more advanced stuff, you need
to first display competence with the basic concepts.
Your first step with SixXS will be to request a tunnel. SixXS
offers three types of tunnels:
- static tunnels, for those with static IPs,
- heartbeat tunnels, for those with dynamic IPs, and
- AYIYA tunnels, for those behind NAT gateways.
AYIYA addresses these problems by using signed
packets, but that solution comes with extra computation overhead
and smaller MTUs.
I suggest to use the first type of tunnel that fits your
situation. Debian s aiccu package can take care
of heartbeat and AYIYA tunnels for you, and it can
even set up static ones.
During registration, you will also need to choose a PoP , which
stands for Point of Presence . If your country only has a single
PoP, that s the one you will end up using (unless you have a good
reason for another one), but if there are more options, I strongly
suggest that you go through the list of PoPs and select the
one with the best roundtrip time and lowest latency from your
location! Note that you must answer ping requests
(ICMP echo-request) from the PoP you
chose, or else the tunnel will not be created.
Once your tunnel request gets approved, you ll get a
/64 prefix, in which you only use two addresses: the
PoP will configure the :1 address and you need to
configure your host to use the :2 address on the
tunnel interface. You ll also be told the IPv4 address of your PoP
endpoint .
Joey Hess taught me that aiccu can set up the
interface for you, using the data it queries from the SixXS
registration (TIC) server. I tried it, and it works. However, I
prefer the pure ifupdown approach, as it
makes things explicit and allows me to use the hooks for stuff like
loading the packet filter. So in my
/etc/network/interfaces, you can find:
auto sixxs
iface sixxs inet6 v4tunnel
endpoint 194.1.163.40
address 2001:41e0:ff00:3b::2
netmask 64
gateway 2001:41e0:ff00:3b::1
ttl 64
pre-up ip6tables-restore < /etc/network/ip6tables
up ip link set mtu 1480 dev $IFACE
up invoke-rc.d aiccu start
down invoke-rc.d aiccu stop
Make sure to read about MTU values of the
tunnel and adjust the 1480 value in the above to your tunnel
settings and ISP connectivity.
Also set ipv6_interface sixxs in
/etc/aiccu.conf, if you are using aiccu,
or else aiccu will bring up a duplicate/additional
interface. If you tell it to use the same interface, it will
actually execute all the same commands (which will fail), but won t
report any errors. A future version will have a switch to prevent
it from configuring the interface.
Unfortunately, this will probably not work. The reason is that
your regular IP packet filter (iptables, without the
6) doesn t let those encapsulating IPv4 packets pass, unless we
tell it to; we probably want to do this early on in the chain, and
also limit it to our tunnel peer, so:
iptables -I INPUT -p ipv6 -s 194.1.163.40/32 -j ACCEPT
For AYIYA, you need to open port 5072, either for UDP, TCP, or
SCTP, depending on how you configured it. Also have a look at this
FAQ
entry on what a firewall needs to pass. If it still doesn t
work, you have an upstream packet filter that needs some of those
holes poked. Good luck.
In most situations, the FORWARD chain does not get
such a rule, since the tunnel terminates at the gateway, which
routes to a native IPv6 network, or another tunnel. Allowing
tunnels through a gateway is almost always a bad thing, as it would
allow undetected and untraceable traffic from compromised boxes in
the local network. The OUTPUT chain also does not need
such a rule, if you have configured stateful filtering
properly.
Now bring up the interface and verify the connection:
# ifup sixxs
# ping6 -nc1 2001:41e0:ff00:3b::1
PING 2001:41e0:ff00:3b::1(2001:41e0:ff00:3b::1) 56 data bytes
64 bytes from 2001:41e0:ff00:3b::1: icmp_seq=1 ttl=64 time=74.0 ms
[...]
# ping6 -nc1 ipv6.aerasec.de
PING ipv6.aerasec.de(2001:a60:9002:1::184:1) 56 data bytes
64 bytes from 2001:a60:9002:1::184:1: icmp_seq=1 ttl=55 time=91.5 ms
[...]
Welcome to the Internet of the future!
Setting up an IPv6-capable gateway
Your IPv6 connection works, but it s limited to a single
address, and you do not get to specify the reverse DNS
PTR record for it. Since the concept of NAT is mostly
absent from IPv6 (thanks! thanks! thanks!), you will not be able to
connect any other hosts to the IPv6 network. If your local network
has a few hosts behind a gateway, you will need to request a subnet
from SixXS and configure your gateway (which has the tunnel
connection) appropriately. Don t worry, this is not really very
difficult.
First, request a subnet for your tunnel from your PoP via your
SixXS homepage. Once approved, you will get a /48
prefix for your own use: 2^80 1.2 heptillion addresses which are
yours to assign to every dust particle in your office or
home, if you so desire.
The way I set it up is to add the first of these addresses to
your internal interface on the gateway, by adding the following two
lines to the interface s stanza in
/etc/network/interfaces; you will need the iproute package installed
(which you should be using for everything network-related
anyway):
up ip -6 addr add 2001:41e0:ff12::1/64 dev $IFACE
down ip -6 addr del 2001:41e0:ff12::1/64 dev $IFACE
Instead of bringing the interface down and up, just run ip
-6 addr add 2001:41e0:ff12::1/64 dev eth0. Note the use of
the /64 prefix instead of the /48 that
got assigned, leaving only 20 pentillion addresses. Oh no! The
reason for this is buried in the specs: basically, /48
is a site prefix, but individual networks should not be larger than
/64, which is the prefix length of links in the IPv6
domain.
Now is also a good time to enable IPv6 forwarding, e.g. like
so:
# echo net.ipv6.conf.all.forwarding = 1 >> /etc/sysctl.conf
# sysctl -p /etc/sysctl.conf
Obviously, you will also need to change the policy on the
ip6tables FORWARD chain. For now, let s
just set it to accept. You should later create a proper ruleset,
though!
# ip6tables -I FORWARD -j ACCEPT
Bringing IPv6 to your local network
The final step is to spread the love to your local network.
Refrain from selecting addresses from your subnet and assigning
them to the local hosts, or wondering how to configure the DHCP server, because IPv6
does it differently: your gateway will advertise its routes (which
includes a default route) to your network, and each host will pick
an address based on its MAC address
(unless it already has an EUI-64 address
assigned. This all happens automagically, at least with current
Debian and Windows machines.
On the gateway, you need to install radvd and simply tell it
which prefix to use on which interface. My /etc/radvd
looks like this, and I won t explain it:
interface eth0
AdvSendAdvert on;
prefix 2001:41e0:ff12::/64
;
;
Note again how we advertise a /64 network rather
than the /48 we own . You cannot advertise smaller
networks if you want automatic configuration to work, and you
should not use networks larger than /64 in any case.
If 2^64 addresses are not enough for you, I trust you ll be able to
figure out how to advertise another of your 65536 /64
prefixes in the /48 subnet to appropriate hosts.
Restart radvd and run over to another host to
witness how it automagically gets connected to the IPv6 network by
scanning /var/log/kern.log and watching the output of
ip -6 addr and ip -6 route. Try
ping6ing from there! Find the dancing turtle! It should all work.
If you don t like the automagic aspect of this, look into
stateful configuration, using DHCPv6, as provided by
dibbler-server
and ?wide-dhcpv6-server.
Resolving names
Take note of the IPv6 address of each host. There s a way to
determine it given the host s MAC address, but this is easier
(ipv6calc is also
useful). You might want to let your local DNS server know by adding
AAAA records in parallel to the existing
A records, and possibly even adding PTR
entries.
If you re serious about IPv6, you can tell SixXS to delegate
reverse lookups for the IPv6 addresses to your DNS servers, but you
ought to refrain from polluting the DNS
namespace.
Note that bind9-host provides
an improved host tool, which fetches all kinds of
information about names, not just the one single information
configured as default:
% host pulse.madduck.net
pulse.madduck.net has address 130.60.75.74
pulse.madduck.net has IPv6 address 2001:41e0:ff1a::1
pulse.madduck.net mail is handled by 99 b.mx.madduck.net.
pulse.madduck.net mail is handled by 10 a.mx.madduck.net.
% host 2001:41e0:ff1a::1
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.a.1.f.f.0.e.1.4.1.0.0.2.ip6.arpa
domain name pointer pulse.madduck.net.
Oh, and if you re really that curious about how IPv6 addresses
are computed from MAC addresses, read RFC 2464. Basically,
given a prefix 2001:41e0:ff1a:: and a MAC address
aa:bb:cc:dd:ee:ff, the resulting IPv6 address is
obtained by:
- inserting
ff:fe into the middle of the MAC address
to yield aa:bb:cc:ff:fe:dd:ee:ff;
- flipping the second lowest bit of the first octet to yield
a8:bb:cc:ff:fe:dd:ee:ff;
- removing the odd colons to yield
a8bb:ccff:fedd:eeff, the EUI-64;
- concatenating the prefix and this result to get
2001:41e0:ff1a::a8bb:ccff:fedd:eeff.
If you find your (Windows) IPv6 addresses changing all the time,
you might be faced by privacy
features .
Remaining issues
Even though my IPv6 connectivity works, I have two remaining
issues.
Sending larger amounts of data to the network
I am experiencing a curious issue where outgoing ssh IPv6
connections time out and outgoing data transfers hiccup. I have
yet to find out what s going on.
Mapping names to laptops
Laptops generally have two interfaces, one with a cable, and the
other wireless. Both of these interfaces will have separate MAC
addresses, and by extension, the laptop will have different IPv6
addresses depending on how it is connected to the local
network.
I want to be able to connect to laptops without knowing the
medium they use to connect to the network. Unfortunately, there
seems to be no feasible way. The solutions I see are:
- override the MAC address of one interface with that of the
other, which is going to cause bgi problems in the case when the
laptop (accidentally) gets connected to the same network
twice;
- add both IPv6 addresses as
AAAA records to the
laptop s DNS name, which will cause random delays when connecting
as the resolver may return the currently inactive address
first;
- set up mobile IPv6, e.g.
by following this Mobile IPv6
how-to, which would allow accessing the laptop uniformly, no
matter where in the world it is. Unfortunately, Debian s support
for Mobile IPv6 is severly lacking at time of writing. Also,
Yves-Alexis Perez notes that this how-to is horribly outdated and
promised to tend to it Real Soon Now .
The second solution works for me for now, but I am interested in
the third.
In response to this document, Andreas Henriksson has suggested
the replace the stateless configuration (radvd) with
stateful configuration, using DHCPv6. I have yet to
investigate this option.
Jeroen Massar suggests to unite cable and wireless into a
bridged interface, which seems like a very good idea.
Credits
Thanks to Bernhard Schmidt, William Boughton, and Jeroen Massar,
and everyone on #ipv6/irc.freenode.org
for their help over the past few weeks, and all those who fed back
comments in response to this document!
up ip -6 addr add 2001:41e0:ff12::1/64 dev $IFACE
down ip -6 addr del 2001:41e0:ff12::1/64 dev $IFACE
# echo net.ipv6.conf.all.forwarding = 1 >> /etc/sysctl.conf
# sysctl -p /etc/sysctl.conf
# ip6tables -I FORWARD -j ACCEPT
/etc/radvd
looks like this, and I won t explain it:
interface eth0
AdvSendAdvert on;
prefix 2001:41e0:ff12::/64
;
;
Note again how we advertise a /64 network rather
than the /48 we own . You cannot advertise smaller
networks if you want automatic configuration to work, and you
should not use networks larger than /64 in any case.
If 2^64 addresses are not enough for you, I trust you ll be able to
figure out how to advertise another of your 65536 /64
prefixes in the /48 subnet to appropriate hosts.
Restart radvd and run over to another host to
witness how it automagically gets connected to the IPv6 network by
scanning /var/log/kern.log and watching the output of
ip -6 addr and ip -6 route. Try
ping6ing from there! Find the dancing turtle! It should all work.
If you don t like the automagic aspect of this, look into
stateful configuration, using DHCPv6, as provided by
dibbler-server
and ?wide-dhcpv6-server.
Resolving names
Take note of the IPv6 address of each host. There s a way to
determine it given the host s MAC address, but this is easier
(ipv6calc is also
useful). You might want to let your local DNS server know by adding
AAAA records in parallel to the existing
A records, and possibly even adding PTR
entries.
If you re serious about IPv6, you can tell SixXS to delegate
reverse lookups for the IPv6 addresses to your DNS servers, but you
ought to refrain from polluting the DNS
namespace.
Note that bind9-host provides
an improved host tool, which fetches all kinds of
information about names, not just the one single information
configured as default:
% host pulse.madduck.net
pulse.madduck.net has address 130.60.75.74
pulse.madduck.net has IPv6 address 2001:41e0:ff1a::1
pulse.madduck.net mail is handled by 99 b.mx.madduck.net.
pulse.madduck.net mail is handled by 10 a.mx.madduck.net.
% host 2001:41e0:ff1a::1
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.a.1.f.f.0.e.1.4.1.0.0.2.ip6.arpa
domain name pointer pulse.madduck.net.
Oh, and if you re really that curious about how IPv6 addresses
are computed from MAC addresses, read RFC 2464. Basically,
given a prefix 2001:41e0:ff1a:: and a MAC address
aa:bb:cc:dd:ee:ff, the resulting IPv6 address is
obtained by:
- inserting
ff:fe into the middle of the MAC address
to yield aa:bb:cc:ff:fe:dd:ee:ff;
- flipping the second lowest bit of the first octet to yield
a8:bb:cc:ff:fe:dd:ee:ff;
- removing the odd colons to yield
a8bb:ccff:fedd:eeff, the EUI-64;
- concatenating the prefix and this result to get
2001:41e0:ff1a::a8bb:ccff:fedd:eeff.
If you find your (Windows) IPv6 addresses changing all the time,
you might be faced by privacy
features .
Remaining issues
Even though my IPv6 connectivity works, I have two remaining
issues.
Sending larger amounts of data to the network
I am experiencing a curious issue where outgoing ssh IPv6
connections time out and outgoing data transfers hiccup. I have
yet to find out what s going on.
Mapping names to laptops
Laptops generally have two interfaces, one with a cable, and the
other wireless. Both of these interfaces will have separate MAC
addresses, and by extension, the laptop will have different IPv6
addresses depending on how it is connected to the local
network.
I want to be able to connect to laptops without knowing the
medium they use to connect to the network. Unfortunately, there
seems to be no feasible way. The solutions I see are:
- override the MAC address of one interface with that of the
other, which is going to cause bgi problems in the case when the
laptop (accidentally) gets connected to the same network
twice;
- add both IPv6 addresses as
AAAA records to the
laptop s DNS name, which will cause random delays when connecting
as the resolver may return the currently inactive address
first;
- set up mobile IPv6, e.g.
by following this Mobile IPv6
how-to, which would allow accessing the laptop uniformly, no
matter where in the world it is. Unfortunately, Debian s support
for Mobile IPv6 is severly lacking at time of writing. Also,
Yves-Alexis Perez notes that this how-to is horribly outdated and
promised to tend to it Real Soon Now .
The second solution works for me for now, but I am interested in
the third.
In response to this document, Andreas Henriksson has suggested
the replace the stateless configuration (radvd) with
stateful configuration, using DHCPv6. I have yet to
investigate this option.
Jeroen Massar suggests to unite cable and wireless into a
bridged interface, which seems like a very good idea.
Credits
Thanks to Bernhard Schmidt, William Boughton, and Jeroen Massar,
and everyone on #ipv6/irc.freenode.org
for their help over the past few weeks, and all those who fed back
comments in response to this document!
% host pulse.madduck.net
pulse.madduck.net has address 130.60.75.74
pulse.madduck.net has IPv6 address 2001:41e0:ff1a::1
pulse.madduck.net mail is handled by 99 b.mx.madduck.net.
pulse.madduck.net mail is handled by 10 a.mx.madduck.net.
% host 2001:41e0:ff1a::1
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.a.1.f.f.0.e.1.4.1.0.0.2.ip6.arpa
domain name pointer pulse.madduck.net.
ff:fe into the middle of the MAC address
to yield aa:bb:cc:ff:fe:dd:ee:ff;a8:bb:cc:ff:fe:dd:ee:ff;a8bb:ccff:fedd:eeff, the EUI-64;2001:41e0:ff1a::a8bb:ccff:fedd:eeff.Sending larger amounts of data to the network
I am experiencing a curious issue where outgoing ssh IPv6
connections time out and outgoing data transfers hiccup. I have
yet to find out what s going on.
Mapping names to laptops
Laptops generally have two interfaces, one with a cable, and the
other wireless. Both of these interfaces will have separate MAC
addresses, and by extension, the laptop will have different IPv6
addresses depending on how it is connected to the local
network.
I want to be able to connect to laptops without knowing the
medium they use to connect to the network. Unfortunately, there
seems to be no feasible way. The solutions I see are:
- override the MAC address of one interface with that of the
other, which is going to cause bgi problems in the case when the
laptop (accidentally) gets connected to the same network
twice;
- add both IPv6 addresses as
AAAA records to the
laptop s DNS name, which will cause random delays when connecting
as the resolver may return the currently inactive address
first;
- set up mobile IPv6, e.g.
by following this Mobile IPv6
how-to, which would allow accessing the laptop uniformly, no
matter where in the world it is. Unfortunately, Debian s support
for Mobile IPv6 is severly lacking at time of writing. Also,
Yves-Alexis Perez notes that this how-to is horribly outdated and
promised to tend to it Real Soon Now .
The second solution works for me for now, but I am interested in
the third.
In response to this document, Andreas Henriksson has suggested
the replace the stateless configuration (radvd) with
stateful configuration, using DHCPv6. I have yet to
investigate this option.
Jeroen Massar suggests to unite cable and wireless into a
bridged interface, which seems like a very good idea.
Credits
Thanks to Bernhard Schmidt, William Boughton, and Jeroen Massar,
and everyone on #ipv6/irc.freenode.org
for their help over the past few weeks, and all those who fed back
comments in response to this document!
- override the MAC address of one interface with that of the other, which is going to cause bgi problems in the case when the laptop (accidentally) gets connected to the same network twice;
- add both IPv6 addresses as
AAAArecords to the laptop s DNS name, which will cause random delays when connecting as the resolver may return the currently inactive address first; - set up mobile IPv6, e.g. by following this Mobile IPv6 how-to, which would allow accessing the laptop uniformly, no matter where in the world it is. Unfortunately, Debian s support for Mobile IPv6 is severly lacking at time of writing. Also, Yves-Alexis Perez notes that this how-to is horribly outdated and promised to tend to it Real Soon Now .
radvd) with
stateful configuration, using DHCPv6. I have yet to
investigate this option.
Jeroen Massar suggests to unite cable and wireless into a
bridged interface, which seems like a very good idea.
in main:

Well I'm back and ready to do some fun work.
In the meantime it seems that at least one of my crash-fixes, from the prior public bugfixing, has been uploaded:
On the testing and unstable systems that i run, i occasionally get a disturbing "there are N newly obsolete packages" message. For example
Exhibit B:
And the classic philosophical gem, Exhibit C:
Is the problem solved, then? Not quite. The current
DebGraph cycle detection operator works well for
dependencies, but we also want to discover cycles of
conflicting packages. Furthermore, one of our documented
use cases involves finding nodes that depend on and
conflict with one another.
(hint: D-I=Debian Installer, the installation system for your favourite distro)
Commenting on 




Yes, me too.
I actually booked a while ago, but never got around to blogging about
it. Oh well. In case you care, my flights: