User Tools

Site Tools


OpenVPN config examples

Links to local pages:

These are examples of OpenVPN ( which I have used myself frequently.

Static-key point-to-point mode

The static-key mode is a quick-and-dirty way to build a VPN tunnel.

  • it is fast if you want to make just one tunnel.
  • it would be inefficient if you want to have multiple client tunnels to connect to one server.


You need to create a static key with command:


openvpn --genkey --secret static.key

Then copy this key to both client/server.


# run with: openvpn --config server-static.conf

mode p2p  # default
proto udp # default
dev tun   # default
port 1194 # default - server will listen on all interfaces, on this port
dev tun
ifconfig # first Tunnel-IP is local, 2nd Tunnel-IP is remote
verb 3
secret static.key # openvpn --genkey --secret static.key
keepalive 10 60


# run with: openvpn --config client-static.conf

mode p2p  # default
proto udp # default
dev tun   # default
remote 1194 # client will connect to this (server) IP + port
ifconfig # first Tunnel-IP is local, 2nd Tunnel-IP is remote
verb 3
secret static.key
keepalive 10 60
explicit-exit-notify 2

Server TLS mode no-client-auth


  • will accept multiple clients to one server instance
  • will automatically assign an IP address to the client from a pool
    (like DHCP, actually more like PPP)
  • can allow communications between clients
  • is easy to setup: all clients have the same config file and cert/key
  • very secure at the cryptographic level


  • overall security is 'medium' because all clients are the same, so there is no individual authentication *1)
  • IP-addresses are allocated from a pool, so no guarantee which address is given. (possible different IP at next login).

*1) this is like the WPA-PSK mode in Wireless LANs, i.e. all clients have the same key, in contrast to the WPA-mode with IEEE802.1x+RADIUS where every client has its own unique username/password or other authentication.

NOTE that the client-tls.conf is the same for every client.


# OpenVPN config "server-tls.conf"
# test using: openvpn –-config server-tls.conf

proto udp #default
dev tun   #default
port 1194 #default
management 1194

# Tunnel IP-number plan:
# network:    all tunnel-endpoints (TEPs)
# IP:       server
# IP:       server   p2p address (not-used)
# IP:       client-1 p2p address (not-used)
# IP:       client-1
# IP:       client-2 p2p address (not-used)
# IP:      client-2
# IP:      client-3 p2p address (not-used)
# IP:      client-3
# etc...                  This setup allows (2^(32-24)/4)-1=63 clients

server # the server Tunnel-IP will be .1

# The 'server' command also established a pool of Tunnel-IPs for the clients (like DHCP)

#route # this command is implicit with 'server' command

cd /etc/openvpn/projectname/
log /var/log/openvpn-projectname.log

ca       ca.projectname.crt
cert     server.projectname.crt
key      server.projectname.key
dh       dh1024.projectname.pem
tls-auth ta.projectname.key 0 # Use 0=server, 1=client

verb 3
keepalive 10 60

duplicate-cn # needed if all clients use same client.crt/key

# Uncomment following line if you want to allow client-to-client traffic:
# (dont use this option if you want to filter the client-to-client packets via iptables)

#push "route" # this is done automatically with client-to-client command (else do specify)

# end of "server-tls.conf"


# OpenVPN config "client-tls.conf"
# run with: openvpn –config client-tls.conf

proto udp #default
dev tun   #default
remote 1194

cd /etc/openvpn/projectname/
log /var/log/openvpn-projectname.log

ca       ca.projectname.crt
cert     client.projectname.crt
key      client.projectname.key
tls-auth ta.projectname.key 1 # Use 0=server, 1=client

# Verify that we are connected with the correct server:

tls-remote "server.projectname"
ns-cert-type    server

verb 3
keepalive 10 60
explicit-exit-notify 2

# end of "client-tls.conf"

Example certs/keys

The “server” mode uses TLS (standardized and enhanced version of SSL) and needs X.509 certificates and keys.

You can use these example certs/keys, which are packaged with openvpn.

Use this for testing only, because everybody would have these certs/keys!

cd /usr/share/doc/openvpn-2.0.9/sample-keys/

Manually create certs/keys using OpenSSL

Or generate all self with these commands (recommended!):

Set the parameters first

# personalize these exports:

export tls_projectname="projectname"
export tls_cert_dir="/etc/openvpn/$tls_projectname/certs/"
export tls_ca_CN="ca.$tls_projectname"
export tls_country="CO"
export tls_province="Province"
export tls_city="City"
export tls_organization="Organisation"
export tls_email=""
export tls_server_CN="server.$tls_projectname"
export tls_client_CN="client.$tls_projectname"

Generate the openssl.cnf file using above export

Save this text to a file, using copy/paste:

# rm -rf "$tls_cert_dir/"
mkdir -pv "$tls_cert_dir/"
cd "$tls_cert_dir/"
chmod go-rwx "$tls_cert_dir/"
touch "$tls_cert_dir/index.txt"
echo 01 > "$tls_cert_dir/serial"
cat > "$tls_cert_dir/"
# run this script to generate "openssl.cnf" using the previously exported values
cat > openssl.cnf <<HERE
# OpenSSL configuration file.
#generated using these variables:
#export tls_projectname="$tls_projectname"
#export tls_cert_dir="$tls_cert_dir"
#export tls_ca_CN="$tls_ca_CN"
#export tls_country="$tls_country"
#export tls_province="$tls_province"
#export tls_city="$tls_city"
#export tls_organization="$tls_organization"
#export tls_email="$tls_email"
#export tls_server_CN="$tls_server_CN"
#export tls_client_CN="$tls_client_CN"
HOME = "$tls_cert_dir"
RANDFILE = \$HOME/random
oid_section = new_oids

