How to: Linux firewall for IPv6

By on 8 Jun 2018

Category: Tech matters

Tags: , , , , ,


Blog home

iptables is a popular utility that allows system administrators to configure tables provided by the Linux kernel firewall and the chains and rules it stores.

It is the most common and widely used Linux firewall for IPv4 traffic and it has a version called ip6tables, which is used for IPv6 traffic. Both versions need to be configured separately.

In this post, I will run through how to configure ip6tables in the Ubuntu 16.04 system. Note, a basic knowledge of iptables, firewall policy, and IPv6 is required.

Read Security basics: firewall policy

IPv6 in the system

Before configuring ip6tables, make sure your system is IPv6 supported. To check, type the following command:

cat /proc/net/if_inet6

00000000000000000000000000000001 01 80 10 80 lo
fe800000000000000a0027fffeec4f60 02 40 20 80 enp0s8

If you see an output similar to this, then your server supports IPv6. Note, the IPv6 address and interface name will differ for your address.

If the /proc/net/if_inet6 file doesn’t exist, you could try loading the IPv6 module via modprobe ipv6.

Learn more about IPv6 at APNIC

Firewall status

In a newly installed Ubuntu server, the firewall chains are empty by default. To see the chains and rules type the following command (-L for listing rules in chains; -n to print IP addresses and ports in numeric format):

imtiaz@lab:~$ sudo ip6tables -L -n
[sudo] password for imtiaz:

You will see an output similar to the example below:

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Notice that all the chains (INPUT, FORWARD, OUTPUT) are empty and the default policy for the chains is set to ACCEPT.


To see only the chains, and the default policy set for the chains, type the following command:

imtiaz@lab:~$ sudo ip6tables -S | grep -e ‘-P’

As you can see, the default policy is set to ACCEPT for all the chains.

First IPv6 rule

Let’s make our first rule. Type the following command to append a rule (the -A option) to our INPUT chain:

sudo ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

This will allow established, related connections, which will be helpful if we change the default INPUT chain policy to DROP so our SSH session is not disconnected. To see the rule, type sudo ip6tables -L -n and notice the difference.

Appending rules

Let’s add some more IPv6 rules to our firewall.

sudo ip6tables -A INPUT -p tcp --dport ssh -s HOST_IPV6_IP -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 21 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 25 -j ACCEPT

The first rule will allow SSH from a specific IPv6 address. The second, third, and fourth rules will allow HTTP(80), FTP(21) and SMTP(25) inbound traffic.

Now let’s review the IPv6 firewall rules.

Check the IPv6 rules

To see the IPv6 rules with line numbers, type the following command:

sudo ip6tables -L -n --line-numbers

We can call these line numbers, rule number — these can be useful to insert or delete a rule.

Deleting rules

In some cases, you may need to delete one or more rules from your iptables chains. There are two ways you can delete rules from the chain — by rule specification and rule number.

Type the following command to delete rules by rule specification; for example, let’s delete the ftp (21) rule:

sudo ip6tables -D INPUT -p tcp --dport 21 -j ACCEPT

Just like the command APPEND (A), replace the A with D to delete a rule.

The same rule can be deleted by rule number (if you haven’t deleted the ftp rule), as follows. First list the rules with line numbers:

sudo ip6tables -L --line-numbers

You will see the rules with rule numbers. To delete the rules from a chain, type the following command:


Be careful when deleting rules by rule number — after deleting one rule the order of the rule numbers in the chain changes.

Inserting rules

Like iptables rules, ip6tables rules are also processed sequentially and if a match is found, then the rest of the rules will be skipped. If you want to rearrange your rules, or want to add a new rule in a specific position, first list the rules with the line-numbers option then type the following command:

sudo ip6tables -I INPUT 2 -p icmpv6 -j ACCEPT

This will insert the rule (-I option) in the second position of the INPUT chain.

Changing the policy

If you need to change the default policy of a chain, type the following command:

sudo ip6tables -P INPUT DROP

In this example, I’m changing the INPUT chain policy from ACCEPT to DROP. Care is needed when changing the default policies as you may lock yourself out of a remote host if the required access rules aren’t configured.

Creating new chains

You can create your own chain in ip6tables. Type the following command to create a new chain name NEW_CHAIN or any other name you like (don’t use a space).

sudo ip6tables -N NEW_CHAIN

If you type sudo ip6tables -L -n, you will see the newly created chain with other chains. To delete the chain, type the following command:

sudo ip6tables -X NEW_CHAIN

Save your work

ip6tables rules will work instantly, however, if you restart your server all rules will be deleted. You need to save the rules so that they become active after a reboot.

There are several ways to do this; the easiest way is to use the iptables-persistent package. Type the following command to install the iptables-persistent package:

sudo apt-get install iptables-persistent

Press ‘Yes’ for both IPv4 and IPv6 rules when prompted. After installation, you will find two files in the /etc/iptables location name IPv4 and IPv6. You can open the file and make your changes here. You can also do a start|restart|reload|force-reload|save|flush from here, for example, if you want to save the current loaded iptables rules, type the following command:

sudo /etc/init.d/iptables-persistent save

This will save both IPv4 and IPv6 rules.

Thanks for reading this post. If you enjoyed it, please share it with your network and let me know your thoughts in the comments below.

Original post appeared on Imtiaz’s blog.

Imtiaz Rahman works for a financial organization in Bangladesh. He has experience in system, network and security administration.

Rate this article

The views expressed by the authors of this blog are their own and do not necessarily reflect the views of APNIC. Please note a Code of Conduct applies to this blog.


  1. Wolfgang Rupprecht

    Great intro. Thanks for taking the time to write it. I’m going to save this URL and point newbies to it.

    (BTW. I like your idea of adding a source address test for ssh. It might save people with default sshd config files and poor passwords some embarrassment and cpu time.)

  2. Sid B.

    Aren’t the commands for iptables and ip6tables essentially identical – and if you set the firewall for one, shouldn’t you set the other the same way?

    It might seem obvious, but never saw anyone actually mention it. 🙂


  3. David Elstob

    I’ve been having issues with Stackpath and inserted the rules one by one. It was a pain.

    Using your method, I have created the new files in minutes. So now I’ve got the IPv4 and IPv6 files full of Stackpath IP blocks.

    So that’s amazing. Thanks.

    Only now I guess they’re just two files – how do I tell the server to load them please, without wiping out the original blocks to my Google Cloud port 22, etc?

    Merge and run them?


    1. Imtiaz Rahman

      Thanks for your comments and good to know that it helps you. I’m not familiar with Stackpath, but yes, there will be two files and it will load automatically during server boot time. For your existing rule, you may marge them or write the rules again, whatever fits in your environment.


Leave a Reply

Your email address will not be published. Required fields are marked *