I am setting up a firewall for ipv6 on Debian Squeeze. It is a webserver, so I think the only port that need to be open to the world for ipv6 is 80.

This is what I have:

:in-new - [0:0]
-A INPUT  -i lo -s ::1/128 -j ACCEPT
-A OUTPUT -o lo -d ::1/128 -j ACCEPT
-A INPUT -s fe80::/10 -j ACCEPT
-A INPUT -m rt --rt-type 0 -j DROP
-A OUTPUT -m rt --rt-type 0 -j DROP
-A FORWARD -m rt --rt-type 0 -j DROP

-A INPUT -p tcp ! --syn -m state --state NEW -j DROP

-A INPUT -m state --state INVALID -j DROP

-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-A INPUT -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN          -j DROP
-A INPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST          -j DROP
-A INPUT -p tcp -m tcp --tcp-flags FIN,RST FIN,RST          -j DROP
-A INPUT -p tcp -m tcp --tcp-flags ACK,FIN FIN              -j DROP
-A INPUT -p tcp -m tcp --tcp-flags ACK,URG URG              -j DROP

-A INPUT -d ff02::1 -j REJECT

-A INPUT  -p tcp -m state --state ESTABLISHED  -j ACCEPT
-A OUTPUT -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT  -p udp -m state --state ESTABLISHED  -j ACCEPT
-A OUTPUT -p udp -m state --state NEW,ESTABLISHED -j ACCEPT

-A INPUT    -p IPv6-icmp -j ACCEPT
-I OUTPUT   -p IPv6-icmp -j ACCEPT
-I FORWARD -p IPv6-icmp -j ACCEPT

-A INPUT -p tcp -m tcp --dport 80 --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j ACCEPT
-A INPUT    -j LOG --log-level 4 --log-prefix "IPT_INPUT: "

-A FORWARD -j LOG --log-level 4 --log-prefix "IPT_FORWARD: "
-A OUTPUT   -j LOG --log-level 4 --log-prefix "IPT_OUTPUT: "


I found it somewhere on the inernet and changed it a little bit, but when I try to retore it it gives the following error:

sudo ip6tables-restore < /etc/ip6tables.firewall.rules
ip6tables-restore: line 47 failed

Any idea how to setup my ip6tables so it will work?

Thank you.


4 Answers 4


I don't know where you got that abomination, but the best thing you can do is delete it and start over from scratch. Its primary problem is that it's needlessly complicated and difficult to follow, even if it might work (and I can't be sure from reading it, so I'm certainly not going to test it).

Firewalls should be as simple as possible: Accept only what you need and reject everything else. Follow this and you won't need any complicated and difficult to understand rules.

So let's take a look at a live, working IPv6 iptables firewall. I just pulled this off one of my live servers:

# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.

We set default policies for the tables to ACCEPT; the traffic will actually be dropped by rules within each table. This gives us more flexibility. In particular, the OUTPUT table should always be set to a default policy of ACCEPT unless you intend to block outgoing connections.

-A INPUT -m rt --rt-type 0 --rt-segsleft 0 -j DROP
-A FORWARD -m rt --rt-type 0 --rt-segsleft 0 -j DROP
-A OUTPUT -m rt --rt-type 0 --rt-segsleft 0 -j DROP

This fixes the IPv6 Routing Header Type 0 security issue. It should appear before any other rules. (Note that modern kernels since automatically drop this traffic and do not need these rules. If you have a previous kernel, contact your distribution vendor for a patch for CVE-2007-2242.) Explicit rules for RH0 is many years obsolete and no longer necessary on modern Linux systems.


This accepts ongoing traffic for any existing connections that we've already accepted through other rules.

-A INPUT -p ipv6-icmp -j ACCEPT

We accept all ICMP packets. Unlike with IPv4, it's not a good idea to block ICMPv6 traffic as IPv6 is much more heavily dependent on it.

-A INPUT -i lo -j ACCEPT

We accept all traffic from/to the local interface.

-A INPUT -m state --state NEW -m udp -p udp --dport 546 -d fe80::/64 -j ACCEPT

We accept DHCPv6 traffic. If you use stateless autoconfiguration, or statically configure your machines, this is not necessary.

-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

These accept new connections for ssh and http.

-A INPUT -j REJECT --reject-with icmp6-port-unreachable
-A FORWARD -j REJECT --reject-with icmp6-port-unreachable

At the end of our rules, we reject all traffic that didn't match a rule, using "port unreachable". This results in the standard "Connection refused" message at the other end, and effectively hides the fact that we have a firewall. Tools such as nmap will report that all our ports are "closed" rather than "filtered" and have a much more difficult time determining that we even have a firewall.


This commits all the table entries.


i was able to reload your ip6tables-dump without problems. i suggest you first try to create your firewall using the ip6tables command, then dump it. it might be much easier to debug.

you can start with the clean slate - firewall.sh that looks like this:

ip6tables -P INPUT DROP
ip6tables -P OUTPUT DROP
ip6tables -P FORWARD DROP

ip6tables -F

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

be careful - this will prevent any ipv6 communication. hopefully you have console/out of band/ipv4 communication channel. if not add at least:

ip6tables -A INPUT  -p tcp --dport 22 -j ACCEPT

once you're happy with the firewall script you can run ip6tables-save > your.rules.


I had the same issue with the commit failing. I am using Debian Wheezy, but I suspect that the problem is the same. It seems that the base install of Debian (at least the one that i am using) does not support connection tracking for ipv6. This causes the lines that attempt to track connection state (-m state...) to fail, though ip6tables-restore is not courteous enough to tell you that, unfortunately. The good news is that this can be solved without too much trouble:

# apt-get install conntrack
# reboot

I am sure it is possible to get around the reboot, but I'm not sure what service needs restart to make this work, so I'm just restarting them all. After that, rulesets such as those posted here which make use of stateful connection tracking seem to work fine.


It's a problem with OpenVZ and ipv6 tables. Use CSF firewall instead and you will have no problems with to setup a firewall for ipv6.

  • 1
    You should mention it's OpenVZ when you ask the question. It makes a big difference. OpenVZ is... weird. Commented Aug 20, 2013 at 13:51
  • Yeah sorry, but I didn't know that was the problem. And now the error came again with a VPS server from an other provider and the support told me this was the problem and that I can use CSF instead. So maybe this solution is useful for somebody with the same error. Commented Aug 20, 2013 at 14:25
  • Now you will know, when you want to ask your next question about those VPSes :) Commented Aug 20, 2013 at 14:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .