OpenVPN Setup

OpenVPN Authentication

Here is a good article on OpenVPN Authentication based on Public Key Infrastructure (PKI)

This article does a good job of explaining TLS/SSL and SSL (X.509) Certificates at length.

A working knowledge of encyrption is necessary. Symmetric key encryption is pretty straightforward but public key encryption has some interesting capabilities. Here is a good article on encryption.

The PKI consists of:

  • A separate certificate (also known as a public key) and private key for the server and each client, and
  • A master Certificate Authority (CA) certificate and key which is used to sign each of the server and client certificates.

Important notes about SSL in general and PKI authentication

  • SSL transport is almost always really TLS. SSL largely replaced TLS but the name persists.
  • What are known as SSL certificates should really be referred to as X.509 certificates.
  • The server will only accept clients whose certificates were signed by the master CA certificate
  • The server and client clocks need to be roughly in sync or certificates might not work properly.
  • From RFC 8446 Section 1: The server side of the channel is always authenticated; the client side is optionally authenticated.
  • During the hanshake protocol a TLS/SSL server will typically provide a certificate. The client may optionally also provide a certificate.

File Formats

DER - All SSL related objects (Certificates, keys etc.) use native ASN.1 DER encoding. DER is a binary (8 bit) encoding.

PEM - Privacy Enhanced Mail (PEM) encodes binary DER in base 64 (RFC 3548) creating a text (ASCII/IA5 subset) version that may be sent by, among other things, mail systems. Objects encoded by PEM include header lines and trailer lines each starting and finishing with precisely 5 dashes to encapsulate the base64 material and provide a human readable indication of its content. PEM files look something like that shown below:

-----BEGIN CERTIFICATE-----
MIIDHDCCAoWgAwIBAgIJALt8VJ...
...
Cfh/ea7F1El1Ym1Zj2v3wLhRl1...
NH5lEmZybl+m2frlkjUv9KAvxc...
IFgovdU8YPMDds=
-----END CERTIFICATE-----

BLAH BLAH BLAH 

Generate the master Certificate Authority (CA) certificate & key

Use easy-rsa 2, a set of scripts which is bundled with OpenVPN. With the Windows OpenVPN client open up a Command Prompt window with administrative privileges and cd to c:\Program Files\OpenVPN\easy-rsa. Run the following batch file to copy configuration files into place (this will overwrite any preexisting vars.bat and openssl.cnf files). Skip this if you already have vars.bat setup the way you like it. :

init-config

Now edit the vars.bat file and set KEY_* parameters. Don’t leave any of these parameters blank. Here is what I set:

set KEY_COUNTRY=US
set KEY_PROVINCE=FL
set KEY_CITY=Niceville
set KEY_ORG=Baggerman
set KEY_EMAIL=xxxxxxxx@baggerman.org
set KEY_CN=Home-VPN-CA
set KEY_NAME=Home-DD-WRT-OpenVPN
set KEY_OU=Home

Next, initialize the PKI.

vars
clean-all
build-ca

The “build-ca” command issues this OpenSSL command:

# Build a cert authority valid for ten years, starting now
openssl req -days 3650 -nodes -new -x509 -keyout %KEY_DIR%\ca.key -out %KEY_DIR%\ca.crt -config %KEY_CONFIG%

Substitute “-enddate YYMMDDHHMMSSZ” to specify an end date instead.

The final command (build-ca) will build the certificate authority (CA) certificate and key by invoking the interactive openssl command. My certificate looked like:

Master Certificate - Encoded

show
 
