Network Topology

- from another Router/Network, more or less a Point-To-Point connection with routing. See Blog Post OpenVPN Routed Client Config for OpenWRT
- from my Laptop when i am on a public (hostile) WiFi, called as a RoadWarrior setup
- from my Phone behind degraded LTE/3G and CGNAT networks
Firewall Rule
First we need to make the OpenVPN available on the WAN Port. For this we add a Firewall Rule to /etc/config/firewall.
config 'rule' option 'name' 'openvpn-udp' option 'src' 'wan' option 'target' 'ACCEPT' option 'proto' 'udp' option 'dest_port' '1194'
Generation of Certificates
Import From Future Blog Post to create your own Certificate Authority with a Root CA, different Intermediate CA’s, and Server + Client Certificates.
For this tutorial we need following Certificate and Key files:
- RootCA (CA)
- Intermediate CA (ICA)
- Server Certificate
- Server Cert & Key (+ Client Cert & Keys for Testing)
- CRL File
- TLS-Auth Key
- Diffie Hellman parameters
Keysize
Regarding an ENISA – Algorithms, Key Sizes and Parameters Report keys specified to be at least ten years in use, RSA keys of 3072 bits or more are recommended.
Creation of 4096 bit RSA keys is recommended by me.
https://community.openvpn.net/openvpn/wiki/Hardening#X.509keysize
CA-Chain File
The RootCA and the ICA Certificates should be bundled into a ca-chain.cert file.
cat RootCa.pem IntermediateCA.pem > ca-chain.pem
TLS-Auth Key
openvpn --genkey --secret openvpn/tls-auth.key
DH Parameters
openssl dhparam -out dhparam4096.pem 4096
- Server Certificate 2048 bit => DH 4096 bit
- Server Certificate 4096 bit => DH 8192 bit
Your Server Certificate should have at least 4096 bit in size.
Subnet
The VPN will create a subnet. You should choose a Net which will not overlap with any other Subnet you will possibly encounter. Stay away from 192.168.0.0/24, 192.168.0.0/24 or 10.0.0.0/24 as these nets are often seen to be used for default LAN ranges in home routers.
Multiclient
My assumption was for this tutorial a /29 net. For example any CIDR Net from a private “Class B” Address Range in between 172.16.0.0–172.31.255.255 can be choosen. Class B has not been used that often, at least it seems to me. Just try to pick a “random” net private, which has a rare chance to be unused by others.
CIDR Net Notation: 172.16.10.0/29 Subnet Mask: 255.255.255.248 Broadcast: 172.16.10.7 CIDR Address Range: 172.16.10.0 - 172.16.10.7 Useable Adresses: 6 (1 Server + 5 Clients) Server: 172.16.10.1 Clients: 172.16.10.2 - 172.16.10.6
Point-To-Point
If the VPN is only planned for a Point-To-Point connection between two Routers or for a single Client, a /30 Net should be chosen instead. It is still a MultiClient Net, but with only two Points.
CIDR Net Notation: 172.18.25.64/30 Subnet Mask: 255.255.255.252 Broadcast: 172.18.25.67 CIDR Address Range: 172.18.25.64 - 172.18.25.67 Useable Adresses: 2 (1 Server + 1 Client) Server: 172.18.25.65 Client: 172.18.25.66
OpenWRT OpenVPN Settings
config openvpn 'cyber' option enabled '1' #Protocol option dev_type 'tun' option dev 'cyber_tun0' option topology 'subnet' option proto 'udp' option port '1194' #Routes option server '172.16.10.0 255.255.255.248' option ifconfig '172.16.10.1 255.255.255.248' list push 'route 192.168.100.0 255.255.255.0' #Client Config option ccd_exclusive '1' option client_config_dir '/etc/openvpn/ccd/' option max_clients '5' option client_to_client '1' #Encryption option ca '/etc/ssl/certs/vpn.cavebeat.lan.ca-chain.cert.pem' option cert '/etc/ssl/certs/ptree.vpn.cavebeat.lan.cert.pem' option key '/etc/ssl/private/ptree.vpn.cavebeat.lan.key.pem' option dh '/etc/ssl/dh4096.pem' option tls_crypt '/etc/ssl/tls-auth.key' option cipher 'AES-256-CBC' option auth 'SHA512' option tls_server '1' option tls_version_min '1.2' option tls_cipher ' option reneg_sec '1800' option remote_cert_tls 'client' #Logging option log_append '/var/log/openvpn/openvpn.log' option status '/var/log/openvpn-status.log' option mute '5' option verb '4' #Connection option keepalive '10 60' option compress 'lzo' option script_security '1' #Connection Reliability option persist_key '1' option persist_tun '1' #Permissions option user 'nobody' option group 'nogroup'
The parameter Deprecated OpenVPN Settings
The default value should require to verify the client cert given to the server. I have placed a PullRequest with a change for OpenWRT to add this setting.
Description of used Settings and Parameters
option enabled '1'
Protocol
option dev_type 'tun' --dev-type device-type Which device type are we using? device-type should be tun (OSI Layer 3) or tap (OSI Layer 2). Use this option only if the TUN/TAP device used with --dev does not begin with tun or tap.
option dev 'tun1' --dev tunX | tapX | null tun devices encapsulate IPv4 or IPv6 (OSI Layer 3) while tap devices encapsulate Ethernet 802.3 (OSI Layer 2).
option topology 'subnet' --topology mode Configure virtual addressing topology when running in --dev tun mode. subnet -- Use a subnet rather than a point-to-point topology by configuring the tun interface with a local IP address and subnet mask, similar to the topology used in --dev tap and ethernet bridging mode. This mode allocates a single IP address per connecting client and works on Windows as well. Note: Using --topology subnet changes the interpretation of the arguments of --ifconfig to mean "address netmask", no longer "local remote".
option server '172.16.10.0 255.255.255.248' --server network netmask ['nopool'] A helper directive designed to simplify the configuration of OpenVPN's server mode. This directive will set up an OpenVPN server which will allocate addresses to clients out of the given network/netmask. The server itself will take the ".1" address of the given network for use as the server-side endpoint of the local TUN/TAP interface.
option ifconfig '172.16.10.1 255.255.255.248' --ifconfig l rn Set TUN/TAP adapter parameters. l is the IP address of the local VPN endpoint. For TAP devices, or TUN devices used with --topology subnet,rn is the subnet mask of the virtual network segment which is being created or connected to. For TAP devices, which provide the ability to create virtual ethernet segments, or TUN devices in --topology subnet mode (which create virtual "multipoint networks"), --ifconfig is used to set an IP address and subnet mask just as a physical ethernet adapter would be similarly configured.
list push 'route 192.168.100.0 255.255.255.0' --push option Push a config file option back to the client for remote execution. Note that option must be enclosed in double quotes ("").
Client Config
option client_config_dir '/etc/openvpn/ccd/' --client-config-dir dir Specify a directory dir for custom client config files. After a connecting client has been authenticated, OpenVPN will look in this directory for a file having the same name as the client's X509 common name. If a matching file exists, it will be opened and parsed for client-specific configuration options. If no matching file is found, OpenVPN will instead try to open and parse a default file called "DEFAULT", which may be provided but is not required. Note that the configuration files must be readable by the OpenVPN process after it has dropped it's root privileges.
option ccd_exclusive '1' --ccd-exclusive Require, as a condition of authentication, that a connecting client has a --client-config-dir file.
option max_clients '5' --max-clients n Limit server to a maximum of n concurrent clients.
option client_to_client '0' --client-to-client Because the OpenVPN server mode handles multiple clients through a single tun or tap interface, it is effectively a router. The --client-to-client flag tells OpenVPN to internally route client-to-client traffic rather than pushing all client-originating traffic to the TUN/TAP interface.
Encryption
option ca '/etc/ssl/certs/vpn.cavebeat.lan.ca-chain.cert.pem' --ca file Certificate authority (CA) file in .pem format, also referred to as the root certificate.
option cert '/etc/ssl/certs/ptree.vpn.cavebeat.lan.cert.pem' --cert file Local peer's signed certificate in .pem format -- must be signed by a certificate authority whose certificate is in --ca file. Each peer in an OpenVPN link running in TLS mode should have its own certificate and private key file. In addition, each certificate should have been signed by the key of a certificate authority whose public key resides in the --ca certificate authority file.
option key '/etc/ssl/private/ptree.vpn.cavebeat.lan.key.pem' --key file Local peer's private key in .pem format.
option dh '/etc/ssl/dh4096.pem' --dh file File containing Diffie Hellman parameters in .pem format (required for --tls-server only).
option tls_crypt '/etc/ssl/tls-auth.key' --tls-auth file [direction] Add an additional layer of HMAC authentication on top of the TLS control channel to mitigate DoS attacks and attacks on the TLS stack. In a nutshell, --tls-auth enables a kind of "HMAC firewall" on OpenVPN's TCP/UDP port, where TLS control channel packets bearing an incorrect HMAC signature can be dropped immediately without response. file (required) is a file in OpenVPN static key format which can be generated by --genkey Use --tls-crypt instead if you want to use the key file to not only authenticate, but also encrypt the TLS control channel. --tls-crypt keyfile Encrypt and authenticate all control channel packets with the key from keyfile. (See --tls-auth for more background.) Encrypting (and authenticating) control channel packets: + provides more privacy by hiding the certificate used for the TLS connection, + makes it harder to identify OpenVPN traffic as such, + provides "poor-man's" post-quantum security, against attackers who will never know the pre-shared key (i.e. no forward secrecy). In contrast to --tls-auth, --tls-crypt does *not* require the user to set --key-direction.
option cipher 'AES-256-CBC' --cipher alg Encrypt data channel packets with cipher algorithm alg.
option auth 'SHA512' --auth alg Authenticate data channel packets and (if enabled) tls-auth control channel packets with HMAC using message digest algorithm alg. If an AEAD cipher mode (e.g. GCM) is chosen, the specified --auth algorithm is ignored for the data channel, and the authentication method of the AEAD cipher is used instead. Note that alg still specifies the digest used for tls-auth.
option tls_server '1' --tls-server Enable TLS and assume server role during TLS handshake.
option tls_version_min '1.2' --tls-version-min version ['or-highest'] Sets the minimum TLS version we will accept from the peer (default is "1.0"). Examples for version include "1.0", "1.1", or "1.2". https://community.openvpn.net/openvpn/wiki/Hardening#Useof--tls-version-min Since OpenVPN 2.3.3, the --tls-version-min option is available to enforce a minimum TLS version. Hardened setups should set --tls-version-min to 1.2 if possible. But be aware that setting tls-version-min to 1.2 will make it impossible to connect for pre-2.3.3 clients
option tls_cipher ' --tls-cipher l A list l of allowable TLS ciphers delimited by a colon (":"). This setting can be used to ensure that certain cipher suites are used (or not used) for the TLS connection. You should use a DHE cipher-suite as well for forward-secrecy. https://community.openvpn.net/openvpn/wiki/Hardening#Useof--tls-cipher To use ECDH(E) or ECDSA cipher-suites, both client and server must be OpenVPN 2.4.0 or newer.
option reneg_sec '3600' --reneg-sec n Renegotiate data channel key after n seconds (default=3600).
option remote_cert_tls 'server' --remote-cert-tls client|server Require that peer certificate was signed with an explicit key usage and extended key usage based on RFC3280 TLS rules.
Logging
option log_append '/var/log/openvpn/openvpn.log' --log-append file Append logging messages to file. If file does not exist, it will be created. This option behaves exactly like --log except that it appends to rather than truncating the log file. --log file Output logging messages to file, including output to stdout/stderr which is generated by called scripts. If file already exists it will be truncated.
option status '/var/log/openvpn-status.log' --status file [n] Write operational status to file every n seconds.
option mute '4' --mute n Log at most n consecutive messages in the same category. This is useful to limit repetitive logging of similar message types.
option verb '4' --verb n Set output verbosity to n (default=1). Each level shows all info from the previous levels. Level 3 is recommended if you want a good summary of what's happening without being swamped by output. - 0 -- No output except fatal errors. - 1 to 4 -- Normal usage range.
Connection
option keepalive '10 60' --keepalive interval timeout A helper directive designed to simplify the expression of --ping and --ping-restart. This option can be used on both client and server side, but it is in enough to add this on the server side as it will push appropriate --ping and --ping-restart options to the client. --ping n Ping remote over the TCP/UDP control channel if no packets have been sent for at least n seconds --ping-restart n Restart after n seconds pass without reception of a ping or other packet from remote. In server mode, --ping-restart, --inactive, or any other type of internally generated signal will always be applied to individual client instance objects, never to whole server itself. Note also in server mode that any internally generated signal which would normally cause a restart, will cause the deletion of the client instance object instead.
option compress 'lzo' --compress [algorithm] Enable a compression algorithm. The algorithm parameter may be "lzo", "lz4", or empty. LZO and LZ4 are different compression algorithms, with LZ4 generally offering the best performance with least CPU usage. For backwards compatibility with OpenVPN versions before v2.4, use "lzo" (which is identical to the older option "--comp-lzo yes").
option script_security '1' --script-security level This directive offers policy-level control over OpenVPN's usage of external programs and scripts. Lower level values are more restrictive, higher values are more permissive. Settings for level: 0 -- Strictly no calling of external programs. 1 -- (Default) Only call built-in executables such as ifconfig, ip, route, or netsh. 2 -- Allow calling of built-in executables and user-defined scripts. 3 -- Allow passwords to be passed to scripts via environmental variables (potentially unsafe).
Connection Reliability
option persist_key '1' --persist-key Don't re-read key files across SIGUSR1 or --ping-restart. This option can be combined with --user nobody to allow restarts triggered by the SIGUSR1 signal. Normally if you drop root privileges in OpenVPN, the daemon cannot be restarted since it will now be unable to re-read protected key files.
option persist_tun '1' --persist-tun Don't close and reopen TUN/TAP device or run up/down scripts across SIGUSR1 or --ping-restart restarts.
Permissions
option user 'nobody' --user user Change the user ID of the OpenVPN process to user after initialization, dropping privileges in the process.
option group 'nogroup' --group group Similar to the --user option, this option changes the group ID of the OpenVPN process to group after initialization.