wiki:OpenVPNBridging

Bridging in OpenVPN

OpenVPN allows two different modes of operation: routed mode and bridged mode. This article is about the latter.

Bridged mode means that the VPN tunnel encapsulates full ethernet frames (up to 1514 bytes long), rather than IP packets (up to 1500 bytes). In itself, this would just add some overhead to the VPN traffic; but in practice, together with some special configuration in the OS (described later), this allows to connect the VPN and its users to a real, physical ethernet network at the data-link level, effectively turning the whole system (ethernet network + VPN) into a single broadcast domain.

Do you need bridging?

This question comes up regularly when somebody asks for advice in configuring a bridged VPN. Bridged mode has a higher traffic overhead, since it works at layer 2 and as such broadcasts are sent into the VPN, and also, as already mentioned, data packets can be up to 1514 bytes. Normally bridged mode is needed only in two cases:

  • You really need to create a layer 2 domain. This may be because you need to use protocols that rely on broadcasts or multicasts (eg netBIOS, LAN games)
  • You need to transport non-IP traffic (eg IPX, AppleTalk?)

If you don't have any of those requirements, you can almost certainly use routed mode. Otherwise, read on.

Bridge setup

For this example, we will assume the following scenario:

+---------+
| client1 +--------\                                            +---------------------------------
+---------+         \    +-------------+                       /            LAN
                     \  +               +                     /         192.168.111.0/24
+---------+            +                 +           +---------+                     
| client2 +-----------+      INTERNET     +---- ppp0 + gateway +eth0          
+---------+            +                 +           +---------+  (192.168.111.254/24)
                      / +               +                     \
+---------+          /   +-------------+                       \
| clientN +---------/                                           +---------------------------------
+---------+

We want VPN clients to connect and feel as if they were physically on the ethernet network, including using IP addresses in the 192.168.111.0/24 range, just like the stations in the LAN.

