Bridging OpenVPN

2015-06-30T18:08:33
ID N0WHERE:32151
Type n0where
Reporter N0where
Modified 2015-06-30T18:08:33

Description

OpenVPN supports two very different means for interconnecting networks: routing and bridging.

Routing refers to the interconnection of separate and independent “sub-networks” (subnets) which have non-overlapping ranges of IP addresses. Upon receiving a packet sent to it, a network “router” examines the destination IP address to determine which of several connected networks should receive it, after which that packet is forwarded to the proper network.

Bridging, by comparison, is much simpler. A network “bridge” is simply an electrical interconnection between separate physical networks that are all carrying the same ranges of IP addresses. Standard dumb network “hubs” and “switches” are examples of network bridges. With a hub, packets arriving at any port are “bridged” and sent out to every other port. A switch is a bit smarter, since it is able to adaptively learn which network interface cards (NICs) are attached to which ports. But a switch is still interconnecting network segments carrying the same ranges of IP addresses.

OpenVPN-road

Making the choice for OpenVPN

Although “routed” connections are the most common and straightforward to configure, they suffer from significant operational limitations. By comparison, “bridged” connections are generally much trickier to configure, and are not even natively available under all operating systems, so they are not the default connection type. But when bridging is properly setup it correctly does everything that we want.

_ DO YOU _

_ EVEN _

_ tap br0 ? _

OpenVPN Routing

When OpenVPN’s virtual adapter is configured for “Routing” of virtual VPN connections, its adapter is given an IP address outside of the range of the local LAN and a separate “virtual subnet” is created for connecting to any remote VPN computers. Those remotely connected computers receive IP addresses within this newly created separate subnet.

This virtual subnet must have a separate IP range from the physical LAN so that the computer running OpenVPN knows whether to “route” packets out to the virtual subnet, or to another machine on the local LAN, or out to the LAN’s gateway

OpenVPN in “routing mode” creates a private network shared by the machines connecting to it through secure VPN tunnels. This is a great solution if the remotely connecting VPN user(s) only wish to have a connection to machine running OpenVPN, but trouble arises if the remote VPN user wants to access any other resources of the local LAN network, or to securely access the Internet through this LAN.

The problem arises because none of the other computers on the local LAN, including the LAN’s gateway, have any way of knowing about the new virtual subnet that was created by OpenVPN. Essentially, OpenVPN is the “gateway” for the virtual subnet, but all of the machines on the main physical LAN already have a “gateway” defined for non-local packet destinations. So if the OpenVPN machine were to send a packet on behalf of one of its remote VPN users to one of the other local machines on the LAN, that machine would see that the packet came from an IP address outside of its own local LAN . . . and would direct any reply packets to the LAN’s gateway rather than back to the OpenVPN machine for forwarding to the remote VPN user.

The upshot of this is the big “gotcha” that hits and deeply frustrates most first-time users of OpenVPN. They can connect to the OpenVPN machine itself, but they can’t reach any other resources on the LAN, nor the Internet through their LAN.

Now . . . networking technology is powerful enough that it is possible for the various machines on the local LAN to be “informed” about the private virtual subnet created by the OpenVPN machine so that they will direct any outbound packets to the OpenVPN machine instead of the LAN’s gateway. The process is known as defining “static routes” which would be placed into every other network machine on the LAN. But this requires manual configuration of network routing tables, and many simple network appliances such as networked printers, gateway routers, and other devices lack any provision for this sort of advanced packet routing.

Routed OpenVPN configurations are useful if the machine running the OpenVPN server is the same machine which is serving as the LAN’s gateway. Then all of the machines on the LAN will send their packets back to the gateway machine, which OpenVPN will route back out to the remote user(s). Advanced users who are already running a Linux or Unix machine as their network gateway may wish to explore this configuration.

Bridging OpenVPN to the Rescue


The alternative and superior solution is to setup OpenVPN’s virtual adapter in a “bridging” configuration.

