Ubuntu tutorial | html
sudo apt-get install openvpn easy-rsa
Alternative for site-to-site (requires public addresses): StrongSwan
Generate all server and client(s) keys on a dedicated host, using easy-rsa script
sudo su make-cadir /etc/openvpn/easy-rsa cd /etc/openvpn/easy-rsa vi vars # Edit KEY specific info # easy-rsa v2 # fix cnf file check with latest open-ssl versions # ln -s openssl-1.0.0.cnf openssl.cnf # . ./vars # ./clean-all
CA uses the follwing files:
CA key is used by neither server nor clients, it is only used to sign/revoque each device keys.
# generate the self-signed CA key pair ./easyrsa init-pki ./easyrsa build-ca nopass Common Name:tognoli.fr # v2: ./build-ca
Server uses the follwing files:
.csr (Certificate Signing Request) are not used/needed after key generation.
# generate and sign server key pair ./easyrsa build-server-full server nopass # v2: ./build-key-server server # generate the Diffie Hellman parameters file ./easyrsa gen-dh # v2: ./build-dh # generate client authentication key openvpn --genkey secret ta.key # pack server keys tar cvzf ../server-keys.tgz ta.key -C pki ca.crt dh.pem -C issued server.crt -C ../private server.key
Generates the following files:
We generate one Client key set per client host.
# generate and sign client key (one for each client) ./easyrsa build-client-full client-x nopass # v2: ./build-key client-x # pack client keys tar cvzf ../client-x-keys.tgz ta.key -C pki ca.crt -C issued client-x.crt -C ../private client-x.key
To check key status:
sudo openssl x509 -in client_dart.crt -text -noout
OpenVPN sample server conf file is a good starting point.
# use the sample server file cd /etc/openvpn/ cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz . gunzip server.conf.gz
vi server.conf
local 192.168.0.234 # dh dh2048.pem dh dh.pem
Install Keys
# get the keys ssh user@keyhost cat private/server-keys.tgz | tar xvzf - # start the server systemctl start openvpn@server # check current server status systemctl status openvpn@server
Some adjustment are needed on the client side
# use the sample client file cd /etc/openvpn/ cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf . # get the keys ssh user@keyhost cat private/client-x-keys.tgz | tar xvzf -
vi client.conf
remote my-server-1 1194 remote server.com 1194 cert client.crt key client.key cert client-x.crt key client-x.key ;tls-auth ta.key 1 tls-auth ta.key 1 ;cipher x cipher AES-256-CBC comp-lzo # comp-lzo
Start the client
# start the client systemctl start openvpn@client # check current client status systemctl status openvpn@client.service
Server is 10.8.0.1 (as per config file), interface is tun0
ip addr show tun0 13: tun0:mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100 link/none inet 10.8.0.6 peer 10.8.0.5/32 scope global tun0 valid_lft forever preferred_lft forever ip -s link show tun0 13: tun0: mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 100 link/none RX: bytes packets errors dropped overrun mcast 8774 88 0 0 0 0 TX: bytes packets errors dropped carrier collsns 9421 68 0 0 0 0 ping 10.8.0.1 -c 4 PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data. 64 bytes from 10.8.0.1: icmp_seq=1 ttl=64 time=95.8 ms 64 bytes from 10.8.0.1: icmp_seq=2 ttl=64 time=91.1 ms 64 bytes from 10.8.0.1: icmp_seq=3 ttl=64 time=90.7 ms 64 bytes from 10.8.0.1: icmp_seq=4 ttl=64 time=90.6 ms --- 10.8.0.1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3003ms rtt min/avg/max/mdev = 90.637/92.112/95.897/2.214 ms
ip addr show tun0 4: tun0:mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100 link/none inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0 valid_lft forever preferred_lft forever inet6 fe80::8b05:3440:a279:508d/64 scope link flags 800 valid_lft forever preferred_lft forever ip -s link show tun0 4: tun0: mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 100 link/none RX: bytes packets errors dropped overrun mcast 9925 74 0 0 0 0 TX: bytes packets errors dropped carrier collsns 11034 123 0 0 0 0 ping 10.8.0.6 -c 4 PING 10.8.0.6 (10.8.0.6) 56(84) bytes of data. 64 bytes from 10.8.0.6: icmp_seq=1 ttl=64 time=91.0 ms 64 bytes from 10.8.0.6: icmp_seq=2 ttl=64 time=93.3 ms 64 bytes from 10.8.0.6: icmp_seq=3 ttl=64 time=99.6 ms 64 bytes from 10.8.0.6: icmp_seq=4 ttl=64 time=94.2 ms --- 10.8.0.6 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3004ms rtt min/avg/max/mdev = 91.040/94.575/99.673/3.173 ms
Next step is to use the VPN tunnel to allow hosts from server LAN to communicate with hosts from client LAN and vice versa.
As depicted, HostA (192.168.0.2) from LanA will use tunnel from VPN Server (192.168.0.99) to VPN Client (192.168.10.200) to reach HostB (192.168.10.230).
Add to the server configuration:
sudo vi /etc/openvpn/server.conf
# Create the routed IP tunnel proto udp dev tun mode server tls-server ;topology subnet topology subnet server 10.8.0.0 255.255.255.0 ifconfig 10.8.0.1 255.255.255.0 # Configure client ;client-config-dir ccd ;route 10.9.0.0 255.255.255.252 client-config-dir ccd route 192.168.10.0 255.255.255.0 10.8.0.2
Also create client configuration file (for each client, named after client certificate Common Name):
sudo mkdir /etc/openvpn/ccd
sudo vi /etc/openvpn/ccd/client-x
ifconfig-push 10.8.0.2 255.255.255.0 push "route 192.168.0.0 255.255.255.0 10.8.0.1" iroute 192.168.10.0 255.255.255.0
Restart the server:
sudo systemctl restart openvpn@server
sudo vi /etc/openvpn/client.conf
client
dev tun
proto udp
topology subnet
Restart the server:
sudo systemctl restart openvpn@client
Server and all clients need to have IP forwarding enabled:
# echo 1 > /proc/sys/net/ipv4/ip_forward sudo sysctl -w net.ipv4.ip_forward=1 # sudo sysctl -w net.ipv6.conf.all.forwarding=1
To make the change permanent:
sudo vi /etc/sysctl.conf
# Uncomment the next line to enable packet forwarding for IPv4 #net.ipv4.ip_forward=1 net.ipv4.ip_forward=1
Local hosts need to have a route to openvpn added (either on the default gateway or on all accessible hosts)
Note: This is not required when OpenVPN is installed on the default gateway
sudo ip route add 192.168.10.0/24 via 192.168.0.99
When OpenVPN server is installed behind a NAT gateway, gateway port 1194 must be forwarded to OpenVPN host
To forward all traffic coming to a port to another host/port:
local=192.168.0.99 lport=8080 dest=10.8.0.6 dport=80 iptables -t nat -A PREROUTING -p tcp --dst $local --dport $lport -j DNAT --to-destination $dest:$dport iptables -t nat -A POSTROUTING -p tcp --dst $dest --dport $dport -j SNAT --to-source $local iptables -t nat -A OUTPUT -p tcp --dst $local --dport $lport -j DNAT --to-destination $dest:$dport
Keep alive may use significant bandwidth on limited plans. to limit:
By default, openvpn sends ping every 10s idle, means 64*26*60*24*31 = 35MB/month (significant is on a 50MB plan)
Switching to 1 ping per minute will reduce to .5M / month
iftop -p -N -n
# The keepalive directive causes ping-like # messages to be sent back and forth over # the link so that each side knows when # the other side has gone down. # Ping every 10 seconds, assume that remote # peer is down if no ping received during # a 120 second time period. keepalive 10 120 keepalive 60 36018-Dec-2023