domingo, 8 de fevereiro de 2015

Multi Wan OpenVPN - the setup

keywords: multi wan openvpn, double wan openvpn, double openvpn,

We have recently realized that the "Multi Wan OpenVPN" question was either an orphaned question or one with a too low signal/noise ratio. We intend to clear things up with this short post.

Facts:
  • some VPNs need multiple entry points with different public IPs for redundancy 
  • if more than one public IP belongs to the same VPN gateway we have a problem if we use OpenVPN because it sends all reply packets through the default route of the system instead of respecting the routing rules, preventing the connection from being established except on the IP of the interface the default route is assigned to - here is the bug report
  • there is a PFSense document on top of Google's results suggesting that the OpenVPN process should bind to localhost and one should setup port forwardings to 127.0.0.1 from both WAN links - as far as we know this doesn't work at least with Linux + iptables
  • the problem can be worked around easily by replicating the server configuration file and letting the init script start several instances of OpenVPN each one bound to a single WAN interface
  • there is an even easier workaround which is changing the protocol from UDP to TCP (but certainly UDP is the default protocol for a reason - changing to TCP should be a last resort measure, some discussion here)
Below you will find an example of an OpenVPN bridge configuration on a multihomed Centos based gateway with two public IPs. The parameters in bold are the ones directly related to the Multi Wan configuration.

 Server configuration for the first WAN interface - /etc/openvpn/server.conf
plugin /usr/lib/openvpn/plugin/lib/openvpn-auth-pam.so passwd
client-cert-not-required
username-as-common-name
proto udp
dev tap0
local wan1.mycompany.com

server-bridge 192.168.5.254 255.255.255.0 192.168.5.230 192.168.5.253
ifconfig-pool-persist /var/tmp/ipp.txt
push "redirect-gateway bypass-dhcp bypass-dns"
push "dhcp-option DNS 192.168.5.254"
client-to-client
keepalive 10 120
persist-key
persist-tun
dh /etc/openvpn/keys/dh1024.pem
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key
port 1194
user nobody
comp-lzo
verb 0

 Server configuration for the second WAN interface - /etc/openvpn/server2.conf
plugin /usr/lib/openvpn/plugin/lib/openvpn-auth-pam.so passwd
client-cert-not-required
username-as-common-name
proto udp
dev tap1
local wan2.mycompany.com

server-bridge 192.168.5.254 255.255.255.0 192.168.5.230 192.168.5.253
ifconfig-pool-persist /var/tmp/ipp.txt
push "redirect-gateway bypass-dhcp bypass-dns"
push "dhcp-option DNS 192.168.5.254"
client-to-client
keepalive 10 120
persist-key
persist-tun
dh /etc/openvpn/keys/dh1024.pem
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key
port 1194
user nobody
comp-lzo
verb 0

Bridge setup script
#!/bin/bash

#################################
# Set up Ethernet bridge on Linux
# Requires: bridge-utils
#################################

# Define Bridge Interface
br="br0"

# Define list of TAP interfaces to be bridged, one per WAN interface
tap="tap0 tap1"

# Define physical ethernet interface to be bridged
# with TAP interface(s) above.
eth="eth0"
eth_ip="192.168.5.254"
eth_netmask="255.255.255.0"
eth_broadcast="192.168.5.255"

brctl addbr $br
brctl addif $br $eth

for t in $tap; do
    brctl addif $br $t
done

for t in $tap; do
    ifconfig $t 0.0.0.0 promisc up
done

ifconfig $eth 0.0.0.0 promisc up

ifconfig $br $eth_ip netmask $eth_netmask broadcast $eth_broadcast
 To start up the OpenVPN instances we only need to run
/usr/local/AS/bin/bridge-start.sh
/etc/init.d/openvpn start
One can check that the init script launched two independent instances as follows
 [root@gateway ~]# netstat  --udp -nlp |grep openvpn
udp        0      0 WANIP1:1194           0.0.0.0:*                               1806/openvpn       
udp        0      0 WANIP2:1194        0.0.0.0:*                               1795/openvpn       
[root@gateway ~]#

For everything to work we need, of course, the linux multihoming configuration to be correclty implemented first. We wrote about that some years ago.

On the client side fault tolerance can be implemented simply by using multiple "remote" statements on the configuration file as in the following example
remote wan1.mycompany.com
remote wan2.mycompany.com
Alternatively, fault tolerance can be controlled by pointing the DNS entry, eg vpn.mycompany.com, to the WAN interface to be used. If that interface fails, a DNS update will enable a reconnection to a different one, given a small enough DNS record TTL.