ip6tables: IPv6 Firewall For Linux

by Vivek Gite on September 12, 2008 · 12 comments

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:

Featured Articles:

Share this with other sys admins!
Facebook it - Tweet it - Print it -

{ 12 comments… read them below or add one }

1 diay September 14, 2008

thanks for sharing a shell script.

Reply

2 Martijn January 5, 2009

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 Vivek Gite January 5, 2009

@ Martijn,

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

Reply

4 Martijn January 6, 2009

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

Reply

5 Alex May 19, 2009

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

cheers!

Reply

6 bibi July 24, 2009

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

Reply

7 Anders November 18, 2009

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

8 Anders November 18, 2009

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

9 Albert February 1, 2011

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

10 Zloy February 1, 2011

># 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

11 Anders February 2, 2011

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

12 Fábio June 25, 2011

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

Leave a Comment

You can use these HTML tags and attributes for your code and commands: <strong> <em> <ol> <li> <u> <ul> <blockquote> <pre> <a href="" title="">




Previous post:

Next post: