Copyright © 2003, 2004, 2005, 2006 Simon Mater, Thomas M. Eastep
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover, and with no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License”.
Table of Contents
This article applies to Shorewall 3.0 and later and to OpenVPN 2.0 and later. If you are running a version of Shorewall earlier than Shorewall 3.0.0 then please see the documentation for that release.
OpenVPN is a robust and highly configurable VPN (Virtual Private Network) daemon which can be used to securely link two or more private networks using an encrypted tunnel over the Internet. OpenVPN is an Open Source project and is licensed under the GPL. OpenVPN can be downloaded from http://openvpn.net/.
Unless there are interoperability issues (the remote systems do not support OpenVPN), OpenVPN is my choice any time that I need a VPN.
It is widely supported -- I run it on both Linux and Windows XP.
It requires no kernel patching.
It is very easy to configure.
It just works!
I recommend reading the VPN Basics article if you plan to implement any type of VPN.
Suppose that we have the following situation:
We want systems in the 192.168.1.0/24 subnetwork to be able to
communicate with the systems in the 10.0.0.0/8 network. This is
accomplished through use of the
/etc/shorewall/tunnels file and the
/etc/shorewall/policy file and OpenVPN.
While it was possible to use the Shorewall start and stop script to start and stop OpenVPN, I decided to use the init script of OpenVPN to start and stop it.
On each firewall, you will need to declare a zone to represent the
remote subnet. We'll assume that this zone is called “vpn”
and declare it in
/etc/shorewall/zones on both
systems as follows.
/etc/shorewall/zones— Systems A & B#ZONE TYPE OPTIONS IN OUT # OPTIONS OPTIONS vpn ipv4
On system A, the 10.0.0.0/8 will comprise the vpn zone.
/etc/shorewall/interfaceson system A:#ZONE INTERFACE BROADCAST OPTIONS vpn tun0
/etc/shorewall/tunnels on system A, we need
#TYPE ZONE GATEWAY GATEWAY ZONE openvpn net 184.108.40.206
This entry in
/etc/shorewall/tunnels opens the
firewall so that OpenVPN traffic on the default port 1194/udp will be
accepted to/from the remote gateway. If you change the port used by
OpenVPN to 7777, you can define /etc/shorewall/tunnels like this:
/etc/shorewall/tunnels with port 7777:#TYPE ZONE GATEWAY GATEWAY ZONE openvpn:7777 net 220.127.116.11
Similarly, if you want to use TCP for your tunnel rather than UDP (the default), then you can define /etc/shorewall/tunnels like this:
/etc/shorewall/tunnels using TCP:#TYPE ZONE GATEWAY GATEWAY ZONE openvpn:tcp net 18.104.22.168
Finally, if you want to use TCP and port 7777:
/etc/shorewall/tunnels using TCP port 7777:#TYPE ZONE GATEWAY GATEWAY ZONE openvpn:tcp:7777 net 22.214.171.124
This is the OpenVPN config on system A:
dev tun local 126.96.36.199 remote 188.8.131.52 ifconfig 192.168.99.1 192.168.99.2 route 10.0.0.0 255.0.0.0 192.168.99.2 tls-server dh dh1024.pem ca ca.crt cert my-a.crt key my-a.key comp-lzo verb 5
Similarly, On system B the 192.168.1.0/24 subnet will comprise the vpn zone
/etc/shorewall/interfaceson system B:#ZONE INTERFACE BROADCAST OPTIONS vpn tun0
/etc/shorewall/tunnels on system B, we
#TYPE ZONE GATEWAY GATEWAY ZONE openvpn net 184.108.40.206
And in the OpenVPN config on system B:
dev tun local 220.127.116.11 remote 18.104.22.168 ifconfig 192.168.99.2 192.168.99.1 route 192.168.1.0 255.255.255.0 192.168.99.1 tls-client ca ca.crt cert my-b.crt key my-b.key comp-lzo verb 5
You will need to allow traffic between the “vpn” zone and the “loc” zone on both systems -- if you simply want to admit all traffic in both directions, you can use the policy file:
/etc/shorewall/policyon systems A & B#SOURCE DEST POLICY LOG LEVEL loc vpn ACCEPT vpn loc ACCEPT
On both systems, restart Shorewall and start OpenVPN. The systems in the two masqueraded subnetworks can now talk to each other.
OpenVPN 2.0 provides excellent support for roadwarriors. Consider the setup in the following diagram:
On the gateway system (System A), we need a zone to represent the remote clients — we'll call that zone “road”.
/etc/shorewall/zones— System A:#ZONE TYPE OPTIONS IN OUT # OPTIONS OPTIONS road ipv4
On system A, the remote clients will comprise the road zone.
/etc/shorewall/interfaceson system A:#ZONE INTERFACE BROADCAST OPTIONS road tun+
/etc/shorewall/tunnels on system A, we need
#TYPE ZONE GATEWAY GATEWAY ZONE openvpn:1194 net 0.0.0.0/0
If you are running Shorewall 2.4.3 or later, you might prefer the
/etc/shorewall/tunnels on system A.
Specifying the tunnel type as openvpnserver has the advantage that the VPN
connection will still work if the client is behind a gateway/firewall that
#TYPE ZONE GATEWAY GATEWAY ZONE openvpnserver:1194 net 0.0.0.0/0
We want the remote systems to have access to the local LAN — we do
that with an entry in
that the local LAN comprises the zone “loc”).
#SOURCE DESTINATION POLICY road loc ACCEPT
The OpenVPN configuration file on system A is something like the following:
dev tun server 192.168.2.0 255.255.255.0 dh dh1024.pem ca /etc/certs/cacert.pem crl-verify /etc/certs/crl.pem cert /etc/certs/SystemA.pem key /etc/certs/SystemA_key.pem port 1194 comp-lzo user nobody group nogroup ping 15 ping-restart 45 ping-timer-rem persist-tun persist-key verb 3
Configuration on the remote clients follows a similar line. We define a zone to represent the remote LAN:
/etc/shorewall/zones— System B:#ZONE TYPE OPTIONS IN OUT # OPTIONS OPTIONS home ipv4
On system A, the hosts accessible through the tunnel will comprise the home zone.
/etc/shorewall/interfaceson system B:#ZONE INTERFACE BROADCAST OPTIONS home tun0
/etc/shorewall/tunnels on system B, we need
#TYPE ZONE GATEWAY GATEWAY ZONE openvpn:1194 net 22.214.171.124
Again, if you are running Shorewall 2.4.3 or later, in
/etc/shorewall/tunnels on system B you might
#TYPE ZONE GATEWAY GATEWAY ZONE openvpnclient:1194 net 126.96.36.199
We want the remote client to have access to the local LAN — we do
that with an entry in
#SOURCE DESTINATION POLICY $FW home ACCEPT
The OpenVPN configuration on the remote clients is along the following line:
dev tun remote 188.8.131.52 up /etc/openvpn/home.up tls-client pull ca /etc/certs/cacert.pem cert /etc/certs/SystemB.pem key /etc/certs/SystemB_key.pem port 1194 user nobody group nogroup comp-lzo ping 15 ping-restart 45 ping-timer-rem persist-tun persist-key verb 3
If you want multiple remote clients to be able to communicate openly with each other then you must:
Include the client-to-client directive in the server's OpenVPN configuration; and
Specify the routeback option on
tun+ device in /etc/shorewall/interfaces.
If you want to selectively allow communication between the clients, then see this article by Marc Zonzon
Occasionally, the need arises to have a single LAN span two different geographical locations. OpenVPN allows that to be done easily.
Consider the following case:
Part of the 192.168.1.0/24 network is in one location and part in another. The two LANs can be bridged with OpenVPN as described in this section. This example uses a fixed shared key for encryption.
OpenVPN configuration on left-hand firewall:
remote 184.108.40.206 dev tap0 secret /etc/openvpn/bridgekey
OpenVPN configuration on right-hand firewall:
remote 220.127.116.11 dev tap0 secret /etc/openvpn/bridgekey
The bridges can be created by manually makeing the tap device tap0 and bridgeing it with the local ethernet interface. Assuming that the local interface on both sides is eth1, the following stanzas in /etc/network/interfaces (Debian and derivatives) will create the bridged interfaces.
/etc/network/interfaces on the left-hand firewall:
iface br0 inet static pre-up /usr/sbin/openvpn --mktun --dev tap0 pre-up /usr/sbin/brctl addbr br1 address 192.168.1.254 network 192.168.1.0 broadcast 192.168.1.255 netmask 255.255.255.0 post-up /sbin/ip link set tap0 up post-up /usr/sbin/brctl addif br0 tap0 post-up /sbin/ip link set eth1 up post-up /usr/sbin/brctl addif br0 eth1 post-down /usr/sbin/brctl delbr br0 post-down /usr/sbin/tunctl -d tap0 post-down /sbin/ip link set eth1 down
/etc/network/interfaces on the right-hand firewall:
iface br0 inet static pre-up /usr/sbin/openvpn --mktun --dev tap0 pre-up /usr/sbin/brctl addbr br1 address 192.168.1.253 network 192.168.1.0 broadcast 192.168.1.255 netmask 255.255.255.0 post-up /sbin/ip link set tap0 up post-up /usr/sbin/brctl addif br0 tap0 post-up /sbin/ip link set eth1 up post-up /usr/sbin/brctl addif br0 eth1 post-down /usr/sbin/brctl delbr br0 post-down /usr/sbin/tunctl -d tap0 post-down /sbin/ip link set eth1 down
The Shorewall configuration is just a Simple Bridge.