[ new_oids ]
[ ca ]
default_ca = CA_default

[ CA_default ]
dir = \$HOME
certs = \$dir
crl_dir = \$dir
database = \$dir/index.txt
new_certs_dir = \$dir
certificate = \$dir/$tls_ca_CN.crt
private_key = \$dir/$tls_ca_CN.key
serial = \$dir/serial
crl = \$dir/crl.pem
RANDFILE = \$dir/.rand
x509_extensions = usr_cert
default_days = 3650
default_crl_days= 30
default_md = md5
preserve = no
policy = policy_match

[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ req ]
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca
string_mask = nombstr

[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = "$tls_country"
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = "$tls_province"
localityName = Locality Name (eg, city)
localityName_default = "$tls_city"
0.organizationName = Organization Name (eg, company)
0.organizationName_default = "$tls_organization"
organizationalUnitName = Organizational Unit Name (eg, section)
commonName = Common Name (eg, your name or your server\'s hostname)
commonName_max = 64
commonName_default = "$tls_ca_CN"
emailAddress = Email Address
emailAddress_default = "$tls_email"
emailAddress_max = 40

[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name

[ usr_cert ]
nsComment = "OpenSSL Generated Certificate"

[ server ]
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment

[ v3_ca ]
basicConstraints = CA:true

[ crl_ext ]

# end of ""

Then run this code to generate the directory and openssl.cnf file:

chmod +x

Generate CA cert/key

# note: we don't need '-newkey rsa:2048 ' because config-file.default_bits = 2048

cd $tls_cert_dir/ ;
/usr/bin/openssl req            \
  -days 3650 -nodes -new -x509  \
  -keyout "$tls_ca_CN.key"      \
  -out "$tls_ca_CN.crt"         \
  -config $tls_cert_dir/openssl.cnf \
  -batch                        \
  -subj "/C=$tls_country/ST=$tls_province/L=$tls_city/O=$tls_organization/CN=$tls_ca_CN/emailAddress=$tls_email" \
/bin/chmod 0600 "$tls_ca_CN.key" ;

Generate Server cert/key

cd $tls_cert_dir/  ;
/usr/bin/openssl req -days 3650 -nodes -new \
  -keyout $tls_server_CN.key                    \
  -out $tls_server_CN.csr                       \
  -extensions server                        \
  -config $tls_cert_dir/openssl.cnf             \
  -batch                                    \
  -subj "/C=$tls_country/ST=$tls_province/L=$tls_city/O=$tls_organization/CN=$tls_server_CN/emailAddress=$tls_email"
/usr/bin/openssl ca -days 3650  \
  -out $tls_server_CN.crt           \
  -in $tls_server_CN.csr            \
  -extensions server            \
  -config $tls_cert_dir/openssl.cnf \
/bin/chmod 0600 $tls_server_CN.key

Generate Client cert/key

NOTE: this code is the same as the Server above, except the paramter “extension server”

cd $tls_cert_dir/  ;
/usr/bin/openssl req -days 3650 -nodes -new \
  -keyout $tls_client_CN.key                    \
  -out $tls_client_CN.csr                       \
  -config $tls_cert_dir/openssl.cnf             \
  -batch                                    \
  -subj "/C=$tls_country/ST=$tls_province/L=$tls_city/O=$tls_organization/CN=$tls_client_CN/emailAddress=$tls_email"
/usr/bin/openssl ca -days 3650  \
  -out $tls_client_CN.crt           \
  -in $tls_client_CN.csr            \
  -config $tls_cert_dir/openssl.cnf \
/bin/chmod 0600 $tls_client_CN.key

Check certificates

# View certificates:
openssl x509 -text -noout -in $tls_ca_CN.crt
openssl x509 -text -noout -in $tls_server_CN.crt
openssl x509 -text -noout -in $tls_client_CN.crt
# View CSRs (Certificate Signing Request):
openssl req -text -noout -in $tls_server_CN.csr
openssl req -text -noout -in $tls_client_CN.csr

Generate Diffie-Hellman key

openssl dhparam -out dh1024.$tls_projectname.pem 1024

Generate TLS-Auth Key

openvpn --genkey --secret ta.$tls_projectname.key

Example of iptables

This firewall example allows only ping and SSH between client-server and client-client.

Note that you should not use the 'client-to-client' option in the openvpn-server, because that would forward all packets with the openvpn-process and those packets will never see iptables and therefor make this firewall code useless.

-A INPUT -i tun104 -s -d -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -i tun104 -s -d -p tcp -m tcp --dport 2221 -j ACCEPT
-A INPUT -i tun104 -j DROP
-A FORWARD -i tun104 -o tun104 -s -d -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A FORWARD -i tun104 -o tun104 -s -d -p tcp -m tcp --dport 22 -j ACCEPT
-A FORWARD -i tun104 -j DROP

Server TLS mode with client-auth

This will be added later (contact me if you want help).

  • This config will be similar to above “Server TLS-mode no-client-auth” but the a script is added that check username/password of clients.
  • when a client logs on, a login screen is presented where a username/password needs to be typed.


# Add to above: server-tls.conf

auth-user-pass-verify   /etc/openvpn/scripts/ via-file
client-connect          /etc/openvpn/scripts/
client-disconnect       /etc/openvpn/scripts/

# Required to ..
# Note: client-cert-not-required # DONT - we do require group-cert


# add to above client-tls.conf

/var/www/html/ · Last modified: 2019/03/06 07:33 (external edit)