OpenVPN is a software that can create complex vpn configuration.
In this guide I will reduce it's configuration for two use-case:
tunnelling internet traffic from a machine to another, create a
virtual network between machines in different lan.
Before starting, I usually generate the keys on my
home computer instead of remote vps server, as it has more
entropy sources and is faster to gather the needed random bits.
Then I copy the generated files on the server as needed.
Create the Certification Authority (CA):
cd /etc/openvpn openssl req -new -newkey rsa:4096 -utf8 -sha256 -days 3650 -nodes -x509 -subj "/CN=server-cname" -keyout ca.key -out ca.crt
This command will generate the private key (ca.key
) and the
public key (ca.crt
); highlighted parts can be edited
to specify better security settings (key type, key length,
algorithm, shorter expiration) and to customize the cname
(usually I just go with the machine hostname).
To simplify the configuration I will use the same certificate
for the CA and the server. To make two distinct certs see the
client certificate generation section.
Create the shared secret key:
openvpn --genkey --secret ta.key
This key is used for tls-auth
(hardened configuration).
Create the Diffie-Hellman parameters:
openssl dhparam -out dh.pem 4096
The Diffie-Hellman parameters is used for hardening the configuration (seeds openssl key exchange with a prime and a generator).
Sample server configuration:
port 1194 proto udp dev tun ca ca.crt cert ca.crt key ca.key dh dh.pem server 10.8.0.0 255.255.255.0 topology subnet ifconfig-pool-persist ipp.txt client-to-client keepalive 10 120 tls-auth ta.key 0 cipher AES-256-CBC persist-key persist-tun status openvpn-status.log log-append openvpn.log verb 4
Short and simple configuration for the server, using the previously
generated files; place the above directives in a file, I usually go
for /etc/openvpn/server.conf.
client-to-client enable the ability for clients to see each other.
For a better understanding of the directives check the comments on
the example files (in my distribution are found in
/usr/share/openvpn/examples
) and the man pages linked at the
bottom of the page.
The logging directives are optional, but useful for diagnosing
a networking issue. Once the network is up and running they can be
commented out. The same apply for the client configuration.
Start the service.
Check your linux distribution or operating system manual on how to
start an openvpn server daemon and load the proper configuration
file.
For reference, in Arch Linux with systemd init the commands are:
systemctl start openvpn@server # to start the server systemctl enable openvpn@server # to persist the start of the service across reboots
The part after the "@"
sign is the name of the .conf
file without
the extension.
Create the client key and sign request:
cd /etc/openvpn openssl req -new -newkey rsa:4096 -utf8 -sha256 -days 3650 -nodes -subj "/CN=client-cname" -keyout client.key -out client.csr
Issue this command on the client, and copy the generated
client.csr
file on the /etc/openvpn
directory on the server.
Do not move the client.key
file on the server, as the point is
to keep the key secret on the machine and exchange only the
public key.
Sign the request on the server:
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -out client.crt -CAcreateserial
Copy back on the client the generated client.crt
file
with ca.crt
and ta.key
.
Sample client configuration (tested on linux client):
client dev tun remote server_host 1194 proto udp resolv-retry infinite nobind persist-key persist-tun ca ca.crt cert client.crt key client.key tls-auth ta.key 1 cipher AES-256-CBC status openvpn-status.log log-append openvpn.log verb 4 redirect-gateway def1
I usually go for /etc/openvpn/client.conf
; replace the highlighted
part with the server hostname or the server ip address and port
and protocol according to the server configuration.
The redirect-gateway directive add proper routes to forward all
the client machine traffic through the vpn tunnel; removing it
will still have the virtual network functional.
Start the service.
Check your linux distribution or operative system manual on how to
start and openvpn client daemon and load the proper configuration
file.
Again, as for the server, in Arch Linux with systemd the commands are:
systemctl start openvpn@client # to start the client service systemctl enable openvpn@client # to persist the start of the service across reboots
This part explain how to create a .ovpn
file, for windows clients.
A .ovpn file is a bundle of the configuration with the required
keys and certificates.
I usually generate the keys on my linux desktop machine and bundle
an .ovpn
file if needed for my windows devices.
A typical .ovpn
contains:
Windows client software can be downloaded in the links at the bottom.
To start the client service right click on the .ovpn
file and select
"Start OpenVPN on this config file."
Windows specific tweak is to change the network location from
Public to Private. See this tutorial.
An example .ovpn file for windows (bold for the differences with the client configuration seen before):
client dev tun remote server_host 1194 proto udp resolv-retry infinite nobind persist-key persist-tun ca [inline] cert [inline] key [inline] tls-auth [inline] 1 cipher AES-256-CBC status openvpn-status.log log-append openvpn.log verb 4 key-direction 1 <ca> [...content of ca.crt...] </ca> <cert> [...content of client.crt...] </cert> <key> [...content of client.key...] </key> <tls-auth> [...content of ta.key...] </tls-auth>
On Android 7.1.1 I can't get working this configuration with the
official app OpenVPN Connect in Play Store (I was connected, I got
the address and the routes working, but no connectivity); I could
get a successful session with OpenVPN for Android, installed via
f-droid store.
The android specific tweak remove the [inline] parts of the
configuration in the .ovpn file.
Here is how an example .ovpn for android looks like:
client dev tun remote server_host 1194 proto udp resolv-retry infinite nobind persist-key persist-tun cipher AES-256-CBC status openvpn-status.log log-append openvpn.log verb 4 key-direction 1 <ca> [...content of ca.crt...] </ca> <cert> [...content of client.crt...] </cert> <key> [...content of client.key...] </key> <tls-auth> [...content of ta.key...] </tls-auth>
Check these scripts for OS differences and .ovpn generation
differences between them:
OpenVPN HOWTO
OpenVPN Hardening
OpenVPN Man Page
OpenVPN installer downloads (for windows clients)