User:CodAv/Drafts/OpenVPN in Bridge Mode

From Gentoo Wiki
Jump to:navigation Jump to:search

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.

Important
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:

KERNEL TUN/TAP support
-> 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:

KERNEL Ethernet Bridging
-> 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.

FILE /etc/systemd/network/VPNTAP.netdevTAP device file
[NetDev]
Name=tap0
Kind=tap

To configure the network settings for this device, another file with a .network extension is required:

FILE /etc/systemd/network/VPNTAP.networkTAP network settings
[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:

FILE /etc/systemd/network/VPNBridge.netdevBridge device file
[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:

FILE /etc/systemd/network/VPNBridge.networkBridge network settings
[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:

FILE /etc/systemd/network/Ethernet.networkExample wired network settings
[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.

Note
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.

Configuring the OpenVPN server

Adding a VPN client