Remote users receive an IP address that is within the same IP range as the other computers on the LAN. The computer running the OpenVPN server not only responds to its own address, but also any others belonging to the connected VPN users. Since remotely-connected users are effectively connected to and “on” their home LAN, their remotely connected computers receive a home LAN IP address, and they are able to transparently access any resources that are present on the LAN – exactly as if their computer was plugged directly into their home router or hub.

Another significant benefit of bridging over routing is that Ethernet bridging passes all Ethernet network traffic whereas IP routing only handles “directed” IP packet traffic. Network wide “broadcasts” are inherently local in scope. Broadcasts are passed along by hubs, switches, and bridges, but not by routers. This is crucial, otherwise the global Internet would be swamped with “broadcasts” and the world would end. This important and useful functionality continues to function perfectly over bridged OpenVPN connections, but is not available over OpenVPN’s routed connections. This is another common source of frustration for first-time OpenVPN users.

Prerequisites

The only prerequisite is having a Ubuntu server running. You will need root access.

Assumptions:

  • Network: 192.168.2.0
  • Router: 192.168.2.1
  • Router DHCP range: 192.168.2.2-99
  • OpenVPN server address: 192.168.2.100
  • OpenVPN Client Range: 192.168.2.101-200

Install and Configure OpenVPN’s Server Environment

Before we install any packages, first we’ll update Ubuntu’s repository lists.

apt-get update

Next we will install the OpenVPN, Easy-RSA and bridge tools packages on the server

sudo apt-get install openvpn easy-rsa bridge-utils

In order to assign the remote workstation a local address we need to be able to bridge the OpenVPN interface (tap0) to the local network. The adding of the tap0 to the bridge interface br0 will be handled by OpenVPN.

Within the servers network configuration file /etc/network/interfaces we first need to create the br0 interface.

auto br0
iface br0 inet static
    address 192.168.2.100
    netmask 255.255.255.0
    network 192.168.2.0
    broadcast 192.168.2.255
    dns-nameservers 192.168.2.100 192.168.2.1 8.8.8.8
    bridge_ports eth0
    bridge_fd 9
    bridge_hello 2
    bridge_maxage 12
    bridge_stp on
    bridge_prio 1000

While we are in the same file we should also mask eth0:

auto eth0
 iface eth0 inet manual
 up ifconfig $IFACE 0.0.0.0 up
 up ip link set $IFACE promisc on
 down ip link set $IFACE promisc off
 down ifconfig $IFACE down

Now, we can move to OpenVPN server configuration.

cd /etc/openvpn/

We need to create two scripts which will be used to bring our interface up when we start our server. Appropriately, we’ll name them up and down but you can use whatever name you like.

up.sh

#!/bin/sh

BR=$1
DEV=$2
MTU=$3
/sbin/ifconfig $DEV mtu $MTU promisc up
/sbin/brctl addif $BR $DEV

Down.sh

#!/bin/sh
BR=$1
DEV=$2
/sbin/brctl delif $BR $DEV
/sbin/ifconfig $DEV down

These files should have executable permitions:

sudo chmod 755 /etc/openvpn/down.sh
sudo chmod 755 /etc/openvpn/up.sh

The example VPN server configuration file needs to be extracted to /etc/openvpn so we can incorporate it into our setup. This can be done with one command:

gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /etc/openvpn/server.conf

Once extracted, open server.conf in a text editor.

nano /etc/openvpn/server.conf

There are several changes to make in this file. First of all, define tap interface

# Use the same setting as you are using on
# the server.
# On most systems, the VPN will not function
# unless you partially or fully disable
# the firewall for the TUN/TAP interface.
dev tap
;dev tun

Then we can set this Server Bridge to have 192.168.2.66 address with 255.255.255.0 mask and provides IP address to its client which are in 192.168.2.201-192.168.2.2.220 range. This is an example of how you should set your VPN server. Of course your network numbers can be different and you will implement your own ranges and numbers.

# Configure server mode for ethernet bridging.
# You must first use your OS's bridging capability
# to bridge the TAP interface with the ethernet
# NIC interface.  Then you must manually set the
# IP/netmask on the bridge interface, here we
# assume 10.8.0.4/255.255.255.0.  Finally we
# must set aside an IP range in this subnet
# (start=10.8.0.50 end=10.8.0.100) to allocate
# to connecting clients.  Leave this line commented
# out unless you are ethernet bridging.
server-bridge 192.168.2.66 255.255.255.0 192.168.2.201 192.168.2.220

