Running incus on vServer with NAT IPv4 but use one of the plenty global IPv6 addresses for the container

I rented a vServer on which I want to run Incus container VMs.

The vServer has assigned a single IPv4 address, but a whole /64 range of IPv6 addresses. I believe this is a common setup these days.

My idea is to use NAT for IPv4 connectivity in the containers, but assign the containers one of the plenty global IPv6 addresses that where assigned to the vServer.

However, while IPv4 connectivity within the container works fine. I can’t seem to figure out how to configure a working non-NATed IPv6 setup. My idea is that the Incus VMs use DHCP for IPv4, but I use a static configuration for IPv6.

Assume the following on the Incus Host:

/etc/systemd/network/ens3.network

[Match]
Name=ens3

[Network]
Address=202.62.237.42/22
Gateway=202.62.236.1
Address=2a03:4002:5c:cf7::1/64
Gateway=fe80::1
DNS=…
# incus network list
+----------+----------+---------+-----------------+------+-------------+---------+---------+
|   NAME   |   TYPE   | MANAGED |      IPV4       | IPV6 | DESCRIPTION | USED BY |  STATE  |
+----------+----------+---------+-----------------+------+-------------+---------+---------+
| ens3     | physical | NO      |                 |      |             | 0       |         |
+----------+----------+---------+-----------------+------+-------------+---------+---------+
| incusbr0 | bridge   | YES     | 10.177.194.1/24 | none |             | 2       | CREATED |
+----------+----------+---------+-----------------+------+-------------+---------+---------+
| lo       | loopback | NO      |                 |      |             | 0       |         |
+----------+----------+---------+-----------------+------+-------------+---------+---------+
# incus ls
+--------+---------+-----------------------+------+-----------+-----------+
|  NAME  |  STATE  |         IPV4          | IPV6 |   TYPE    | SNAPSHOTS |
+--------+---------+-----------------------+------+-----------+-----------+
| nujeru | RUNNING | 10.177.194.147 (eth0) |      | CONTAINER | 0         |
+--------+---------+-----------------------+------+-----------+-----------+

And the following setup on the nujeru VM:

/etc/systemd/network/eth0.network

[Match]
Name=eth0

[Network]
DHCP=ipv4
DNS=…

[DHCP]
ClientIdentifier=mac

How can I assign the nujeru VM the global IPv6 address 2a03:4002:5c:cf7::2/64?

It seems like I can’t use the incusbr0 since it is “managed”. Hence I wonder if need to create an additional bridge.

I have tried incus network attach ens3 nujeru to directly attach the VM to the “physical” interface of the host. This caused a new interface eth2 in the VM to show up. On this eth2 interface I’ve configured the IPv6 address 2a03:4002:5c:cf7::2/64 with fe80::1 as gateway. But this did not have the desired effect.

I went with IPv6 NATing. Bridging wouldn’t work, as I suspect that my vServer provider filters packets from unexpected MAC addresses.

To still “assign” each Incus VM a dedicated IPv6, I first had to add the IPv6 address to the host.

Then I enabled IPv6 NAT on incusbr0:

incus network set incusbr0 ipv6.address=auto ipv6.nat=true ipv6.dhcp=true ipv6.routing=true

and configured a network forward from the public IPv6 to the private IPv6 of the container:

incus network forward create incusbr0 2a03:4002:5c:cf7::3 target_address=fd42:298d:d0ee:df5f:1266:6aff:feca:d6a8

I think it should be possible to setup source NAT (snat), so that the containers outbound IPv6 address would be the one “assigned” to the container and not the IPv6 address of the host. It would be great if incus had built-in support for snat.

1 Like

I like your approach. An alternative at Hetzner is to use a floating IPv6 network at costs of 1 Euro/month excl VAT and use this for your IPv6 network. But why pay extra if forwarding is good enough.

There are pros and cons in using private IPv6 or the public subnet.

On default Incus will setup a private IPv6 during initialisation, except you opted out. In this case IPv6 acts like IPv4 dynamic assigned. To assign static IPv6 you need to set the ipv6.dhcp.stateful flag and assign IP addresses to your containers where you want to have static ones.

To use your public IPv6 subnet you need to add an ip address of your subnet to your incusbr0 interface. Something like ipv6.address: 2a03:4002:5c:cf7::3/64 and of course ipv6.nat: "false", change your Incus host network to:

[Match]
Name=ens3

[Network]
Address=202.62.237.42/22
Gateway=202.62.236.1
Address=2a03:4002:5c:cf7::1/128
Gateway=fe80::1
DNS=…

Important is your host only gets a .../128 IPv6 assigned to free up the subnet for Incus to use. There are a few threads about this topic search for Hetzner and you will get a glory of more details.

With these changes your container will get public IPv6 assigned.

Enjoy