Enable IPv6 permanently

I have an AlmaLinux9 VPS via OVH and am trying to enable IPv6. The OVH documentation isn’t great (it’s not clear if it’s relevant for AlmaLinux 9) but I found I can manually enable IPv6 with these commands:

nmcli connection modify eth0 ipv6.method manual ipv6.addresses 2001:41d0:801:2000::5ed5/64 ipv6.gateway 2001:41d0:801:2000::1 ipv6.dns "2001:4860:4860::8888 2001:4860:4860::8844"
nmcli connection up eth0

That edits /etc/NetworkManager/system-connections/eth0.nmconnection as follows:

[root@lon1 ~]# cat /etc/NetworkManager/system-connections/eth0.nmconnection 
[connection]
id=eth0
uuid=ca53bf05-52db-47e0-af91-aaeb83707ac2
type=ethernet
interface-name=eth0
timestamp=1728982393

[ethernet]

[ipv4]
method=auto

[ipv6]
address1=2001:41d0:801:2000::5ed5/64,2001:41d0:801:2000::1
dns=2001:4860:4860::8888;2001:4860:4860::8844;
may-fail=false
method=manual
route1=::/0,2001:41d0:801:2000::1

[proxy]

That all works, but after a reboot IPv6 is disabled. How do I configure IPv6 permanently?

The method for both ipv4 and ipv6 does default to auto, which for IPv6 means:

auto-configuration. By default, NetworkManager uses Router Advertisements


I.e. you have stored (proper) config, which should therefore take effect on boot, but:

I presume that the file contents has changed and the file’s timestamp is on/after boot?

  • If file still has your settings, then something ignores/overrides the stored config
  • If file has “reverted to no IPv6”, then something has updated the config on boot

My first guess on “who?” is cloud-init. That is a common approach for hypervisors.


The instructions that you point to do curiously show ipv6.method auto and manual address. Not mutually exclusive, but odd nevertheless.

Reading further, there is Step 4: Disable Cloud-init network management

In the case of newer distributions, the default configuration of Cloud-init might sometimes automatically reset the network configuration when the server starts up.

That sounds very much what you get, so follow instructions therein.

I’ve done some more testing on a second AlmaLinux 9 VPS (also with OVH). It has the address 2001:41d0:801:2000::39d8 and gateway 2001:41d0:801:2000::1.

The cloud-init network bit is disabled:

# cat /etc/cloud/cloud.cfg.d/98-disable-network-config.cfg
network: {config: disabled}

This is the original configuration:

# nmcli connection show
NAME         UUID                                  TYPE      DEVICE 
System eth0  5fb06bd0-0bb0-7ffb-45f1-d6edd65f3e03  ethernet  eth0   
lo           0d4ce924-8961-469f-85c4-e4d88259ed8e  loopback  lo     
eth0         ca53bf05-52db-47e0-af91-aaeb83707ac2  ethernet  --  

# ip -6 route
::1 dev lo proto kernel metric 256 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium

I then modified the profile settings:

# nmcli connection modify eth0 ipv6.method manual ipv6.addresses 2001:41d0:801:2000::39d8/64 ipv6.gateway 2001:41d0:801:2000::1 ipv6.dns "2001:4860:4860::8888 2001:4860:4860::8844"

# nmcli connection modify eth0 ipv6.method manual

# nmcli connection modify eth0 connection.autoconnect yes

# nmcli connection up eth0
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/3)

At that point everything looks fine:

# ip -6 route
::1 dev lo proto kernel metric 256 pref medium
2001:41d0:801:2000::/64 dev eth0 proto kernel metric 100 pref medium
fe80::/64 dev eth0 proto kernel metric 1024 pref medium
default via 2001:41d0:801:2000::1 dev eth0 proto static metric 100 pref medium

# ping6 -c 3 ipv6.google.com
PING ipv6.google.com(ams15s48-in-x0e.1e100.net (2a00:1450:400e:811::200e)) 56 data bytes
64 bytes from ams15s48-in-x0e.1e100.net (2a00:1450:400e:811::200e): icmp_seq=1 ttl=109 time=11.9 ms
64 bytes from ams15s48-in-x0e.1e100.net (2a00:1450:400e:811::200e): icmp_seq=2 ttl=109 time=10.2 ms
64 bytes from ams15s48-in-x0e.1e100.net (2a00:1450:400e:811::200e): icmp_seq=3 ttl=109 time=10.2 ms

--- ipv6.google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 10.211/10.794/11.923/0.798 ms

This is the eth0.nmconnection file:

# cat /etc/NetworkManager/system-connections/eth0.nmconnection 
[connection]
id=eth0
uuid=ca53bf05-52db-47e0-af91-aaeb83707ac2
type=ethernet
interface-name=eth0
timestamp=1728984899

[ethernet]

[ipv4]
method=auto

[ipv6]
address1=2001:41d0:801:2000::39d8/64,2001:41d0:801:2000::1
dns=2001:4860:4860::8888;2001:4860:4860::8844;
method=manual

[proxy]

# stat /etc/NetworkManager/system-connections/eth0.nmconnection 
  File: /etc/NetworkManager/system-connections/eth0.nmconnection
  Size: 287       	Blocks: 8          IO Block: 4096   regular file
Device: 804h/2052d	Inode: 25510786    Links: 1
Access: (0600/-rw-------)  Uid: (    0/    root)   Gid: (    0/    root)
Context: system_u:object_r:NetworkManager_etc_rw_t:s0
Access: 2024-10-15 13:19:38.153222403 +0100
Modify: 2024-10-15 13:16:25.402688167 +0100
Change: 2024-10-15 13:16:25.403688170 +0100
 Birth: 2024-10-15 13:16:25.402688167 +0100