We will also increase the length of our encryption key for increased security. If you are worried about your security you can go even higher to 4096 or 8192.

# Diffie hellman parameters.
# Generate your own with:
#   openssl dhparam -out dh1024.pem 1024
# Substitute 2048 for 1024 if you are using
# 2048 bit keys.
dh dh1024.pem

Edit dh1024.pem to say:

dh2048.pem

This will double the RSA key length used when generating server and client keys.

Still in server.conf , now look for this section:

# If enabled, this directive will configure
# all clients to redirect their default
# network gateway through the VPN, causing
# all IP traffic such as web browsing and
# and DNS lookups to go through the VPN
# (The OpenVPN server machine may need to NAT
# or bridge the TUN/TAP interface to the internet
# in order for this to work properly).
push "redirect-gateway def1 bypass-dhcp"

Uncomment push "redirect-gateway def1 bypass-dhcp" so the VPN server passes on clients’ web traffic to its destination.

in the next edit we’ll push DNS options to our clients:

# Certain Windows-specific network settings
# can be pushed to clients, such as DNS
# or WINS server addresses.  CAVEAT:
# http://openvpn.net/faq.html#dhcpcaveats
# The addresses below refer to the public
# DNS servers provided by opendns.com.
;push "dhcp-option DNS 208.67.222.222"
;push "dhcp-option DNS 8.8.8.8"

This tells the server to push OpenDNS to connected clients for DNS resolution where possible. This can help prevent DNS requests from leaking outside the VPN connection. However, it’s important to specify desired DNS resolvers in client devices as well. Though OpenDNS is the default used by OpenVPN, you can use whichever DNS services you prefer.

We’ll also push one route to our clients:

# Push routes to the client to allow it
 # to reach other private subnets behind
 # the server.  Remember that these
 # private subnets will also need
 # to know to route the OpenVPN client
 # address pool (10.8.0.0/255.255.255.0)
 # back to the OpenVPN server.
 push "route 192.168.2.1 255.255.255.0"

Change OpenVPN user in server.conf :

# You can uncomment this out on
# non-Windows systems.
user nobody
group nogroup

By default, OpenVPN runs as the root user and thus has full root access to the system. We’ll instead confine OpenVPN to the user nobody and group nogroup . This is an unprivileged user with no default login capabilities, often reserved for running untrusted applications like web-facing servers.

Our clients should have the ability to get to one another:

# Uncomment this directive to allow different
# clients to be able to "see" each other.
# By default, clients will only see the server.
# To force clients to only see the server, you
# will also need to appropriately firewall the
# server's TUN/TAP interface.
 client-to-client

At the end we will add our script to this file:

up "/etc/openvpn/up.sh br0"
down "/etc/openvpn/down.sh br0"

Now save your changes and exit

Packet Forwarding

This is a _ sysctl _ setting which tells the server’s kernel to forward traffic from client devices out to the Internet. Otherwise, the traffic will stop at the server. Enable packet forwarding during runtime by entering this command:

echo 1 > /proc/sys/net/ipv4/ip_forward

We need to make this permanent so the server still forwards traffic after rebooting.

nano /etc/sysctl.conf

Near the top of the sysctl file, you will see:

# Uncomment the next line to enable packet forwarding for IPv4
#net.ipv4.ip_forward=1

Uncomment net.ipv4.ip_forward . It should look like this when done:

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

Save your changes and exit.

Creating a Certificate Authority and Server-Side Certificate & Key

It is now time to set up our own Certificate Authority (CA) and generate a certificate and key for the OpenVPN server. OpenVPN supports bidirectional authentication based on certificates, meaning that the client must authenticate the server certificate and the server must authenticate the client certificate before mutual trust is established. We will use Easy RSA’s scripts we copied earlier to do this.

First copy over the Easy-RSA generation scripts.

cp -r /usr/share/easy-rsa/ /etc/openvpn

Then make the key storage directory.