—–BEGIN CERTIFICATE—–
MIIG/TCCBOWgAwIBAgIJAIDiFLZkOqoVMA0GCSqGSIb3DQEBCwUAMIGvMQswCQYD
VQQGEwJVUzELMAkGA1UECBMCRkwxEjAQBgNVBAcTCU5pY2V2aWxsZTESMBAGA1UE
ChMJQmFnZ2VybWFuMQ0wCwYDVQQLEwRIb21lMRQwEgYDVQQDEwtIb21lLVZQTi1D
QTEcMBoGA1UEKRMTSG9tZS1ERC1XUlQtT3BlblZQTjEoMCYGCSqGSIb3DQEJARYZ
Ym9iLm9wZW52cG5AYmFnZ2VybWFuLm9yZzAeFw0xODEyMDIwNTAzMTZaFw0yODEx
MjkwNTAzMTZaMIGvMQswCQYDVQQGEwJVUzELMAkGA1UECBMCRkwxEjAQBgNVBAcT
CU5pY2V2aWxsZTESMBAGA1UEChMJQmFnZ2VybWFuMQ0wCwYDVQQLEwRIb21lMRQw
EgYDVQQDEwtIb21lLVZQTi1DQTEcMBoGA1UEKRMTSG9tZS1ERC1XUlQtT3BlblZQ
TjEoMCYGCSqGSIb3DQEJARYZYm9iLm9wZW52cG5AYmFnZ2VybWFuLm9yZzCCAiIw
DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALxnrTUcdkOZMplk4XUfpKE9Z3VM
CMSOLbXkrablD6IkdRP0twv3G/jizxlJV4kCzQdQPUTfS/AwJyi+vJ0/b+PIHFje
X1JZ3Kg9+1k3rHwTu+uadj23M4MNRM+omQuPCi6QwC6wmE3k+Nze0VKX2kWKWHzi
wONuJxYiKlZ89IP3uszdYOctKr8CbEXgWdzmokv656h0N3YLjCnqjfDec0D6zNSE
ZsSXb2y/6geeNK1EIx4rhOc658Yz+ZTruYR2mVRb5sPggu3c9lSLiWylTyM+Gi6/
QVHB8OzRo0+P+YEm551tx7kZeJg8whWnJ0NUE7ZR8PkpOdfeeL56aTAaFnKpBZ0K
vi6s+q43hG0FB4aGjv0Ud3+xzW+96Nnmpr6srUQCxmSZ1c7orrEz0rTWi8IjwzsL
STMwwF5vW8cmBM2+7LqGL+/+flrW2g4bC9Da9/gn8nmpykzHAHjarq+L2Y2waLu7
B12XhSpWhFMNGnrRKuFqW06Uu4tSHcqsk7UNrnivAAkDFDe/YzteourkfhueUk9T
LVzIDafE9aRaGuSWTle9UO37YfwKKgUjKAcyj1dZImoaj7zKBKvcgswY900FRjkM
dxQIiCR8s4Ryrd/gFEF44T2M0jLVJxEnfwnBUe3//qBat0Irj6xwtNzix8TXpc/a
iyfaipxhjAPjgldNAgMBAAGjggEYMIIBFDAdBgNVHQ4EFgQUNBPszBOCYFEYHstL
aTeZPa90PPwwgeQGA1UdIwSB3DCB2YAUNBPszBOCYFEYHstLaTeZPa90PPyhgbWk
gbIwga8xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJGTDESMBAGA1UEBxMJTmljZXZp
bGxlMRIwEAYDVQQKEwlCYWdnZXJtYW4xDTALBgNVBAsTBEhvbWUxFDASBgNVBAMT
C0hvbWUtVlBOLUNBMRwwGgYDVQQpExNIb21lLURELVdSVC1PcGVuVlBOMSgwJgYJ
KoZIhvcNAQkBFhlib2Iub3BlbnZwbkBiYWdnZXJtYW4ub3JnggkAgOIUtmQ6qhUw
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAE7UKWG1qrkI+NFox1+Nh
WuGHjOtW9BQjYn896tl7rDrGEF3JkX98tUznO6yd8oLmqnX5M8qkRl5df3j9CINH
eVyxbDQM35hTpl0QaFS4Fzifv13KStuSRTKjwo624RxTn+0GCsU2YOtKdHTabJSb
vH8GXSXSSrQikwkgXD9ioMk80190KgBkhm/pMa1oEiFFnkN5r8tEv+XmOaE1zkGH
0aQsdvTLNlzD1WszDpf+ljw/19RTadKRjueFVYk04jujcSHMJgPAh3IARrk3L8b9
lJwxikxnLWEUCArCSyNTFRhA6lWo4ZiMzwKr4nKY2Jn6flPtQg1/jT5fdyR4SuWi
gU0JfL2LBPS3/TSqi+xT+1aEBsPpmzcNBM/c6s6jAZkz9FM56A02sXRaaaAp1c8v
V0ykfMNxjfeF9SdKYs9149G8YrUEkE08XCDPQss0fjCwxBpRkAoMIEViGlHRHS9k
AiJeaZ+PAUgu0gU/wAe/0NEDzSkZwWXHc6q+7A8rcLPOlJSmFouMJHoQ54AcbVkw
ux3TvtdSJOwl+6BAuFbIH091hjXXVrdaawNEhR8SSb7yBNyXG056d64kw34PIrQS
6oqA+t8dYzYkRsNmJP8rJDYhzHgqA9Ip/vbOx4ioOdc4m9fbbQ8uXdxChQ4/NFL3
u15eRCSnJnzfXHQ62UaR1gc=
—–END CERTIFICATE—–

Use openssl or an SSL certificate decoder to view the contents.

openssl x509 -in ca.crt -text -noout

My humanly readable certificate looked like:

Master Certificate - Decoded

show
 
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 9287008155189553685 (0x80e214b6643aaa15)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, ST=FL, L=Niceville, O=Baggerman, OU=Home, CN=Home-VPN-CA/name=Home-DD-WRT-OpenVPN/emailAddress=bob.openvpn@baggerman.org
        Validity
            Not Before: Dec  2 05:03:16 2018 GMT
            Not After : Nov 29 05:03:16 2028 GMT
        Subject: C=US, ST=FL, L=Niceville, O=Baggerman, OU=Home, CN=Home-VPN-CA/name=Home-DD-WRT-OpenVPN/emailAddress=bob.openvpn@baggerman.org
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Modulus:
                    00:bc:67:ad:35:1c:76:43:99:32:99:64:e1:75:1f:
                    a4:a1:3d:67:75:4c:08:c4:8e:2d:b5:e4:ad:a6:e5:
                    0f:a2:24:75:13:f4:b7:0b:f7:1b:f8:e2:cf:19:49:
                    57:89:02:cd:07:50:3d:44:df:4b:f0:30:27:28:be:
                    bc:9d:3f:6f:e3:c8:1c:58:de:5f:52:59:dc:a8:3d:
                    fb:59:37:ac:7c:13:bb:eb:9a:76:3d:b7:33:83:0d:
                    44:cf:a8:99:0b:8f:0a:2e:90:c0:2e:b0:98:4d:e4:
                    f8:dc:de:d1:52:97:da:45:8a:58:7c:e2:c0:e3:6e:
                    27:16:22:2a:56:7c:f4:83:f7:ba:cc:dd:60:e7:2d:
                    2a:bf:02:6c:45:e0:59:dc:e6:a2:4b:fa:e7:a8:74:
                    37:76:0b:8c:29:ea:8d:f0:de:73:40:fa:cc:d4:84:
                    66:c4:97:6f:6c:bf:ea:07:9e:34:ad:44:23:1e:2b:
                    84:e7:3a:e7:c6:33:f9:94:eb:b9:84:76:99:54:5b:
                    e6:c3:e0:82:ed:dc:f6:54:8b:89:6c:a5:4f:23:3e:
                    1a:2e:bf:41:51:c1:f0:ec:d1:a3:4f:8f:f9:81:26:
                    e7:9d:6d:c7:b9:19:78:98:3c:c2:15:a7:27:43:54:
                    13:b6:51:f0:f9:29:39:d7:de:78:be:7a:69:30:1a:
                    16:72:a9:05:9d:0a:be:2e:ac:fa:ae:37:84:6d:05:
                    07:86:86:8e:fd:14:77:7f:b1:cd:6f:bd:e8:d9:e6:
                    a6:be:ac:ad:44:02:c6:64:99:d5:ce:e8:ae:b1:33:
                    d2:b4:d6:8b:c2:23:c3:3b:0b:49:33:30:c0:5e:6f:
                    5b:c7:26:04:cd:be:ec:ba:86:2f:ef:fe:7e:5a:d6:
                    da:0e:1b:0b:d0:da:f7:f8:27:f2:79:a9:ca:4c:c7:
                    00:78:da:ae:af:8b:d9:8d:b0:68:bb:bb:07:5d:97:
                    85:2a:56:84:53:0d:1a:7a:d1:2a:e1:6a:5b:4e:94:
                    bb:8b:52:1d:ca:ac:93:b5:0d:ae:78:af:00:09:03:
                    14:37:bf:63:3b:5e:a2:ea:e4:7e:1b:9e:52:4f:53:
                    2d:5c:c8:0d:a7:c4:f5:a4:5a:1a:e4:96:4e:57:bd:
                    50:ed:fb:61:fc:0a:2a:05:23:28:07:32:8f:57:59:
                    22:6a:1a:8f:bc:ca:04:ab:dc:82:cc:18:f7:4d:05:
                    46:39:0c:77:14:08:88:24:7c:b3:84:72:ad:df:e0:
                    14:41:78:e1:3d:8c:d2:32:d5:27:11:27:7f:09:c1:
                    51:ed:ff:fe:a0:5a:b7:42:2b:8f:ac:70:b4:dc:e2:
                    c7:c4:d7:a5:cf:da:8b:27:da:8a:9c:61:8c:03:e3:
                    82:57:4d
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                34:13:EC:CC:13:82:60:51:18:1E:CB:4B:69:37:99:3D:AF:74:3C:FC
            X509v3 Authority Key Identifier: 
                keyid:34:13:EC:CC:13:82:60:51:18:1E:CB:4B:69:37:99:3D:AF:74:3C:FC
                DirName:/C=US/ST=FL/L=Niceville/O=Baggerman/OU=Home/CN=Home-VPN-CA/name=Home-DD-WRT-OpenVPN/emailAddress=bob.openvpn@baggerman.org
                serial:80:E2:14:B6:64:3A:AA:15
            X509v3 Basic Constraints: 
                CA:TRUE
    Signature Algorithm: sha256WithRSAEncryption
         13:b5:0a:58:6d:6a:ae:42:3e:34:5a:31:d7:e3:61:5a:e1:87:
         8c:eb:56:f4:14:23:62:7f:3d:ea:d9:7b:ac:3a:c6:10:5d:c9:
         91:7f:7c:b5:4c:e7:3b:ac:9d:f2:82:e6:aa:75:f9:33:ca:a4:
         46:5e:5d:7f:78:fd:08:83:47:79:5c:b1:6c:34:0c:df:98:53:
         a6:5d:10:68:54:b8:17:38:9f:bf:5d:ca:4a:db:92:45:32:a3:
         c2:8e:b6:e1:1c:53:9f:ed:06:0a:c5:36:60:eb:4a:74:74:da:
         6c:94:9b:bc:7f:06:5d:25:d2:4a:b4:22:93:09:20:5c:3f:62:
         a0:c9:3c:d3:5f:74:2a:00:64:86:6f:e9:31:ad:68:12:21:45:
         9e:43:79:af:cb:44:bf:e5:e6:39:a1:35:ce:41:87:d1:a4:2c:
         76:f4:cb:36:5c:c3:d5:6b:33:0e:97:fe:96:3c:3f:d7:d4:53:
         69:d2:91:8e:e7:85:55:89:34:e2:3b:a3:71:21:cc:26:03:c0:
         87:72:00:46:b9:37:2f:c6:fd:94:9c:31:8a:4c:67:2d:61:14:
         08:0a:c2:4b:23:53:15:18:40:ea:55:a8:e1:98:8c:cf:02:ab:
         e2:72:98:d8:99:fa:7e:53:ed:42:0d:7f:8d:3e:5f:77:24:78:
         4a:e5:a2:81:4d:09:7c:bd:8b:04:f4:b7:fd:34:aa:8b:ec:53:
         fb:56:84:06:c3:e9:9b:37:0d:04:cf:dc:ea:ce:a3:01:99:33:
         f4:53:39:e8:0d:36:b1:74:5a:69:a0:29:d5:cf:2f:57:4c:a4:
         7c:c3:71:8d:f7:85:f5:27:4a:62:cf:75:e3:d1:bc:62:b5:04:
         90:4d:3c:5c:20:cf:42:cb:34:7e:30:b0:c4:1a:51:90:0a:0c:
         20:45:62:1a:51:d1:1d:2f:64:02:22:5e:69:9f:8f:01:48:2e:
         d2:05:3f:c0:07:bf:d0:d1:03:cd:29:19:c1:65:c7:73:aa:be:
         ec:0f:2b:70:b3:ce:94:94:a6:16:8b:8c:24:7a:10:e7:80:1c:
         6d:59:30:bb:1d:d3:be:d7:52:24:ec:25:fb:a0:40:b8:56:c8:
         1f:4f:75:86:35:d7:56:b7:5a:6b:03:44:85:1f:12:49:be:f2:
         04:dc:97:1b:4e:7a:77:ae:24:c3:7e:0f:22:b4:12:ea:8a:80:
         fa:df:1d:63:36:24:46:c3:66:24:ff:2b:24:36:21:cc:78:2a:
         03:d2:29:fe:f6:ce:c7:88:a8:39:d7:38:9b:d7:db:6d:0f:2e:
         5d:dc:42:85:0e:3f:34:52:f7:bb:5e:5e:44:24:a7:26:7c:df:
         5c:74:3a:d9:46:91:d6:07</code>

