Aus SchnallIchNet
Wechseln zu: Navigation, Suche

some general things to secure openvpn


to get extra security use a preshared tls-auth key.
this key is generated at server-side and published to all clients...
do NOT create a new key at client-side! this won't work!

create the key (server):

openvpn --genkey --secret ta.key

activate the key at server-side:

tls-auth ta.key 0

be sure to use parameter '0' (zero) at server-side
now copy the ta.key to the client using a secure connection
and add this to the config:

tls-auth ta.key 1

be sure to use parameter '1' (one) at client-side

dh (Diffie hellman parameters)

this will be created seperatly for server and clients.
create the file with:

openssl dhparam -out dh1024.pem 1024

or, if you wand to use 2048-bit key

openssl dhparam -out dh2048.pem 2048

and add it to you config-file (same for server and client):

dh dh1024.pem


dh dh2048.pem


asuming that you added

client-config-dir ccd

to your config at server-side, add the following:


this adds the apropriate routes to the server to route the
rage through the tunnel-interface...

now create a file inside the ccd directory named like the CN of the signed cert.
so if the CN of the cert is CN=openVPN_Good.Boy then create the file ccd/openVPN_Good.Boy
now add the 2 ip's out of the middle of the range:


the client now gets the ip: with a P-t-P/Peer-Address of
you can add additional routes here to push to that client only:

push "route"

this will set a route at client-side to route the range through the tunnel interface...


this is an external script which validates CN's of client-key's
this is to get some more extra-security!!

so put to you server.config:

tls-verify "/etc/openvpn/openvpn-verify-cn /etc/openvpn/valid-CNs"

every time a clients try's to auth with a cert/key the script /etc/openvpn/openvpn-verify-cn is run
with the parameter /etc/openvpn/valid-CNs

valid-CNs contains all CN's i want to allow to connect, e.g.

# this is the cn of "good boy"

the validation script 'openvpn-verify-cn' is this:


# verify-cn -- a sample OpenVPN tls-verify script
# Return 0 if cn matches the common name component of
# X509_NAME_oneline, 1 otherwise.
# For example in OpenVPN, you could use the directive:
#   tls-verify "./verify-cn Test-Client"
# This would cause the connection to be dropped unless
# the client common name is "Test-Client"

die "usage: verify-cn cn certificate_depth X509_NAME_oneline" if (@ARGV != 3);

# Parse out arguments:
#   cn    -- The common name which the client is required to have,
#            taken from the argument to the tls-verify directive
#            in the OpenVPN config file.
#   depth -- The current certificate chain depth.  In a typical
#            bi-level chain, the root certificate will be at level
#            1 and the client certificate will be at level 0.
#            This script will be called separately for each level.
#   x509  -- the X509 subject string as extracted by OpenVPN from
#            the client's provided certificate.
($cnfile, $depth, $x509) = @ARGV;

my @CNs;
open(IN, "<$cnfile") or die("Unable to open CN file: $!\n");
while (<IN>) {
        next if ($_ =~ /^#/);
        next if ($_ eq '');
        push(@CNs, $_);

if ($depth == 0) {
    # If depth is zero, we know that this is the final
    # certificate in the chain (i.e. the client certificate),
    # and the one we are interested in examining.
    # If so, parse out the common name substring in
    # the X509 subject string.

    if ($x509 =~ /\/CN=([^\/]+)/) {
        # Accept the connection if the X509 common name
        # string matches the passed cn argument.
        my $x509_cn = $1;

        foreach my $validCn (@CNs) {
                if ($x509_cn =~ m/^${validCn}$/s) {
                    exit 0;

    # Authentication failed -- Either we could not parse
    # the X509 subject string, or the common name in the
    # subject string didn't match the passed cn argument.
    exit 1;

# If depth is nonzero, tell OpenVPN to continue processing
# the certificate chain.
exit 0;