mkdir /etc/openvpn/easy-rsa/keys

Easy-RSA has a variables file we can edit to create certificates exclusive to our person, business, or whatever entity we choose. This information is copied to the certificates and keys, and will help identify the keys later.

nano /etc/openvpn/easy-rsa/vars

The variables below marked in red should be changed according to your preference.

export KEY_COUNTRY="AQ"
export KEY_PROVINCE="Antarctica"
export KEY_CITY="TuX City"
export KEY_ORG="N0WHERE"
export KEY_EMAIL="admin@n0where.net"
export KEY_OU="CyberPunk"

In the same vars file, also edit this one line shown below. For simplicity, we will use server as the key name. If you want to use a different name, you would also need to update the OpenVPN configuration files that reference server.key and server.crt .

export KEY_NAME="server"

We need to generate the Diffie-Hellman parameters; this can take several minutes.

openssl dhparam -out /etc/openvpn/dh2048.pem 2048

Now let’s change directories so that we’re working directly out of where we moved Easy-RSA’s scripts to earlier.

cd /etc/openvpn/easy-rsa

Initialize the PKI (Public Key Infrastructure).

. ./vars

The output from the above command is shown below. Since we haven’t generated anything in the keys directory yet, the warning is nothing to be concerned about.

NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys

Now we’ll clear the working directory of any possible old or example keys to make way for our new ones.

./clean-all

This final command builds the certificate authority (CA) by invoking an interactive OpenSSL command. The output will prompt you to confirm the Distinguished Name variables that were entered earlier into the Easy-RSA’s variable file (country name, organization, etc.).

./build-ca

Simply press ENTER to pass through each prompt. If something must be changed, you can do that from within the prompt.

Generate a Certificate and Key for the Server

Still working from /etc/openvpn/easy-rsa , now enter the command to build the server’s key. Where you see server marked in red is the export KEY_NAME variable we set in Easy-RSA’s vars file earlier in

./build-key-server server

Similar output is generated as when we ran ./build-ca , and you can again press ENTER to confirm each line of the Distinguished Name. However, this time there are two additional prompts:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Both should be left blank, so just press ENTER to pass through each one.

Two additional queries at the end require a positive ( y ) response:

Sign the certificate? [y/n]
1 out of 1 certificate requests certified, commit? [y/n]

The last prompt above should complete with:

Write out database with 1 new entries
Data Base Updated

Move the Server Certificates and Keys

OpenVPN expects to see the server’s CA, certificate and key in /etc/openvpn . Let’s copy them into the proper location.

cp /etc/openvpn/easy-rsa/keys/{server.crt,server.key,ca.crt} /etc/openvpn

You can verify the copy was successful with:

ls /etc/openvpn

You should see the certificate and key files for the server.

At this point, the OpenVPN server is ready to go. Start it and check the status.

service openvpn start
service openvpn status

The status command should return:

VPN 'server' is running

Congratulations! Your OpenVPN server is operational. If you encounter any errors you should restart the system ( since we defined a new interface previously )

Generate Certificates and Keys for Clients

So far we’ve installed and configured the OpenVPN server, created a Certificate Authority, and created the server’s own certificate and key. In this step, we use the server’s CA to generate certificates and keys for each client device which will be connecting to the VPN. These files will later be installed onto the client devices such as a laptop or smartphone.

Key and Certificate Building

It’s ideal for each client connecting to the VPN to have its own unique certificate and key. This is preferable to generating one general certificate and key to use among all client devices.

Note: By default, OpenVPN does not allow simultaneous connections to the server from clients using the same certificate and key. (See duplicate-cn in /etc/openvpn/server.conf .)

To create separate authentication credentials for each device you intend to connect to the VPN, you should complete this step for each device, but change the name client1 below to something different such as myLaptop or myPhone.

As we did with the server’s key, now we build one for our client1 example. You should still be working out of /etc/openvpn/easy-rsa .

./build-key client1

Once again, you’ll be asked to change or confirm the Distinguished Name variables and these two prompts which should be left blank. Press ENTER to accept the defaults.

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

As before, these two confirmations at the end of the build process require a ( y ) response:

