User:CodAv/Drafts/OpenVPN in Bridge Mode
Using virtual private networks to connect remote computers is a common practice today, yet almost all of these VPNs only use IP tunneling mode to transfer data. For most applications, this is totally fine, but if an application or service (e.g. a LAN game) relies on broadcasts, it won't work. A way to get around this is to use a bridged VPN, which tunnels the whole ethernet layer instead of just the IP protocol.
While this solves a lot of potential issues, a bridged VPN is generally less performant and can create a lot of traffic if there are many active VPN connections, as broadcasts and multicasts are transferred through each tunnel. In small scale or private setups, this should not cause issues, but in larger company networks a bridged VPN should only be deployed very carefully with additional measures in place to limit or filter unwanted traffic.
It is assumed that the local system is configured to use systemd and OpenVPN 2.4 or higher. Besides package names and some paths, the guide should also apply to most other modern Linux distributions without changes.
Kernel configuration
Make sure the kernel supports TUN/TAP devices:
-> Device Drivers
-> Network device support
-> Network core driver support
Universal TUN/TAP device driver support
To connect the VPN to the local network, Ethernet Bridging support is also required:
-> Networking support
-> Networking options
802.1d Ethernet Bridging
Installing required software packages
OpenVPN is required on both server and client sides. Make sure the openssl
(since 2.5, or ssl
until 2.4.9) and systemd
USE flags are enabled:
root #
emerge --ask net-vpn/openvpn
To create ethernet bridges, the bridge-utils package also needs to be present:
root #
emerge --ask net-misc/bridge-utils
Setting up the Network
To prepare the network on the VPN server, at least a TAP device is required, which is the counterpart to the TUN device used for IP-based tunneling. It can be used as a standalone network interface, only available on the VPN server machine, or added to a bridge interface with any physical network ports (or other VPN endpoints) to connect the clients to other networks. If clients only need to access the VPN server machine (and other clients), setting up the bridge interface can be skipped.
Adding a TAP device
OpenVPN can create a TAP device when the server is started, and add it to a bridge. But if any system-based network change happens, the bridge configuration might be reset and the vPN stops working. To circumvent this issue, systemd-networkd should do the job and OpenVPN will use the already created device when it starts.
The following file, using the .netdev
extension, will add a TAP device. The filename can be chosen freely, as long as the extension is kept. Additionally, the device name (tap0
) can also be changed and must be unique.
[NetDev]
Name=tap0
Kind=tap
To configure the network settings for this device, another file with a .network
extension is required:
[Match]
Name=tap0
[Network]
Bridge=br0
ConfigureWithoutCarrier=yes
In the [Network]
section, the Bridge
option adds the tap0
device to the (yet to be created) bridge device br0
. This option must be removed if no bridge is used.
The ConfigureWithoutCarrier
option tells systemd that the device should be configured regardless of having a carrier and can be removed if the OpenVPN server using the TAP device is also started on boot. For a TAP device, having a carrier means that an application like OpenVPN has taken control of the device, so if OpenVPN is not started during the boot process, systemd-networkd will wait two minutes for the device to be ready and then goes into an error state.
If no bridge is used, the TAP device possibly requires the assignment of an IP address and other network settings as described on the systemd Wiki page.
Adding a network bridge
To connect the VPN client with the rest of a local, physical network or other VPN servers, a bridge device can be used.
Same as with the TAP device, setting up a bridge also requires two files. First, the device needs to be created:
[NetDev]
Name=br0
Kind=bridge
The network file should contain the same settings as the existing physical network device in the [Network]
section, the example uses DHCP for simplicity:
[Match]
Name=br0
[Link]
MACAddress=01:23:45:67:89:ab
[Network]
DHCP=yes
If the physical network device's MAC address is registered with the DHCP server, adding the MACAddress
option set to the same hardware address as the physical device will ensure that the bridge device will receive the same network settings.
As the last step, the existing network interface must be added to the bridge as well:
[Match]
Name=eno1
[Network]
Bridge=br0
The Name
option in the [Match]
section must match the physical device(s) that should be added to the bridge. Wildcards are allowed.
A more complete manual to configure bridges can be found on the Network bridge page.
Reloading systemd and apply the changes
To apply the changes, create and configure the new devices, systemd-networkd needs to be reloaded:
root #
systemctl daemon-reload
root #
systemctl restart systemd-networkd
If all went well, the bridge device should now have the same settings as the former physical interface, and the bridge should contain all required devices:
root #
brctl show
bridge name bridge id STP enabled interfaces
br0 8000.00d861dd2fc7 no eno1
tap0
Creating VPN certificates
While the VPN can also be set up to use static, pre-shared keys, it is always better to use TLS certificates for authentication. This adds server verification to make sure clients are not connecting to a malicious server, the server can revoke client certificates to disallow future access and each communication link will use its own keys to encrypt data.
VPN server and client certificates can also be issued by an existing company SSL CA. In this case, only generating a Diffie-Hellman secret for the VPN server is required and the other steps can be skipped.
To create a local certificate authority for the VPN server, using the easy-rsa wrapper is more comfortable than directly using OpenSSL.
root #
emerge --ask app-crypt/easy-rsa
Creating the CA directory structure
All certificates are created and managed by the to-be-created certificate authority. Besides the private keys and certificates, some additional data like serial numbers and a revoke list needs to be permanently stored as long as the CA is used. This guide will use /root/openvpn-pki as an example path, but any other (secure) directory will work.
For business setups requiring higher security, the CA should be set up on a separate machine which is ideally not even connected to the network, protecting the CA private key. Certificates and revoke lists can then be copied to the VPN server.