After a reboot there’s no IPv6:

# ip -6 route
::1 dev lo proto kernel metric 256 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium

The eth0.nmconnection file wasn’t modified:

# stat /etc/NetworkManager/system-connections/eth0.nmconnection 
  File: /etc/NetworkManager/system-connections/eth0.nmconnection
  Size: 287       	Blocks: 8          IO Block: 4096   regular file
Device: 804h/2052d	Inode: 25510786    Links: 1
Access: (0600/-rw-------)  Uid: (    0/    root)   Gid: (    0/    root)
Context: system_u:object_r:NetworkManager_etc_rw_t:s0
Access: 2024-10-15 13:19:38.153222403 +0100
Modify: 2024-10-15 13:16:25.402688167 +0100
Change: 2024-10-15 13:16:25.403688170 +0100
 Birth: 2024-10-15 13:16:25.402688167 +0100

I can see this in the journal, so I suspect it has something to do with cloud-init…

# journalctl -u cloud-init
Oct 15 13:22:40 lon2 systemd[1]: Starting Initial cloud-init job (metadata service crawler)...
Oct 15 13:22:41 lon2 cloud-init[967]: Cloud-init v. 23.4-7.el9_4.6.alma.1 running 'init' at Tue, 15 Oct 2024 12:22:41 +0000. Up 10.43 seconds.
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: ++++++++++++++++++++++++++++++++++++++++Net device info++++++++++++++++++++++++++++++++++++++++
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: +--------+------+------------------------------+-----------------+--------+-------------------+
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: | Device |  Up  |           Address            |       Mask      | Scope  |     Hw-Address    |
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: +--------+------+------------------------------+-----------------+--------+-------------------+
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: |  eth0  | True |        57.128.182.116        | 255.255.255.255 | global | fa:16:3e:02:d8:6b |
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: |  eth0  | True | fe80::f816:3eff:fe02:d86b/64 |        .        |  link  | fa:16:3e:02:d8:6b |
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: |   lo   | True |          127.0.0.1           |    255.0.0.0    |  host  |         .         |
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: |   lo   | True |           ::1/128            |        .        |  host  |         .         |
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: +--------+------+------------------------------+-----------------+--------+-------------------+
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: +++++++++++++++++++++++++++++++Route IPv4 info+++++++++++++++++++++++++++++++
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: +-------+--------------+--------------+-----------------+-----------+-------+
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: | Route | Destination  |   Gateway    |     Genmask     | Interface | Flags |
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: +-------+--------------+--------------+-----------------+-----------+-------+
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: |   0   |   0.0.0.0    | 57.128.176.1 |     0.0.0.0     |    eth0   |   UG  |
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: |   1   | 57.128.176.1 |   0.0.0.0    | 255.255.255.255 |    eth0   |   UH  |
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: +-------+--------------+--------------+-----------------+-----------+-------+
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: +++++++++++++++++++Route IPv6 info+++++++++++++++++++
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: +-------+-------------+---------+-----------+-------+
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: | Route | Destination | Gateway | Interface | Flags |
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: +-------+-------------+---------+-----------+-------+
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: |   1   |  fe80::/64  |    ::   |    eth0   |   U   |
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: |   3   |  multicast  |    ::   |    eth0   |   U   |
Oct 15 13:22:41 lon2 cloud-init[967]: ci-info: +-------+-------------+---------+-----------+-------+
Oct 15 13:22:41 lon2 cloud-init[967]: 2024-10-15 12:22:41,333 - schema.py[DEPRECATED]: Deprecated cloud-config provided:
Oct 15 13:22:41 lon2 cloud-init[967]: chpasswd.list: List of ``username:password`` pairs. Each user will have the corresponding password set. >
Oct 15 13:22:41 lon2 systemd[1]: Finished Initial cloud-init job (metadata service crawler).

There is also a warning that could be relevant:

# journalctl -p 3
Oct 15 13:22:38 lon2.beepmode.co.uk kernel: Warning: Unmaintained driver is detected: ip_set

I’ll keep debugging but any suggestions would be very welcome!

Disabling cloud-init (touch /etc/cloud/cloud-init.disabled) makes no difference, so that doesn’t seem to be the culprit.

Success… it looks like cloud-init was the culprit after all, but not in the way I expected…

The issue appears to be the ifcfg-eth0 file:

[root@lon2 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
# Created by cloud-init automatically, do not edit.
#
AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=eth0
HWADDR=fa:16:3e:02:d8:6b
MTU=1500
ONBOOT=yes
TYPE=Ethernet
USERCTL=no

It seems odd the file even exists as a README file in the directory explains that /etc/sysconfig/network-scripts/ should no longer be used. In any case, disabling cloud-init and renaming the file does the trick:

# touch /etc/cloud/cloud-init.disabled
# mv /etc/sysconfig/network-scripts/ifcfg-eth0{,.bak}
# nmcli connection modify eth0 ipv6.method dhcp
# nmcli connection up eth0
# reboot

After that you still have IPv6.

If there’s a way to do this without disabling cloud-init then I’d be keen to test that.

1 Like

What about just removal of /etc/sysconfig/network-scripts/ifcfg-eth0
and addition of network: {config: disabled} to config of enabled cloud-init?

Would that still recreate the /etc/sysconfig/network-scripts/ifcfg-eth0 and undesired config?

Good question…

I just did two tests. First, I removed the /etc/cloud/cloud-init.disabled file and rebooted the machine. That worked; the IPv6 configuration was still there.

I then also removed /etc/cloud/cloud.cfg.d/98-disable-network-config.cfg and again rebooted the machine. That worked as well.

So it looks like the issue was purely the ifcfg-eth0 file.