There is intense interest in communications privacy at the moment thanks to the Snowden scandal. Open source software has offered credible solutions for privacy and encryption for many years. Sadly, making these solutions work together is not always plug-and-play.
In fact, secure networking, like VoIP, has been plagued by problems with interoperability and firewall/filtering issues although now the solutions are starting to become apparent. Here I will look at some of them, such as the use of firewall zones to simplify management or the use of ECDSA certificates to avoid UDP fragmentation problems. I've drawn together a lot of essential tips from different documents and mailing list discussions to demonstrate how to solve a real-world networking problem.
Here is a diagram of the network that will be used to help us examine the capabilities of these open source solutions.
Some comments about the diagram:
The major components are packaged on all the major Linux distributions. Nonetheless, in every case, I found that it is necessary to re-compile fresh strongSwan packages from sources. It is not so hard to do but it is necessary and worth the effort. Here are related blog entries where I provide the details about how to re-build fresh versions of the official packages with all necessary features enabled:
For convenience, many people building a point-to-point VPN start with passwords (sometimes referred to as pre-shared keys (PSK)) as a security mechanism. As the VPN grows, passwords become unmanageable.
In this solution, we only look at how to build a VPN secured by X.509 certificates. The certificate concept is not hard.
In this scenario, there are a few things that make it particularly easy to work with certificates:
A common problem for IPsec VPNs using X.509 certificates is the fragmentation of key exchange datagrams during session setup. Sometimes it works, sometimes it doesn't. Various workarounds exist, such as keeping copies of all certificates from potential peers on every host. As the network grows, this becomes inconvenient to maintain and to some extent it eliminates the benefits of using PKI.
Fortunately, there is a solution: Elliptic Curve Cryptography (ECC). Many people currently use RSA key-pairs. Best practice suggests using RSA keys of at least 2048 bits and often 4096 bits. Using ECC with a smaller 384-bit key is considered to be equivalent to a 7680 bit RSA key pair. Consequently, ECDSA certificates are much smaller than RSA certificates. Furthermore, at these key sizes, the key exchange packets are almost always smaller than the typical 1500 byte MTU.
A further demand for ECDSA is arising due to the use of ECC within smart cards. Many smartcards don't support any RSA key larger than 2048 bits. The highly secure 384-bit ECC key is implemented in quite a few common smart cards. Smart card vendors have shown a preference for the ECC keys due to the US Government's preference for ECC and the lower computational overheads make them more suitable for constrained execution environments. Anyone who wants to use smart cards as part of their VPN or general IT security now, or in the future, needs to consider ECC/ECDSA.
For this example, we are not just taking some easy point-to-point example. We have a real-world, multi-site, multi-device network with road warriors. Simplifying this architecture is important to help us understand and secure it. The solution? Each of these is abstracted to a "zone" in Shorewall. In the diagram above, the zone names are in square brackets. The purpose of each zone is described below:
Zone name | Description |
---|---|
loc | This is the private LAN and contains servers like databases, private source code respositories and NFS file servers |
dmz | This is the DMZ and contains web servers that are accessible from the public internet. Some of these servers talk to databases or message queues in the LAN network loc |
vpn_a | These are road warriors that are not very trustworthy, such as mobile devices. They are occasionally stolen and usually full of spyware (referred to by users as "apps"). They have limited access to ports on some DMZ servers, e.g. for sending and receiving mail using SMTP and IMAP (those ports are not exposed to the public Internet at large). They use the VPN tunnel for general internet access/browsing, to avoid surveillance by their mobile carrier. |
vpn_b | These are managed laptops that have a low probability of malware infection. They may well be using smart cards for access control. Consequently, they are more trusted than the vpn_a users and have access to some extra intranet pages and file servers. Like the smart-phone users, they use the VPN tunnel for general internet access/browsing, to avoid surveillance by third-party wifi hotspot operators. |
vpn_c | This firewall zone represents remote sites with managed hardware, such as branch offices or home networks with IPsec routers running OpenWRT. |
cust | These are servers hosted for third-parties or collaborative testing/development purposes. They have their own firewall arrangements if necessary. |
net | This zone represents traffic from the public Internet. |
Shorewall is chosen to manage the iptables and ip6tables firewall rules. Shorewall provides a level of abstraction that makes netfilter much more manageable than manual iptables scripting. The Shorewall concept of zones is very similar to the zones implemented in OpenWRT and this is an extremely useful paradigm for firewall management.
Practical configuration of Shorewall is very well explained in the Shorewall quick start. The one thing that is not immediately obvious is a strategy for planning the contents of the /etc/shorewall/policy and /etc/shorewall/rules files. The exact details for making it work effectively with a modern IPsec VPN are not explained in a single document, so I've gathered those details below as well.
An effective way to plan the Shorewall zone configuration is with a table like this:
Destination zone | ||||||||
---|---|---|---|---|---|---|---|---|
loc | dmz | vpn_a | vpn_b | vpn_c | cust | net | ||
Source zone | loc | \ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
dmz | ? | \ | X | X | X | ✔ | ✔ | |
vpn_a | ? | ? | \ | X | X | ✔ | ✔ | |
vpn_b | ? | ? | X | \ | X | ✔ | ✔ | |
vpn_c | X | ✔ | ✔ | ✔ | \ | ✔ | ✔ | |
cust | X | ? | X | X | X | \ | ✔ | |
net | X | ? | X | X | X | ✔ | \ |
The symbols in the table are defined:
Symbol | Meaning |
---|---|
✔ | ACCEPT in policy file |
X | REJECT or DROP in policy file |
? | REJECT or DROP in policy file, but ACCEPT some specific ports in the rules file |
Naturally, this modelling technique is valid for both IPv4 and IPv6 firewalling (with Shorewall6)
Looking at the diagram in two dimensions, it is easy to spot patterns. Each pattern can be condensed into a single entry in the rules file. For example, it is clear from the first row that the loc zone can access all other zones. That can be expressed very concisely with a single line in the policy file:
loc all ACCEPT
Shorewall has several web pages dedicated to VPNs, including the IPsec specific documentation.. Personally, I found that I had to gather a few details from several of these pages to make an optimal solution. Here are those tips:
Otherwise, just follow the typical examples from the Shorewall quick start guide and configure it to work the way you want.
Here is an example /etc/shorewall/zones file:
fw firewall net ipv4 dmz ipv4 loc ipv4 cust ipv4 vpn_a ipsec mode=tunnel mss=1024 vpn_b ipsec mode=tunnel mss=1024 vpn_c ipsec mode=tunnel mss=1024
Here is an example /etc/shorewall/hosts file describing the VPN ranges from the diagram:
vpn_a eth0:10.1.100.0/24 ipsec vpn_b eth0:10.1.200.0/24 ipsec vpn_c eth0:192.168.1.0/24 ipsec
Here is an example /etc/shorewall/policy file based on the table above:
loc all ACCEPT vpn_c all ACCEPT cust net ACCEPT net cust ACCEPT all all REJECT
Here is an example /etc/shorewall/rules file based on the network:
SECTION ALL # allow connections to the firewall itself to start VPNs: # Rule source dest protocol/port details ACCEPT all fw ah ACCEPT all fw esp ACCEPT all fw udp 500 ACCEPT all fw udp 4500 # allow access to HTTP servers in DMZ: ACCEPT all dmz tcp 80 # allow connections from HTTP servers to MySQL database in private LAN: ACCEPT dmz loc:10.2.0.43 tcp 3306 # allow connections from all VPN users to IMAPS server in private LAN: ACCEPT vpn_a,vpn_b,vpn_c loc:10.2.0.58 tcp 993 # allow VPN users (but not the smartphones in vpn_a) to the # PostgresQL database for PostBooks accounting system: ACCEPT vpn_b,vpn_c loc:10.2.0.48 tcp 5432 SECTION ESTABLISHED ACCEPT all all SECTION RELATED ACCEPT all all
Once the files are created, Shorewall can be easily activated with:
# shorewall compile && shorewall restart
Like Shorewall, strongSwan is also very well documented and I'm just going to focus on those specific areas that are relevant to this type of VPN project.
Although they are not present in the diagram, IPv6 networks are also configured in these strongSwan examples. It is very easy to combine IPv4 and IPv6 into a single /etc/ipsec.conf file. As long as the road-warriors have leftsourceip=%config4,%config6 in their own configurations, they will operate dual-stack IPv4/IPv6 whenver they connect to the VPN.
Here is an example /etc/ipsec.conf for the central VPN gateway:
config setup charonstart=yes charondebug=all plutostart=no conn %default ikelifetime=60m keylife=20m rekeymargin=3m keyingtries=1 keyexchange=ikev2 conn branch1 left=198.51.100.1 leftsubnet=203.0.113.0/24,10.0.0.0/8,2001:DB8:12:80:/64 leftcert=fw1Cert.der leftid=@fw1.example.org leftfirewall=no lefthostaccess=no right=%any rightid=@branch1-fw.example.org rightsubnet=192.168.1.0/24 auto=add conn rw_vpn_a left=198.51.100.1 leftsubnet=0.0.0.0/0,::0/0 leftcert=fw1Cert.der leftid=@fw1.example.org leftfirewall=no lefthostaccess=no right=%any rightid="OU=vpn_a, CN=*" rightsourceip=10.1.100.0/24,2001:DB8:1000:100::/64 auto=add conn rw_vpn_b left=198.51.100.1 leftsubnet=0.0.0.0/0,::0/0 leftcert=fw1Cert.der leftid=@fw1.example.org leftfirewall=no lefthostaccess=no right=%any rightid="OU=vpn_b, CN=*" rightsourceip=10.1.200.0/24,2001:DB8:1000:200::/64 auto=add
Here is an example /etc/ipsec.conf for the Linux server or OpenWRT VPN at the branch office or home:
conn head_office left=%defaultroute leftid=@branch1-fw.example.org leftcert=branch1-fwCert.der leftsubnet=192.168.1.0/24,2001:DB8:12:80:/64 leftfirewall=no lefthostaccess=no right=fw1.example.org rightid=@fw1.example.org rightsubnet=203.0.113.0/24,10.0.0.0/8,2001:DB8:1000::/52 auto=start # notice we only allow vpn_b users, not vpn_a # these users are given virtual IPs from our own # 192.168.1.0 subnet conn rw_vpn_b left=branch1-fw.example.org leftsubnet=192.168.1.0/24,2001:DB8:12:80:/64 leftcert=branch1-fwCert.der leftid=@branch1-fw.example.org leftfirewall=no lefthostaccess=no right=%any rightid="OU=vpn_b, CN=*" rightsourceip=192.168.1.160/27,2001:DB8:12:80::8000/116 auto=add
Shorewall and Shorewall6 don't currently support a unified configuration. This can make it slightly tedious to duplicate rules between the two IP variations. However, the syntax for IPv4 and IPv6 configuration is virtually identical.
Shorewall only currently supports Linux netfilter rules. In theory it could be extended to support other types of firewall API, such as pf used by OpenBSD and the related BSD family of systems.
A more advanced architecture would split the single firewall into multiple firewall hosts, like the inner and outer walls of a large castle. The VPN gateway would also become a standalone host in the DMZ. This would require more complex routing table entries.
Smart cards with PIN numbers provide an effective form of two-factor authentication that can protect certificates for remote users. Smart cards are documented well by strongSwan already so I haven't repeated any of that material in this article.
Managing a private X.509 certificate authority in practice may require slightly more effort than I've described, especially when an organisation grows. Small networks and home users don't need to worry about these details too much, but for most deployments it is necessary to consider things like certificate revocation lists and special schemes to protect the root certificate's private key. EJBCA is one open source project that might help.
Some users may want to consider ways to prevent the road-warriors from accidentally browsing the Internet when the IPsec tunnel is not active. Such policies could be implemented with some basic iptables firewalls rules in the road-warrior devices.
Using these strategies and configuration tips, planning and building a VPN will hopefully be much simpler. Please feel free to ask questions on the mailing lists for any of the projects discussed in this blog.