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.
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.
Chains
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’ -P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT imtiaz@lab:~$
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:
sudo iptables -D INPUT RULES_LINE_NUMBER
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.
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.
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.)
Thanks. i will be happy if you points newbies to it.
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. 🙂
Sid
Thanks for your comments. Yes, they are identical but, if you are not using ufw then you have to configure both separately for ipv4 and ipv6 traffic.
Useful tips…Thanks
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?
Cheers!
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.