I’m using my raspberry pi as a NAS with a samba server to provide the content through my home network. I wanted to have that content directly accessible from the rest of the world but without the traffic to be visible to anybody else than me. I then decide to use OpenVPN in bridged mode.
- TL-841 as router
- Raspberry Pi as NAS
- Internal IP : 192.168.42.0/24
- Range IP router: 192.168.42.10 – 192.168.42.120
- Range IP OpenVPN: 192.168.42.128 – 192.168.42.254
First, important point, if you have a DHCP server on your router, be sure to configure it to not assign IP address for the whole subnet, but only a part (as I’ve done in the setup). If you don’t, you could encounter 2 devices sharing the same IP, and trust me you don’t want that.
You need to download and extract my scripts and configuration. I’ll walk you through each of those. The following command will download the files and extract them into /tmp/openvpn-scripts:
wget -O /tmp/download https://gist.github.com/Belphemur/3b03eaad96172b2159fc/download && mkdir /tmp/openvpn-scripts && tar -zxf /tmp/download --strip-components 1 -C /tmp/openvpn-scripts/
Explanation of the command: Wget download the gist on GitHub with my scripts then mkdir create a temporary directory where tar extract them. I advise you to run it WITHOUT root or sudo it is not needed.
sudo apt-get install openvpn
We need the easy-rsa to easily create our root certificate, the certificate of the server and the one for each client. Using those cert, the client will authenticate themselves to the server. No need for login/password.
mkdir /etc/openvpn/easy-rsa sudo cp -R /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa/
sudo apt-get install easy-rsa sudo mkdir /etc/openvpn/easy-rsa sudo cp -R /usr/share/easy-rsa/* /etc/openvpn/easy-rsa/
Edit /etc/openvpn/easy-rsa/vars bottom according to your organization.
Look for those in the file and change them for your needs.
export KEY_COUNTRY="US" export KEY_PROVINCE="CA" export KEY_CITY="SanFrancisco" export KEY_ORG="Fort-Funston" export KEY_EMAIL="[email protected]" export [email protected] export KEY_SIZE=2048
Now execute those command to prepare for the generation of the certificate and keys:
cd /etc/openvpn/easy-rsa/ sudo -s #because of the sourcing of the ./vars file you need to be root to do this mkdir keys touch keys/index.txt echo 01 > keys/serial . ./vars # set environment variables ./clean-all
From Debian wiki on OpenVPN:
- only .key files should be kept confidential.
- .crt and .csr files can be sent over insecure channels such as plaintext email.
- do not need to copy a .key file between computers.
- each computer will have its own certificate/key pair.
Generating the certs and keys
Those commands will generate the root certificate, the server certificate and the DH keys.
cd /etc/openvpn/easy-rsa/ ./build-ca ./build-key-server server ./build-dh #takes time
Disabling Current Systemd Service
By default when you’re installing the OpenVPN server, the installer take care of setting OpenVPN to start with your system.
We don’t want that since you’re installing another service configuration that takes care of the Bridge.
sudo systemctl disable openvpn sudo systemctl stop openvpn
Because we’re going to create a bridge, we need to set the kernel to let the IP packet transit through it. To do this, we’ll use sysctl.
You’ll need to edit the file
/etc/sysctl.conf to add the following line:
net.ipv4.ip_forward = 1
Then you reload the configuration:
sysctl -p /etc/sysctl.conf
The packet switching is not set in your kernel and will stay after reboot.
Following the OpenVPN tutorial on how to create a bridge and make it work with OpenVPN, I created my own scripts to do this. First, you need to install the bridge-utils, scripts used to create network bridge then create a directory to put my scripts into it.
sudo apt-get install bridge-utils
My bridge scripts are in 3 parts:
- Bridge-conf: to configure the scripts
- Bridge-start: to start the bridge
- Bridge-stop: to destroy the bridge
My scripts are made to restore the system to its previous state after destroying the bridge. I tested them and they work on Debian Jessie on a raspberry pi.
You’ll find all the following file in /tmp/openvpn-scripts/ if you used the command to download the gist.
You NEED to modify this file with your own configuration.
Should give you the information you need to put here. The idea is to make your bridge act like your normal Ethernet interface with the same properties
In the same folder, you find the server.conf. The file contains the configuration for OpenVPN in server mode.
You should update the port, protocol (proto) and the server-bridge with your network setting.
- Port: the port your sever will listen on
- Proto: which protocol used (either TCP or UDP)
- 192.168.42.2: the internal IP of your device in your home network
- 255.255.255.0: it’s mask (represent the /24)
- 192.168.42.128: starting IP to get assigned to the clients
- 192.168.42.254: the last IP to be assigned to the clients
You’ll find also this:
#set the dns servers push "dhcp-option DNS 192.168.42.1" #set the WINS server (SAMBA) push "dhcp-option WINS 192.168.42.2"
It needs to be changed also, the first one to point at your router (that surely act as a DNS server) and the second one to your SAMBA server (NAS). In my case, it’s the same IP as the server because I’m hosting the Samba server and the OpenVPN server on the same device.
Client Configuration Script
Last file that needs to be changed for your needs, build-client. The script generates a configuration file for OpenVPN in the folder you launch it. Either you edit the configuration script with your variable or use the environment variable to set it (See Generate a client configuration)
You’ll find a section VARIABLES with :
- PROTO: The protocol used on the server. (Need to be the same as you set on the server)
- REMOTE: The IP address or HOST of your server. It needs to be your external IP address or an hostname (like exmaple.com) that point to your external IP. (I’m using no-ip as a DDNS service). If you leave it empty, the script will retrieve your external IP for you.
- PORT: the port used by the server
- COMPRESS: the compression algorithm used
- OPENVPN_CLIENT_DIRECTIVE: if you need to add another directive in the client configuration
Installing the configuration and scripts
Now that the preparation is ready, let’s put all the script and configuration where they should be.
Move the server.conf into /etc/openvpn/
sudo mv /tmp/openvpn-scripts/server.conf /etc/openvpn/
sudo mkdir /etc/openvpn/bridge sudo mv /tmp/openvpn-scripts/bridge-* /etc/openvpn/bridge/ sudo chmod +x /etc/openvpn/bridge/bridge-*
Client Generator Script
sudo mv /tmp/openvpn-scripts/build-client /etc/openvpn/easy-rsa/ sudo chmod +x /etc/openvpn/easy-rsa/build-client
Service Script for systemd
If you are using Debian Jessie or your distribution is using systemd as an init do this to add service unit for OpenVPN Bridged.
sudo mv /tmp/openvpn-scripts/openvpn@.service /etc/systemd/system/ sudo systemctl daemon-reload
To make SystemD start the service at boot time
sudo systemctl enable [email protected]
Generate a client configuration
Now we will generate a client configuration that will be used on your computer to connect to the OpenVPN server. Here we build for the client OnMyWay.
cd /etc/openvpn/easy-rsa/ sudo ./build-client OnMyWay
cd /etc/openvpn/easy-rsa/ sudo PROTO=udp REMOTE=example.com PORT=1255 COMPRESS=comp-lzo ./build-client OnMyWay
Using the environment variable is another way to generate a client configuration.
You need to say yes to the signing of the cert and the commit.
You should see something like this:
/etc/openvpn/easy-rsa /home/pi NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys Generating a 2048 bit RSA private key ..................................................................................+++ ...................................+++ writing new private key to 'OnMyWay.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) [US]: State or Province Name (full name) [NY]: Locality Name (eg, city) [New-York]: Organization Name (eg, company) [Raspy]: Organizational Unit Name (eg, section) [RaspberryPiOrg]: Common Name (eg, your name or your server's hostname) [OnMyWay]: Name [RaspyKey]: Email Address [[email protected]]: 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:'US' stateOrProvinceName :PRINTABLE:'NY' localityName :PRINTABLE:'New-York' organizationName :PRINTABLE:'Raspy' organizationalUnitName :PRINTABLE:'RaspberryPiOrg' commonName :PRINTABLE:'OnMyWay' name :PRINTABLE:'RaspyKey' emailAddress :IA5STRING:[email protected]' Certificate is to be certified until Jan 18 17:49:16 2025 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
You’ll find an OnMyWay.ovpn in the same folder you are. It’s the configuration with the certificate embedded into it.
Revoke a user
sudo -s cd /etc/openvpn/easy-rsa . ./vars ./revoke-full OnMyWay exit
Start the server
If you used my service unit for systemd :
sudo service [email protected] start
sudo /etc/openvpn/bridge/bridge-start sudo service openvpn start
Stop the server
If you used my service unit for systemd :
sudo service [email protected] stop
sudo service openvpn stop sudo /etc/openvpn/bridge/bridge-stop