Aug 222011
 

Welcome to part six of my multipart series on IPv6. In this post I’ll cover how to configure a dual-stacked PPPoE tunnel on FreeBSD using mpd. The host is a FreeBSD 8.2 box using mpd5 from ports.

My ISP is testing IPv6; if you sign up they assign you a dual-stacked PPPoE connection with /64 and /56 IPv6 subnets assigned, in addition to a regular IPv4 address. Note that I have a bonded DSL connection (discussed in further detail here), which is why you’ll see two link definitions below.

I was assigned 2001:0DB8:a000:01f3::/64 and 2001:0DB8:f00e:eb00::/56. I decided to use the /64 on the tunnel itself, though it’s entirely possible to run the tunnel using only the link-local addresses, and to use the /64 on your LAN. I also decided to split the /56 up into /64 subnets, so that I could assign different hosts to different subnets. The first subnet, 2001:0DB8:f00e:eb00::/64, will be for my LAN. The second subnet, 2001:0DB8:f00e:eb01::/64, will be for my DMZ.

The first step is to enable IPv6 and mpd on the system. Add the following entries to your /etc/rc.conf:

[cc lang=”bash”]
$ cat /etc/rc.conf | egrep ‘(ipv6|mpd)’ | grep -v ifconfig
ipv6_enable=”YES”
ipv6_gateway_enable=”YES”
mpd_enable=”YES”
[/cc]

To enable the configuration without rebooting, run the following command:

[cc lang=”bash”]
$ /etc/rc.d/network_ipv6 start
[/cc]

Now you need to configure mpd5. Here’s my /usr/local/etc/mpd5/mpd.conf:

[cc lang=”bash”]
$ cat /usr/local/etc/mpd5/mpd.conf
default:
create bundle static IPv6
set bundle links IPv6Link1 IPv6Link2
set bundle disable round-robin
set bundle disable bw-manage
set bundle enable ipv6cp
set ipcp ranges 0.0.0.0/0 0.0.0.0/0
set ipcp disable vjcomp
set iface disable on-demand
set iface route default
set iface up-script /usr/local/etc/mpd5/if-up.sh
set iface down-script /usr/local/etc/mpd5/if-down.sh

create link static IPv6Link1 pppoe
set auth authname username
set auth password password
set pppoe iface em1
set pppoe service “teksavvy”
set link max-redial 0
set link keep-alive 10 60
set link enable multilink
set link enable shortseq
set link mrru 1524
set link mtu 1486
set link mru 1486
set link bandwidth 5056000
set link action bundle IPv6
open

create link static IPv6Link2 pppoe
set auth authname username
set auth password password
set pppoe iface em2
set pppoe service “teksavvy”
set link max-redial 0
set link keep-alive 10 60
set link enable multilink
set link enable shortseq
set link mrru 1524
set link mtu 1486
set link mru 1486
set link bandwidth 5056000
set link action bundle IPv6
open
[/cc]

I also have if-up.sh and if-down.sh scripts:

[cc lang=”bash”]
$ cat /usr/local/etc/mpd5/if-up.sh
#!/bin/sh
/sbin/ifconfig ng0 inet6 2001:0DB8:a000:01f3::1 prefixlen 64
/sbin/route -n add -inet6 default -iface ng0

$ cat /usr/local/etc/mpd5/if-down.sh
#!/bin/sh
/sbin/route -n delete -inet6 default -iface ng0
[/cc]

The important bits are the “set bundle enable ipv6cp” and the contents of the if-up and if-down scripts, which manually assign the IP address to the PPPoE tunnel. TekSavvy uses ICMPv6 router advertisements to advertise the assigned /64 over the PPPoE interface but mpd5 does not assign an address out of the advertised subnet by default. It might be possible to use the rtsold daemon to pick up those advertisements and assign an address, but since this box will function as a router, I’ve elected to manually assign an easier to remember address out of the subnet. To bring the PPPoE tunnel up, run

[cc lang=”bash”]
# /usr/local/etc/rc.d/mpd5 start
[/cc]

Here’s what the interface looks like:

[cc lang=”bash”]
$ ifconfig ng0
ng0: flags=88d1 metric 0 mtu 1500
inet6 fe80::216:3eff:fe11:7844%ng0 prefixlen 64 scopeid 0x9
inet 203.0.113.88 –> 206.248.154.103 netmask 0xffffffff
inet6 2001:0DB8:a000:1f3::1 prefixlen 64
nd6 options=3 [/cc]

Note there are actually two IPv6 addresses on the interface. One is the link-local address (the one starting with fe80), which is used for neighbour and router solicitation and discovery purposes, among other uses. The link-local address is assigned automatically, and is based on the MAC address. The other is the globally routable IPv6 address that is what other IPv6 enabled hosts will use to communicate with this host.

Next, up we need to configure the LAN and DMZ. For IPv4 connectivity the LAN is setup with private address space, while the DMZ uses a public /29 routed to me by my ISP. I decided to replicate this configuration for IPv6, though the LAN will use a globally routed IPv6 subnet. Note that this does have significant consequences for how you approach and implement security on your network. My LAN consists of a mix of Linux, Mac OS X, and Windows hosts, plus a smattering of gadgets and devices including game consoles, smartphones, VoIP devices, etc. One pleasant surprise is that Microsoft completely rewrote the networking stack for Windows Vista and above and it plays very nicely with IPv6.

On my router, the LAN is connected to em3 and the DMZ is connected to em0. To configure these interfaces for IPv6, add the following lines to /etc/rc.conf:

[cc lang=”bash”]
$ cat /etc/rc.conf | grep ipv6_ifconfig
ipv6_ifconfig_em0=”2001:0DB8:f00e:eb01::1 prefixlen 64″
ipv6_ifconfig_em3=”2001:0DB8:f00e:eb00::1 prefixlen 64″
[/cc]

To configure the IPv6 addresses and packet forwarding without rebooting just run the following:

[cc lang=”bash”]
# /etc/rc.d/network_ipv6 restart
[/cc]

I want hosts on my LAN to be able to connect automatically without having to manually assign IPv6 addresses. There are two methods for assigning an IPv6 address in an automated fashion – stateful and stateless.

Stateless configuration uses ICMPv6 router and neighbor advertisements and solicitations to advertise /64 subnets over connected networks. Hosts can then assign themselves an IPv6 address, with the last 64 bits of the IP address being based on the MAC address of the interface if it’s an Ethernet device. Other types of interfaces have their own methods for determining the last 64 bits of the address. This type of addressing us usually called SLAAC – StateLess Address AutoConfiguration.

Stateful addresses are assigned using a DHCPv6 server. It should be noted that DHCPv6 still requires router and neighbor advertisements; it’s just that in this case the advertisements tell the host to not assign itself an address but to instead request one from DHCPv6. It’s also possible to have hosts assign themselves an address and also request one from DHCPv6, or to have the host assign itself an address and then get other configuration information from DHCPv6 (such as domain name servers, etc) but not an IPv6 address.

I’ll cover DHCPv6 in another post, so for now we’ll just cover configuring SLAAC. By default, FreeBSD comes with rtadvd. If you want SLAAC on both the LAN and DMZ with sane default options, just run the following commands:

[cc lang=”bash”]
# echo ‘rtadvd_enable=”YES”’ >> /etc/rc.conf
# /etc/rc.d/rtadvd start
[/cc]

The rtadvd has a config file to modify its behavior as well, it’s at /etc/rtadvd.conf, though it is not created by default, even if the rtadvd daemon is running.

Instead of using rtadvd I chose to use radvd, which you’ll find in the ports tree at /usr/ports/net/radvd. The config file for radvd is more readable, and because it’s the default daemon on Linux there’s more documentation for it. I only wanted to run SLAAC on my LAN, while leaving the hosts in the DMZ to need static configuration. To do this, I use the following /usr/local/etc/radvd.conf:

[cc lang=”bash”]
interface em3
{
AdvSendAdvert on;
AdvManagedFlag off;
AdvOtherConfigFlag on;
MinRtrAdvInterval 3;
MaxRtrAdvInterval 10;

prefix 2607:f2c0:f00e:eb00::/64
{
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr off;
};
RDNSS 2607:f2c0:f00e:eb00::1
{
AdvRDNSSLifetime 30;
};
DNSSL nullpointer.ca
{
AdvDNSSLLifetime 30;
};
};
[/cc]

For details of what each option does I recommend reading the man page. But in effect, I have SLAAC configured to tell hosts to assign themselves an address (AdvAutonomous on;) and to not get an address from DHCPv6 (AdvManagedFlag off;) but to get extra config options like DNS and NTP servers from DHCPv6 (AdvOtherConfigFlag on;). Again, I cover the details of DHCPv6 in this blog post. To enable the radvd daemon without rebooting just run:

[cc lang=”bash”]
# /usr/local/etc/rc.d/radvd start
[/cc]

With the above configuration, hosts on my LAN that support IPv6 will acquire an address automatically and can use the IPv6 Internet.

Sorry, the comment form is closed at this time.