Support for the Internet Protocol version 6 is available on Linux since 1996. The kernel implements this functionality, which is usually active and enabled by default on all the major distributions, via the “ipv6” module. Sometimes, for various reasons, it may be desirable to temporarily or permanently disable IPv6 networking.
In this tutorial we learn how to temporarily or permanently disable IPv6 networking on Linux, using sysctl, NetworkManager, or kernel command line arguments.
In this tutorial you will learn:
- How to temporarily disable IPv6
- How to permanently disable IPv6 using NetworkManager, sysctl or via kernel command line arguments
Temporary disabling IPv6
The simplest way to temporarily disable IPv6 networking at runtime on Linux, is by writing the appropriate value to the files exposed as an interface by the kernel under the /proc/sys/net/ipv6/conf
directory. This directory contains a subdirectory for each existing network interface, plus the “all”, and “default” directories:
$ ls /proc/sys/net/ipv6/conf all default enp1s0 lo
To disable IPv6 for a specific interface, all we have to do is to write
1
to the "disable_ipv6"
file located under the directory named after the target interface. Say, for example, we want to disable IPv6 for the loopback interface (lo); we would run:
$ echo 1 | sudo tee /proc/sys/net/ipv6/conf/lo/disable_ipv6
What are the “all” and “default” directories for? Changes we make to configuration files under the “default” directory will be effective on network interfaces added from the moment we make those changes on; changes we make to configuration files under the “all” directory, instead, affect all existing interfaces and default settings at once. We can easily verify this. On the machine I am using, there are actually two network interfaces: enp1s0
and lo
; both of them have been assigned an IPv6 address (inet6):
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host noprefixroute valid_lft forever preferred_lft forever 2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether BA-6F-9B-BB-26-DE brd ff:ff:ff:ff:ff:ff inet 192.168.122.103/24 brd 192.168.122.255 scope global dynamic noprefixroute enp1s0 valid_lft 3547sec preferred_lft 3547sec inet6 fe80::5054:ff:fe36:2597/64 scope link noprefixroute valid_lft forever preferred_lft forever
Let’s retrieve the value currently written to the “disable_ipv6” files under the corresponding directories in /proc/sys/net/ipv6/conf/, including “all” and “default”:
$ cat /proc/sys/net/ipv6/conf/*/disable_ipv6 0 0 0 0
As expected, the value is “0” in all files: this means IPv6 is enabled. Now, let’s write “1” to the “disable_ipv6” file under the “all” directory:
$ echo 1 | sudo tee /proc/sys/net/ipv6/conf/all/disable_ipv6
Observe how IPv6 has been disabled for all interfaces; the same value has been set as a default:
$ cat /proc/sys/net/ipv6/conf/*/disable_ipv6 1 1 1 1
IPv6 addresses have also been removed from the network interfaces:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether BA-6F-9B-BB-26-DE brd ff:ff:ff:ff:ff:ff inet 192.168.122.103/24 brd 192.168.122.255 scope global dynamic noprefixroute enp1s0 valid_lft 3361sec preferred_lft 3361sec
Disabling IPv6 using sysctl
Another way of temporarily disabling IPv6, is by changing kernel parameters values at runtime using the sysctl
utility. Writing to the /proc/sys/net/ipv6/conf/all/disable_ipv6 file, as we did in the previous example, is equivalent to assigning the same value to the sysctl net.ipv6_conf.all.disable_ipv6
variable. To use sysctl in “write” mode, we invoke it with the -w
option:
$ sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
Changes we perform manually or by using sysctl, are not persistent. Let’s see how to make them survive a reboot.
Disabling IPv6 permanently
There are a few methods we can use to permanently disable IPv6. If the NetworkManager service is enabled, and network interfaces are managed by it, the preferred method is to use the “connection-editor” utility. The graphical version of the tool can be invoked by running:
$ nm-connection-editor
We select the appropriate connection (enp1s0 in this case), then we click on the “gear” button, to edit its configuration:
We click on the “IPv6 Settings” tab, and in the dropdown widget associated to the “Method” label, we select “Ignore”. To confirm our choice, we click on the “Save” button:
The change will be effective after we restart the NetworkManager service:
$ sudo systemctl restart NetworkManager
If the interface we want to disable IPv6 for is not managed by NetworkManager, we can make sysctl variables values persistent, by writing them in a file under the /etc/sysctl.d
directory, or in the /etc/sysctl.conf
file. The reason we don’t want to use this method if NetworkManager is enabled, is that it could override sysctl values. In order to disable IPv6 for all active interfaces, and make it a default, we may write the following line in the /etc/sysctl.d/90-disable_ipv6.conf
file (the name of the file is arbitrary, the essential thing is that it has the “.conf” extension):
net.ipv6.conf.all.disable_ipv6 = 1
To disable IPv6 for a specific interface (e.g. enp1s0), instead:
net.ipv6.conf.enp1s0.disable_ipv6 = 1
Changes are read and applied on boot by the systemd-sysctl
service; to make them immediately effective, we can also run the following command:
$ sudo systctl -p /etc/sysctl.d/90-disable_ipv6.conf
The -p
option of the sysctl utility is the short version of --load
: it is used to load settings from the /etc/sysctl.conf file, or from the one we pass as argument.
Disabling the IPv6 stack completely
Until now, we disabled IPv6 networking for all or some network interfaces. One more radical solution consists into completely disabling the IPv6 stack in the kernel. We can do this by setting the ipv6.disable
kernel parameter to 1. When using the GRUB bootloader, we can do this by modifying the GRUB_CMDLINE_LINUX_DEFAULT or the GRUB_CMDLINE_LINUX lines in the /etc/default/grub
file (changes made to the former are applied only on normal boot, while those made to the latter are applied also when booting in “recovery” mode) :
GRUB_CMDLINE_LINUX_DEFAULT="quiet ipv6.disable=1"
To rebuild the bootloader configuration on Debian and Debian-based distributions, we run:
$ sudo update-grub
On Fedora and other distributions based on it, instead:
$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg
The next time we boot the system, since we completely disabled the IPv6 stack, we will find the /proc/sys/net/ipv6
directory doesn’t exist anymore:
$ ls /proc/sys/net/ipv6/ ls: cannot access '/proc/sys/net/ipv6/': No such file or directory
Closing thoughts
In this tutorial we learned how to disable IPv6 networking on Linux. We saw how to temporarily disable it by simply writing the appropriate values to the file exposed as interface under the /proc pseudo filesystem, or by using the sysctl utility. We also saw how to disable the protocol permanently by using NetworkManager, and finally, how to completely disable IPv6 stack in the kernel.