Difference between revisions of "OpenVPN Bridge"

From ArchWiki
Jump to: navigation, search
(changed the bridge paragraph because of net-tools deprecation)
m (Using Systemd: .service not needed)
(16 intermediate revisions by 7 users not shown)
Line 1: Line 1:
[[Category:Networking (English)]]
+
[[Category:Virtual Private Network]]
'''TODO:''' check this now updated article for accuracy, readability and completeness
+
This page describes how to create a network bridge on Arch Linux and host an OpenVPN server using a IP layer-2 based Ethernet bridge (TAP) rather than a IP layer-3 based IP tunnel (TUN). The general [[OpenVPN]] page describes setting up PAM authentication or OpenSSL security certificates in more detail.
 
+
This page describes multiple ways to create a network bridge on Arch Linux and host an OpenVPN server using a IP layer-2 based Ethernet bridge (TAP) rather than a IP layer-3 based IP tunnel (TUN). The general [[OpenVPN]] page describes setting up PAM authentication or OpenSSL security certificates in more detail.
+
  
 
==Introduction==
 
==Introduction==
  
The [http://openvpn.net/index.php/open-source/documentation.html OpenVPN documentation pages] give a full overview of server-side and client-side options that OpenVPN supports. It is easier to set up OpenVPN in tunneling mode and control routing the traffic and it is generally advised to do so if it serves your purpose. However, some applications, such as Windows file sharing or Samba, rely on network broadcasts at the Ethernet level and benefit from believing they are physically located on the same subnet, and software bridging serves this purpose.
+
The [http://openvpn.net/index.php/open-source/documentation.html OpenVPN documentation] page gives a full overview of server-side and client-side options that OpenVPN supports. It is easier to set up OpenVPN in tunneling mode and control routing the traffic and it is generally advised to do so if it serves your purpose. However, some network applications, such as Windows file sharing, rely on network broadcasts at the Ethernet level and benefit from believing they are physically located on the same subnet, and software bridging serves this purpose.
  
==Installation==
+
There are multiple ways to set bridging up. The dynamic method is where OpenVPN will be managing its own bridge on the system and will start, stop and configure it itself. This is the quickest way to set bridging up, although it interrupts other network services when OpenVPN starts and stops. If the system is going to manage its own bridge, maybe because other virtual network adapters connect to the bridge besides just that of OpenVPN, then it is preferable to use the static method.
  
The first thing you want to do is install OpenVPN, the Linux bridging utilities and [[netcfg]].
+
==Dynamic Bridge Installation==
<pre>
+
pacman -S openvpn bridge-utils netcfg
+
</pre>
+
  
==Configuration==
+
You will need to install OpenVPN and Linux bridging utilities
 
+
Earlier versions of guides for OpenVPN provided by the OpenVPN team or various Linux packagers give example scripts for constructing a bridge when starting OpenVPN and destroying it when shutting OpenVPN down.
+
 
+
However, this is a somewhat deprecated approach, since OpenVPN as of 2.1.1 defaults to not allowing itself to call external scripts or programs unless explicitly enabled to, for security reasons.
+
 
+
Also, constructing the bridge is relatively slow compared to all other parts of the network initialization process. (In fact, so slow that dhcpcd will time out before the bridge is ready. See [[#Troubleshooting]].) Also, when restarting OpenVPN after configuration changes, there is no reason to rebuild a working bridge, interrupting all your other network applications. So, setting up a static bridge configuration as follows is one recommended method.
+
 
+
===Bridge===
+
 
+
Add a tap interface for OpenVPN to use in '''/etc/conf.d/openvpn-tapdev'''
+
 
<pre>
 
<pre>
#
+
pacman -S openvpn bridge-utils
# /etc/conf.d/openvpn-tapdev
+
#
+
# Place openvpn-tapdev before network into your DAEMONS array
+
# This will create permanent tap devices which you can use for bridging
+
#
+
# Example:
+
# TAPDEVS="work home"
+
# Will create two tap devices "work" and "home"
+
#
+
TAPDEVS="tap0"
+
 
</pre>
 
</pre>
  
Creating the bridge is not possible anymore with rc.conf since net-tools is deprecated. You are going to have to use [[netcfg]] instead.
+
==Dynamic Bridge Configuration==
Go to /etc/network.d/ and copy the bridge example file:
+
<pre>
+
cd /etc/network.d/
+
cp examples/bridge openvpn_bridge
+
</pre>
+
Now edit /etc/network.d/openvpn_bridge. It may look like this:
+
<pre>
+
INTERFACE="br0"
+
CONNECTION="bridge"
+
DESCRIPTION="OpenVPN Bridge"
+
BRIDGE_INTERFACES="eth0 tap0"
+
IP='static'
+
ADDR='192.168.11.1'
+
GATEWAY='192.168.11.254'
+
DNS=('192.168.11.254')
+
</pre>
+
For more information, for example how to use DHCP instead, check the [[netcfg]] article.
+
  
===Server===
+
OpenVPN will create/destroy the TAP device automatically for the name specified in the config file. OpenVPN settings common to TUN or TAP are not shown in the example config file below, only settings that affect TAP mode. Make sure the 'up' and 'down' scripts are executable with 'chmod +x' after you write them.
  
There are a few example server configurations located in '''/usr/share/openvpn/examples''' to look at.
+
/etc/openvpn/server.conf (sections common to TUN and TAP omitted)
 
+
Here is a server configuration that uses dhcp, and some features only available since 2.1.1, saved as '''/etc/openvpn/server.conf'''
+
 
+
{{Note|Setting '''multihome''' allows OpenVPN to listen on multiple interfaces with UDP but respond only on the one it first received a request from. Otherwise, if listening on multiple interfaces, OpenVPN may switch from one to the other during communication with a client, and clients would not accept packets originating from something other than the original endpoint. Lowering the value for '''script-security''' is necessary to write and invoke scripts that call external programs during OpenVPN operation}}
+
 
<pre>
 
<pre>
# /etc/openvpn/server.conf
+
# this uses a dhcp server, server-side
# 2009.12.31
+
clients must support binding their dhcp client to their tap adapter
#
+
# do not append 'nogw' if using dhcp
# address to bind to, instead of all available
+
server-bridge
;local 192.168.3.252
+
# can specify interface, like tap0 or tap1
# new features, as of v2.1.1
+
#can listen on multiple ips over udp
+
multihome
+
# needed to allow internally called scripts like up/down
+
#  to call external programs like ifup, etc
+
;script-security 2
+
 
+
# tcp might work better on certain "dev tun" setups
+
#  but not for wrapping more tcp or further encrypted
+
#  streams, as that would be redundant, and very slow
+
# "port 1194" and "proto udp" are defaults
+
port 1194
+
proto udp
+
 
+
# could specify interface, like tap0 or tap1
+
 
#  or use up/down routing scripts to handle
 
#  or use up/down routing scripts to handle
 
#  more than one, if needed
 
#  more than one, if needed
 
dev tap0
 
dev tap0
 
+
# needed to call scripts like up/down
# simple scripts
+
which call external programs within the scripts
#  for adding/removing  to tap
+
script-security 2
;up "up.sh br0:0"
+
# user defined scripts for adding/removing tap to bridge
;down "down.sh br0:0"
+
'dev mtu link_mtu ifconfig_local_ip ifconfig_remote_ip' are appended if set
 
+
# make sure 'user' has permission to run 'down' ('up' will be root)
# identical certificate on server & client
+
up "up br0 eth0"
ca config/keys/ca.crt
+
down "down br0 eth0"
 
+
# call 'down' before TUN/TAP close
# server's own cert/key
+
down-pre
cert config/keys/server.crt
+
key config/keys/server.key # keep secret
+
 
+
# for certificate handshake
+
dh config/keys/dh1024.pem
+
 
+
# no arguments will use this subnet's dhcp server
+
#  not openvpn dynamic/static assigment
+
# either way is good, but if you know you're not conflicting
+
#  with any other IP addressing schemes on your subnet,
+
#  this is much faster
+
# this directive expands to include "mode server" and "tls-server"
+
#  so including them elsewhere is redundant
+
;server-bridge 192.168.3.252 255.255.255.0 192.168.3.1 192.168.3.16
+
# like what dhcp does, reuses IPs
+
;ifconfig-pool-persist ipp.txt
+
 
+
# this one uses a dhcp server, server-side
+
potentially better for controlling ip addresses from one location
+
# clients must support binding their dhcp client to their tap adapter
+
server-bridge nogw # 'nogw' is optional
+
 
+
# openvpn server routes client packets to each other itself
+
#  should happen anyway in 'dev tap' mode, but this saves time
+
client-to-client
+
 
+
# ping clients to auto close server side connection
+
keepalive 10 60
+
 
+
# 0 for server, 1 for client
+
tls-auth config/keys/ta.key 0 # This file is secret
+
 
+
# cryptographic cipher.
+
;cipher BF-CBC        # Blowfish (default)
+
cipher AES-128-CBC  # AES
+
 
+
# compression is useful for xfer of
+
#  not already compressed files, like database
+
#  files, otherwise add needless overhead
+
# comp-lzo [mode] ; yes|no|adaptive, adaptive default
+
;comp-lzo
+
 
+
# not needed yet
+
;max-clients 100
+
 
+
 
# drop root priveledges once connected
 
# drop root priveledges once connected
 
#  good idea, for servers running on linux
 
#  good idea, for servers running on linux
user nobody
+
# 'up' script not affected, 'down' script is
group nobody
+
;user nobody
 
+
;group nobody
# avoid accessing things you no longer can
+
persist-key
+
persist-tun
+
 
+
# short status file showing current connections
+
#  rewritten every minute.
+
status openvpn-status.log
+
 
+
# use one or the other, useful for managing multiple
+
#  concurrent servers on a system
+
;log        openvpn.log
+
;log-append  openvpn.log
+
 
+
# 0 is silent, except for fatal errors
+
# 4 is reasonable for general usage
+
# 5 and 6 can help to debug connection problems
+
# 9 is extremely verbose
+
verb 3
+
 
+
# silence repeating messages past certain number, in log
+
;mute 20
+
 
</pre>
 
</pre>
  
The following modules will be automatically loaded, but you could specify them by editing '''/etc/rc.conf'''
+
/etc/openvpn/up
<pre>
+
#...
+
MODULES=(... tun bridge ...)
+
#...
+
</pre>
+
 
+
Now, add the following daemons to '''/etc/rc.conf'''
+
{{Note|'''openvpn-tapdev''' must come before '''net-profiles'''}}
+
<pre>
+
#...
+
DAEMONS=(... openvpn-tapdev net-profiles openvpn ...)
+
#...
+
</pre>
+
 
+
===Client===
+
 
+
The following is a matching '''client.ovpn''' for the options used in '''server.conf''' above, tested in Windows.
+
{{Note|Windows supports authenticating via a dhcp server located on the OpenVPN server's side automatically because of how the TCP stack works on Windows; a Linux client may take more steps to get dhcp to work}}
+
<pre>
+
# /%openvpn%/config/client.conf
+
# 2009.12.31
+
 
+
# defines order of certificate authentification
+
# this directive expands to "pull" "tls-client"
+
#  so including them elsewhere is redundant
+
client
+
 
+
# type of server
+
dev tap
+
 
+
# windows needs tap name, if more than one
+
;dev-node OpenVPN Bridge Connection
+
 
+
# remote <hostname> [port] [proto]
+
remote remote 1194 udp
+
 
+
# only works for peers using the "remote" option
+
# ok if the ip address for remote changes during session
+
float
+
# uses a random port client-side
+
nobind
+
 
+
# this is for laptops or internet conditions
+
#  where openvpn server hostname cannot be resolved easily,
+
#  or changes often, etc
+
# infinte is the default, or value for seconds
+
resolv-retry infinite
+
 
+
# public
+
ca keys/ca.crt
+
cert keys/satellite.crt
+
# private
+
key keys/satellite.key
+
# needed when specified in server
+
# 0 = server, 1 = client
+
tls-auth keys/ta.key 1
+
 
+
# verify that the server has certificate field "server"
+
# protects against certain attacks
+
ns-cert-type server
+
 
+
;cipher BF-CBC
+
cipher AES-128-CBC
+
 
+
# comp-lzo [mode] ; yes|no|adaptive, adaptive default
+
;comp-lzo
+
 
+
# try to preserve some states across restarts
+
persist-key
+
persist-tun
+
 
+
verb 3
+
</pre>
+
 
+
==Tips and Tricks==
+
 
+
===Dynamically create and destroy the bridge===
+
You may not always want a static bridge, as there may be cases that you don't always want OpenVPN on, and when off you would prefer not having the bridge in place. In that case you have multiple options to achieve this.
+
 
+
====Option 1====
+
 
+
Script for creating the bridge:
+
 
<pre>
 
<pre>
 
#!/bin/bash
 
#!/bin/bash
#################################
+
br=$1
# Set up Ethernet bridge on Linux
+
eth=$2
# Requires: bridge-utils
+
dev=$3
#################################
+
mtu=$4
 +
cd /usr/sbin/
  
# Define Bridge Interface
+
# only if you start dhcpcd and leave it
br="br0"
+
#  running for eth
 +
#dhcpcd -k $eth
  
# Define list of TAP interfaces to be bridged,
+
# needed if script is run independently
# for example tap="tap0 tap1 tap2".
+
# but when run through openvpn
tap="tap0"
+
# openvpn will do this automatically
 
+
# could also use 'ip tuntap ..'
# Define physical ethernet interface to be bridged
+
#openvpn --mktun --dev $dev
# with TAP interface(s) above.
+
eth="eth0"
+
 
+
for t in $tap; do
+
    openvpn --mktun --dev $t
+
done
+
  
 
brctl addbr $br
 
brctl addbr $br
 +
# set forwarding delay to 0
 +
#  otherwise dhcp called below would timeout
 +
brctl setfd $br 0
 
brctl addif $br $eth
 
brctl addif $br $eth
 +
# order matters here.. right now there is only
 +
#  one mac in the bridge's table
 +
# if there were two.. there is no guarantee
 +
#  which would be passed to the dhcp server
 +
dhcpcd $br
 +
brctl addif $br $dev
  
for t in $tap; do
+
ip link set $eth up promisc on mtu $mtu
    brctl addif $br $t
+
ip link set $dev up promisc on mtu $mtu
done
+
 
+
for t in $tap; do
+
    ifconfig $t 0.0.0.0 promisc up
+
done
+
 
+
ifconfig $eth 0.0.0.0 promisc up
+
 
+
# If static ip:
+
eth_ip="10.10.0.100"
+
eth_netmask="255.255.255.0"
+
eth_broadcast="10.10.0.255"
+
gw="10.10.0.254"
+
ifconfig $br $eth_ip netmask $eth_netmask broadcast $eth_broadcast
+
route add default gw $gw $br
+
 
+
# If dynamic IP:
+
;dhcpcd $br
+
 
+
 
</pre>
 
</pre>
  
Script for destroying the bridge:
+
/etc/openvpn/down
 
+
 
<pre>
 
<pre>
 
#!/bin/bash
 
#!/bin/bash
####################################
+
br=$1
# Tear Down Ethernet bridge on Linux
+
eth=$2
####################################
+
cd /usr/sbin/
 
+
# Define Bridge Interface
+
br="br0"
+
  
# Define list of TAP interfaces to be bridged together
+
dhcpcd -k $br
tap="tap0"
+
  
ifconfig $br down
+
ip link set $br down
 
brctl delbr $br
 
brctl delbr $br
  
for t in $tap; do
+
# needed if script is run independently
    openvpn --rmtun --dev $t
+
# but when run through openvpn
done
+
# openvpn will do this automatically
 +
#  could also use 'ip tuntap ..'
 +
#openvpn --rmtun --dev $dev
  
/etc/rc.d/network restart
+
# only if you start dhcpcd and leave it
 +
#  running for eth
 +
#dhcpcd $eth
 
</pre>
 
</pre>
  
====Option 2====
+
These examples are for using dhcp. If you are going to use static IP addresses, you will need to adjust accordingly.
  
{{Warning|This script doesn't always correctly report [FAIL] or [DONE] so output can't be relied upon and may be confusing. Also, it is very old and should probably be revisited and revised}}
+
==Using Systemd==
  
Replace '''/etc/rc.d/openvpn''' with
+
The OpenVPN systemd script looks for <name>.conf files in the /etc/openvpn folder by default. So assuming you have a file named server.conf:
 
<pre>
 
<pre>
#!/bin/bash
+
systemctl enable openvpn@server
 +
systemctl start openvpn@server
 +
</pre>
  
# /etc/rc.d/openvpn
+
Be careful about having dhcpcd enabled separately (ie. dhcpcd@eth0.service) at the same time. It is possible, though unlikely, for it to complete after OpenVPN and ruin your dhcp setup for OpenVPN. You could probably disable dhcpcd@eth0.service since you know openvpn@server.service will be resetting dhcp anyway.
#
+
# An init script to start and stop OpenVPN daemons
+
  
. /etc/rc.conf
+
{{Warning| The Static Bridge section does not describe a method using systemd at all. In addition, it may contain outdated information. It should be revised at some point.}}
. /etc/rc.d/functions
+
  
openvpn_config_dir=/etc/openvpn
+
==Static Bridge Installation==
  
make_bridge ()
+
The first thing you want to do is install OpenVPN, the Linux bridging utilities and [[netcfg]].
{
+
<pre>
#echo "# mkbr $1"
+
pacman -S openvpn bridge-utils netcfg
# for example $1 = "br0" and
+
</pre>
# $br0 = ("br0 192.168.2.1 netmask 255.255.255.0 broadcast 192.168.2.255" eth1)
+
eval brvar="(\"\${${1}[@]}\")"
+
brdev=$1
+
  
brctl addbr $brdev
+
==Static Bridge Configuration==
add_to_bridge ${brvar[1]} $brdev
+
  
        ifconfig ${brvar[0]}
+
Earlier versions of guides for OpenVPN provided by the OpenVPN team or various Linux packagers give example scripts for constructing a bridge when starting OpenVPN and destroying it when shutting OpenVPN down.
return $?
+
}
+
  
add_to_bridge ()
+
However, this is a somewhat deprecated approach, since OpenVPN as of 2.1.1 defaults to not allowing itself to call external scripts or programs unless explicitly enabled to, for security reasons.
{
+
#echo "# addbr $1 $2"
+
# for example $1=tap0 and $2=br0
+
ifconfig $1 down >/dev/null 2>&1
+
brctl addif $2 $1
+
ifconfig $1 0.0.0.0 promisc up
+
}
+
  
destroy_bridge ()
+
Also, constructing the bridge is relatively slow compared to all other parts of the network initialization process. (In fact, so slow that dhcpcd will time out before the bridge is ready. See [[#Troubleshooting]].) Also, when restarting OpenVPN after configuration changes, there is no reason to rebuild a working bridge, interrupting all your other network applications. So, setting up a static bridge configuration as follows is the recommended method.
{
+
eval brvar="(\"\${${1}[@]}\")"
+
brdev=$1
+
+
ifconfig $brdev down
+
brctl delbr $brdev
+
}
+
  
make_vpn ()
+
To create an OpenVPN bridge for your server, you are going to have to use [[netcfg]] and create two network profiles - one for the tap interface and one for the bridge.
{
+
#echo  "# mkvpn $1"
+
# for example $1 = vpn0 and
+
# $vpn0 = ("default.conf" tap0 br0)
+
eval vpnvar="(\"\${${1}[@]}\")"
+
+
openvpn --mktun --dev ${vpnvar[1]} > /dev/null
+
if [ "${vpnvar[2]}" != "" ]; then
+
add_to_bridge ${vpnvar[1]} ${vpnvar[2]}
+
fi
+
  
openvpn --cd $openvpn_config_dir --daemon --config ${vpnvar[0]}
+
Go to /etc/network.d/. Then copy the tuntap example file to the directory.
return $?
+
<pre>
}
+
cd /etc/network.d/
 +
cp examples/tuntap openvpn_tap
 +
</pre>
  
destroy_vpn ()
+
Now edit openvpn_tap to create a tap interface. It may look like this.
{
+
<pre>
eval vpnvar="(\"\${${1}[@]}\")"
+
INTERFACE='tap0'
openvpn --rmtun --dev ${vpnvar[1]} > /dev/null
+
CONNECTION='tuntap'
return $?
+
MODE='tap'
}
+
USER='nobody'
 +
GROUP='nobody'
 +
</pre>
  
case "$1" in
+
Do not configure the IP address here, this is going to be done for the bridge interface!
        start)
+
        stat_busy "Starting OpenVPN daemons"
+
  
        # enable IP forwarding
+
To create the bridge profile, copy the example file:
        echo 1 > /proc/sys/net/ipv4/ip_forward
+
  
# create bridge(s)
+
<pre>
error=0
+
cp examples/bridge openvpn_bridge
      for brconf in ${BRIDGES[@]}; do
+
              if echo $brconf | grep '^[^\!]' >/dev/null 2>&1; then
+
                      make_bridge $brconf || error=1
+
              fi
+
      done
+
 
+
# create vpn(s)
+
      for vpnconf in ${VPNS[@]}; do
+
              if echo $vpnconf | grep '^[^\!]' >/dev/null 2>&1; then
+
                      make_vpn $vpnconf || error=1
+
              fi
+
      done
+
 
+
if [ $error -eq 0 ]; then
+
stat_done
+
else
+
stat_fail
+
fi
+
;;
+
        stop)
+
        stat_busy "Stopping OpenVPN daemons"
+
 
+
        killall `which openvpn` 2> /dev/null
+
 
+
# destroy bridge(s)
+
error=0
+
      for brconf in ${BRIDGES[@]}; do
+
              if echo $brconf | grep '^[^\!]' >/dev/null 2>&1; then
+
                      destroy_bridge $brconf || error=1
+
              fi
+
      done
+
 
+
# destroy vpn(s)
+
      for vpnconf in ${VPNS[@]}; do
+
              if echo $vpnconf | grep '^[^\!]' >/dev/null 2>&1; then
+
                      destroy_vpn $vpnconf || error=1
+
              fi
+
      done
+
 
+
if [ $error -eq 0 ]; then
+
stat_done
+
else
+
stat_fail
+
fi
+
;;
+
        restart)
+
                $0 stop
+
sleep 1
+
                $0 start
+
                ;;
+
        *)
+
                echo $"Usage: $0 {start|stop|restart}"
+
                RETVAL=1
+
esac
+
 
</pre>
 
</pre>
  
And then make the script executable.
+
Now edit openvpn_bridge. It may look like this:
 
<pre>
 
<pre>
chmod 755 /etc/rc.d/openvpn
+
INTERFACE="br0"
 +
CONNECTION="bridge"
 +
DESCRIPTION="OpenVPN Bridge"
 +
BRIDGE_INTERFACES="eth0 tap0"
 +
IP='static'
 +
ADDR='192.168.11.1'
 +
GATEWAY='192.168.11.254'
 +
DNS=('192.168.11.254')
 
</pre>
 
</pre>
 +
For more information, for example how to use DHCP instead, check the [[netcfg]] article.
  
====Option 3====
+
Now set the NETWORKS array in /etc/conf.d/netcfg (order is important!):
  
You can create scripts OpenVPN can use with '''up''' and '''down''' options to create and destroy tap interfaces dynamically, rather than using the provided openvpn-tapdev daemon, to add more options when adding it to a bridge. Here are some generic ones; make sure they are executable.
 
 
'''up.sh'''
 
 
<pre>
 
<pre>
#!/bin/bash -e
+
NETWORKS=(openvpn_tap openvpn_bridge)
 
+
BR=$1
+
DEV=$2
+
MTU=$3
+
 
+
/sbin/ifconfig $DEV mtu $MTU promisc up
+
/usr/sbin/brctl addif $BR $DEV
+
 
+
exit 0
+
 
</pre>
 
</pre>
  
'''down.sh'''
+
Then add net-profiles to your [[Rc.conf#Daemons|DAEMONS array]] (net-profiles must be before openvpn!):
 
<pre>
 
<pre>
#!/bin/bash -e
+
DAEMONS=(... net-profiles openvpn ...)
 
+
BR=$1
+
DEV=$2
+
 
+
/usr/sbin/brctl delif $BR $DEV
+
/sbin/ifconfig $DEV down
+
 
+
exit 0
+
 
</pre>
 
</pre>
  
==Troubleshooting==
+
==Static Bridge Troubleshooting==
  
 
Q: Why does starting the network [FAIL] ?
 
Q: Why does starting the network [FAIL] ?
  
A: If you followed the server.conf example above, it is because you are using dhcp on the bridge and setting up the bridge takes longer than dhcpcd is willing to wait. You can fix this by dropping the forwarding delay when adding the bridge to a lower number by adding the following line to '''/etc/rc.d/network'''
+
A:This is probably because you are using DHCP on the bridge and setting up the bridge takes longer than dhcpcd is willing to wait. You can fix this by setting the FWD_DELAY parameter in your bridge network profile (openvpn_bridge). Start with a value of 5 and decrease it until it works.
<pre>
+
.. /usr/sbin/brctl addbr $br
+
+  /usr/sbin/brctl setfd $br 5
+
.. eval brifs="\$bridge_${br}"
+
</pre>
+
  
 
==More Resources==
 
==More Resources==

Revision as of 12:32, 27 October 2012

This page describes how to create a network bridge on Arch Linux and host an OpenVPN server using a IP layer-2 based Ethernet bridge (TAP) rather than a IP layer-3 based IP tunnel (TUN). The general OpenVPN page describes setting up PAM authentication or OpenSSL security certificates in more detail.

Introduction

The OpenVPN documentation page gives a full overview of server-side and client-side options that OpenVPN supports. It is easier to set up OpenVPN in tunneling mode and control routing the traffic and it is generally advised to do so if it serves your purpose. However, some network applications, such as Windows file sharing, rely on network broadcasts at the Ethernet level and benefit from believing they are physically located on the same subnet, and software bridging serves this purpose.

There are multiple ways to set bridging up. The dynamic method is where OpenVPN will be managing its own bridge on the system and will start, stop and configure it itself. This is the quickest way to set bridging up, although it interrupts other network services when OpenVPN starts and stops. If the system is going to manage its own bridge, maybe because other virtual network adapters connect to the bridge besides just that of OpenVPN, then it is preferable to use the static method.

Dynamic Bridge Installation

You will need to install OpenVPN and Linux bridging utilities

pacman -S openvpn bridge-utils

Dynamic Bridge Configuration

OpenVPN will create/destroy the TAP device automatically for the name specified in the config file. OpenVPN settings common to TUN or TAP are not shown in the example config file below, only settings that affect TAP mode. Make sure the 'up' and 'down' scripts are executable with 'chmod +x' after you write them.

/etc/openvpn/server.conf (sections common to TUN and TAP omitted)

# this uses a dhcp server, server-side
#  clients must support binding their dhcp client to their tap adapter
# do not append 'nogw' if using dhcp
server-bridge
# can specify interface, like tap0 or tap1
#  or use up/down routing scripts to handle
#  more than one, if needed
dev tap0
# needed to call scripts like up/down
#  which call external programs within the scripts
script-security 2
# user defined scripts for adding/removing tap to bridge
#  'dev mtu link_mtu ifconfig_local_ip ifconfig_remote_ip' are appended if set
# make sure 'user' has permission to run 'down' ('up' will be root)
up "up br0 eth0"
down "down br0 eth0"
# call 'down' before TUN/TAP close
down-pre
# drop root priveledges once connected
#  good idea, for servers running on linux
# 'up' script not affected, 'down' script is
;user nobody
;group nobody

/etc/openvpn/up

#!/bin/bash
br=$1
eth=$2
dev=$3
mtu=$4
cd /usr/sbin/

# only if you start dhcpcd and leave it
#  running for eth
#dhcpcd -k $eth

# needed if script is run independently
# but when run through openvpn
# openvpn will do this automatically
#  could also use 'ip tuntap ..'
#openvpn --mktun --dev $dev

brctl addbr $br
# set forwarding delay to 0
#  otherwise dhcp called below would timeout
brctl setfd $br 0
brctl addif $br $eth
# order matters here.. right now there is only
#  one mac in the bridge's table
# if there were two.. there is no guarantee
#  which would be passed to the dhcp server
dhcpcd $br
brctl addif $br $dev

ip link set $eth up promisc on mtu $mtu
ip link set $dev up promisc on mtu $mtu

/etc/openvpn/down

#!/bin/bash
br=$1
eth=$2
cd /usr/sbin/

dhcpcd -k $br

ip link set $br down
brctl delbr $br

# needed if script is run independently
# but when run through openvpn
# openvpn will do this automatically
#  could also use 'ip tuntap ..'
#openvpn --rmtun --dev $dev

# only if you start dhcpcd and leave it
#  running for eth
#dhcpcd $eth

These examples are for using dhcp. If you are going to use static IP addresses, you will need to adjust accordingly.

Using Systemd

The OpenVPN systemd script looks for <name>.conf files in the /etc/openvpn folder by default. So assuming you have a file named server.conf:

systemctl enable openvpn@server
systemctl start openvpn@server

Be careful about having dhcpcd enabled separately (ie. dhcpcd@eth0.service) at the same time. It is possible, though unlikely, for it to complete after OpenVPN and ruin your dhcp setup for OpenVPN. You could probably disable dhcpcd@eth0.service since you know openvpn@server.service will be resetting dhcp anyway.

Warning: The Static Bridge section does not describe a method using systemd at all. In addition, it may contain outdated information. It should be revised at some point.

Static Bridge Installation

The first thing you want to do is install OpenVPN, the Linux bridging utilities and netcfg.

pacman -S openvpn bridge-utils netcfg

Static Bridge Configuration

Earlier versions of guides for OpenVPN provided by the OpenVPN team or various Linux packagers give example scripts for constructing a bridge when starting OpenVPN and destroying it when shutting OpenVPN down.

However, this is a somewhat deprecated approach, since OpenVPN as of 2.1.1 defaults to not allowing itself to call external scripts or programs unless explicitly enabled to, for security reasons.

Also, constructing the bridge is relatively slow compared to all other parts of the network initialization process. (In fact, so slow that dhcpcd will time out before the bridge is ready. See #Troubleshooting.) Also, when restarting OpenVPN after configuration changes, there is no reason to rebuild a working bridge, interrupting all your other network applications. So, setting up a static bridge configuration as follows is the recommended method.

To create an OpenVPN bridge for your server, you are going to have to use netcfg and create two network profiles - one for the tap interface and one for the bridge.

Go to /etc/network.d/. Then copy the tuntap example file to the directory.

cd /etc/network.d/
cp examples/tuntap openvpn_tap

Now edit openvpn_tap to create a tap interface. It may look like this.

INTERFACE='tap0'
CONNECTION='tuntap'
MODE='tap'
USER='nobody'
GROUP='nobody'

Do not configure the IP address here, this is going to be done for the bridge interface!

To create the bridge profile, copy the example file:

cp examples/bridge openvpn_bridge

Now edit openvpn_bridge. It may look like this:

INTERFACE="br0"
CONNECTION="bridge"
DESCRIPTION="OpenVPN Bridge"
BRIDGE_INTERFACES="eth0 tap0"
IP='static'
ADDR='192.168.11.1'
GATEWAY='192.168.11.254'
DNS=('192.168.11.254')

For more information, for example how to use DHCP instead, check the netcfg article.

Now set the NETWORKS array in /etc/conf.d/netcfg (order is important!):

NETWORKS=(openvpn_tap openvpn_bridge)

Then add net-profiles to your DAEMONS array (net-profiles must be before openvpn!):

DAEMONS=(... net-profiles openvpn ...)

Static Bridge Troubleshooting

Q: Why does starting the network [FAIL] ?

A:This is probably because you are using DHCP on the bridge and setting up the bridge takes longer than dhcpcd is willing to wait. You can fix this by setting the FWD_DELAY parameter in your bridge network profile (openvpn_bridge). Start with a value of 5 and decrease it until it works.

More Resources

OpenVPN | General page on configuring OpenVPN, including setting up authentication methods.


Any additions, clarifications, reorganizations, feedback etc. etc. are more than appreciated.