I wanted to download some videos of the 27C3 from an IPv6 only site. My goal was to setup IPv6 connectivity with minimal effort. I went for 6to4 as it does not require any tunnel brokers and works out of the box on a recent FreeBSD (and Linux) box.
My router at home runs a selfmade NanoBSD, which is basically a FreeBSD i386 that boots from a readonly compact flash card (see /usr/src/tools/tools/nanobsd). It is connected to the Internet thru DSL and gets an official, but dynamically allocated IPv4 address by PPPoE. Every 24 hours the provider drops the PPP session so that my router has to reconnect. The router has two internal interfaces, vr0 and vr1 to which my other computers are connected. I added the following to /etc/rc.conf:
ipv6_enable="YES" ipv6_gateway_enable="YES" ipv6_network_interfaces="vr0 vr1" ipv6_defaultrouter="2002:c058:6301::" rtadvd_enable="YES" rtadvd_interfaces="vr0 vr1"What are those entries good for:
MYADDR: bg /etc/ppp/ppp.linkup.sh MYADDRWhenever my provider assigns me a new IPv4 address (when I receive a fresh MYADDR), the pppd executes the /etc/ppp/ppp.linkup.sh shell script and runs it in background. The first parameter MYADDR is replaced by the actual IPv4 address. So my /etc/ppp/ppp.linkup.sh starts like this:
#!/bin/sh MYADDR="$1" echo "stf_interface_ipv4addr=\"$MYADDR\"" >/etc/rc.conf.localThis way /etc/rc.d/network_ipv6 will create a stf tunnel interface and assign it the correct 6to4 address. As it is valid for any interface to have multiple IPv6 addresses, none of the scripts in /etc/rc.d will remove old addresses. So we have to do this on our own and extend ppp.linkup.sh to remove any 6to4 address (IPv6 addresses starting with 2002:):
ifconfig stf0 | \ awk '{if(/inet6 2002/){print $2;}}' | \ while read L; do ifconfig stf0 inet6 "$L" -alias doneNow we can safely call network_ipv6:
/etc/rc.d/network_ipv6 restartAfter restarting the pppd by /etc/rc.d/ppp restart you should be able to ping any IPv6 host on the Internet from the router, eg. ping6 ipv6.ogris.de or ping6 www.heise.de. You will also notice that a stf0 interface has been created. Did we miss something? Yip. Our inside interfaces vr0 and vr1 still have link local addresses. My Gentoo box on the internal network also has a link local address, as link local addresses are automatically created upon interface initialization. So I can ping and connect from my router to my Linux box and vice versa. But I cannot reach any IPv6 host outside my local network because link local addresses won't get routed - not even within your internal network (hence the name link local). Of course there is no NAT for IPv6. So ppp.linkup.sh has to reconfigure vr0 and vr1, too. My complete script looks like this:
#!/bin/sh # remove 6to4 addresses from all selected interfaces for i in stf0 vr0 vr1; do ifconfig $i | \ awk '{if(/inet6 2002/){print $2;}}' | \ while read L; do ifconfig $i inet6 "$L" -alias done done # MYADDR is a official dynamic IPv4 address # MYNET is 2002:AABB:CCDD where AABB:CCDD is hex for MYADDR MYADDR="$1" MYNET="2002:"`echo "$MYADDR" | \ /usr/bin/awk -F'.' '{printf("%02x%02x:%02x%02x",$1,$2,$3,$4)}'` # stf0 gets 2002:AABB:CCDD::1/16 # vr0 gets 2002:AABB:CCDD::2/64 # vr1 gets 2002:AABB:CCDD::3/64 echo "stf_interface_ipv4addr=\"$MYADDR\" ipv6_ifconfig_vr0=\"$MYNET::2/64\" ipv6_ifconfig_vr1=\"$MYNET::3/64\"" >/etc/rc.conf.local /etc/rc.d/network_ipv6 restartLuckily, we don't have to restart rtadvd. It monitors $rtadvd_interfaces and announces the 6to4 prefix (2002:AABB:CCDD::/64) on these interfaces. So my Linux box will configure itself with an IPv6 address based on the given 6to4 prefix.
I use OpenBSD's pf for firewalling. First of all, I had to allow any IPv6 traffic encapsulated in IPv4 (read: 6to4 traffic) on the PPP interface:
pass out quick on tun0 proto ipv6Filtering IPv6 traffic then takes place at stf0, eg. for HTTP:
pass out quick on stf0 proto tcp to port http
Setting up 6to4 on a server with a static IPv4 address (eg. _this_ webserver) is quite simple. Just added the following to my /etc/rc.conf:
ipv6_enable="YES" ipv6_interfaces="" ipv6_defaultrouter="2002:c058:6301::" stf_interface_ipv4addr="212.62.68.23"I set $ipv6_interfaces to an empty string as I wanted to omit native IPv6 configuration on any interface. After /etc/rc.d/network_ipv6 start an interface named stf0 appeared:
stf0: flags=1Again d43e:4417 is hex for 212.62.68.23.metric 0 mtu 1280 inet6 2002:d43e:4417::1 prefixlen 16
ipv6.ogris.de. 86400 IN AAAA 2002:d43e:4417::1Reverse DNS is awkward. First, you have to create a zone like 7.1.4.4.e.3.4.d.2.0.0.2.ip6.arpa on your nameservers. This zone has to contain your PTR record, eg.:
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 86400s IN PTR ipv6.ogris.de.To get the reverse delegation working, you have to use the webinterface at 6to4.nro.net. NRO is a joint venture of several RIRs. Note that you have to connect right from your 6to4 address you requesting the PTR for. Luckily it's a simple CGI that you can use by command line tools:
fetch -6 'https://6to4.nro.net/cgi-bin/6to4_reverse_wget.pl?method=direct&new_password=PASSWORD&email=EMAILADDRESS&ns1=NAMESERVER1&ns2=NAMESERVER2'As of 2011-01-02, 6to4.nro.net resolves to 2 IPv6 addresses. One of theses IPs seems to be dead. So you could directly use the remaining one:
fetch -6 'https://[2001:dc0:2001:11::234]/cgi-bin/6to4_reverse_wget.pl?method=direct&new_password=PASSWORD&email=EMAILADDRESS&ns1=NAMESERVER1&ns2=NAMESERVER2'You have to replace
Listen 0.0.0.0:80 Listen 0.0.0.0:443 Listen [::]:80Don't touch the NameVirtualHost statement. The following will yield a warning:
NameVirtualHost 0.0.0.0:80 NameVirtualHost [::]:80Either NameVirtualHost 0.0.0.0:80, NameVirtualHost [::]:80, or NameVirtualHost *:80 will do the trick. I am using
NameVirtualHost 0.0.0.0:80There is no need for NameVirtualHosts with IPv6 as there are sufficient addresses. My VirtualHost section reads like this:
<VirtualHost [2002:d43e:4417::1]:> DocumentRoot ... ServerName ipv6.ogris.de ErrorLog ... CustomLog ... ... </VirtualHost>
If you are connected to the Internet by DSL, ISDN, or cable, then your router at home normally gets one official, dynamically allocated IPv4 address. Your provider's dialin router assigns this ip address either by PPPoE, PPP, or DHCP. Your home network runs a private network as defined by RfC1918. Your router maps each internal address to its one external address by using NAT. The internal hosts do not know anything about the external address. When the provider assigns you a new ip address (eg. most providers in Germany disconnect you every 24 hours), it does not have an impact on your internal network. This will change with IPv6. One design goal of IPv6 was to provide each device connected to the Internet an unique/public/official/fully routeable IP address. That led to such a large IPv6 address space. Hence an ISP must not only assign you a single address, but a whole subnet or, in terms of IPv6, a prefix. The smallest size of a prefix is a /64. I assume that providers will assign the typical home user a /56 prefix, while business customers will receive a /48. However, your nodes on the internal network will have to know which prefix is currently assigned to your router. This could be done statically, eg. assign each computer on your network its own official IPv6 address taken from your prefix. Of course you will have to change all IP addresses once your provider reassigns you a new prefix. Luckily, another design goal of IPv6 was autoconfiguration. Thatswhy we have rtadvd on the BSDs or radvd on Linux (and on the BSDs, too). You normally run rtadvd or radvd on the inside interface of your router. It will announce your site's prefix to any host on the internal network. But there is currently no defacto mechanism to reconfigure rtadvd or radvd! FreeBSD's ppp(8) is not able to reconfigure rtadvd or any interfaces besides its tun interface. rtadvd itself is not able to fetch a site's prefix from another interface than the ones it announces the prefixes to. Three solutions come to mind:
# request "Identity Assocication for Prefix Delegation" from your ISP # read: send DHCPv6 request on tun0 interface tun0 { send ia-pd 0; }; # if we receive an Identity Association for Prefix Delegation, then # reconfigure interface vr2 # sla-id is the subnet id # sla-len is smallest IPv6 prefix size (/64) minus the prefix size our ISP # assigns us (eg. /56) # eg. if the ISP assigns us the prefix 2001:AABB:CCDD:EE00/56, then vr2 will # get an IPv6 address like 2001:AABB:CCDD:EE02/64 id-assoc pd { prefix-interface vr2 { sla-id 2; sla-len 8; }; };