With the release of Ubuntu 18.04, it was decided to replace the traditional network configuration with the YAML-based netplan. Although the configuration initially seems a lot easier and more user-friendly, when you add IPv6 and routing in the mix, it soon goes terribly wrong. Most explanations on netplan show you how to set it up on a host machine, or with static routing, but none show the hassle of setting it up as a router with a dynamic IPV6 address-space given by your ISP.
Create a .yaml file in /etc/netplan, or edit the one that's already there.
network:
version: 2
renderer: networkd
ethernets:
enp1s0f1:
match:
maccaddress: 00:15:XX:XX:XX:01
addresses:
- 192.168.1.1/24
- 2001:abba:abba:abba::1/64
nameservers:
addresses:
- 8.8.8.8
- 8.8.4.4
set-name: lan
enp1s0f0:
match:
maccaddress: 00:15:XX:XX:XX:00
set-name: wan
dhcp4: true
dhcp6: true
accept-ra: true
macaddress: 01:02:03:04:05:06
So we have 2 network interfaces, enp1s0f0
wich will be our wan-interface and enp1s0f1
our lan-interface. To be certain I added the mac-addresses of the interfaces in a match
section, then I renamed the interfaces with set-name
. So a ifconfig
will show a lan
and a wan
interface.
We defined the lan with 2 static ip addresses, assume that the IPv6 address is the lowest address in the /64 subnet given to you by your ISP.
My ISP expects the DHCP IPv4 request to come from a registered MAC address (01:02:03:04L05:06 in this case). I'll get to the IPv6 in a minute...
Ok, so far so good, netplan apply
activates the configuration. Beware however it does not remove any previous active configurations, so you old interfaces still exist with their ip addresses, ... And while you are testing, sometimes you'll get multiple of the same address on interfaces, and what more. If you are sure of your config, I prefer a reboot.
##Enabling routing After the reboot, test your IP connectivity and if it is working, then it is time to add the routing.
As explained in all tutorials, you activate routing by sysctl -w net.ipv4.ip_forward=1
, followed by sysctl -p
, and addin the necessary masquerading rules to iptables.
If all is OK, you should now be able to access the internet from a workstation, providing it has the correct ip and gateway. You should setup a dhcp-server, for a tutorial unverified, look here. Don't forget to make the changes permanent by adding them to /etc/sysctl.conf
or they will be gone after a reboot.
Now to enable IPv6 routing, we should just do the same... sysctl -w net.ipv6.conf.all.forward=1
, sysctl -p
. But sadly that is not enough... To do routing in an IPv6 environment you need to do router-anouncements (or short RA), this can be done with radvd
. So we apt install
this, and configure it:
interface lan {
AdvManagedFlag off; # no DHCPV6 server here.
AdvOtherConfigFlag off; # not even for options;
AdvSendAdvert on;
AdvDefaultPreference high;
AdvLinkMTU 1280;
prefix 2001:abba:abba:abba::/64
{
AdvOnLink on;
AdvAutonomous on;
};
RDNSS 2001:abba:abba:abba::1 { };
};
This config assumes you have a DNS server running on this host as well... (the RDNSS line).
Checking on a client machine on the network, yes we have an IPV6, and I can ping6
this host.
Trying to ping a host on the internet using IPv6 fails... Huh, what is going on?
My ISP (Telenet in Belgium) requires me to fill in a DUID, a DHCP Unique Identifier. This is can be done using the wide_mkduid.pl
script with the the name of the interface. It shows the DUID, enter it on the webpage. Reboot the server so it refreshes it's dhcp info, and try again. Still no luck. Checking the docs for netplan, shows a dhcp-identifier
, sadly the only option you can specify is mac
, and it only works for IPv4. Ah, but networkd
has an option for this, add/edit the file /etc/systemd/networkd.conf
and add
[DHCP]
DUIDType=vendor
DUIDRawData=00:00:<followed by the DUID>
Try again. Still not working!
Back to the drawing board! It seems netplan can not configure this in the right way to ask networkd to make a correct dhcp request with the DUID. I know from using ubuntu 16.04 that wide-dhcpv6-client can, but how do we get this working?
Replace This is apparently no longer neccessary, just set both dhcp6
and accept-ra
, from the enp1s0f0
section of the netplan yaml-file, with link-local: [ ]
. This will effectively disable IPv6 on the interface. Why, because netplan hogs port 546 on that interface even if we say we do not want it to do dhcp6, and dhcp6c
needs to be able to bind to it.dhcp6
and accept_ra
to false. If you leave the link-local: []
, the wide-dhcpv6-client will error out with client6_send: transmit failed: Cannot assign requested address
.
Create or edit the file /etc/wide-dhcpv6/dhcp6c.conf
:
# Default dhpc6c configuration: it assumes the address is autoconfigured using
# router advertisements.
profile default
{
# information-only;
# request domain-name-servers;
# request domain-name;
script "/etc/wide-dhcpv6/dhcp6c-script";
};
interface wan {
send ia-pd 0;
send ia-na 0;
};
id-assoc pd 0 {
prefix-interface lan {
sla-len 8;
sla-id 0;
ifid 1;
};
};
id-assoc na 0 {
};
Remember when we ran wide_mkduid.pl
? It not only showed us the DUID, but it also created a dhcp6c_duid
file in folder where we ran it. Move this file to /var/lib/dhcpv6/
.
So after -yet another- reboot, you check your lan interface, ifconfig lan
, only to find that it has no more IPv6. Yes, by removing the IPv6 options in Step 1, networkd disabled IPv6 on the interface, as can be seen in /proc/sys/net/ipv6/conf/wan/disable_ipv6
, it now contains 1.
echo 0 > /proc/sys/net/ipv6/conf/wan/disable_ipv6
, and we have a link-local IPv6 address, systemctl restart wide-dhcpv6-client
, and we have a public ip, but no access.
Some more research and I found that linux disables accept_ra
when you enable forwarding
on an interface!???
So sysctl -w net.ipv6.conf.wan.accept_ra=2
, followed by sysctl -p
. And we have internet over IPv6, locally and for the rest of the network!
To make these changes permanent, I created a /etc/rc.local
file, and made it executable.
Yes, a final reboot, to check that everything is working.
Instead of making the changes to /etc/sysctl.conf
you could also add these commands to /etc/rc.local
to be executed upon boot.
My ISP does give me a static IPv6 range. The WAN-interface gets a dynamic address, but it also gets an RA with the subnet that is then announced by radvd, allowing the hosts on my LAN to get their IPv6.