«

»

Jun 09

Adding a firewall and NAT to my FreedomBox

Something every FreedomBox should have is a firewall combined with NAT functionality. These functions are provided by every router, so why not let the router take care of these functions? There are several reasons against using the router for these functions:

  • Firewall and NAS functions are of vital importance for the security of a FreedomBox. These functions should therefore be implemented on the FreedomBox hardware and not be delegated to third party hardware. Most routers don’t come with source code or hardware specs and cannot be fully trusted.
  • The FreedomBox cannot control the firewall or NAT of a particular router. There are just too many different brands and models. As a device for non technical users the FreedomBox cannot ask the user to manage the router firewall and NAT every time a new program is (de-)installed.
  • Having a firewall on the FreedomBox gives us the possibility to log attacks and implement our own counter measures.

Read this first.

This article is one in a series that describes the building of my FreedomBox. Not all information from the previous articles is repeated.

A short overview of my FreedomBox architecture.

In order to understand the configuration of the firewall you need to have a high level view of the architecture of my FreedomBox. In my architecture I use virtual machines (Linux Containers: LXC) that are all part of the same bridged network br0. All VM’s use DHCP to get an IP address. There are two static IP addresses:

192.168.1.3

This is the address of the br0 interface. (a.k.a. the internal address of my FreedomBox)

192.168.1.10

This address belongs to a special VM: the internet module. The internet module is a so called bastion host. A bastion host is a special hardened system that is placed in the DMZ of the router as a gateway to the internal systems (or programs).

In my architecture I try to run every service that is connected to the internet inside its own VM. Access from the internet to a service inside a VM always passes the internet module first.

Sometimes it is not possible to run a service inside a VM. In that case I use NAT to route incoming requests from the DMZ (IP: 192.168.1.10) to the host system (IP: 192.168.1.3). At the moment OpenVPN is the only service connected to the internet that is running directly on the host.

Objectives.

Installing a firewall/NAT should accomplish the following:

  • Strengthen the isolation of the VM’s.
  • Make it possible to have firewall settings for a single VM or a group of VM’s.
  • Prevent VM’s to access services on the host system except for some necessary services.
  • Create routes for traffic that cannot be routed by the internet module.
  • Make it possible to run services on non standard ports.
  • Forward traffic to other FreedomBox systems.
  • Logging attacks.

Some small adjustments.

In order to integrate the firewall into my FreedomBox I had to make the following changes to my setup:

  • Add a vendor class identifier to the DHCP request of a LXC module.
  • Use the vendor class identifier to give LXC modules IP addresses from a separate DHCP range.

For the vendor class identifier I changed my lxc-debian-box script. Click the link for the update. If you have already made some LXC modules you can bring them up to date by adding the following line to the /etc/dhcp/dhclient.conf file inside the container:

send vendor-class-identifier "lxc.module";

The vendor-class-identifier is used by dnsmasq. The file /etc/dnsmasq.conf should be edited as follows:

change:

dhcp-range=192.168.1.10,192.168.1.250,12h

to:

dhcp-vendorclass=set:lxc,lxc.module
dhcp-range=net:lxc,192.168.1.10,192.168.1.50,12h
dhcp-range=192.168.1.100,192.168.1.150,12h

Restart dnsmasq and all the containers to activate the changes.

Installing Shorewall.

On my FreedomBox I use Shorewall for the firewall/NAT functions. It is a very mature and flexible program. Installing is simple:

apt-get install shorewall

Configuring Shorewall.

Shorewall is well documented so I only give a quick overview before presenting my Shorewall configuration.

Central in the Shorewall configuration is the concept of zones. A zone is one-to-one coupled to a network interface. If it is necessary to have multiple zones within the same network (this is the case with my FreedomBox) you can specify sub-zones. Only traffic between different (sub-)zones is examined by the firewall. Default actions for inter-zone traffic are specified by a policy. Exceptions to the policy are specified by rules.

All Shorewall configuration files are in the directory /etc/shorewall. After installing this directory only has one file (shorewall.conf) in it that does not have to be changed. The actual configuration is in the files:

  • interfaces – specifies network interface <> zone relations.
  • zones – defines zones and sub-zones
  • hosts – specifies sub-zones
  • policy – the default actions for inter-zone traffic
  • rules – the exceptions to the policy
  • tunnels – needed for VPN
  • routestopped – specifies the state after Shorewall is stopped.

I have the following configuration:

interfaces

#ZONE   INTERFACE     BROADCAST     OPTIONS

net     br0           detect        bridge,dhcp
vpn     tap0

