Lucid Lynx with IPv6 – firewalling

Open Office has been building Linux networks for office automation since the last century. As we would like to be ready for the next century, we are currently doing IPv6 wherever possible.
In a series of articles, we will explain how to set up an Ubuntu 10.04 “ipv6 only” network of Linux machines: that is server, and desktops. In this episode: firewalling on the gateway.

We are going to build an IPv6 network: with servers, desktop PC’s, and maybe other stuff. While most of the cook book information on the internet starts with basic connectivity, I will first set up firewalling; then set up the IPv6 end points and/or tunnels.

This way, your network will be safe all the time. Disclaimer applies: “safe” is relative: we are not building a full IPv6 aware firewall, nor will this article go over all security issues that you may have. Also, we will make a couple of basic assumptions that help us set up our firewall; but if these assumptions are not true on your network, then the firewall won’t be safe as well.

Basically, there are two ways to operate. You can either have a host that does nothing but provide IPv6 connectivity. In this case, firewalling should be almost trivial. You will not have to protect services on the host itself, as there aren’t any. The other way of operation is to have a server provide your IPv6 connectivity. In this case, there are probably lots of services to protect.

Either way, in the rest of this article, the machine that is going to provide IPv6 connectivity will be called “gateway” or “IPv6 gateway”.

How should you firewall?

Let’s first try to find out, what sort of firewalling you are going to need.

There is a chance, that you are running some other way of firewall administration already. For example, you could be running Shorewall; or the Uncomplicated Firewall (ufw) of Ubuntu; or any other firewalling product. If so, the resolution is easy: go see if your firewalling administration product helps you using IPv6.

For ufw: set “IPV6=yes” in /etc/default/ufw. Then (at least that is what I have understood) you need to remove and re-add all your firewalling rules. I might be wrong here, as I do not normally use ufw for my firewalling.
For Shorewall and other products, you’ll need to read the Other Product’s documentation, for I don’t know anything about it.

If you are still reading, it either means that you don’t know what you are running; or that you are not running any firewalling product and you want an IPv6 firewall on your gateway.

Let’s first check how many services are running on your gateway. A simple check is to run the “netstat” command. This is the output on a server:

# netstat -6ltunp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp6       0      0 :::80                   :::*                    LISTEN      1201/apache2    
tcp6       0      0 :::53                   :::*                    LISTEN      32185/named     
tcp6       0      0 :::22                   :::*                    LISTEN      842/sshd        
tcp6       0      0 :::631                  :::*                    LISTEN      1171/cupsd      
tcp6       0      0 ::1:88                  :::*                    LISTEN      20946/kdc       
tcp6       0      0 ::1:953                 :::*                    LISTEN      32185/named     
tcp6       0      0 :::443                  :::*                    LISTEN      1201/apache2    
tcp6       0      0 :::389                  :::*                    LISTEN      877/slapd       
udp6       0      0 ::1:464                 :::*                                20949/kpasswdd  
udp6       0      0 ::1:88                  :::*                                20946/kdc       
udp6       0      0 ::1:123                 :::*                                1074/ntpd       
udp6       0      0 :::123                  :::*                                1074/ntpd       
udp6       0      0 :::53                   :::*                                32185/named     

… while the output on a more “stripped down” machine that is going to be the gateway would look as follows:

netstat -6ltunp
 Active Internet connections (only servers)
 Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
 tcp6       0      0 :::22                   :::*                    LISTEN      733/sshd

Our firewall will try to protect your gateway like it is the machine above: it will only accept IPv6 to TCP port 22 (the SSH protocol). It will accept ICMPv6, too.

For forwarding, the situation is a bit more complicated. A proper IPv6 subnet normally is a /48 network. This leaves you with 2^80 IP addresses to protect. So we will go the easy way now: we will drop everything that is initiated from the outside; and we will accept everything that is initiated from the inside.

We will do this with IPv6 stateful firewalling. As I don’t know which sort of connection you are going to use, I used both a “sixxs” network adapter and a “tun6to4” network adapter to decide if traffic should be allowed. If your ISP provides native IPv6, you should add the network interface where your IPv6 connection comes in.

#!/bin/sh
# we accept ICMPv6 and ssh connections, and drop all else.
ip6tables -P INPUT DROP
ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -A INPUT -m state --state INVALID -j DROP
ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT
ip6tables -A INPUT -p icmpv6 -j ACCEPT

# are we living dangerously?
ip6tables -P OUTPUT ACCEPT

# we accept everything initiated from the inside; drop all else
# we do this through an intermediate table, to be able to change
# this behaviour later
ip6tables -P FORWARD DROP
ip6tables -N forward-incoming
ip6tables -N forward-outgoing
ip6tables -A forward-incoming -j DROP
ip6tables -A forward-outgoing -j ACCEPT

ip6tables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -A FORWARD -m state --state INVALID -j DROP
ip6tables -A FORWARD -m state --state NEW -o sixxs -j forward-outgoing
ip6tables -A FORWARD -m state --state NEW -i sixxs -j forward-incoming
ip6tables -A FORWARD -m state --state NEW -o tun6to4 -j forward-outgoing
ip6tables -A FORWARD -m state --state NEW -i tun6to4 -j forward-incoming

With the above firewall in place, you are reasonably protected against IPv6 connections to your gateway; also, the network behind it should be protected against anything from the outside connecting to it.

Please note, that there is another way that your network is (still) protected by now, which is the sysctl “ipv6.forwarding” variable. As is the case with IPv4, IPv6 has it’s own forwarding in the kernel and normally, this is set to off, as in: won’t forward. You may, if the above rules are in place, set the kernel forwarding to on. Add a file named /etc/sysctl.d/60-ipv6.conf with the following content:

net.ipv6.conf.all.forwarding=1
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_source_route = 0

Use “sysctl -p /etc/sysctl.d/60-ipv6.conf” to activate the new sysctl parameters right away. Once your gateway gets IPv6 connectivity, it should forward it to the inside now.