IPv6, ULAs and FreeBSD

Niklaas Baudet von Gersdorff stdin at niklaas.eu
Tue May 24 08:17:07 CEST 2016


Hello,

I already consulted related lists @freebsd.org [1,2] but I have remained
unsuccessful to solve the following issue: VPN works for an internal
IPv4 subnet, but I doesn't for an internal IPv6 subnet with ULAs. To be
honest, I don't have any experience setting up a local IPv6; so I guess
that I'm doing something wrong here.

For those that know FreeBSD: The main aim is to connect several jails
that are running on two different machines. For those who don't: jails
are like virtual machines but actually they aren't.

I want to serve IPv4 subnets 10.1.0.0/16 (machine A) and 10.2.0.0/16
(machine B), and IPv6 subnets fd16:dcc0:f4cc:0:0:1::/96 (machine A) and
fd16:dcc0:f4cc:0:0:2::/96 (machine B) respectively. The jails are
connected on lo1.

    A $ netstat -rn | grep -e 'fd16' -e '10\.'
    10.0.0.0/8         link#4             U          tap0
    10.1.0.1           link#4             UHS         lo0
    10.1.1.1           link#3             UH          lo1
    10.2.0.0/16        10.1.0.1           UGS        tap0
    10.2.0.1           10.1.0.1           UGHS       tap0
    fd16:dcc0:f4cc::/80               link#4                        U          tap0
    fd16:dcc0:f4cc::1:0:0/96          link#3                        U           lo1
    fd16:dcc0:f4cc::1:0:1             link#4                        UHS         lo0
    fd16:dcc0:f4cc::1:1:1             link#3                        UHS         lo0
    fd16:dcc0:f4cc::2:0:0/96          fd16:dcc0:f4cc::1:0:1         UGS         lo1
    fd16:dcc0:f4cc::2:0:1             fd16:dcc0:f4cc::1:0:1         UGHS        lo1
    ff01::%lo1/32                     fd16:dcc0:f4cc::1:1:1         U           lo1
    ff01::%tap0/32                    fd16:dcc0:f4cc::1:0:1         U          tap0
    ff02::%lo1/32                     fd16:dcc0:f4cc::1:1:1         U           lo1
    ff02::%tap0/32                    fd16:dcc0:f4cc::1:0:1         U          tap0


    B $ netstat -rn | grep -e 'fd16' -e '10\.'
    10.0.0.0/8         link#4             U          tap0
    10.1.0.0/16        10.2.0.1           UGS        tap0
    10.1.0.1           10.2.0.1           UGHS       tap0
    10.2.0.1           link#4             UHS         lo0
    10.2.1.1           link#3             UH          lo1
    fd16:dcc0:f4cc::/80               link#4                        U          tap0
    fd16:dcc0:f4cc::1:0:0/96          fd16:dcc0:f4cc::2:0:1         UGS         lo1
    fd16:dcc0:f4cc::1:0:1             fd16:dcc0:f4cc::2:0:1         UGHS        lo1
    fd16:dcc0:f4cc::2:0:0/96          link#3                        U           lo1
    fd16:dcc0:f4cc::2:0:1             link#4                        UHS         lo0
    fd16:dcc0:f4cc::2:1:1             link#3                        UHS         lo0
    ff01::%lo1/32                     fd16:dcc0:f4cc::2:1:1         U           lo1
    ff01::%tap0/32                    fd16:dcc0:f4cc::2:0:1         U          tap0
    ff02::%lo1/32                     fd16:dcc0:f4cc::2:1:1         U           lo1
    ff02::%tap0/32                    fd16:dcc0:f4cc::2:0:1         U          tap0

Note: 10.{1,2}.1.1 are two jails running on machine A and B respectively.
These jails have also assigned IPv6 addresses fd16:dcc0:f4cc::{1,2}:1:1
respectively. 10.{1,2}.0.1 and fd16:dcc0:f4cc::{1,2}:0:1 are manually
assigned because tinc's documentation asks me to do so.

So, on both machines I can `ping 10.{1,2}.{0,1}.1` and I get a response.
But if I `ping6 fd16:dcc0:f4cc::{1,2}:{0,1}:1` I only get a response
from the machine the ping6 originates from; that is, routing over the
VPN seems to work for IPv4 but not for IPv6.