On my system there are two network interfaces. Br0 is placed in the net zone, this zone represents the internet. For OpenVPN I have a second zone (I will write about my OpenVPN configuration in a next article)

zones

#                                 IN          OUT
#ZONE       TYPE      OPTIONS     OPTIONS     OPTIONS

fw          firewall
vpn         ipv4

net         ipv4
loc:net     ipv4
vmnet:net   ipv4
imod:vmnet  ipv4

The fw zone is a special firewall zone. Think of “fw” as the system on which Shorewall runs. The net zone is split in tho sub-zones: loc and vmnet. Loc stands for all the systems that are not VM’s, those systems are in the vmnet zone. One special VM, the internet module, is placed inside its own imod sub-zone.

hosts

#ZONE     HOST(S)                           OPTIONS

imod      br0:192.168.1.10
vmnet     br0:192.168.1.11-192.168.1.50     routeback
loc       br0:192.168.1.100-192.168.1.150   routeback

This file has all the sub-zones

policy

#SOURCE	    DEST     POLICY     LOG LEVEL     LIMIT:BURST

net         all      DROP       info

imod        vmnet    ACCEPT
imod        all      REJECT     info

vmnet       net      ACCEPT
vmnet       all      REJECT     info

loc         all      ACCEPT
$FW         all      ACCEPT
vpn         all      ACCEPT

# The FOLLOWING POLICY MUST BE LAST

all         all      REJECT     info

The policies are examined from top to bottom and the first match cancels further processing of policies. You can see that no traffic from the net zone to any other zone is allowed by the default policy. The exceptions to the policies are in the rules configuration file.

rules

#                                                           DEST     SOURCE     ORIGINAL     RATE     USER/     MARK
#ACTION        SOURCE      DEST                     PROTO   PORT     PORT(S)    DEST         LIMIT    GROUP

SECTION NEW

Ping(DROP)     net         all

# enable DHCP and DNS access for zones on the freedombox

ACCEPT         imod        $FW                      udp     67:68
DNS(ACCEPT)    imod        $FW

ACCEPT         vmnet       $FW                      udp     67:68
DNS(ACCEPT)    vmnet       $FW

ACCEPT         loc         $FW                      udp     67:68
DNS(ACCEPT)    loc         $FW

# enable HTTP and SSH access, use a non-standard port for SSH

ACCEPT:info    net         imod                     tcp     http
DNAT:info      net         imod:192.168.1.10:22     tcp     99999

# enable OpenVPN

DNAT:info      net         fw:192.168.1.3:1194      udp     1194

The only traffic from the net zone to my FreedomBox is HTTP, SSH and OpenVPN traffic.

It’s amazing how many people try a brute-force attack on your SSH port. Even if you clearly indicate that it is only possible to login with RSA. I got very annoyed by the constant flickering of my lan-light so for SSH i’m using a non-standard port (not port 99999 ;-) ).

tunnels

#TYPE                ZONE    GATEWAY      GATEWAY_ZONE

#openvpnserver:1194  net     0.0.0.0/0

routestopped

#                                               DEST      SOURCE
#INTERFACE     HOST(S)    OPTIONS     PROTO     PORTS     PORTS

br0            -          source

Running Shorewall

With the configuration in place Shorewall can be started. The Debian packagers have wisely prevented Shorewall to start by default. For this you have to edit /etc/default/shorewall and change the startup configuration option. Shorewall is a very flexible program. This flexibility comes at a price: it is very easy to make a mistake, and mistakes can lock you out. I think it is best to start Shorewall manually. If you make a mistake you can correct the error after restarting the system.

2 comments

  1. Anders Jackson

    First, a nice blog post about your firewall. Shorewall is a good choice.

    Secondly, NAT has nothing to do with net security, that is what the firewall are there for. NAT only makes the firewall rules harder to write correct, and there are ways of getting past NAT from outside.

    Last, you should really have a look into IPv6. You should be able to make a IPv6 tunnel through any normal IPv4 NAT router (tunneling or 4to6). And you get at least one real global /64 net to play with on yo.ur bridge, if you ask you should get a /48 or /56 net. And no problems with setting up NAT rules to reach your services, just set up your Shorewall firewall right, as Shorewall has support for IPv6 now.
    You should only use IPv4 for share data with the local net.

    But again, good blog.

    1. robvanderhoeven

      Thank you for your comment Anders. I agree that NAT complicates things but this should not affect the end user. The FreedomBox is for normal (non geek) users and complicated sysadmin tasks are simply not acceptable. Configuration of NAT should be done by the configuration software. I have not looked into IPv6 yet but will do so in the future.

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>