Protecting your IPv6 world

This is the third and (probably) final post in my series about enabling IPv6 on your home network. The first, Banish Mavis and Connect to the Future, explains the basics and why I think this stuff is really important. The second, Tunnelling your way to the future, tells you how, if you have a Linux box on your network, you can give full IPv6 connectivity to all your machines, even if your ISP doesn’t support it yet.

This is all great fun, but at the end of the last article I pointed out that there were also security considerations associated with making all of your machines accessible to the ravages of the outside world, and it was only something you should do if they had a modern operating system, up-to-date security patches, and were running a firewall. This may, understandably, make you feel a little nervous, so in this final section I’ll show you how to implement a simple firewall on the machine that’s acting as your IPv6 gateway, so you can choose what traffic you want to let in, from where, and to which machines.

This is still, by the way, very much better than the old NAT-based world of IPv4, because you are separating policy from capability: you can choose to allow SSH and HTTPS traffic to two different web servers inside your network, FTP access to one of them, and plain HTTP to a webcam, and give them all proper DNS addresses, while still blocking incoming connections to anything else.

As a simple example, I’m going to explain how to set up a firewall that allows incoming HTTP, HTTPS and SSH connections over IPv6 but blocks everything else, so you’re not at risk when, say, enabling file sharing between your home computers.

Turning the IPtables with Shorewall

If you set up your system as per my description in the previous article, your linux machine is connecting to an IPv6 tunnel provider, receiving the IPv6 packets for your network on a virtual interface we called he-ipv6 and routing them out to your network over the normal ethernet interface, eth0.

Now, the way in which the Linux kernel routes data between interfaces is controlled by an internal table of rules, which is used to examine each packet and work out whether and how to send it on its way. These tables can be manipulated from the command line through a utility called iptables, or ip6tables for the IPv6 variant, and you could use these to set up the rules you need to let some stuff in and keep other stuff out.

It’s all very powerful, but unless you are part-robot yourself, trying to do much of this will make your brain hurt. This is the assembly-language equivalent of network configuration; you can make it do anything, and a very large number of the options you could choose will be the wrong ones. Eventually, you will get everything nicely set up, and all will be well until 18 months down the line when you have to change something and you have to remember what all those arcane lines of configuration were about.

So we’re going to use a system called Shorewall, which has a nicer way to describe what you want in a few simple configuration files, and then arranges all that iptables stuff for you behind the scenes.

Installing and configuring Shorewall6

We want the IPv6 version of Shorewall, so, assuming you’re on a Debian/Ubuntu-type system, you can install it with:

 sudo apt-get install shorewall6

This will install both shorewall (the IPv4 version) and shorewall6, and will create configuration directories /etc/shorewall and /etc/shorewall6.

It will also put files to control the basic startup of each in /etc/defaults/shorewall and /etc/defaults/shorewall6. For our purposes, we can ignore the IPv4 version. There’s a line in each of these files that looks like:


The firewall will not start up unless you change the 0 to 1, so do this in /etc/defaults/shorewall6 and leave the other one alone. The only other change you need to make to the defaults is to look for a line in /etc/shorewall6/shorewall6.conf that says:


and change it to


otherwise the machine will stop operating as a router.

OK. Now we’re going to create four configuration files. Four?, I hear you squeak. Yes, four, but trust me, they’re wonderfully brief and straightforward. We’re just going to create them from scratch because they’re so simple.

Here’s how it works:

  • We’re going to define three ‘zones’: net, which represents the outside world, fw, which represents the firewall itself, and lan, which represents your local network.
  • We’re going to say which network interfaces connect to each zone.
  • We’re going to define the basic high-level policy of how data can flow between zones.
  • Finally, we define some rules which specify in more detail the connections that are and aren’t allowed.

These are done in simple text files called:


See? At least the naming is nice and logical. There are man pages describing these in detail if you want to know more – just run man shorewall6-zones, man shorewall6-interfaces, etc. I’m certainly not an expert, having tried this for the first time today, but the following files work for me.


This is just a list of zone names and types:

fw     firewall
net  ipv6
lan  ipv6


Specify where these zones live:

lan     eth0       -        tcpflags
net     he-ipv6    -        tcpflags


By default, data from the firewall or LAN destined for the outside world is accepted. Data from the outside world is dropped. Everything else is rejected.


fw      net     ACCEPT
lan     net     ACCEPT
net     all     DROP
all     all     REJECT

At this point, you can start up the firewall to test it:

  /etc/init.d/shorewall6 start

And you should then find that you can make outgoing connections, for example to, but not incoming ones. If you don’t have easy access to an external IPv6-capable machine, try using a service like this one on to ping one of your internal IPv6 addresses. It should fail.


Finally, in this file, let’s define some rules to let in ping, http, https and ssh.

# These rules apply to all new connections

#ACTION     SOURCE      DEST      PROTO      DEST PORT    

# Allow ping6 from outside world to firewall or LAN
ACCEPT      net         fw        ipv6-icmp
ACCEPT      net         lan       ipv6-icmp    

# Allow http, https and ssh from outside world to firewall or LAN machines
ACCEPT      net         fw        tcp        80,443,22
ACCEPT      net         lan       tcp        80,443,22

That’s it! Restart your firewall:

/etc/init.d/shorewall6 restart

And you should now find you can ping, ssh or get web pages from machines inside your network, but all other incoming connections will be blocked. If you want to allow access to a particular machine instead of all of them, change the rule line to include both the zone and the IP address:

ACCEPT  net    lan:2001:470:1f39:1824:fa1e:dfef::d5dc   tcp    80,443,22

Well done! There’s an amazing amount more you can do with Shorewall – have a look at the man pages – but that at least should give you the basics and let you sleep at night!

Feedback and suggestions welcome, as always: I’m a novice at this too.

Enjoyed this post? Why not sign up to receive Status-Q in your inbox?


Hi Q,

Thanks for your IPv6 series. I’ve had IPv6 running at home for few years on my custom router. One more use for IPv6 is for Apple’s “Back to my Mac” iCloud feature, which conveniently ignores IPv6 firewalls, as it establishes its own tunnel. I was slightly surprised to find out that I should ssh into my MacBook at work, without using any VPN software! If you run “dns-sd -B _ssh | grep icloud” on your mac, you’ll get a list of hostnames where you’ve enabled this feature in the Control Panel (in my case, my iMac, Macbook at home and Macbook at work). It will also list them in a domain, where nnnnnnnn is your account number.

You can then just “ssh -2 -6”, where ‘host’ is the hostname of whichever macbook want to to ssh into. I was surprised this worked through our corporate firewall, but on looking closely, it appears that my MacBook sets up a ‘utun0’ device, with IPv6 addresses. More details are here:

Ha! Very cool – thanks Jonathan!

I’d something about it using IP6 tunneling, but it’s great to know more.

I know another system where I could employ similar ideas usefully. So do you 🙂

Got Something To Say:

Your email address will not be published. Required fields are marked *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    Markdown is turned off in code blocks:
     [This is not a link](

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see


© Copyright Quentin Stafford-Fraser