Contents

Installing OpenVPN server

| Ubuntu 22.04 | Openvpn 2.6

openvpn3 client
openvpn Free | No time limit, no credit card
Community Resources

Create vpn server anywhere, I created on Hetzner. And make A-record to ip address. For example ovpn.dodcaf.ru A 5.161.48.201.

Install openvpn:

1
2
sudo apt update \
  && sudo apt install -y openvpn easy-rsa

EasyRSA:

1
2
sudo cp -r /usr/share/easy-rsa /etc/openvpn \
  && sudo ln -s /etc/openvpn/easy-rsa/openssl-easyrsa.cnf /etc/openvpn/easy-rsa/openssl.cnf

Create vars and fill:

1
echo "$(cat /etc/openvpn/easy-rsa/vars.example | grep -Ev "^# |^$|^#$")" | sudo tee /etc/openvpn/easy-rsa/vars

My vars:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
cat /etc/openvpn/easy-rsa/vars
if [ -z "$EASYRSA_CALLER" ]; then
	echo "You appear to be sourcing an Easy-RSA 'vars' file." >&2
	echo "This is no longer necessary and is disallowed. See the section called" >&2
	echo "'How to use this file' near the top comments for more details." >&2
	return 1
fi
set_var EASYRSA 				"$PWD"
set_var EASYRSA_PKI				"$EASYRSA/pki"
set_var EASYRSA_DN				"cn_only"
set_var EASYRSA_REQ_COUNTRY		"RU"
set_var EASYRSA_REQ_PROVINCE	"Arkhangelsk"
set_var EASYRSA_REQ_CITY		"Arkhangelsk"
set_var EASYRSA_REQ_ORG			"Copyleft Certificate Co"
set_var EASYRSA_REQ_EMAIL		"root@local"
set_var EASYRSA_REQ_OU			"ovpn server"
set_var EASYRSA_KEY_SIZE		4096
set_var EASYRSA_ALGO			rsa
set_var EASYRSA_CA_EXPIRE		7500
set_var EASYRSA_CERT_EXPIRE		3650
set_var EASYRSA_NS_SUPPORT		"no"
set_var EASYRSA_NS_COMMENT		"Easy-RSA Generated Certificate"
set_var EASYRSA_EXT_DIR			"$EASYRSA/x509-types"
set_var EASYRSA_SSL_CONF		"$EASYRSA/openssl.cnf"
set_var EASYRSA_DIGEST			"sha512"

Let’s start from creating Certification authority:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
cd /etc/openvpn/easy-rsa
source ./vars
sudo ./easyrsa init-pki

sudo ./easyrsa build-ca

sudo ./easyrsa gen-req ovpn-server nopass
sudo ./easyrsa sign-req server ovpn-server
sudo openssl verify -CAfile pki/ca.crt pki/issued/ovpn-server.crt
	pki/issued/ovpn-server.crt: OK

sudo ./easyrsa gen-dh
sudo ./easyrsa gen-crl

sudo mkdir /etc/openvpn/keys/
sudo cp pki/ca.crt /etc/openvpn/keys/
sudo cp pki/issued/ovpn-server.crt /etc/openvpn/keys
sudo cp pki/private/ovpn-server.key /etc/openvpn/keys

sudo cp pki/dh.pem /etc/openvpn/keys
sudo cp pki/crl.pem /etc/openvpn/keys

Create cert and key for user:

1
2
3
4
5
6
7
8
9
sudo ./easyrsa gen-req user01 nopass
sudo ./easyrsa sign-req client user01
sudo openssl verify -CAfile pki/ca.crt pki/issued/user01.crt
sudo ./easyrsa export-p12 user01

sudo cp pki/ca.crt /etc/openvpn/client/
sudo cp pki/issued/user01.crt /etc/openvpn/client/
sudo cp pki/private/user01.key /etc/openvpn/client/
sudo cp pki/private/user01.p12 /etc/openvpn/client/

Also we can use script to generate user:

For example: cat /home/deploy/EasyRSA-v3.0.6_server/gen_user.sh chown +x /home/deploy/EasyRSA-v3.0.6_server/gen_user.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/usr/bin/env bash

./easyrsa gen-req "${1}" nopass
./easyrsa sign-req client "${1}"
openssl verify -CAfile pki/ca.crt pki/issued/"${1}".crt
./easyrsa export-p12 "${1}"

cp pki/ca.crt /etc/openvpn/client/
cp pki/issued/"${1}".crt /etc/openvpn/client/
cp pki/private/"${1}".key /etc/openvpn/client/
cp pki/private/"${1}".p12 /etc/openvpn/client/

Create ta.key:

The tls-auth directive adds an additional HMAC signature to all SSL/TLS handshake packets for integrity verification. The tls-auth HMAC signature provides an additional level of security above and beyond that provided by SSL/TLS. It can protect against: link

1
2
sudo openvpn --genkey secret /etc/openvpn/keys/ta.key \
  && sudo cp /etc/openvpn/keys/ta.key /etc/openvpn/client/ta.key

Get template for server/client configs:

1
2
gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/ovpn-server.conf
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/client

My server config:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
cat /etc/openvpn/ovpn-server.conf
;local a.b.c.d
port 1194
;proto tcp
proto udp4
;dev tap
dev tun
;dev-node MyTap

ca keys/ca.crt
cert keys/ovpn-server.crt
key keys/ovpn-server.key
dh keys/dh.pem
# https://community.openvpn.net/openvpn/wiki/Topology#Topologysubnet
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100
;server-bridge
;push "route 192.168.10.0 255.255.255.0"
;push "route 192.168.20.0 255.255.255.0"
;client-config-dir ccd
;route 192.168.40.128 255.255.255.248
;client-config-dir ccd
;route 10.9.0.0 255.255.255.252
;learn-address ./script
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 1.1.1.1"
push "dhcp-option DNS 8.8.8.8"
client-to-client
;duplicate-cn
keepalive 10 120
; tls-auth keys/ta.key 0 # This file is secret
tls-crypt keys/ta.key 0 # This file is secret
data-ciphers AES-256-GCM:AES-128-GCM
data-ciphers-fallback AES-256-CBC
;compress lz4-v2
;push "compress lz4-v2"
;comp-lzo
;max-clients 100
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log         /var/log/openvpn/openvpn.log
;log-append  /var/log/openvpn/openvpn.log
verb 3
;mute 20
explicit-exit-notify 1

up /etc/firewall

Create /etc/firewall:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
sudo touch /etc/firewall
sudo chmod +x /etc/firewall
cat /etc/firewall
#!/bin/sh

# enable forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

# reset firewall
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X


# Allow ours connections
iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow SSH
iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT

# Allow OpenVPN
iptables -A INPUT -i eth0 -p udp --dport 1194 -j ACCEPT

# Deny input connections from world
iptables -A INPUT -i eth0 -j DROP

# Allow forward connections
iptables -A FORWARD -i eth0 -o tun0 -m state --state ESTABLISHED,RELATED -j ACCEPT

# Deny forward connections from world
iptables -A FORWARD -i eth0 -o tun0 -j DROP

# Enable nat
iptables -t nat -A POSTROUTING -o eth0 -s 10.8.0.0/24 -j MASQUERADE

Run the ovpn-server:

1
sudo systemctl status openvpn@ovpn-server.service

My client config:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
client

dev tun
proto udp
remote ovpn.dodcaf.ru 1194

resolv-retry infinite
nobind

user nobody
group nogroup

persist-key
persist-tun

remote-cert-tls server

ca ca.crt
pkcs12 user01.p12

tls-auth ta.key 1
key-direction 1

data-ciphers AES-256-GCM:AES-128-GCM
data-ciphers-fallback AES-256-CBC

verb 3
auth-nocache
mssfix 0
; mute 20

script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf

Create directory /etc/openvpn/dodcaf and put files:

1
2
$ ls
ca.crt  client.conf  ta.key  user01.p12

Run connection:

1
sudo openvpn --config client.conf

Import to NetworkManager:

1
2
sudo nmcli connection import type openvpn file client.conf
	Connection 'client' (c423e851-be07-4f99-bfc4-06ab5b989b13) successfully added.

Check:

1
journalctl -u NetworkManager.service --follow

Bonus about p12:

1
2
3
4
5
6
# disassemble .p12
openssl pkcs12 -in cert.p12 -nodes -out temp
# assemble back .p12
openssl pkcs12 -export -in temp -nodes -out cert.p12
# gen .p12 from several files
openssl pkcs12 -export -in yuri.crt -inkey yuri.key -certfile ca.crt -out yuri.p12

Alternative way:

1
2
mkdir ~/client-configs/
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf

Change in ~/client-configs/base.conf:

  • remote your_server_ip 1194
  • proto udp
  • user nobody
  • group nogroup
  • ; ca ca.crt
  • ; cert client.crt
  • ; key client.key
  • ; tls-auth ta.key 1
  • cipher AES-256-GCM
  • auth SHA256
  • key-direction 1
  • ; script-security 2
  • ; up /etc/openvpn/update-resolv-conf
  • ; down /etc/openvpn/update-resolv-conf
  • ; script-security 2
  • ; up /etc/openvpn/update-systemd-resolved
  • ; down /etc/openvpn/update-systemd-resolved
  • ; down-pre
  • ; dhcp-option DOMAIN-ROUTE .

Crate ~/client-configs/make_config.sh script:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash

# First argument: Client identifier

KEY_DIR=/etc/openvpn/keys
CLIENT_KEY_DIR=/etc/openvpn/client
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf

mkdir -pv "${OUTPUT_DIR}"

cat ${BASE_CONFIG} \
    <(echo -e '<ca>') \
    ${KEY_DIR}/ca.crt \
    <(echo -e '</ca>\n<cert>') \
    ${CLIENT_KEY_DIR}/${1}.crt \
    <(echo -e '</cert>\n<key>') \
    ${CLIENT_KEY_DIR}/${1}.key \
    <(echo -e '</key>\n<tls-crypt>') \
    ${CLIENT_KEY_DIR}/ta.key \
    <(echo -e '</tls-crypt>') \
    > ${OUTPUT_DIR}/${1}.ovpn

And be sure to mark this file as executable:

1
sudo chmod 700 ~/client-configs/make_config.sh

Set permissions:

1
sudo chown "${USER}" /etc/openvpn/client/ -Rv

Run the script:

1
2
cd ~/client-configs
./make_config.sh client1

Helpful link