This article is for information regarding firewalls on an IPv6 network.
Please see the SixXS FAQ for some information on what one should filter.
Linux Kernel (ip6tables)
You don't have to build a specialized script for every firewall; there are configurable ones. If you are familiar with Shorewall (and even if you aren't) you may like 6wall, originally from the LEAF Project, rescued from oblivion and packaged for Debian/Ubuntu by Flavio Visentin. The configuration files are very similar to Shorewall's.
Beginning with Shorewall version 4.2.4, there are two additional packages that provide IPv6 support that can be installed to ipv4 Shorewall in parallel.
shorewall6, is documented at shorewall6
6wall, much like the example script below, is ready for old kernels (up to 2.6.20) that do not support properly IPv6 connection tracking. It relies on the SYN flag to allow new TCP connections, and makes no distinction between new and established connections for UDP and other protocols.
If you are running Linux 2.6.21+, you can apply a patch to add proper connection tracking support.
Using upstart on Ubuntu without additional packages
If you don't feel like using some additional software to manage couple of firewall lines you can use upstart to trigger firewall rules. Rules can be saved in whichever place using iptables-save, below upstart task is using /etc/default/iptables: File: /etc/init/iptables.conf
description "Starts and stops firewall by restoring iptables policies. Save rules with iptables-save > /etc/default/iptables and ip6tables-save > /etc/default/ip6tables" start on runlevel  or net-device-up IFACE!=lo stop on runlevel [!2345] emits firewall console output pre-start script test -f /etc/default/iptables && /sbin/iptables-restore < /etc/default/iptables test -f /etc/default/ip6tables && /sbin/ip6tables-restore < /etc/default/ip6tables end script post-stop script /sbin/iptables -F /sbin/ip6tables -F end script
Save and restore IPv6 firewall rules
To configure firewall rules you can execute commands from below examples and then save them with:
# ip6tables-save > /etc/default/ip6tables.rules
To restore stored firewall rules, run:
# ip6tables-restore < /etc/default/ip6tables.rules
Example script for IPv6 stateless firewall
Note that this example, is exactly that, an example. It doesn't show best practices or what one should do.
#!/bin/sh # Flush & default ip6tables -F INPUT ip6tables -F OUTPUT ip6tables -F FORWARD ip6tables -F # Set the default policy to accept #ip6tables -P INPUT ACCEPT #ip6tables -P OUTPUT ACCEPT #ip6tables -P FORWARD ACCEPT # Enable the following lines only if a router! # Enabling IPv6 forwarding disables route-advertisement reception. # A static gateway will need to be assigned. # #echo "1" >/proc/sys/net/ipv6/conf/all/forwarding # #End router forwarding rules # Disable processing of any RH0 packet # Which could allow a ping-pong of packets ip6tables -A INPUT -m rt --rt-type 0 -j DROP ip6tables -A OUTPUT -m rt --rt-type 0 -j DROP ip6tables -A FORWARD -m rt --rt-type 0 -j DROP # Allow anything on the local link ip6tables -A INPUT -i lo -j ACCEPT ip6tables -A OUTPUT -o lo -j ACCEPT # Allow Link-Local addresses ip6tables -A INPUT -s fe80::/10 -j ACCEPT ip6tables -A OUTPUT -s fe80::/10 -j ACCEPT # Allow multicast ip6tables -A INPUT -d ff00::/8 -j ACCEPT ip6tables -A OUTPUT -d ff00::/8 -j ACCEPT # Allow ICMP ip6tables -A INPUT -p icmpv6 -j ACCEPT ip6tables -A OUTPUT -p icmpv6 -j ACCEPT #ip6tables -A FORWARD -p icmpv6 -j ACCEPT # Disable privileged ports for the outside, except ports 22, 515, and 631 # Specifying an interface (-i ethX) is probably a good idea to specify what is the outside ip6tables -A INPUT -p tcp --dport 1:21 -j REJECT ip6tables -A INPUT -p udp --dport 1:21 -j REJECT ip6tables -A INPUT -p tcp --dport 23:514 -j REJECT ip6tables -A INPUT -p udp --dport 23:514 -j REJECT ip6tables -A INPUT -p tcp --dport 516:630 -j REJECT ip6tables -A INPUT -p udp --dport 516:630 -j REJECT ip6tables -A INPUT -p tcp --dport 632:1024 -j REJECT ip6tables -A INPUT -p udp --dport 632:1024 -j REJECT
NOTE: REJECT target support for netfilter/IPv6 was first introduced with Linux-kernel v2.6.14.
Example script for IPv6 stateful firewall
Almost as above, but with state. You need a new kernel with the correct modules (see above). This firewall denies everything by default, but allows link-local addresses, multicast and icmpv6. Everything internal is also allowed. The host itself and every client can access the Internet and it also forward (inwards) ssh and bittorrent traffic to a specified host on the subnet.
sixxs is the external interface, br-lan is internal.
# First, delete all: ip6tables -F ip6tables -X # Allow anything on the local link ip6tables -A INPUT -i lo -j ACCEPT ip6tables -A OUTPUT -o lo -j ACCEPT # Allow anything out on the internet ip6tables -A OUTPUT -o sixxs -j ACCEPT # Allow the localnet access us: ip6tables -A INPUT -i br-lan -j ACCEPT ip6tables -A OUTPUT -o br-lan -j ACCEPT # Filter all packets that have RH0 headers: ip6tables -A INPUT -m rt --rt-type 0 -j DROP ip6tables -A FORWARD -m rt --rt-type 0 -j DROP ip6tables -A OUTPUT -m rt --rt-type 0 -j DROP # Allow Link-Local addresses ip6tables -A INPUT -s fe80::/10 -j ACCEPT ip6tables -A OUTPUT -s fe80::/10 -j ACCEPT # Allow multicast ip6tables -A INPUT -d ff00::/8 -j ACCEPT ip6tables -A OUTPUT -d ff00::/8 -j ACCEPT # Allow ICMPv6 everywhere ip6tables -I INPUT -p icmpv6 -j ACCEPT ip6tables -I OUTPUT -p icmpv6 -j ACCEPT ip6tables -I FORWARD -p icmpv6 -j ACCEPT # Allow forwarding ip6tables -A FORWARD -m state --state NEW -i br-lan -o sixxs -s <subnet-prefix>::/48 -j ACCEPT ip6tables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # SSH in ip6tables -A FORWARD -i sixxs -p tcp -d <subnet-prefix>::5 --dport 22 -j ACCEPT # Bittorrent ip6tables -A FORWARD -i sixxs -p tcp -d <subnet-prefix>::5 --dport 33600:33604 -j ACCEPT # Set the default policy ip6tables -P INPUT DROP ip6tables -P FORWARD DROP ip6tables -P OUTPUT DROP
FreeBSD supports 3 different firewalls (although two of them are very close):
- ipfw6 is the IPv6 version of ipfw and has been part of FreeBSD for a long time.
- ipf aka IPFirewall by Darren Reed
- pf was started as a fork of ipf. pf was integrated in FreeBSD starting at version 5.3
The FreeBSD Handbook entry on firewalls is a good introduction to the concepts and tools.
To enable pf on FreeBSD, you need to insert the following lines in /etc/rc.conf:
pf_enable="YES" pflog_enable="YES" pf_rules="/etc/filters/pf.conf" # rules definition file for pf pflog_logfile="/var/log/pflog" # where pflogd should store the logfile
You can change the path specified in pf_rules of course. The pf.conf(5) manpage give some extensive examples (incl. the complete grammar for rules and configuration).
You can also find more information on the web (tutorials, book and so on). You can start with these: Wikipedia page on pf
Your main source of information will be the following page in the handbook ipfw page
ipfw6 is the IPv6 version of ipfw. It can be enabled in /etc/rc.conf with these lines:
firewall_flags="" # Flags passed to ipfw when type is a file firewall_myservices="" # List of TCP ports on which this host # offers services firewall_allowservices="" # List of IPs which has access to # $firewall_myservices firewall_trusted="" # List of IPs which has full access to this host firewall_logdeny="NO" # Set to YES to log default denied incoming # packets. firewall_nologports="135-139,445 1026,1027 1433,1434" # List of TCP/UDP ports # for which denied incoming packets are not # logged.
More information within the default rc file in /etc/default/rc.conf and in the /etc/rc.firewall6 script.
Main page in the handbook on ipf is here
To enable ipf on FreeBSD, you need to insert the following lines in /etc/rc.conf:
ipfilter_enable="YES" ipnat_enable="YES" ipmon_enable="YES" ipfs_enable="NO" ipfilter_rules="/etc/filters/adsl.rules" ipnat_rules="/etc/filters/nat.rules" ipmon_flags="-Ds" ipfilter_flags="6"
IPnat is not required for IPv6 support of course.