Generate Certificate & Key for Server

Generate a certificate and private key for the server. On Windows:

build-key-server server

As in the previous step, most parameters can be defaulted. When the Common Name is queried, enter “server”. Two other queries require positive responses,

  • “Sign the certificate? [y/n]”
  • “1 out of 1 certificate requests certified, commit? [y/n]”.

The “build-key-server” command generates server files by first building a Certificate Signing Request (CSR) and then signing the CSR. It issues these OpenSSL commands:

# Build a request for a cert that will be valid for ten years
openssl req -days 3650 -nodes -new -keyout %KEY_DIR%\%1.key -out %KEY_DIR%\%1.csr -config %KEY_CONFIG%
# Sign the cert request with our ca, creating a cert/key pair
openssl ca -days 3650 -out %KEY_DIR%\%1.crt -in %KEY_DIR%\%1.csr -extensions server -config %KEY_CONFIG%

Generate Certificates & Keys for Clients

Generating client certificates is very similar to the previous step. On Windows:

build-key client1

To password-protect your client keys, substitute the build-key-pass script.

Remember that for each client, make sure to type the appropriate Common Name when prompted, i.e. “client1”, “client2”, or “client3”. Always use a unique common name for each client.

The “build-key” command generates client files by first building a Certificate Signing Request (CSR) and then signing the CSR. It issues these OpenSSL commands:

