In our previous article we introduced the iptables firewall for our Wireguard VPN server. The firewall regulates which traffic is permitted between the individual customer VPNs and the management VPN and prevents access that poses a security risk.
Although it is possible to manage these rules using the iptables command line tools, it quickly becomes confusing and difficult to understand, especially for outsiders. We have therefore tested the firewall configuration using the “Shorewall” tool and found it to be suitable.
Shorewall is a tool that reads simple text files with firewall rules according to a predefined format, validates them and converts them into iptables rules. It is therefore only a front end that operates iptables and not an independent firewall in the strict sense.
The static configuration in individual semantically separated text files makes it easier to maintain an overview. Iptables rules can also be persisted in text files via netfilter-persistent (or iptables-persistent), but the syntax is difficult to understand at a glance. This may be sufficient for smaller setups - but we are planning to set up some VPN networks with individual authorisations, among other things. With Shorewall as an iptables configurator, we can keep a better overview of the firewall rules and avoid errors.
With Shorewall, the firewall configuration is distributed across several files in the configuration directory
/etc/shorewall/zones: Defines the firewall zones that can later be used in the rule sets.
/etc/shorewall/interfaces: Defines which network interfaces are to be used with Shorewall and which zone they belong to.
/etc/shorewall/policy: Defines the default policies between zones. Is traffic allowed to pass between zones or not?
/etc/shorewall/rules: The fine-grained rules are defined here: For example, if a
REJECTpolicy was previously defined between zones, port/protocol-based exceptions can be defined here.
Below we take a look at our configuration:
We define zone
$FW) as the firewall’s own zone and define further zones for our WAN interface and our VPN networks.
wan eth0 detect dhcp,routefilter,tcpflags
customer1-vpn customer1-vpn detect routeback
customer2-vpn customer2-vpn detect routeback
mastervpn mastervpn detect routeback
The network interface and zone are linked here - the zone in the first column, the assigned network interface in the second column. The
routeback option is particularly important for the VPN zones, which ensures that traffic arriving at a VPN interface can also leave it again directly, as is the rule with a VPN interface when clients communicate with each other. This client-to-client communication will be deactivated again later, but we want to retain the option of enabling it for individual VPN clients.
# Source # Dest # Policy
wan all REJECT
$FW all ACCEPT
mastervpn all ACCEPT
customer1-vpn all REJECT
customer2-vpn all REJECT
Incoming traffic on the WAN should always be blocked first. Individual exceptions - for example for the VPN server ports - are made later in the
The firewall itself has no restrictions and can address other zones or interfaces as required.
mastervpn may also communicate without restrictions. This is the admin interface from which our developers establish connections to various VPN clients.
We take a more restrictive approach with the two customer VPNs
customer2-vpn: These are locked in using
REJECT and are not allowed to communicate with anyone by default.
rules: The exceptions for the policies just explained now follow:
# Policy # Source # Dest # Prot # Port
# Allow access to VPN ports
ACCEPT wan $FW UDP 51821,51822,51823
# Allow SSH from internet
SSH(ACCEPT) wan $FW
# Allow pings from all VPNs to their Server VPN interface
Ping(ACCEPT) customer1-vpn $FW:10.2.1.1
Ping(ACCEPT) customer2-vpn $FW:10.3.0.1
Ping(ACCEPT) mastervpn $FW:10.4.0.1
# Explicitly allow inter-client connections on some VPN devices (legacy "admin" devices)
ACCEPT customer1-vpn:10.2.1.10 customer1-vpn # device 1
ACCEPT customer1-vpn:10.2.1.11 customer1-vpn # device 2
ACCEPT customer1-vpn:10.2.1.12 customer1-vpn # device 3
# Prevent inter-client connections on VPNs for all devices that have not explicitly been allowed in the section before
REJECT customer1-vpn customer1-vpn:10.2.1.0/24
REJECT customer2-vpn customer2-vpn:10.3.0.0/16
Firstly, access to the WAN ports
51821,51822,51823 is permitted so that Wireguard VPN clients can connect to the VPN server. We also connect to the VPN server via SSH - this should also remain permitted. In this case, we use the
SSH(ACCEPT) macro from Shorewall so that we do not have to define the port and protocol separately.
Pings from VPN clients to their respective server-side interface and its IP addresses should be allowed in all cases. We usually ping the server interface to determine the functionality of a VPN connection.
In the next section, client-to-client communication is explicitly enabled for individual VPN clients of the
… For all other devices, this type of communication is prevented in the following section using
REJECT. Consequently, they can only send back response packets (implicit rule in Shorewall) and cannot initiate connections of their own accord.
IP forwarding is already activated on our server. If you have not yet activated the setting
net.ipv4.ip_forward in /etc/sysctl.conf, you can also set
Finally, we took ’netfilter-persistent’ out of the boat:
systemctl disable netfilter-persistent
… and emptied the iptables rules:
… to be able to test the new Shorewall rules:
After everything worked as hoped, Shorewall was added to the autostart:
systemctl enable shorewall