ip6tables: IPv6 Firewall For Linux

by on September 12, 2008 · 15 comments· LAST UPDATED July 27, 2010

in , ,

Q. IPv4 by default protect internal host using RFC 1918 private IP address. But IPv6 offers direct global address which result into exposing all internal hosts as well. How do I create default IPv6 firewall to drop all incoming (except ping6 request) connection and only allow outgoing requests from Linux workstation?

A. You need to use Ip6tables command to create IPv6 firewall scripts. Ip6tables is used to set up, maintain, and inspect the tables of IPv6 packet filter rules in the Linux kernel.

A note about IPv6 private ips

IPv6 does not include private network features such as NAT. Because of the very large number of IPv6 addresses. However, FC00::/7 prefix used to identify Local IPv6 unicast addresses. All IPv6 users should be able to obtain IPv6 address space for use at their discretion and without artificial barriers between their network and the Internet.

Redhat / CentOS / Fedora Linux Specific Configuration

The /etc/sysconfig/ip6tables can be used to configure and open ports, the default config is as follows:

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -i eth0 -j ACCEPT
-A RH-Firewall-1-INPUT -i br0 -j ACCEPT
-A RH-Firewall-1-INPUT -p icmpv6 -j ACCEPT
-A RH-Firewall-1-INPUT -p 50 -j ACCEPT
-A RH-Firewall-1-INPUT -p 51 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp --dport 5353 -d ff02::fb -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 32768:61000 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 32768:61000 ! --syn -j ACCEPT
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp6-adm-prohibited
COMMIT

To open port tcp and udp port 53 add the following line before final --reject-with icmp6-adm-prohibited line:

# open port 22
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 22 -j ACCEPT

At the end it should look as follows to which will open IPv6 port numbers, 53, 22, 25, 80, 110, and 443:

 
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -i eth0 -j ACCEPT
-A RH-Firewall-1-INPUT -i br0 -j ACCEPT
-A RH-Firewall-1-INPUT -p icmpv6 -j ACCEPT
-A RH-Firewall-1-INPUT -p 50 -j ACCEPT
-A RH-Firewall-1-INPUT -p 51 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp --dport 5353 -d ff02::fb -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 32768:61000 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 32768:61000 ! --syn -j ACCEPT
 
# open port 53
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 53 -j ACCEPT
-A RH-Firewall-1-INPUT -m udp -p udp --dport 53 -j ACCEPT
 
# open port 22
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 22 -j ACCEPT
 
# open mail server ports smtp, pop3, and imap
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 25 -j ACCEPT
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 110 -j ACCEPT
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 143 -j ACCEPT
 
# open port 80 & 443
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 80 -j ACCEPT
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 443 -j ACCEPT
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp6-adm-prohibited
COMMIT
 

Save and close the file. Now, you can restart firewall as follows:
# service ip6tables restart
# ip6tables -L -v -n

Sample Restricted IPv6 Linux Firewall Script

#!/bin/bash
IPT6="/sbin/ip6tables"
PUBIF="eth1"
echo "Starting IPv6 firewall..."
$IPT6 -F
$IPT6 -X
$IPT6 -t mangle -F
$IPT6 -t mangle -X
 
#unlimited access to loopback
$IPT6 -A INPUT -i lo -j ACCEPT
$IPT6 -A OUTPUT -o lo -j ACCEPT
 
# DROP all incomming traffic
$IPT6 -P INPUT DROP
$IPT6 -P OUTPUT DROP
$IPT6 -P FORWARD DROP
 
# Allow full outgoing connection but no incomming stuff
$IPT6 -A INPUT -i $PUBIF -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT6 -A OUTPUT -o $PUBIF -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
 
# allow incoming ICMP ping pong stuff
$IPT6 -A INPUT -i $PUBIF -p ipv6-icmp -j ACCEPT
$IPT6 -A OUTPUT -o $PUBIF -p ipv6-icmp -j ACCEPT
 
############# add your custom rules below ############
### open IPv6  port 80 
#$IPT6 -A INPUT -i $PUBIF -p tcp --destination-port 80 -j ACCEPT
### open IPv6  port 22
#$IPT6 -A INPUT -i $PUBIF -p tcp --destination-port 22 -j ACCEPT
### open IPv6  port 25
#$IPT6 -A INPUT -i $PUBIF -p tcp --destination-port 25 -j ACCEPT
############ End custom rules ################
 
#### no need to edit below ###
# log everything else
$IPT6 -A INPUT -i $PUBIF -j LOG
$IPT6 -A INPUT -i $PUBIF -j DROP

Further readings:

TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!

{ 15 comments… read them below or add one }

1 diay September 14, 2008 at 5:47 pm

thanks for sharing a shell script.

Reply

2 Martijn January 5, 2009 at 5:14 pm

Hi, interesting script. Thanks for sharing it.

However, it’s missing one thing that would make it a lot more useful:
The PUBIF variable is set but never used, so the rules now apply to all interfaces, instead of just the public interface. If you could modify the script to use the PUBIF variable, it will still be useful for pc’s but also for IPv6 routers.