This is how the interfaces look like:

    A $ ifconfig tap0
    tap0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=80000<LINKSTATE>
        ether 00:bd:6b:e5:19:00
        inet6 fd16:dcc0:f4cc::1:0:1 prefixlen 80 
        inet6 fe80::2bd:6bff:fee5:1900%tap0 prefixlen 64 scopeid 0x4 
        inet 10.1.0.1 netmask 0xff000000 broadcast 10.255.255.255 
        nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>
        media: Ethernet autoselect
        status: active
        Opened by PID 6110


    B $ ifconfig tap0
    tap0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=80000<LINKSTATE>
        ether 00:bd:60:ca:17:00
        inet6 fd16:dcc0:f4cc::2:0:1 prefixlen 80 
        inet6 fe80::2bd:60ff:feca:1700%tap0 prefixlen 64 scopeid 0x4 
        inet 10.2.0.1 netmask 0xff000000 broadcast 10.255.255.255 
        nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>
        media: Ethernet autoselect
        status: active
        Opened by PID 16037

I have configured both machines as IPv6 gateway (/etc/rc.conf):

    ipv6_gateway_enable="YES"

See also:

    A $ sysctl net.inet6.ip6.forwarding
    net.inet6.ip6.forwarding: 1


    B $ sysctl net.inet6.ip6.forwarding
    net.inet6.ip6.forwarding: 1

I don't think it's a firewall problem because I I've already tried
disabling the firewall without any success: IPv4 worked while IPv6
didn't.

The following is the tinc-up script on each machine that assignes IP
addresses and creates routes. I commented out some variations that
I tried but haven't had success with either:

    A $ cat /usr/local/etc/tinc/klaas/tinc-up
    ifconfig $INTERFACE inet6 fd16:dcc0:f4cc:0:0:1:0:1 prefixlen 80
    route -6 add -host fd16:dcc0:f4cc:0:0:2:0:1 fd16:dcc0:f4cc:0:0:1:0:1
    route -6 add -net  fd16:dcc0:f4cc:0:0:2::/96  fd16:dcc0:f4cc:0:0:1:0:1
    #route -6 add -ifp $INTERFACE -host fd16:dcc0:f4cc::2:0:1    fd16:dcc0:f4cc::1:0:1
    #route -6 add -ifp $INTERFACE -net  fd16:dcc0:f4cc::2:0:0/96 fd16:dcc0:f4cc::1:0:1

    ifconfig $INTERFACE 10.1.0.1 netmask 255.0.0.0
    route -4 add -host 10.2.0.1    10.1.0.1
    route -4 add -net  10.2.0.0/16 10.1.0.1

This looks pretty the same on machine B.

I tried the variants with explicitly setting `-ifp $INTERFACE` because
I realised that

                                                                                vvv
    fd16:dcc0:f4cc::1:0:0/96          link#3                        U           lo1

although

                                                     vvvv
    10.2.0.0/16        10.1.0.1           UGS        tap0

Explicitly setting the interface changes the first entry above to tap0.
Still, I couldn't ping the other machine over the VPN via IPv6.

Is there anything specifically IPv6-related that I am missing?

This is tinc.conf on machine A:

    Name = A
    ConnectTo = B
    BindToAddress = <public-ipv4>
    BindToAddress = <public-ipv6>
    Device = /dev/tap0

It looks pretty the same for machine B. Since the tinc daemons can
connect, I assume everything is set up correctly here.

This is the host configuration file for A:

    Address = A.domain.tld
    Subnet = fd16:dcc0:f4cc:0:0:1::/96
    Subnet = 10.1.0.0/16

    -----BEGIN RSA PUBLIC KEY-----
    <secret>
    -----END RSA PUBLIC KEY-----

Again, the configuration file for machine B looks pretty the same. Except
that the subnets are the ones mentioned above.

I already stumbled upon http://www.tinc-vpn.org/examples/ipv6-network/
but setting `Mode = switch` resulted in IPv4 not working either. So
I reverted to the configuration as stated above.

Any help is very much appreciated!

    Niklaas


References:

1. http://docs.freebsd.org/cgi/mid.cgi?20160519124446.GB2444
2. https://lists.freebsd.org/pipermail/freebsd-net/2016-May/045349.html


More information about the tinc mailing list