# Build a request for a cert that will be valid for ten years
openssl req -days 3650 -nodes -new -keyout %KEY_DIR%\%1.key -out %KEY_DIR%\%1.csr -config %KEY_CONFIG%
# Sign the cert request with our ca, creating a cert/key pair
openssl ca -days 3650 -out %KEY_DIR%\%1.crt -in %KEY_DIR%\%1.csr -config %KEY_CONFIG%

Clients can generate their own private key locally. To do this they submit a Certificate Signing Request (CSR) to the key signer. The key-signer can then processed the CSR and returned a signed certificate to the client.

Generate Diffie Hellman Parameters

Diffie Hellman parameters must be generated for the OpenVPN server. On Windows:

build-dh

Key Files

Here is an explanation of the relevant files:

Filename Needed By Purpose Secret
ca.crt server + all clients Root CA certificate NO
ca.key key signing machine only Root CA key YES
dh{n}.pem server only Diffie Hellman parameters NO
server.crt server only Server Certificate NO
server.key server only Server Key YES
client1.crt client1 only Client1 Certificate NO
client1.key client1 only Client1 Key YES

DD-WRT Router Setup

From DD-WRT OpenVPN Wiki Page and OpenVPN Remote Access By Static Key (The Simple Way)

Here is another great article on setting up a home OpenVPN server.

