Disabling IPv6

This is an optional step only if you ARE NOT utilizing IPv6.

Why disable IPv6? Well, mostly because unless you are explicitly using it, some server hardening tasks (like firewall rules) are applied separately to IPv4 and IPv6 – forgetting that might leave you wide open to an attacker unexpectedly.

If you are not using IPv6, don’t know what it is and have never used IP address references that look like a382::ff2e:6afc:c6f5:22c5 – then there is a good chance you can safely disable IPv6 on your server.

Checking if IPv6 is enabled

You can quickly check if your server is running IPv6 by typing the following command:

ip a

If you dig through the output, you may see a few lines that start with inet6, like so:

inet6 a382::ff2e:6afc:c6f5:22c5/64 scope link

If you do, then IPv6 is running. If you don’t, then you may not have anything to do here.

Why do we want to disable IPv6?

The reason for disabling IPv6 if you don’t need it, is because many of the commands you use to secure the networking stack of a Linux machine, apply separately to the IPv4 and IPv6 stacks – potentially putting you in a position to think your server is secure but in reality it’s wide open.

Disabling IPv6

As captured from this tutorial, you can disable IPv6 temporarily (until next reboot) or permanently (will persist through server reboots).

I recommend you disable it permanently as you’d want this change to survive reboots of the server without you intervening.

This is done by editing the GRUB boot loader’s config directly; go ahead and open the config up with this command:

sudo nano -w /etc/default/grub

You want to scroll down and find the two CMDLINE arguments; this is what mine look like on a stock Ubuntu 20.04 LTS install:

GRUB_CMDLINE_LINUX_DEFAULT="maybe-ubiquity"
GRUB_CMDLINE_LINUX=""

We want to add the ipv6.disable=1 directive to both of those command line arguments, like so:

GRUB_CMDLINE_LINUX_DEFAULT="maybe-ubiquity ipv6.disable=1"
GRUB_CMDLINE_LINUX="ipv6.disable=1"

Now you want to save the file and update GRUB using the following command so it picks up the arguments:

sudo update-grub

You should see output that looks similar to the following as GRUB updates itself:

Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.5.5-55-generic
Found initrd image: /boot/initrd.img-5.5.5-55-generic
done

Note: At this point, to ensure your setting worked correctly, you should reboot your server with a shutdown -r now command – this will close your session so don’t be alarmed if you see a “closed by remote host” message in your terminal.

Give your machine a few minutes to reboot, SSH back into it and issue the ip a command again to confirm there are no inet6 entries:

$ ip a
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: enp1s0f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether a4:1c:3f:e2:a3:c4 brd ff:ff:ff:ff:ff:ff
3: enp1s0f1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether a4:1c:3f:e2:a3:c5 brd ff:ff:ff:ff:ff:ff
    inet 99.99.99.99/29 brd 99.99.99.99 scope global enp1s0f1
       valid_lft forever preferred_lft forever

Huzzah, IPv6 is disabled and your server is a tiny bit more secure!

Let’s keep going!