How to disable IPv6 on Linux

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

how to disable IPv6 on linux

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 sysctlutility. 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:

networkmanager connection editor
NetworkManager connection editor

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:

disabling IPv6 for the enp1s0 interface
Disabling IPv6 for the enp1s0 interface

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.conffile (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.



Comments and Discussions
Linux Forum