Why
There are many howto's explaining the set-up of an OpenVPN server. The majority of what I have seen, provide instructions about setting up a tunnel device. This allows you to gain access to the OpenVPN server itself, but requires a lot more customisation if you want to access other computers on the remote LAN.
Using a tap device is much easier, and allows the OpenVPN client to be able to access not only the server but all other computers connected to the same LAN.
The basic idea is that you create an Ethernet bridge on the VPN server. Each time clients connect, the server taps them to that bridge and so clients behave as if they are physically connected to the remote LAN.
How
I would advice starting your setup with a clean fresh install. Before proceeding to follow the instructions below, issue:
pi@gabriella:~ $ sudo apt-get update && sudo apt-get dist-upgrade
Install the bridge
The first step is to set up our bridge:
pi@gabriella:~ $ sudo apt-get install bridge-utils uml-utilities
After the bridge-utils
package is installed, we need to change the server's network configuration file in order to activate the bridge.The actual file is:/etc/network/interfaces
and the definition of the bridge is :
# interfaces(5) file used by ifup(8) and ifdown(8)
# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'
# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d
auto lo
iface lo inet loopback
iface eth0 inet manual
iface tap0 inet manual
# Our bridge initially contains just the ethernet interface and is configured to use DHCP
auto br0
iface br0 inet dhcp
bridge_ports eth0
# You can delete these lines if you do not whish to use Wi-fi
allow-hotplug wlan0
iface wlan0 inet manual
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
allow-hotplug wlan1
iface wlan1 inet manual
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
This setup uses DHCP for the bridge. Setting up a static IP is explained in the Network Configuration
section of the Debian Wiki. The same pages provide more information and details about bridging. The actual link is
here.
At this point a server reboot is required in order to verify the bridge setup. When the server is up again you can check that the bridge is working by examining the outcome of the ip addr
command which should be similar to this:
pi@gabriella:/etc/openvpn $ ip addr
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
link/ether b8:27:eb:b2:d8:f2 brd ff:ff:ff:ff:ff:ff
inet 169.254.30.59/16 brd 169.254.255.255 scope global eth0
valid_lft forever preferred_lft forever
3: br0: mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether b8:27:eb:b2:d8:f2 brd ff:ff:ff:ff:ff:ff
inet 10.0.1.240/24 brd 10.0.1.255 scope global br0
valid_lft forever preferred_lft forever
inet 10.0.1.205/24 brd 10.0.1.255 scope global secondary br0
valid_lft forever preferred_lft forever
inet6 fe80::ba27:ebff:feb2:d8f2/64 scope link
valid_lft forever preferred_lft forever
install openvpn
With the bridge working the next step will be installation and configuration of the OpenVPN server itself. Before we proceed with the server installation we will lay out the necessary fact about the network the server is on:
- Our network is a class C net with a broadcast address of 10.0.1.0/24
- Default gateway is 10.0.1.1
- Network DNS is 10.0.1.152
- The target network uses DHCP. We have set aside the range between 10.0.1.32 and 10.0.1.39 to be used by our clients,
Having clear our theses fact we may begin our installation.
pi@gabriella:~ $ sudo apt-get install openvpn easy-rsa
Since all the commands that we will type from now on will require root privileges, it is wise to do a :
pi@gabriella:~ $ sudo su -
root@gabriella:~# cd /etc/openvpn/
root@gabriella:/etc/openvpn#
We will create a new server configuration file. This file is /etc/openvpn/server.conf
with the following contents
# --------------------------------------------------------------------------------
# OpenVPN bridging configuration file.
# Adopted from the Ubuntu Community Page at https://help.ubuntu.com/community/OpenVPN
# Date may -15th 2016
# --------------------------------------------------------------------------------
mode server
tls-server
local 10.10.1.240 ## ip/hostname of server
port 1194 ## default openvpn port
proto udp
# --------------------------------------------------------------------------------
# Bidging directive
# --------------------------------------------------------------------------------
dev tap0
script-security 2 ## allow calling up.sh and down.sh
up "/etc/openvpn/up.sh br0 tap0 1500"
down "/etc/openvpn/down.sh br0 tap0"
persist-key
persist-tun
# --------------------------------------------------------------------------------
# certificates and encryption
# --------------------------------------------------------------------------------
ca ca.crt
cert server.crt
key server.key # This file should be kept secret
dh dh2048.pem
tls-auth ta.key 0 # This file is secret
cipher BF-CBC # Blowfish (default)
comp-lzo
# Allow multiple clients to connect using the same client keys
# duplicate-cn
# --------------------------------------------------------------------------------
# DHCP Information
# --------------------------------------------------------------------------------
ifconfig-pool-persist ipp.txt
# The first address is the bridge address of the server the second is the netmask to use
# and the next twoo addresses are the range that should be assigned to clients
server-bridge 10.0.1.240 255.255.255.0 10.0.1.32 10.0.1.39
push "dhcp-option DNS 10.0.1.152"
push "dhcp-option DOMAIN simsons"
max-clients 8 ## set this to the max number of clients that should be connected at a time
# --------------------------------------------------------------------------------
# log and security
# --------------------------------------------------------------------------------
user nobody
group nogroup
keepalive 10 120
status openvpn-status.log
verb 3
Next we will need to create the two scripts that hook and unhook our tap device to the server bridge. These files should be called up.sh
and down.sh
(These are the names in server.conf file) with the following contents.
#!/bin/sh
# File up.sh adds a device to a bridge with a specified MTU
BR=$1 # bridge to add device to
DEV=$2 # actual device to add
MTU=$3 # MTU value
/sbin/ip link set "$DEV" up promisc on mtu "$MTU"
/sbin/brctl addif $BR $DEV
and
#!/bin/sh
# file down.sh remove a device from a bridge
BR=$1
DEV=$2
/sbin/brctl delif $BR $DEV
/sbin/ip link set "$DEV" down
Do not forget, to make both scripts executable
root@gabriella:/etc/openvpn# chmod +x up.sh down.sh
Having done all that, it's time for a break. We will create our own DH 2048 bit file.
root@gabriella:/etc/openvpn# openssl dhparam -out dh2048.pem 2048
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
................+........................................................................................................+.........................................
Even on a four core Raspberry-PI2 model B board, this takes well over 40 minutes, so sit back and relax
Create the Certificates
With the dh2048.pem file in place, we will start creating our server and client certificates by first copying the easy-rsa scripts to our servers setup directory and next creating the folder that will host our keys.
In order to make things a bit more secure we will create an additional tls-auth directive and the related key
root@gabriella:/etc/openvpn# openvpn --genkey --secret ta.key
root@gabriella:/etc/openvpn# cp -r /usr/share/easy-rsa/ /etc/openvpn
root@gabriella:/etc/openvpn# cd easy-rsa/
root@gabriella:/etc/openvpn/easy-rsa# mkdir keys
The Easy-RSA package that comes with the latest version of Rasbian (June-2019) provides three openssl.conf files depending on the installed version of the openssl package.
Raspberry pi uses openssl 1.0 so, we need to link the correct version configuation file to openssl.conf.
# ln -sf openssl-1.0.0.cnf openssl.cnf
Next step is the creation of the actual server certificates. Open file /etc/openvpn/easy-rsa/vars
and fill in the details accordingly.
root@gabriella:/etc/openvpn# vim /etc/openvpn/easy-rsa/vars
Change the lines (first one is line 64 in my version) that refer to the certificate creation parameters, so they look similar to this:
# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY="gr"
export KEY_PROVINCE="Rodope"
export KEY_CITY="Komotini"
export KEY_ORG="Aryballos"
export KEY_EMAIL="admin@aryballos.gr"
export KEY_OU="Aryballos-IT-Services"
# X509 Subject Field
export KEY_NAME="server"
# Add this for Debian Stretch. ./build-ca will not work otherwise
export KEY_ALTNAMES="server"
Save, exist, run the file ... and do a clean-all to start fresh.
root@gabriella:/etc/openvpn/easy-rsa# . ./vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys
root@gabriella:/etc/openvpn/easy-rsa# ./clean-all
The next command will build the required certificate authorities for the server (Hit ENTER when there is a prompt).
root@gabriella:/etc/openvpn/easy-rsa# ./build-ca
Generating a 2048 bit RSA private key
...........................................................................................................+++
..............................................+++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [gr]:
State or Province Name (full name) [Rodope]:
Locality Name (eg, city) [Komotini]:
Organization Name (eg, company) [Aryballos]:
Organizational Unit Name (eg, section) [Aryballos-IT-Services]:
Common Name (eg, your name or your server's hostname) [Aryballos CA]:
Name [server]:
Email Address [admin@aryballos.gr]:
root@gabriella:/etc/openvpn/easy-rsa#
Now it's time to build the actual server key.
root@gabriella:/etc/openvpn/easy-rsa# ./build-key-server server
Generating a 2048 bit RSA private key
.................................................................................................................................+++
....................................................+++
writing new private key to 'server.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [gr]:
State or Province Name (full name) [Rodope]:
Locality Name (eg, city) [Komotini]:
Organization Name (eg, company) [Aryballos]:
Organizational Unit Name (eg, section) [Aryballos-IT-Services]:
Common Name (eg, your name or your server's hostname) [server]:
Name [server]:
Email Address [admin@aryballos.gr]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'gr'
stateOrProvinceName :PRINTABLE:'Rodope'
localityName :PRINTABLE:'Komotini'
organizationName :PRINTABLE:'Aryballos'
organizationalUnitName:PRINTABLE:'Aryballos-IT-Services'
commonName :PRINTABLE:'server'
name :PRINTABLE:'server'
emailAddress :IA5STRING:'admin@aryballos.gr'
Certificate is to be certified until May 13 14:09:17 2026 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
root@gabriella:/etc/openvpn/easy-rsa#
Copy the certificates to their designated place.
root@gabriella:/etc/openvpn/easy-rsa# cp /etc/openvpn/easy-rsa/keys/{server.crt,server.key,ca.crt} /etc/openvpn
Yes we are ready fire up the openvpn server!
root@gabriella:/etc/openvpn/easy-rsa# service openvpn start
root@gabriella:/etc/openvpn/easy-rsa# service openvpn status
● openvpn.service - OpenVPN service
Loaded: loaded (/lib/systemd/system/openvpn.service; enabled)
Active: active (exited) since Sun 2016-05-15 17:13:53 EEST; 4s ago
Process: 2009 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 2009 (code=exited, status=0/SUCCESS)
May 15 17:13:53 gabriella systemd[1]: Started OpenVPN service
At this point it would be very wise to switch to your ISP's router or firewall setup page and enable port 1194 forwarding between the external IP address of your router and the internal IP address of the OpenVPN server.
The final step will be to generate keys for the client. OpenVPN will not allow two clients with the same key to log on simultaneously, unless you add a line with duplicate-cn
in the server.conf parameter file. Client certificates are build the same way as the server's, only this time you get to use the build-key
script
root@gabriella:/etc/openvpn/easy-rsa# ./build-key client
Generating a 2048 bit RSA private key
..................+++
................+++
writing new private key to 'client.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [gr]:
State or Province Name (full name) [Rodope]:
Locality Name (eg, city) [Komotini]:
Organization Name (eg, company) [Aryballos]:
Organizational Unit Name (eg, section) [Aryballos-IT-Services]:
Common Name (eg, your name or your server's hostname) [client]:
Name [server]:
Email Address [admin@aryballos.gr]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'gr'
stateOrProvinceName :PRINTABLE:'Rodope'
localityName :PRINTABLE:'Komotini'
organizationName :PRINTABLE:'Aryballos'
organizationalUnitName:PRINTABLE:'Aryballos-IT-Services'
commonName :PRINTABLE:'client'
name :PRINTABLE:'server'
emailAddress :IA5STRING:'admin@aryballos.gr'
Certificate is to be certified until May 13 14:31:07 2026 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
root@gabriella:/etc/openvpn/easy-rsa#
You may create a different key for each of the clients you want to allow access. Otherwise enable the duplicate-cn
option on your server configuration file to allow multiple clients to connect with the same key.
Client setup
Each client must have the openvpn package installed. After installation move to the /etc/openvpn folder create a file named client.conf and enter the following:
### Client configuration file for OpenVPN
# Specify that this is a client
client
# Same setting as on server
script-security 3
# Bridge device setting
dev tap
proto udp
# Host name and port for the server (default port is 1194)
# note: replace with the correct values your server set up
remote extennal_ip.of.openvpn.server 1194
# Client does not need to bind to a specific local port
nobind
user nobody
group nogroup
# Keep trying to resolve the host name of OpenVPN server.
## The windows GUI seems to dislike the following rule.
##You may need to comment it out.
resolv-retry infinite
# Preserve state across restarts
persist-key
persist-tun
mute-replay-warnings
# SSL/TLS parameters - files created previously
ca /etc/openvpn/ca.crt
cert /etc/openvpn/client.crt
key /etc/openvpn/client.key
ns-cert-type server
# Since we specified the tls-auth for server, we need it for the client
# note: 0 = server, 1 = client
tls-auth /etc/openvpn/diaamath/ta.key 1
# Specify same cipher as server
cipher BF-CBC
# Use compression
comp-lzo
# Log verbosity (to help if there are problems)
verb 3
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf
Next, copy the files ta.key, ca.crt, client.crt and client.key from the the server to the clients /etc/openvpn
. directory.
Disable autostart of the OpenVPN service.
sudo update-rc.d openvpn disable
Reboot the client. (The OpenVPn setup usually fires up the OpenVPN service) And finally connect
sudo openvpn /etc/openvpn.client.conf
That should do it!
Links
This howto has been assembled using various sources. Most important being:
- The Ubuntu Community OpenVPN Wiki
- The Digital Ocean Tutorail about setting up an Open VPN Server on Debian 9
- The OpenVPN howto on the Debian Wiki