The first step to achieve this goal is to create a special interface on the VPN gateway. This interface (also known as a bridge) is what connects, or bridges, together the "real" layer 2 domain (ie the LAN) and the layer 2 VPN. Basically a bridge like this can be thought as a mini-ethernet switch internal to the OS, whose ports are connected to ethernet interfaces on the host. So for example, on a host with two ethernet interfaces (eth0 and eth1), a two-ports bridge could be created by enslaving eth0 and eth1 into the special bridge interface (let's call it br0). The enslaved interfaces can usually be added and removed dynamically from the bridge. The bridge interface behaves like an ethernet switch (well, because it effectively is an ethernet switch): it learns which MAC addresses are on each ports, and forwards frames accordingly (broadcasts and unknown MACs are flooded on all ports). The interfaces that are enslaved into the bridge (eth0 and eth1 in our example) operate purely at layer 2, and can not have IP addresses of their own. However, the bridge interface can have an IP address and is otherwise a normal interface, and as such can have firewall rules, routes etc.

To get to OpenVPN: the virtual tap interface that OpenVPN uses in bridged mode is an ethernet interface, and as such can be part of a bridge. This is key: for our scenario, we are going to create a bridge interface that includes the gateway's eth0 LAN interface, and OpenVPN's tap0 interface. This is what bridges the VPN with the LAN.

While the concept of a bridge interface is common, the methods used to actually create a bridge interface are OS dependent. In the following paragraphs instructions are provided for the most common systems, using the addresses and interface names from the above example.

Permanent vs. transient bridge

There are two ways to use a bridge with OpenVPN. One is to create the bridge on the fly just before OpenVPN starts, adding eth0 and tap0 to it, and destroy it when OpenVPN terminates. The second way is to have a permanent bridge interface comprising just eth0, to which OpenVPN's tap0 is added during the time OpenVPN is running.

The first method has several drawbacks: the biggest one is that it involves removing the IP address from the eth0 interface and assigning it to the bridge interface (and the reverse when the bridge is destroyed). On most systems, deleting an IP address from an interface has the effect of removing all routes pointing out that interface, which means that these routes have to be recreated to point to the bridge when it is set up, and again recreated to point to eth0 again when the bridge is destroyed. Also, in some operating systems, there is a delay of some seconds when bringing up the bridge due to STP, and this is turn delays the start of the OpenVPN daemon. Thus setting up a transient bridge is not only complicated to get right, but it also disrupts connectivity for some time.

So, having a permanent bridge created at boot time and only adding/removing tap0 is largely preferable, and this is what the following instructions do.

Windows

Under Windows, the tap interface exists as soon as OpenVPN is installed, even if OpenVPN is not running, and so the bridge can permanently include both interfaces. Also, interfaces are not named "eth0" and "tap0" under Windows, but it should be possible to tel which is which by their descriptions.

Under Windows, open the network interface screen, and select (using CTRL-click) the interfaces that you want to bridge (in our example, the LAN interface and the tap-32 adapter). When they are selected, right-click on the selection and choose "Bridge...". The configuration dialog for the bridge interface will appear, complete it with the information that was previously applied to the regular ethernet interface (ie IP address 192.168.111.254/24 and so).

(to be verified and completed)

Linux

Under Linux, the tool needed to manage bridge interfaces is brctl, which is usually provided in a package called bridge-utils. If we want to use the network configuration facilities provided by the distribution, then the details vary. Here are instructions for Debian-like and Redhat-like distros.

Debian-like (Debian, Ubuntu and derivatives)

Install bridge-utils:

apt-get install bridge-utils

The actual configuration is done in the file /etc/network/interfaces

auto br0
iface br0 inet static
    address 192.168.111.254
    netmask 255.255.255.0
    network 192.168.111.0
    broadcast 192.168.111.255
    bridge_ports eth0

Redhat-like (RHEL, CentOS, Fedora)

Install bridge-utils

yum install bridge-utils

File: /etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE=eth0
ONBOOT=yes
TYPE=Ethernet
BRIDGE=br0

File: /etc/sysconfig/network-scripts/ifcfg-br0

DEVICE=br0
TYPE=Bridge
ONBOOT=yes
STP=on
IPADDR=192.168.111.254
NETMASK=255.255.255.0

If the resulting network topology has no loops (which is probably likely), STP can be disabled.

Mac OS X

(to be completed - need info)

FreeBSD

(to be completed - need info)

Solaris

(to be completed - need info)

OpenVPN configurations

Once the bridge interface is in place, here are sample configurations for the server and for the client(s).

Server configuration

port 1194
proto udp
dev tap
# Windows needs the TAP-Win32 adapter name
# from the Network Connections panel if you
# have more than one.
# Non-Windows systems usually don't need this.
;dev-node MyTap

# script used to add the tap interface to the bridge
# windows servers comment this out
up up.sh

ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
ifconfig-pool-persist ipp.txt

# addresses from .100 to .200 are reserved for VPN clients.
# Obviously, they should not be used by real LAN clients.
server-bridge 192.168.111.254 255.255.255.0 192.168.111.100 192.168.111.200

# Certain Windows-specific network settings
# can be pushed to clients, such as DNS
# or WINS server addresses.  CAVEAT:
# http://openvpn.net/faq.html#dhcpcaveats
;push "dhcp-option DNS 192.168.111.1"
;push "dhcp-option WINS 192.168.111.2"

# can clients see each other? (regardless of firewalling on the server)
;client-to-client

keepalive 10 120
comp-lzo
persist-key
persist-tun
status openvpn-status.log
verb 3

Following are sample up.sh scripts for UNIX systems (in Windows it's not needed since the bridge permanently include both interfaces)

Linux

#!/bin/sh

# the tap interface name is passed as first argument

bridge=br0

brctl addif "$bridge" "$1"

Mac OS X

(to be completed, need info)

FreeBSD

(to be completed, need info)

Solaris

(to be completed, need info)

Client configuration

client
dev tap
# Windows needs the TAP-Win32 adapter name
# from the Network Connections panel
# if you have more than one.
;dev-node MyTap

proto udp

remote my-server-1 1194
resolv-retry infinite
nobind
persist-key
persist-tun

ca ca.crt
cert client.crt
key client.key

ns-cert-type server
comp-lzo
verb 3
Last modified 14 years ago Last modified on 07/15/10 18:55:20