When using tunneling mode, to avoid IP address conflicts in a routed configuration:

  • the private LAN IP subnet
  • the VPN subnet
  • the remote LAN subnet

must all be different from each other. I used bridge mode and avoided all the routing stuff.

Choose subnets for the private LAN and the VPN that are unlikely to conflict. I chose 192.168.100.x for my home LAN.

Customizable Web Page Setup Parameters

Settings are stored in NVRAM which is limited in size. Only store the PEM version of keys and certs to save space. If there isn't enough space in NVRAM some of these settings will mysteriously disappear after saving.

Setting Description Default
Start Type Use “System”. “WAN Up” doesnt work.
Server Mode The mode of tunneling. TUN: routing (layer 3), TAP: bridging networks (layer 2).
DHCP-Proxy mode Only in bridge mode. Let the clients use the network DHCP server not the OpenVPN DHCP.
Pool start IP 1st IP of the IP pool used (Only in bridge mode).
Pool end IP Last IP of the IP pool used (Only in bridge mode).
Gateway Default gateway to use (Only in bridge mode).
Network (e.g. 10.10.10.0) Network to use for the tunnel (Only in routing mode).
Netmask (e.g. 255.255.255.0) Netmask of the used network.
Block DHCP across the tunnel Don't allow DHCP requests across tunnel (Only in bridge mode).
Port Port which OpenVPN server listens on. 1194
Tunnel Protocol The subprotocol the connection will use on the real used tcp connection. UDP
Encryption Cipher The encryption algorithm that will be used for the tunnel. Blowfish: fastest to AES512 safest. AES128
Hash Algorithm (None and MD4 to SHA512) The hash algorithm that will be used. MD4: fastest (maybe unsafe) to SHA512. SHA256
Advanced options Leave defaults as is if you dont know what you are doing. disabled
LZO Compression Enables compression over VPN. This might speedup the connection. Must be the same value as on server. yes
Redirect default Gateway Force the clients to use the tunnel as default gateway. disabled
Allow Client to Client Allow clients to see each other. disabled
Allow duplicate cn Allow to use 1 client cert to use on multiple clients (security risk)
TUN MTU Setting Set the MTU of the tunnel 1500
MSS-Fix/Fragment across the tunnel Set mss-fix and fragmentaion accross the tunnel.
TLS Cipher What encryption algorithm OpenVPN should use for encrypting its control channel. disabled
Additional Config Any additional configurations you want to define for the VPN connection.
Public Server Cert Server certificate issued by CA for this particular router (usually server.crt); also only part between 'BEGIN' and 'END' is required.
CA Cert The master key which is used to sign each of the server and client certificates. Certificate in PEM form (usually ca.crt); only part between (and including) —–BEGIN CERTIFICATE—– and —–END CERTIFICATE—– is necessary; as it is stored in NVRAM, everything else from that file should be removed to conserve space.
Private Server Key Key associated with certificate above (usually server.key); should be kept secret because anybody who knows this key can successfully authenticate client certificates.
DH PEM Diffie Hellman parameters generated for the OpenVPN server (usually dh1024.pem)
Additional Config Any additional configurations you want to define for the VPN connection.
TLS Auth Key The static key OpenVPN should use for generating HMAC send/receive keys. For extra security beyond that provided by SSL/TLS, create an “HMAC firewall” to help block DoS attacks and UDP port flooding. The server and each client must have a copy of this key.
Certificate Revoke List

OpenVPN Client Setup

remote nnn.nnn.nnn.nnn
dev tun
ifconfig 192.168.112.2 192.168.112.1
route 192.168.111.0 255.255.255.0
secret secret.key
comp-lzo
keepalive 10 60
ping-timer-rem
persist-tun
persist-key