OpenVPN¶
This section of the guide will focus on installing a VPN service in the server. This process can be a little bit tedious and even complicated, it is all explained here step by step.
Installation¶
We'll install two packages and make a folder.
sudo apt-get install openvpn easy-rsa
make-cadir ~/openvpn-ca
cd ~/openvpn-ca
Setting Up and Building Certificate Authority¶
We'll change the certificate authority variables.
nano vars
Change the following information according to your needs, I recommend you leaving KEY_NAME as "server".
export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="[email protected]"
export KEY_OU="MyOrganizationalUnit"
export KEY_NAME="server"
We source the variables now and clean our environment.
source vars
./clean-all
ln -s openssl-1.0.0.cnf openssl.cnf
We can now build our certificate authority (hit enter for everything, leave any challenge password blank).
./build-ca
Building Server Certificate, Key and Encryption¶
We now need to generate our server and Diffie-Hellman keys and our HMAC signature (leave blank when asked for challenge password).
./build-key-server server BLANK PASS
./build-dh
openvpn --genkey --secret keys/ta.key
Configuring the VPN Server¶
We'll transfer the server keys and certificates generated previously to /etc/openvpn
.
cd keys
sudo cp ca.crt server.crt server.key ta.key dh2048.pem /etc/openvpn
Now we'll create a server configuration file, you can look up for server configurations, base yourself from the default one or just copy my own. If you want to base yourself from the default one, run:
gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/server.conf
Since I already know what settings I'm going to need for the VPN server, I'll directly create the server configuration.
sudo nano /etc/openvpn/server.conf
My own configuration goes as follows:
local 0.0.0.0
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
keepalive 10 60
cipher AES-256-CBC
comp-lzo
max-clients 20
persist-key
persist-tun
status openvpn-status.log
verb 3
client-to-client
tls-auth ta.key
key-direction 0
auth SHA256
user nobody
group nogroup
# ROUTE
push "remote-gateway def1"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
Allow IP Forwarding¶
In order for the server to forward inbound VPN connections to the main network interface the server uses, we'll need to set up IP forwarding. Access the following file:
sudo nano /etc/sysctl.conf
Uncomment the following line:
net.ipv4.ip_forward=1
To see if changes were made, run:
sudo sysctl -p
Now, we need to know what is our main network interface, you can use:
ifconfig
You'll receive a similar output:
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.15 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 ::a00:27ff:fe49:8561 prefixlen 64 scopeid 0x0<global>
inet6 fe80::a00:27ff:fe49:8561 prefixlen 64 scopeid 0x20<link>
ether 08:00:27:49:85:61 txqueuelen 1000 (Ethernet)
RX packets 755025 bytes 1132393073 (1.1 GB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 94785 bytes 9330879 (9.3 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
The network interface is the first word you see in the output (in this case enp0s3), save it for later because we'll need it. Edit the UFW rules from the config file:
sudo nano /etc/ufw/before.rules
Inside this file you'll see the following:
#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
# ufw-before-input
# ufw-before-output
# ufw-before-forward
#
Just after these lines we'll add the following:
# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to enp0s3 (change to the interface you discovered!)
-A POSTROUTING -s 10.8.0.0/8 -o enp0s3 -j MASQUERADE
COMMIT
# END OPENVPN RULES
We also need to change UFW's configuration.
sudo nano /etc/default/ufw
Here we'll replace DEFAULT_FORWARD_POLICY="DROP"
to DEFAULT_FORWARD_POLICY="ACCEPT"
and save the file.
Now to add the firewall rules to enable connections to the VPN and allow any connection through the VPN:
sudo ufw allow 1194/udp
sudo ufw allow in on tun0
sudo ufw allow out on tun0
Starting the Server¶
The server is ready to start (make sure to replace server
with whatever server name you used when creating the server keys):
sudo systemctl start openvpn@server
If there were no issues you'll be able to see a new interface called tun0
when using ifconfig
. If that isn't the case then most likely your server configuration is causing issues.
To enable the service so the server auto-starts on login:
sudo systemctl enable openvpn@server
Creating a Client Base Configuration¶
The server isn't ready yet, we still need to create client keys, certificates and profiles. To make this job a lot easier we'll create a base configuration which is going to serve as the base for all clients generated and we'll create a client generating script. For the base configuration we'll create some folders and the base configuration itself.
mkdir -p ~/client-configs/files
chmod 700 ~/client-configs/files
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf
nano ~/client-configs/base.conf
In the text editor you'll see that a configuration is already there, we'll need to make some changes in there to suit our needs.
- Firstly, look for
remote server_IP_address 1194
and changeserver_IP_address
to your server's external IP address, you can add your numerical IP address (xxx.xxx.xxx.xxx) only if it's static, if that's not your case I recommend you checking out the following: NO-IP DUC. - We'll now uncomment the following items:
user nobody
,group nogroup
andcomp-lzo
. - Now we need to comment the following items:
ca ca.crt
,cert client.crt
andkey client.key
. - We need to add the following in a separate line:
cipher AES-256-CBC
,auth SHA256
andkey-direction 1
.
Save and quit the file.
Client Generating Script¶
Create a script in the ~/client-configs
folder:
nano ~/client-configs/make_config.sh
Paste the following in the text editor:
#!/bin/bash
# First argument: Client identifier
KEY_DIR=~/openvpn-ca/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf
cat ${BASE_CONFIG} \
<(echo -e '<ca>') \
${KEY_DIR}/ca.crt \
<(echo -e '</ca>\n<cert>') \
${KEY_DIR}/${1}.crt \
<(echo -e '</cert>\n<key>') \
${KEY_DIR}/${1}.key \
<(echo -e '</key>\n<tls-auth>') \
${KEY_DIR}/ta.key \
<(echo -e '</tls-auth>') \
> ${OUTPUT_DIR}/${1}.ovpn
To make the following script executable:
chmod 700 ~/client-configs/make_config.sh
Creating Keys, Certificates and Profiles for Clients¶
You'll need to repeat this process for every client that will use the VPN, client profiles are not interchangeable, meaning that each client needs to use it's own generated profile and set of keys, trying to use a single profile for multiple devices will result in issues when connecting to the VPN. We'll go to the ~/openvpn-ca
folder where all our keys are saved and source our variables.
cd ~/openvpn-ca
source vars
For every client, run the following, make sure to change $CLIENT with the client name and remember to set a blank challenge password:
./build-key $CLIENT
Once we've generated all the client keys and certificates we need, we'll go back to the folder where our script is located and run it for every client we made.
cd ~/client-configs
./make_config.sh $CLIENT
Our client profiles will be saved in the ./files
folder.
Tunnel all traffic through the VPN¶
My VPN configuration requires me to have two profiles, one where I can connect to my self-hosted services through a VPN and one where I can route all my traffic through the VPN. To route all the traffic to the VPN, simply copy your client profile and add the following line to the config:
redirect-gateway def1
Connecting to the VPN¶
To connect to the VPN your client device will need OpenVPN installed, you can find it for almost any platform. You'll need to transfer from the server to the client device their respective profile: ~/client-configs/files/$CLIENT.ovpn
and the ta.key file ~/openvpn-ca/keys/ta.key
(this seems to be only required on mobile clients but chances are your desktop client may need it as well). When connecting to the VPN, the client will receive it's own virtual private IP (10.8.0.x
), the server's IP is generally 10.8.0.1
. You can now establish connections to the server that are not port forwarded by the router (Samba/CIFS for example).