Hope you’ll consider this. Thanks.

Reply

3 nixCraft January 5, 2009 at 6:40 pm

@ Martijn,

I’ve just updated the script. Hope this helps!

Reply

4 Martijn January 6, 2009 at 11:35 pm

Yes, that is definitely useful! Thanks for the quick response Vivek. Implementing it now.

Reply

5 Alex May 19, 2009 at 3:54 pm

Hi :)
I’m just wondering if the last Input DROP is necessary as the default policy already is DROP ?

cheers!

Reply

6 j July 3, 2009 at 6:51 am

alex – you are right

but if you set default policy to ACCEPT then you can use this:

# log everything else
$IPT6 -A INPUT -j LOG
$IPT6 -A INPUT -j DROP

PS: taken from http://tnt.aufbix.org/linux/firewall6

Reply

7 bibi July 24, 2009 at 8:11 am

this script is NOT secure, read on icmpv6 security problems….

Reply

8 Anders November 18, 2009 at 6:56 pm

Alex: Last drop is not necessary, but it should be put there to be secure, it’s easy to make mistakes, and this will hopefully catch some…

Becouse the script doesn’t warn about this: IPv6 ICMP is much more than just PING. If one filter that one, IPv6 will not work propperly.

Bibi: Any links with more information? I am interested in all stuff about IPv6.

Reply

9 Anders November 18, 2009 at 7:01 pm

Yes, I forgot.

NAT has nothing to do with security. Firewall is the tool for that. There is ways of pass a NAT without a propper firewall setting.

There is LOTS of people that don’t understand this, and some will argue about that. Please don’t do that, just read relevant RFC:s. And use a propper firewall setting on all your machines.

Reply

10 Albert February 1, 2011 at 3:02 pm

Hello

Private networks I guess still have their use. It is difficult to convince certain organizations (health, banks, etc) to use ipv6 in their internal networks, as if they somehow need to “use the internet” for anything, their whole internal network is just a part of the whole “ipv6″ internet. They still want their “private” addressing while using IP protocols. They don’t want external “anlytics” being performed on what each of their potential ipv6 addresses look on the internet.

What’s the option for doing something like that, that does not imply application level proxies?

Reply

11 Zloy February 1, 2011 at 7:48 pm

># Allow full outgoing connection but no incomming stuff
>$IPT6 -A INPUT -i $PUBIF -m state –state ESTABLISHED,RELATED -j ACCEPT
>$IPT6 -A OUTPUT -o $PUBIF -m state –state NEW,ESTABLISHED,RELATED -j ACCEPT

These lines do not work in RHEL/CentOS 5.x because its kernel does not support stateful IPv6 firewalling. See https://bugzilla.redhat.com/show_bug.cgi?id=243739
But I use similar configuration in another distros with newer kernel.

Reply

12 Anders February 2, 2011 at 5:17 pm

There are ways of randomize/annonymize your IPv6 host address.
With that you can’t analyze trafick outside your corporate firewall to see what is inside just by checking IPv6 addresses.

NAT is just not a good solution to any problem I have seen. The problem is the mind set on people that has been forced to use NAT the last 15 years.

NAT is a hack, to get around the problem with IPv4 addresses running out. It don’t give you any security that you can’t get with IPv6 and firewalls, which you MUST have anyway, even if you use NAT.

Reply

13 Fábio June 25, 2011 at 5:31 pm

Using this firewall I’m not able to use autoconfiguration. Am I right? ‘Cause it uses ICMPv6 messages that you are blocking here, allowing only “ping” messages.

Reply

14 Jon July 18, 2012 at 8:26 pm

Despite popular believe NAT does have uses outside of getting around IPv4′s limited address space. For instance, transparent Squid proxies on the network gateway require the nat table to intercept and redirect HTTP traffic. Personally I also use the nat table for intercepting DNS requests on my network to use my caching and ad-blocking DNS server as it is very hard or impossible to change DNS settings on many devices like Android phones and streaming media players. Neither of these cases will work without NAT and thus can’t be used with IPv6 unless it is implemented.

Reply

15 Anders July 19, 2012 at 12:13 pm

Do it the right way then!

Block all outgoing port 80 in the firewall and set proxie on all machines in your network. That is the propper way AND it will use your proxie when surfing on other ports. Any other use of the port that doesn’t use proxie will be stoped, like worms calling home through port 80.

Your use of NAT is just an uggly hack, like all the use of NAT in the first place, on a problem that is already solved properly.

Have to still to see one use case of NAT that isn’t just a hack to “solve” a problem with IPv4 that hasn’t been solved before or is a direct reason of IPv4 has runned out of free addresses. Which it has in any practical sense has done 10-15 years ago.

NAT is not the answer , it’s a question. The answer ia IPv6.

Reply

Leave a Comment

Tagged as: , , , , , , , , , , , , , , , ,

Previous Faq:

Next Faq: