This note refers to the free community edition of OpenVPN, and not to the commercial product OpenVPN Access Server. It explains how to configure a Debian or Ubuntu Linux server to act as an OpenVPN server. We assume your server is located in a data center and has a unique IP address, which is accessible from the outside world.
This note collects together points from various sources around the web, among them the following:
https://community.openvpn.net/openvpn/wiki/EasyRSA3-OpenVPN-Howto
https://github.com/TinCanTech/easy-tls/wiki
You need to open your firewall for input on port udp/1194
. Your server provider may refer to your firewall as "security groups."
If you are using iptables
as your firewall, and if you have already installed iptables-persistent
, the relevant commands would look something like this:
iptables -A INPUT -p udp --dport 1194 -j ACCEPT
dpkg-reconfigure iptables-persistent
Issue the commands:
apt update && apt upgrade
apt install openvpn
This installs OpenVPN and creates /usr/share/easy-rsa
.
In a browser, visit https://github.com/TinCanTech/easy-tls/releases. Determine the most recent release archive, e.g. https://github.com/TinCanTech/easy-tls/files/7873797/easytls-2.7.0.tar.gz
.
In your SSH session with the server, download the release archive:
cd /usr/share/easy-rsa
apt install curl
curl -L https://github.com/TinCanTech/easy-tls/files/7873797/easytls-2.7.0.tar.gz -O
Extract the archive:
tar -xf easytls-2.7.0.tar.gz
This adds 8 files into /usr/share/easy-rsa
:
easytls
easytls-client-connect.sh
easytls-client-connect.vars-example
easytls-client-disconnect.sh
easytls-client-disconnect.vars-example
easytls-conntrac.lib
easytls-cryptv2-verify.sh
easytls-cryptv2-verify.vars-example
Make a working copy of the EasyRSA and EasyTLS materials:
cp -r /usr/share/easy-rsa /etc/openvpn
Navigate into the working copy of easy-rsa
:
cd /etc/openvpn/easy-rsa
Copy the file vars.example
to a file named vars
:
cp vars.example vars
Open vars
for editing:
vi vars
Read through vars
for instructions on what to edit. For example, you can choose if your PKI will use RSA or Elliptic Curve cryptography.
Save your changes.
Initialize your Public Key Infrastructure (PKI):
./easyrsa init-pki
Your newly created PKI directory is /etc/openvpn/easy-rsa/pki
. Create your Certificate Authority (CA):
./easyrsa build-ca nopass
Option nopass
disables password locking the CA. You are asked to enter a common name. Type a common name, e.g. MyVPN
, and press Enter.
Your new CA certificate is at /etc/openvpn/easy-rsa/pki/ca.crt
.
Build a server certificate and key:
./easyrsa build-server-full lima nopass
Replace lima
in the above command with your own server name. Option nopass
disables password locking the key.
When prompted, type the word yes
to confirm.
Your server certificate is created at /etc/openvpn/easy-rsa/pki/issued/lima.crt
.
Build a client certificate and key:
./easyrsa build-client-full charlie nopass
Replace charlie
in the above command with your actual client name. Option nopass
disables password locking the key.
When prompted, type the word yes
to confirm.
Your client certificate is created at /etc/openvpn/easy-rsa/pki/issued/charlie.crt
.
Repeat the client part of the process for as many clients as you need.
This next command will generate Diffie-Hellman (DH) parameters, which will be used during the TLS handshake with connecting clients:
./easyrsa gen-dh
The DH parameters are not security sensitive and are needed only on the OpenVPN server, not on the client(s).
DH parameters of size 2048 are created at /etc/openvpn/easy-rsa/pki/dh.pem
.
OpenVPN uses two communication channels during a VPN session: the control channel, which handles authentication, key negotiation, and configuration; and the data channel, which encrypts and transports packets.
The control channel can be encrypted by TLS Auth. TLS Crypt improves upon TLS Auth by adding symmetric encryption to the control channel. This extra layer of encryption applies even to the key-exchange before the TLS session starts. TLS Auth and TLS Crypt provide protection against TLS-level attacks with post-quantum resistance, provided the preshared keys are kept secret.
TLS Crypt v2 improves on TLS Crypt by using a unique key per client or group of clients.
Initialize EasyTLS:
./easytls init-tls
Your newly created TLS directory is /etc/openvpn/easy-rsa/pki/easytls
.
Create a TLS Crypt v2 server key:
./easytls build-tls-crypt-v2-server lima
Replace lima
in the above command with your own server name.
The TLS crypt v2 server key is created in /etc/openvpn/easy-rsa/pki/easytls/lima-tls-crypt-v2.key
. This key must be kept secure.
Create a TLS Crypt v2 client key:
./easytls build-tls-crypt-v2-client lima charlie
Replace lima
by your server name and charlie
by your client name. The server key is used to encrypt the client key, which is why the server must also be specified.
Follow this by:
./easytls inline-tls-crypt-v2 charlie
The inline TLS crypt v2 file is created at /etc/openvpn/easy-rsa/pki/easytls/charlie.inline
. The inline file is for eventual incorporation into your client configuration .ovpn
file.
Create your server configuration file /etc/openvpn/server/lima.conf
. You can use this example as your starting point:
port 1194 proto udp dev tun topology subnet cipher AES-256-GCM ca /etc/openvpn/easy-rsa/pki/ca.crt cert /etc/openvpn/easy-rsa/pki/issued/lima.crt key /etc/openvpn/easy-rsa/pki/private/lima.key dh /etc/openvpn/easy-rsa/pki/dh.pem tls-crypt-v2 /etc/openvpn/easy-rsa/pki/easytls/lima-tls-crypt-v2.key server 10.8.0.0 255.255.255.0 ifconfig-pool-persist ipp.txt push "redirect-gateway def1" push "dhcp-option DNS 1.1.1.1" push "dhcp-option DNS 1.0.0.1" push "block-outside-dns" keepalive 10 60 persist-key persist-tun explicit-exit-notify 1 verb 3
Save the configuration file.
Edit the system control configuration file:
vi /etc/sysctl.conf
Uncomment the line:
#net.ipv4.ip_forward=1
so that it reads:
net.ipv4.ip_forward = 1
Save the file. Activate the change:
sysctl -p
Determine your default interface:
ip r
Masquerade the source IP address on packets outbound from your default interface:
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o ens3 -j MASQUERADE
Save the iptables
rules as they now stand:
dpkg-reconfigure iptables-persistent
systemctl enable openvpn-server@lima
systemctl start openvpn-server@lima
systemctl status openvpn-server@lima
You can use this example as your starting point. Copy and paste the inline client certificates and keys from /etc/openvpn/easy-rsa/pki/easytls/charlie.inline
. Insert your actual server IP address or DNS name on the remote
line.
client dev tun proto udp cipher AES-256-GCM remote 123.123.123.123 1194 resolv-retry infinite nobind persist-key persist-tun # EASYTLS # EasyTLS version 2.7.0.0 # Common name: charlie # X509 serial: 3615725ECBB726608AB65B5955C89C2C <cert> Certificate: Data: Version: 3 (0x2) Serial Number: 36:15:72:5e:cb:b7:26:60:8a:b6:5b:59:55:c8:9c:2c Signature Algorithm: sha256WithRSAEncryption Issuer: CN=MyVPN Validity Not Before: May 3 18:40:24 2024 GMT Not After : Aug 6 18:40:24 2026 GMT Subject: CN=charlie Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:a5:33:dc:ff:30:d5:9c:d5:7d:29:96:6c:43:cf: c6:40:b1:57:a7:f5:66:0f:3b:24:7e:41:2e:78:ac: 1a:21:fb:26:b5:4a:78:95:11:98:5b:0d:4b:aa:38: 5b:01:bc:81:76:92:25:c6:8c:df:34:91:17:6a:be: 5f:64:69:73:03:91:fa:41:b7:68:33:10:28:d6:52: 9e:ed:d5:67:46:07:9f:1f:19:83:10:86:69:de:52: 60:f1:e5:c9:21:07:fb:81:91:d5:91:ee:b2:34:94: 3b:bc:7e:85:37:52:7b:bf:4e:3b:5c:4f:e1:f5:41: 21:38:9b:77:62:20:88:54:fd:06:64:24:07:05:fe: 83:15:9a:6f:60:db:b5:3e:e5:ef:e2:81:d2:2a:fd: 5f:50:8f:68:2c:16:0b:e0:1a:56:b6:8f:6f:56:d6: 85:07:25:9b:e5:1b:46:80:8b:4a:2b:49:c1:0f:64: 7c:3d:86:3d:8b:5e:d7:7e:a9:2a:91:85:6d:dc:bc: 77:0c:c9:c2:bb:a0:04:fa:f8:f6:b9:d5:36:00:48: 02:3d:f5:5c:6a:08:58:ce:dc:f4:ac:c4:07:76:50: 6b:2e:e0:67:3a:01:ec:20:9b:40:2c:32:a8:dc:84: a3:47:29:a9:4a:d9:88:e0:b1:4c:62:73:4b:c5:03: d7:27 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE X509v3 Subject Key Identifier: B8:CF:57:AF:BF:DE:59:AB:FF:75:D3:24:36:AB:6B:6D:52:84:C9:60 X509v3 Authority Key Identifier: keyid:7C:6A:30:BF:4E:3D:90:61:02:1C:EB:92:4A:8C:E4:66:C3:7E:84:E3 DirName:/CN=MyVPN serial:42:22:9A:FF:12:1A:09:11:8D:BE:52:B0:18:AA:21:90:56:5C:97:8F X509v3 Extended Key Usage: TLS Web Client Authentication X509v3 Key Usage: Digital Signature Signature Algorithm: sha256WithRSAEncryption Signature Value: 56:6c:b7:b6:5d:57:a2:b1:71:d4:87:5f:6e:35:a6:5f:72:94: 7e:a4:a7:fc:2e:68:93:50:86:7f:c4:a3:a9:9e:55:04:27:f0: 92:f1:bf:ef:86:b5:d8:fc:78:a7:59:4a:52:2c:2a:4f:95:2f: e7:74:21:14:cd:8a:2e:ff:90:d5:36:50:67:08:1a:58:e7:4e: 14:c4:66:c4:5b:ef:de:7a:b9:f3:54:c4:d5:2a:d5:23:0f:56: c4:08:5f:94:33:24:9b:ca:26:24:cc:4e:16:9d:59:02:da:ef: ba:88:57:ba:98:4d:3b:7d:91:e9:2f:b8:88:82:46:40:78:86: c5:15:c1:cd:86:e0:da:e6:a7:c3:52:3a:65:ce:00:91:00:50: f1:5f:fc:58:15:ff:81:1f:2b:2a:ee:99:76:88:ae:65:2a:47: 87:7f:0c:2d:ff:0a:ca:ce:bb:ec:08:af:7f:70:bf:f0:1f:e0: 67:0c:2b:f2:cd:9b:43:6c:1e:b9:f1:9e:98:37:b8:5b:61:b6: 08:0f:d2:54:e5:8c:ab:5e:44:fe:a9:31:20:dc:70:0b:a8:47: 8c:8e:2d:05:4e:17:2e:99:b2:93:e1:76:c3:e5:23:2e:ab:85: 91:56:cc:4e:8e:85:50:3c:15:6d:59:35:f2:24:75:26:bf:2d: 88:cc:05:04 -----BEGIN CERTIFICATE----- MIIDSTCCAjGgAwIBAgIQNhVyXsu3JmCKtltZVcicLDANBgkqhkiG9w0BAQsFADAQ MQ4wDAYDVQQDDAVNeVZQTjAeFw0yNDA1MDMxODQwMjRaFw0yNjA4MDYxODQwMjRa MBIxEDAOBgNVBAMMB2NoYXJsaWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK AoIBAQClM9z/MNWc1X0plmxDz8ZAsVen9WYPOyR+QS54rBoh+ya1SniVEZhbDUuq OFsBvIF2kiXGjN80kRdqvl9kaXMDkfpBt2gzECjWUp7t1WdGB58fGYMQhmneUmDx 5ckhB/uBkdWR7rI0lDu8foU3Unu/TjtcT+H1QSE4m3diIIhU/QZkJAcF/oMVmm9g 27U+5e/igdIq/V9Qj2gsFgvgGla2j29W1oUHJZvlG0aAi0orScEPZHw9hj2LXtd+ qSqRhW3cvHcMycK7oAT6+Pa51TYASAI99VxqCFjO3PSsxAd2UGsu4Gc6Aewgm0As MqjchKNHKalK2YjgsUxic0vFA9cnAgMBAAGjgZwwgZkwCQYDVR0TBAIwADAdBgNV HQ4EFgQUuM9Xr7/eWav/ddMkNqtrbVKEyWAwSwYDVR0jBEQwQoAUfGowv049kGEC HOuSSozkZsN+hOOhFKQSMBAxDjAMBgNVBAMMBU15VlBOghRCIpr/EhoJEY2+UrAY qiGQVlyXjzATBgNVHSUEDDAKBggrBgEFBQcDAjALBgNVHQ8EBAMCB4AwDQYJKoZI hvcNAQELBQADggEBAFZst7ZdV6KxcdSHX241pl9ylH6kp/wuaJNQhn/Eo6meVQQn 8JLxv++Gtdj8eKdZSlIsKk+VL+d0IRTNii7/kNU2UGcIGljnThTEZsRb7956ufNU xNUq1SMPVsQIX5QzJJvKJiTMThadWQLa77qIV7qYTTt9kekvuIiCRkB4hsUVwc2G 4Nrmp8NSOmXOAJEAUPFf/FgV/4EfKyrumXaIrmUqR4d/DC3/CsrOu+wIr39wv/Af 4GcMK/LNm0NsHrnxnpg3uFthtggP0lTljKteRP6pMSDccAuoR4yOLQVOFy6ZspPh dsPlIy6rhZFWzE6OhVA8FW1ZNfIkdSa/LYjMBQQ= -----END CERTIFICATE----- </cert> <key> -----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQClM9z/MNWc1X0p lmxDz8ZAsVen9WYPOyR+QS54rBoh+ya1SniVEZhbDUuqOFsBvIF2kiXGjN80kRdq vl9kaXMDkfpBt2gzECjWUp7t1WdGB58fGYMQhmneUmDx5ckhB/uBkdWR7rI0lDu8 foU3Unu/TjtcT+H1QSE4m3diIIhU/QZkJAcF/oMVmm9g27U+5e/igdIq/V9Qj2gs FgvgGla2j29W1oUHJZvlG0aAi0orScEPZHw9hj2LXtd+qSqRhW3cvHcMycK7oAT6 +Pa51TYASAI99VxqCFjO3PSsxAd2UGsu4Gc6Aewgm0AsMqjchKNHKalK2YjgsUxi c0vFA9cnAgMBAAECggEACmuCBfU+PqfXPtdGZDnnvE7d7jHJSoP6zPKENtz2wlaa s2v2Em5LWNA23zlcwXhIBi2OWmlU7suJWZSWZGP4+tcAnO0vklZI7R5wTc9cYItn MElQqKssZEx34ZS9Ies5+Ys0QwHLlbYVKnzPHuqB9FK/5cECyeWzbbmd8b+G5IKo T+goAEx08J1p5KH6y8LXLKLJ3JU/8Mlf6KVH1QjhRWNwf757SSW60T09crQRn5hD nNgzldS3V5GexytuXwEzuwD59P1N66F/oQlSvy6y7qUtQt8TEc2aS9J+MKxOFEhg bu2ibHrKQPX+e0X1Lw2/9aTLRZcrPWoi46maG4KvQQKBgQDoknyTdYHQWHG7zOFV X5nWqfRrA4B5NMs8rneUnMyF8fMw3dqtwwpe5nYtBeujaAaWr1tzXdyNA8xKnfbg IJ/3dA8+jDaR2UGsOmISnSEuN3+NrYlhzdKH5V3bvG1IbpZk1gsOjW7nS7bBlyYE SualX6dhvEHHVok7uf8+1iuvxwKBgQC12BDc4Ucs7F6R97Gphg6q31/vkGlw3y3C dJC/6JKvFPO89u5RSsX2UDQtprTvbZQDZLudlmFipQh3EhAPtDMuWa/dkdunu52K fZqup8rLB6K+1iJ948fnaGe1I0wxLEdY3F6alOybhh9NEAQhS84R15un1ckavtC+ sfXPI9ldoQKBgQCsIzg3gGLLzZqosNUbdn4L55Ez38yoaY3/5PY3NfMfNNyWD676 q4Cyiwtu+ZHWSXmO8E3UzuUeLnB3zgFbFGqyIeHinq8JNm+oRTIvqsNTTNqJB6fG jyvDT94vdIDCeq+wBMj8RWyPn3euQ+xsgu/B+VGPQmLBYuiCH4GvhZ+iIwKBgBnm z+gWcqP0ezgBdx31iWtPbAPcpxg7wfHb1q5vO02TB3DYH3QW2YHPRM9n2ofsLNQa 6hp1TCPX7A/B0+XYvh2RCtrdptMKh1MttvW/0sP+r3DNYZZa9qOAnJ0RjQ3IB9Wh dhxAsD8q6JR6fowblxu1gWdzrTSRD3zKLoA11AVhAoGAa+EXK+CWEx+HYTIMOKUX mD4ni71NFsxpOTHG1U1VLJQBhEHa/ghSitSuS53kuo9f9w/W/6pf/dGaM7JDQSLS Hyx+G7dUjoBT5Hoj62ZNoyKPCNqrusZF4W3ZAD9KL01VnFC9vg6eIOTP/5V5+eE7 iR9ebeM3TW6G3fUxO4nxRbo= -----END PRIVATE KEY----- </key> <ca> -----BEGIN CERTIFICATE----- MIIDOTCCAiGgAwIBAgIUQiKa/xIaCRGNvlKwGKohkFZcl48wDQYJKoZIhvcNAQEL BQAwEDEOMAwGA1UEAwwFTXlWUE4wHhcNMjQwNTAzMTgzODQyWhcNMzQwNTAxMTgz ODQyWjAQMQ4wDAYDVQQDDAVNeVZQTjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC AQoCggEBAJ4hoyn4uqFZpeD0hSF+LWKWb5vUSKX5fWp9KlgTQCXtW6EzYBa/aRzo 68gYvFYA9wkiaIki+Bt1Fl4gCpAabfYJVAkOXxLnpwblRDY6fXGqnKvVT4QSuAcX sZXwitT5yNDCjljZxVIck+uDv2Ysx5hHqmBjv/W4BmkeM4OmKP+I4QKf+9LSpjIb gr6gYQHYMnP4MDEUCcWKLnzeHvQ9BaC6390GMSOZ8X/txQKjKp2hjdFZArFtXnP9 iUllanGXPbA437xwM7TkNo7JxuqJ7AS4DlWEPXAuyqm2dGu7KynOH7/bRJbgV2Et D9PAgIUZEJbbzGSxucePvbTBbXQMxLkCAwEAAaOBijCBhzAMBgNVHRMEBTADAQH/ MB0GA1UdDgQWBBR8ajC/Tj2QYQIc65JKjORmw36E4zBLBgNVHSMERDBCgBR8ajC/ Tj2QYQIc65JKjORmw36E46EUpBIwEDEOMAwGA1UEAwwFTXlWUE6CFEIimv8SGgkR jb5SsBiqIZBWXJePMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAkKXZ t2T1/znnHf/prT83kmS9mVPiXSsU78rzbl2bdZbu//Mxt9G6VEjVDZ0/FdAjW44m DZ+PV3VF9b7kviM5JUjxWaPmCcYWBbn4cEU4ycpi1LKVm7aep66SqNTGjGryaC5r K/IHxDR/RLRhntQEYgwci5eezz6QPA+InR8b1gdAgsmSa48n/+lfI4TfxysU2xBb oF9dfxog/fmXgPWgT6qvlLew4GVWMu5jVSauRuGelxnqr7gB3XXk2dw26N2+55+H HWyiqhvuW3LbZvDBgU+c2FTcXqAt5Ln1kIP3U5rcWksKN1IaZZBgI2C6pMrTSHPV h7XuvD9l+Ps+mgZQrw== -----END CERTIFICATE----- </ca> # metadata Easy-TLS-version 2.7.0.0 - TLS-Crypt-v2 key # metadata CA-serial: 42229AFF121A09118DBE52B018AA2190565C978F # metadata tlskey-serial: 5462c67eb8a81dcb93111232854c7a9e545caecc159f9d00ef8e4e5e818943e8 # metadata Creation-Date: 2024/05/03-18:44:33 # metadata Custom-Group: EASYTLS # metadata Server-Common-Name: lima # metadata Client-Common-Name: charlie # metadata Key-status: Open setenv UV_TLSKEY_SERIAL 5462c67eb8a81dcb93111232854c7a9e545caecc159f9d00ef8e4e5e818943e8 push-peer-info <tls-crypt-v2> -----BEGIN OpenVPN tls-crypt-v2 client key----- 4KTq0o94eKeBWTHEPphVzd/efiCkEs30cVGD8to5g+28M2DU+QXvdrVJ6pqa6rLQ FIVT1cskd+PCXKfoN1KMvgXgq6I6BWhctMh+gRGuzxo3iGi/Bk4vomTVgPMbjCmV J8q18/CcSBONkAa4MySuGXhHNywqLGBcmlRDgM8ZjCBD3A8p2x1e1eTlZ5uOZy7O k5BtMsaAlpHDK9gxbGCAZK94bs/Ai8QVTWyrFOyNkejWB0Dt2ojIGAmUvDFMXUwg Pys/Nq31oMc5xWqgS3ytAHSOSjPmxUcP9cnbIwNaWSDFVNfzScKQ3sWfn3CCcDwn Uv+y8CFIiHI8gfb9ymAPw5DTFQM4Ej69nPdaeQMr7NEN53BRt76BEoEhzYqHVhsB 3/AIGaU6KF8IO1AQ0clgCNzX+I0auKIjdrQ0evotRh70n8YW6MMSvjRinzAOsgUR TGMf6Dn/49YzemJ5ZVAFuAd1IM9sCAUbhnhdjqkB97lk3lSvK1VRBoK+E0h5+oCS PzPfViP5NQCqyotzMf6lACvL4cQenzVvKQDtO0KjBnl9w5SjWQT0/mD5SVJ05uKp XXZlC04JYFDY9L7YI4EpSW8ZDMCpsl6noQmGGDLf6vVlRV3aT1zPltmevsjtBW7a KV5Q0/2BH4tMait+sdmLIqYRBrK2whjECmi1z4hFY5p79CtSCbTn55PgFZ3n0Jg2 CN6NWsT/jwi+kHZ2d7qpcR6Vj/f8v4QSlCiflUG/6AK9oFkC85PDHWF5Eh8Fc3W5 +eJiaWRbEx9TxIn+QkUZEAX5OewYlawSR2ANHJVeIYTEqWSpC2+DpG6g2o62N/+p vnK9dZXPT4Ywc03Q46rg77nK69ReW4kcmkW6RuzrLPePTxmjiA1deTAQ/JNOih8p 9KZDFhD6vpzLLa9OLiXmet4TPXb3dFOpset2Uo05J4RffqlHm+enFrWFMA8lIKIv GcsiKQ3P6XUNkBh9/KMKITUHBKXo/FfPJge3lfIEtXb99emo8s1yaQ1keXaLuIel ADDXIayp2QA0NrADHs28fV1ZcG0ftsazJgIb -----END OpenVPN tls-crypt-v2 client key----- </tls-crypt-v2> remote-cert-tls server verb 3
Since this file includes inline keys, you must securely transfer it to your client.