How to set up a basic OpenVPN bridging server

      2 Comments on How to set up a basic OpenVPN bridging server

Beside the official OpenVPN documentation there’s a vast number of howtos and guides out there, that’ll tell you how to set up an OpenVPN server. Unfortunately, most of these use a tunneling setup including some sort of router and packet filter. If you want to transport non-IP based traffic and can accept the increased broadcast overhead and poor scalability, you need to setup an OpenVPN bridge.

Installing the packages

Since OpenVPN is one of the most popular VPN solutions, we don’t have to worry about compiling the software ourselves. Fedora ships a pre-packaged version and even offers a bunch of scripts (easy-rsa) that greatly simplify key-handling.

yum install openvpn easy-rsa

Generating the keys

Before we can configure the actual OpenVPN server, we have to deal with key management. There are a couple of ways to authenticate with an OpenVPN server instance, but the best choice is usually an X.509 certificate and pre-shared keys.

The first step is to set some environment variables (KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG, KEY_EMAIL), which are found at the bottom of /usr/share/easy-rsa/2.0/vars

[...]
export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="City"
export KEY_ORG="Company"
export KEY_EMAIL=mail@example.org
export KEY_CN=server-CA
export KEY_NAME=server-CA
export KEY_OU=""

Next, we can create our Certificate Authority key

# cd /usr/share/openvpn/easy-rsa/2.0/
# source ./vars 
NOTE: If you run ./clean-all, I will be doing a rm -rf on /usr/share/easy-rsa/2.0/keys
# ./clean-all
# ./build-ca 
Generating a 1024 bit RSA private key
[...]

and generate the server key and Diffie-Hellman key afterwards.

# ./build-key-server server
Generating a 1024 bit RSA private key
[...]

# ./build-dh
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
[...]

Finally, we need to build a certificate and key for each client with a unique common name. OpenVPN assigns IP addresses by common name, so non-unique names would result in conflicting IP addresses.

# ./build-key client
Generating a 1024 bit RSA private key
..............++++++
...........................................++++++
writing new private key to 'client.key'
[...]

The only thing left to do is copying the keys to the OpenVPN configuration directory and adjusting the permissions accordingly.

# cp -a keys/ /etc/openvpn/
# chmod 755 /etc/openvpn/keys/

Setting up the server

To set up the server, generate a configuration file in /etc/openvpn with the following content:

port 1194
proto udp
server-bridge 192.168.8.10 255.255.255.0 192.168.8.20 192.168.8.30
dev tap
ca keys/ca.crt
cert keys/server.crt
key keys/server.key 
dh keys/dh1024.pem
up bridge-start
down bridge-stop
keepalive 10 600
comp-lzo
persist-key
persist-tun
verb 3
mute 20
status openvpn-status.log
script-security 2

# The server doesn't need privileges
user openvpn
group openvpn

For a full list of options have a look at the OpenVPN manpage.

To start and stop the bridge device, the OpenVPN package supplies two simple scripts. Copy them into the OpenVPN config directory

# cp /usr/share/doc/openvpn/sample/sample-scripts/bridge-start /etc/openvpn/
# cp /usr/share/doc/openvpn/sample/sample-scripts/bridge-stop /etc/openvpn/

You have to alter both scripts slightly to match your configuration

#!/bin/sh

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

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:$PATH

# Define Bridge Interface
br="br0"

# Define list of TAP interfaces to be bridged,
# for example tap="tap0 tap1 tap2".
tap="tap0 tap1"

# Define physical ethernet interface to be bridged
# with TAP interface(s) above.
eth="eth0"
eth_ip="192.168.8.10"
eth_netmask="255.255.255.0"
eth_broadcast="192.168.8.255"
eth_gateway="192.168.8.254"

for t in $tap; do
    openvpn --mktun --dev $t
done

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
sleep 1
route add default gw $eth_gateway
#!/bin/sh

####################################
# Tear Down Ethernet bridge on Linux
####################################

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:$PATH

# Define Bridge Interface
br="br0"

# Define list of TAP interfaces to be bridged together
tap="tap0 tap1"

ifconfig $br down
brctl delbr $br

for t in $tap; do
    openvpn --rmtun --dev $t
done

Note that you have to change the PATH variable in order for the script to work with Fedora 20. You’ll also need to add a single tap device for every client and might want to add a default route after enabling the bridge.

The fact that OpenVPN supports multiple servers and every deamon requires a single configuration file collides with the systemd way of doing things. This is simply something that is not supported by systemd out of the box. To enable and start the OpenVPN service, run

# ln -s /lib/systemd/system/openvpn\@.service /etc/systemd/system/multi-user.target.wants/openvpn\@server.service 
# systemctl -f enable openvpn@server.service 
# systemctl start openvpn@server.service 

Note that the name of the service (“openvpn@server.service”) corresponds with the name of the configuration file in /etc/openvpn

Watching the status log

You can see who is currently connected to your OpenVPN server, by observing the openvpn-status.log file.

# watch -n 1 cat /etc/openvpn/openvpn-status.log

Resources:
https://fedoraproject.org/wiki/Openvpn
https://wiki.archlinux.org/index.php/Create_a_Public_Key_Infrastructure_Using_the_easy-rsa_Scripts

2 thoughts on “How to set up a basic OpenVPN bridging server

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.