Sign the certificate? [y/n]
1 out of 1 certificate requests certified, commit? [y/n]

If the key build was successful, the output will again be:

Write out database with 1 new entries
Data Base Updated

The example client configuration file should be copied to the Easy-RSA key directory too. We’ll use it as a template which will be downloaded to client devices for editing. In the copy process, we are changing the name of the example file from client.conf to client.ovpn because the .ovpn file extension is what the clients will expect to use.

cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/easy-rsa/keys/client.ovpn

You can repeat this section again for each client, replacing client1 with the appropriate client name throughout.

Transferring Certificates and Keys to Client Devices

For each client we need to transfer the client certificate, key, and profile template files to a folder on our local computer or another client device.

In this example, our client1 device requires its certificate and key, located on the server in:

  • /etc/openvpn/easy-rsa/keys/ client1 .crt
  • /etc/openvpn/easy-rsa/keys/ client1 .key

The ca.crt and client.ovpn files are the same for all clients.

  • /etc/openvpn/easy-rsa/keys/client.ovpn
  • /etc/openvpn/ca.crt

In the end, make sure you have these four files on your client device ( for each device) :

  • client1 .crt
  • client1 .key
  • client.ovpn
  • ca.crt

Creating a Unified OpenVPN Profile for Client Devices

There are several methods for managing the client files but the easiest uses a _ unified _ profile. This is created by modifying the client.ovpn template file to include the server’s Certificate Authority, and the client’s certificate and its key. Once merged, only the single client.ovpn profile needs to be imported into the client’s OpenVPN application.

We will create a single profile for our client1 device on the local computer we downloaded all the client files to. This local computer could itself be an intended client or just a temporary work area to merge the authentication files. The original client.ovpn template file should be duplicated and renamed. How you do this will depend on the operating system of your local computer.

Note: The name of your duplicated client.ovpn doesn’t need to be related to the client device. The client-side OpenVPN application will use the file name as an identifier for the VPN connection itself. Instead, you should duplicate client.ovpn to whatever you want the VPN’s nametag to be in your operating system. For example: work.ovpn will be identified as work , school.ovpn as school , etc.

In this tutorial, we’ll name the VPN connection CyberPunk so CyberPunk.ovpn will be the file name referenced from this point on. Once named, we then must open CyberPunk.ovpn in a text editor; you can use whichever editor you prefer.

The first area of attention will be for the IP address of your server. Near the top of the file, change my-server-1 to reflect your VPN’s IP.

# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote my-server-1 1194

Next, find the area shown below and uncomment user nobody and group nogroup , just like we did in server.conf :

# Downgrade privileges after initialization (non-Windows only)
user nobody
group nogroup

The area given below needs the three lines shown to be commented out so we can instead include the certificate and key directly in the CyberPunk.ovpn file:

# SSL/TLS parms.
# . . .
#ca ca.crt
#cert client.crt
#key client.key

To merge the individual files into the one unified profile, the contents of the ca.crt , client1 .crt, and client1 .key files are pasted directly into the .ovpn profile using a basic XML-like syntax. The XML at the end of the file should take this form:

<ca>
(insert ca.crt here)
</ca>
<cert>
(insert client1.crt here)
</cert>
<key>
(insert client1.key here)
</key>

When finished, the end of the file should be similar to this abbreviated example:

<ca>
-----BEGIN CERTIFICATE-----
. . .
-----END CERTIFICATE-----
</ca>

<cert>
Certificate:
. . .
-----END CERTIFICATE-----
. . .
-----END CERTIFICATE-----
</cert>

<key>
-----BEGIN PRIVATE KEY-----
. . .
-----END PRIVATE KEY-----
</key>

The client1.crt file has some extra information in it; it’s fine to just include the whole file.

Save the changes and exit. We now have a unified OpenVPN client profile to configure our client1 . You can now transfer this ovpn file to you device and OpenVPN client of choice. Also do not forget to set port forwarding in your router. You need to forward UDP 1194 to your server.

Congratulations! You are now securely traversing the internet protecting your identity, location, and traffic from snoopers and censors.