Preliminary
Goals
- Direct connection to the containers over the internet with IPv6
- Hint: If you point a Cloudflare proxied FQDN to the IPv6 of the container Cloudflare will add IPv4 compatibility for you
- Optional for Ubuntu users: Disable netplan and use systemd-networkd directly, because netplan doesn’t handle NDP proxying at the moment of writing this
- Making it work if your ISP uses MAC address based routing
- Making it work if they use NDP by using NDP proxying with systemd-networkd
Prerequisites
- Having an /64 or larger IPv6 subnet assigned to your Incus host server
- Running a newer Distro with
- Recent systemd version with systemd-networkd for networking (or netplan)
- For testing IPv6 connectivity from your local browser you will have to have IPv6 connectivity fomr your local network. Alternatively you can use something like Cloudflare WARP to achieve that.
Networking
If you want to keep netplan you can skip Networking and continue with Incus. You will have to make sure though that forwarding is enabled (2.1).
0. [Optional] for Ubuntu users: Remove Netplan
WARNING: This might break things for you. Do this at your own risk.
Run the following snippet in your terminal:
if apt -q list --installed 2>/dev/null | grep -q "^netplan.io"; then
systemctl enable systemd-networkd
apt -y autoremove --purge netplan.io netplan-generator python3-netplan
rm -r /etc/netplan
apt -y autoremove netplan-generator python3-netplan libnetplan1
rm -f /usr/lib/systemd/system-generators/netplan
rm -f /run/systemd/network/*.network
fi
1. Setup systemd-networkd
Here a basic networking setup with networkd, you will most probably have to change things here:
instance_mac_address="REPLACE WITH YOURS"
instance_ipv4_gateway="$(ip route list default |
grep -o "via [0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" |
grep -o "[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*")"
instance_ipv4_netmask_cidr="$(ip a | grep "inet " | grep -v "host lo" |
grep " e[a-z0-9]*" | grep -o "/[0-9]*" | sed "s|/||")"
instance_ipv6_gateway="fe80::1"
tee /etc/systemd/network/ethernet.network <<EOF
[Match]
PermanentMACAddress=$instance_mac_address
Name=e*
[Network]
LinkLocalAddressing=ipv6
Address=$instance_ipv4_address/$instance_ipv4_netmask_cidr
Address=$instance_ipv6_address/128
DNS=1.1.1.1
DNS=8.8.8.8
DNS=2606:4700:4700::1111
DNS=2001:4860:4860::8888
Domains=invalid
#IPv6ProxyNDP=true
[Route]
Destination=0.0.0.0/0
Gateway=$instance_ipv4_gateway
GatewayOnLink=true
[Route]
Destination=::/0
Gateway=$instance_ipv6_gateway
GatewayOnLink=true
EOF
systemctl restart systemd-networkd
2. Turn on IPv6 forwarding and NDP proxying in the Kernel (in case we need it)
tee --append /etc/sysctl.conf <<EOF
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.eth0.forwarding=1
net.ipv6.conf.all.proxy_ndp=1
net.ipv6.conf.eth0.proxy_ndp=1
EOF
Also make sure IPv6 is not disabled in /etc/sysctl.conf by looking at the whole file.
You may then run: sysctl --system
2.1 Change firewall settings if forwarding is blocked through the firewall.
If you are using UFW you may check the /etc/default/ufw
file for DEFAULT_FORWARD_POLICY="ACCEPT"
No matter what frontend you may use for firewalling, you can check all nftables rules with this command: nft list ruleset
Incus
3. Install and setup Incus
When initiating Incus after the install put the IPv6/64 range as the incusbr0 IPv6 address. Beware that you should not use the same address on the host’s ethernet connection and on incusbr0. The ipv4 stuff can be left alone and set to auto
and stay with NAT.
If already installed you can run:
incus network set incusbr0 ipv6.address $ipv6address2/64 # Other one than host ethernet
This way the containers are going to get an ipv6 address from incusbr0.
Also the following options should be set:
incus network set incusbr0 ipv6.dhcp false
incus network set incusbr0 ipv6.nat false
incus network set incusbr0 ipv6.routing true
4. Run a Linux Container and test connectivity
Enjoy a container with an universally routable IPv6.
To get the address you can run incus list
Install NGINX inside the container and paste the IPv6 in a browser on your local computer in [ ] braces.
If you get the NGINX standard page you are done. If not read on about NDP proxying.
NDP Proxying
If you kept netplan you can use the instructions by @candlerb from a comment below: Globally routable IPv6 for your Incus Linux Containers - #4 by candlerb
After augmenting your netplan config with these steps NDP Proxying will also work.
5. Enable NDP proxying
Enable NDP proxying in /etc/systemd/network/ethernet.network
by removing the hash in front of IPv6ProxyNDP and adding the IPv6 of the container with IPv6ProxyNDPAddress.
For each container IPv6 there will have to be an additional line like below.
DNS=2606:4700:4700::1111
DNS=2001:4860:4860::8888
Domains=invalid
IPv6ProxyNDP=true
IPv6ProxyNDPAddress=$ipv6_container
[Route]
Destination=0.0.0.0/0
Then simply reload networkd:
systemctl reload systemd-networkd
After a short while and making a few requests through your browser it should work and you should finally get the standard page of NGINX. Going inside of the container and doing some network requests to IPv6 addresses/hosts might also help.