EasyRSA: Difference between revisions

From Lolly's Wiki
Jump to navigationJump to search
No edit summary
m (Text replacement - "[[Kategorie:" to "[[Category:")
 
(8 intermediate revisions by the same user not shown)
Line 1: Line 1:
[[Kategorie: Security]]
[[Category: Security]]
[[Kategorie: Linux]]
[[Category: Linux]]
 
=create CA user=
 
<syntaxhighlight lang=bash>
# groupadd -g 22000 ca && adduser --uid 22000 --gid 22000 --gecos "CA user" --encrypt-home ca
</syntaxhighlight>
 
=Do everything CA specific as CA user!=
<syntaxhighlight lang=bash>
# su - ca
ca@rzeasyrsa:~$ ecryptfs-mount-private
ca@rzeasyrsa:~$ cd
ca@rzeasyrsa:~$ exec bash
</syntaxhighlight>
 
=Setup EasyRSA=
 
==Ubuntu packets==
<syntaxhighlight lang=bash>
# aptitude install openvpn easy-rsa
</syntaxhighlight>
 
==Create your CA==
<syntaxhighlight lang=bash>
mkdir --mode=0700 OpenVPN-CA
cd OpenVPN-CA
for i in /usr/share/easy-rsa/* ; do ln -s $i ; done
rm -f vars clean-all
cp /usr/share/easy-rsa/vars .
</syntaxhighlight>
 
==Edit the defaults==
Setup proper defaults in your vars file.
Source it every time before you do CA work.
 
==Base setup (Only one time at the beginning!!!)==
 
'''Really just do this before you start with your CA. It will delete everything: keys and certificates!!!'''
$ cd OpenVPN-CA
$ . vars
$ /usr/share/easy-rsa/clean-all
 
==Generate DH parameter==
$ cd OpenVPN-CA
$ . vars
$ KEY_SIZE=4096 ./build-dh
or
$ cd OpenVPN-CA/keys
$ openssl dhparam -2 -out dh4096.pem 4096
 
==Generate TLS-auth parameter==
$ cd OpenVPN-CA/keys
$ /usr/sbin/openvpn --genkey --secret ta.key


==User certificates with passwords in scripts==
==User certificates with passwords in scripts==
If you want to work with password encrypted keys and wat to batch process many users, you might find this helpful.


Add a line after <i># output_password = secret</i>:
Add a line after <i># output_password = secret</i>:
<source lang=bash>
<syntaxhighlight lang=bash>
# output_password = secret
# output_password = secret
output_password = $ENV::KEY_PASS
output_password = $ENV::KEY_PASS
</source>
</syntaxhighlight>


After that the openssl calls taking the needed password from the environment variable <i>KEY_PASS</i>.
After that the openssl calls taking the needed password from the environment variable <i>KEY_PASS</i>.


You can call it like this for example:
You can call it like this for example:
<source lang=bash>
<syntaxhighlight lang=bash>
KEY_PASS="password" ./build-key-pass --batch user
KEY_PASS="password" ./build-key-pass --batch user
</source>
</syntaxhighlight>
 
==Create your CA certificate==
$ cd OpenVPN-CA
$ . vars
$ ./buid-ca
 
Check it with
$ openssl x509 -noout -text -in keys/ca.crt
 
==Create the server certificate==
$ cd OpenVPN-CA
$ . vars
$ ./build-key-server openvpn-server
 
For example server keys with 5 years validity:
$ KEY_EXPIRE=1825 ./build-key-server openvpn-server
 
=Create your OpenVPN config=
 
==get_ovpn.sh==
I wrote a little helper script called get_ovpn.sh:
<syntaxhighlight lang=bash>
#!/bin/bash
 
# Written by Lars Timmann L@rs.Timmann.de> 2016
# You may use it for free but on your own risk!!!
 
TYPE="client"
KEY_DIR="OpenVPN-CA/keys"
 
function usage() {
  if [ "_${1}_" != "_help_" ]
  then
    printf "ERROR: $*\n"
  fi
  printf "Options:\n"
  cat <<EOF
  -h|--help                             This help
  -c|--config-type Default: client              (client|server)
  -k|--key-dir Default: OpenVPN-CA/keys    Directory where certificates and keys can be found
  -t|--template Default: ${configtype}.ovpn  The template to use   
  -u|--user                             User to create config for
  -s|--server                             Servername for --config-type=server
  --what-ever=value Replace <WHAT_EVER> in template with value e.g.: --server-net=... replaces <SERVER_NET> with the given value
EOF
  exit 1
}
 
while [ $# -gt 0 ]
do
  #if [ $# -ge 2 ]; then value=$2; fi
  case $1 in
  -h|--help)
    usage "help"
    ;;
  --?*=?*|-?*=?*)
    param=${1%=*}
    value=${1#*=}
    shift;
    ;;
  --?*=|-?*=)
    param=${1%=*}
    usage "${param} needs a vlaue!"
    ;;
  *)
    if [ $# -lt 2 ] ; then usage "$1 needs a value!"; fi
    param=$1
    value=$2
    shift; shift;
    ;;
  esac
 
  case $param in
  -t|--template)
    TEMPLATE=${value}
    ;;
  -k|--key-dir)
    KEY_DIR=${value}
    ;;
  -u|--user)
    OVPN_USER=${value}
    ;;
  -c|--config-type)
    TYPE=${value}
    ;;
  -s|--server-name)
    SERVER=${value}
    ;;
  *)
    param=${param#--}
    param=${param/-/_}
    export ${param^^}=${value}
    ;;
  esac
done
TEMPLATE=${TEMPLATE:-"${TYPE}.ovpn"}
 
[ -z "${SERVER}"    -a "_${TYPE}_" == "_server_" ] && usage "For which server?\n"
[ -z "${OVPN_USER}" -a "_${TYPE}_" == "_client_" ] && usage "For which user?\n"
[ ! -f "${TEMPLATE}" ] && usage "Template file ${TEMPLATE} not found!\n"
[ ! -d "${KEY_DIR}" ] && usage "Key directory ${KEY_DIR} not found!\n"
[ ! -f "${KEY_DIR}/ta.key" ] && usage "TLS Auth ${KEY_DIR}/ta.key not found!\n"
[ ! -f "${KEY_DIR}/ca.crt" ] && usage "CA Certificate ${KEY_DIR}/ca.crt not found!\n"
[ ! -f "${KEY_DIR}/${SERVER}.key" -a "_${TYPE}_" == "_server_" ] && usage "Private key ${KEY_DIR}/${SERVER}.key not found!\n"
[ ! -f "${KEY_DIR}/${SERVER}.crt" -a "_${TYPE}_" == "_server_" ] && usage "Certificate ${KEY_DIR}/${SERVER}.crt not found!\n"
[ ! -f "${KEY_DIR}/${OVPN_USER}.key" -a "_${TYPE}_" == "_client_" ] && usage "Private key ${KEY_DIR}/${OVPN_USER}.key not found!\n"
[ ! -f "${KEY_DIR}/${OVPN_USER}.crt" -a "_${TYPE}_" == "_client_" ] && usage "Certificate ${KEY_DIR}/${OVPN_USER}.crt not found!\n"
 
export SERVER
gawk \
  -v user="${OVPN_USER}" \
  -v key_dir="${KEY_DIR}" \
  -v configtype="${TYPE}" \
  -v server="${SERVER}" \
'
function print_fingerprint(certfile){
  command="openssl x509 -noout -fingerprint -in "certfile;
  FS="=";
  while(command | getline);
  retval=$2;
  close(command);
  return retval;
}
function print_part(part,certfile){
  command="openssl x509 -noout -text -in "certfile;
  while(command | getline){
    if ($1 == part) {
      for(i=2;i<=NF;i++){
        if(i==NF) gsub(/\//,", ", $i)
        retval=retval""$i;
        if(i<NF) retval=retval" ";
      }
    }
  };
  close(command);
  return retval;
}
function print_cert(name,certfile){
  # Header
  #printf "# %s\n",certfile;
  while(getline < certfile){if(/^#/) print $0};
  close(certfile);
  printf "<%s>\n",name;
  while(getline < certfile){if(!/^#/) print $0};
  close(certfile);
  printf "</%s>\n",name;
}
{
  # Static part
  rest=$0;
  while(match(rest,/<[A-Z0-9_]+>/)) {
    matched=substr(rest,RSTART+1,RLENGTH-2);
    ##print "Matched:",matched;
    if (ENVIRON[matched]) gsub("<"matched">",ENVIRON[matched]);
    rest=substr(rest,RSTART+RLENGTH);
  }
  print $0;
}
END{
  # Dynamic part
  if(configtype=="client") {
    printf "remote-cert-tls server\n";
  } else {
    printf "remote-cert-tls client\n";
  }
 
  # TLS Auth
  print_cert("tls-auth",key_dir"/ta.key");
  printf "key-direction %d\n",(configtype=="client");
  printf "\n";
 
  print_cert("dh",key_dir"/dh4096.pem");
  printf "\n";
 
  # Ca Certificate
  if (configtype=="client") {
    printf "verify-x509-name \"%s\"\n",print_part("Subject:",key_dir"/"server".crt");
  }
  printf "verify-hash %s\n",print_fingerprint(key_dir"/ca.crt");
  print_cert("ca",key_dir"/ca.crt");
  printf "\n";
 
  # User Data
  if (configtype=="client") {
    print_cert("cert",key_dir"/"user".crt");
    printf "\n";
    print_cert("key",key_dir"/"user".key");
    printf "\n";
  } else {
    print_cert("cert",key_dir"/"server".crt");
    printf "\n";
    # key secret/<SERVER>.key is in template
  }
  #print ENVIRON["SERVER_NET"];
}' ${TEMPLATE}
</syntaxhighlight>
 
ca@rzeasyrsa:~$ ./get_ovpn.sh --help
Options:
  -h|--help                             This help
  -c|--config-type Default: client              (client|server)
  -k|--key-dir Default: OpenVPN-CA/keys    Directory where certificates and keys can be found
  -t|--template Default: .ovpn  The template to use   
  -u|--user                             User to create config for
  -s|--server                             Servername for --config-type=server
  --what-ever=value Replace <WHAT_EVER> in template with value e.g.: --server-net=... replaces <SERVER_NET> with the given value
 
==OpenVPN Server ==
===OpenVPN Server Template===
 
# I am using the mysql-auth-plugin from [https://github.com/chantra/openvpn-mysql-auth https://github.com/chantra/openvpn-mysql-auth]
# On the OpenVPN-Server the user openvpn has uid 1195 and gid 1195 and I have a TMP-dir for this user in the /etc/fstab like this:
none            /run/openvpn_tmp                tmpfs          nodev,noexec,nosuid,size=5m,mode=0700,uid=1195,gid=1195 0 0
 
 
Example server.ovpn:
<pre>
local <SERVER_IP>
port <SERVER_PORT>
tmp-dir /run/openvpn_tmp
management <MANAGEMENT_IP> <MANAGEMENT_PORT> /etc/openvpn/management-password
proto udp
dev tun
tun-mtu 1500
mssfix
 
topology subnet
server <SERVER_NET> <SERVER_NETMASK>
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS <DNS1>"
push "dhcp-option DNS <DNS2>"
 
push "route 192.168.18.0 255.255.255.0 net_gateway"
push "route 192.168.0.0 255.255.0.0"
push "route 10.0.0.0 255.0.0.0"
push "route 172.28.0.0 255.255.0.0"
 
client-to-client
duplicate-cn
keepalive 10 120
auth  SHA512
cipher AES-256-CBC
tls-cipher DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-RSA-AES128-SHA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA
reneg-sec 36000
comp-lzo adaptive
max-clients 25
user openvpn
group openvpn
persist-key
persist-tun
 
status /var/log/openvpn/<SERVER>-status.log 2
status-version 2
log-append  /var/log/openvpn/<SERVER>-openvpn.log
verb 3
plugin /usr/lib/openvpn/libopenvpn-mysql-auth.so -c /etc/openvpn/auth/<SERVER>_auth_mysql.conf
 
key secret/<SERVER>.key  # This file should be kept secret
 
remote-cert-tls client
username-as-common-name
</pre>
 
===Generate OpenVPN Config for server===
<syntaxhighlight lang=bash>
ca@rzeasyrsa:~$ ./get_ovpn.sh  \
  --server openvpn \
  --config-type server \
  --server-ip=192.168.18.23 \
  --server-port=1234 \
  --server-net=10.214.60.128 \
  --server-netmask=255.255.255.128 \
  --management-ip=192.168.17.23 \
  --management-port=11234 \
  --dns1=192.168.0.50 \
  --dns2=192.168.0.30 \
  --template server.ovpn \
  --key-dir=OpenVPN-CA/keys
</syntaxhighlight>
 
==OpenVPN Client==
===OpenVPN client template===
Example client.ovpn:
<pre>
client
dev tun
proto udp
remote <SERVER_IP> <SERVER_PORT>
tls-client
ns-cert-type server
comp-lzo
 
auth-user-pass
auth  SHA512
cipher AES-256-CBC
tls-cipher DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-RSA-AES128-SHA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA
#tls-version-min 1.2


This is useful for batch generation of many client certificates.
route-delay 5 30
persist-key
persist-tun
nobind
mssfix
push-peer-info
reneg-sec 0
tun-mtu 1500
verb 3
#auth-nocache
</pre>
===Generate OpenVPN Config for server===
<syntaxhighlight lang=bash>
ca@rzeasyrsa:~$ ./get_ovpn.sh  \
  --config-type client \
  --server-ip  192.168.18.23 \
  --server-port 1234 \
  --template    client.ovpn \
  --key-dir    OpenVPN-CA/keys \
  --user        vpnclient
</syntaxhighlight>

Latest revision as of 04:54, 26 November 2021


create CA user

# groupadd -g 22000 ca && adduser --uid 22000 --gid 22000 --gecos "CA user" --encrypt-home ca

Do everything CA specific as CA user!

# su - ca
ca@rzeasyrsa:~$ ecryptfs-mount-private 
ca@rzeasyrsa:~$ cd 
ca@rzeasyrsa:~$ exec bash

Setup EasyRSA

Ubuntu packets

# aptitude install openvpn easy-rsa

Create your CA

mkdir --mode=0700 OpenVPN-CA
cd OpenVPN-CA
for i in /usr/share/easy-rsa/* ; do ln -s $i ; done
rm -f vars clean-all
cp /usr/share/easy-rsa/vars .

Edit the defaults

Setup proper defaults in your vars file. Source it every time before you do CA work.

Base setup (Only one time at the beginning!!!)

Really just do this before you start with your CA. It will delete everything: keys and certificates!!!

$ cd OpenVPN-CA
$ . vars
$ /usr/share/easy-rsa/clean-all

Generate DH parameter

$ cd OpenVPN-CA
$ . vars
$ KEY_SIZE=4096 ./build-dh

or

$ cd OpenVPN-CA/keys
$ openssl dhparam -2 -out dh4096.pem 4096

Generate TLS-auth parameter

$ cd OpenVPN-CA/keys
$ /usr/sbin/openvpn --genkey --secret ta.key

User certificates with passwords in scripts

If you want to work with password encrypted keys and wat to batch process many users, you might find this helpful.

Add a line after # output_password = secret:

# output_password = secret
output_password = $ENV::KEY_PASS

After that the openssl calls taking the needed password from the environment variable KEY_PASS.

You can call it like this for example:

KEY_PASS="password" ./build-key-pass --batch user

Create your CA certificate

$ cd OpenVPN-CA
$ . vars
$ ./buid-ca

Check it with

$ openssl x509 -noout -text -in keys/ca.crt

Create the server certificate

$ cd OpenVPN-CA
$ . vars
$ ./build-key-server openvpn-server

For example server keys with 5 years validity:

$ KEY_EXPIRE=1825 ./build-key-server openvpn-server

Create your OpenVPN config

get_ovpn.sh

I wrote a little helper script called get_ovpn.sh:

#!/bin/bash

# Written by Lars Timmann L@rs.Timmann.de> 2016
# You may use it for free but on your own risk!!!

TYPE="client"
KEY_DIR="OpenVPN-CA/keys"

function usage() {
  if [ "_${1}_" != "_help_" ]
  then
    printf "ERROR: $*\n"
  fi
  printf "Options:\n"
  cat <<EOF
  -h|--help		                             This help
  -c|--config-type	Default: client              (client|server)
  -k|--key-dir		Default: OpenVPN-CA/keys     Directory where certificates and keys can be found
  -t|--template		Default: ${configtype}.ovpn  The template to use     
  -u|--user		                             User to create config for
  -s|--server		                             Servername for --config-type=server
  --what-ever=value	Replace <WHAT_EVER> in template with value e.g.: --server-net=... replaces <SERVER_NET> with the given value
EOF
  exit 1
}

while [ $# -gt 0 ]
do
  #if [ $# -ge 2 ]; then value=$2; fi
  case $1 in
  -h|--help)
    usage "help"
    ;;
  --?*=?*|-?*=?*)
    param=${1%=*}
    value=${1#*=}
    shift;
    ;;
  --?*=|-?*=)
    param=${1%=*}
    usage "${param} needs a vlaue!"
    ;;
  *)
    if [ $# -lt 2 ] ; then usage "$1 needs a value!"; fi
    param=$1
    value=$2
    shift; shift;
    ;;
  esac

  case $param in
  -t|--template)
    TEMPLATE=${value}
    ;;
  -k|--key-dir)
    KEY_DIR=${value}
    ;;
  -u|--user)
    OVPN_USER=${value}
    ;;
  -c|--config-type)
    TYPE=${value}
    ;;
  -s|--server-name)
    SERVER=${value}
    ;;
  *)
    param=${param#--}
    param=${param/-/_}
    export ${param^^}=${value}
    ;;
  esac
done
TEMPLATE=${TEMPLATE:-"${TYPE}.ovpn"}

[ -z "${SERVER}"    -a "_${TYPE}_" == "_server_" ] && usage "For which server?\n" 
[ -z "${OVPN_USER}" -a "_${TYPE}_" == "_client_" ] && usage "For which user?\n" 
[ ! -f "${TEMPLATE}" ] && usage "Template file ${TEMPLATE} not found!\n"
[ ! -d "${KEY_DIR}" ] && usage "Key directory ${KEY_DIR} not found!\n"
[ ! -f "${KEY_DIR}/ta.key" ] && usage "TLS Auth ${KEY_DIR}/ta.key not found!\n"
[ ! -f "${KEY_DIR}/ca.crt" ] && usage "CA Certificate ${KEY_DIR}/ca.crt not found!\n"
[ ! -f "${KEY_DIR}/${SERVER}.key" -a "_${TYPE}_" == "_server_" ] && usage "Private key ${KEY_DIR}/${SERVER}.key not found!\n"
[ ! -f "${KEY_DIR}/${SERVER}.crt" -a "_${TYPE}_" == "_server_" ] && usage "Certificate ${KEY_DIR}/${SERVER}.crt not found!\n"
[ ! -f "${KEY_DIR}/${OVPN_USER}.key" -a "_${TYPE}_" == "_client_" ] && usage "Private key ${KEY_DIR}/${OVPN_USER}.key not found!\n"
[ ! -f "${KEY_DIR}/${OVPN_USER}.crt" -a "_${TYPE}_" == "_client_" ] && usage "Certificate ${KEY_DIR}/${OVPN_USER}.crt not found!\n"

export SERVER
gawk \
  -v user="${OVPN_USER}" \
  -v key_dir="${KEY_DIR}" \
  -v configtype="${TYPE}" \
  -v server="${SERVER}" \
'
function print_fingerprint(certfile){
  command="openssl x509 -noout -fingerprint -in "certfile;
  FS="=";
  while(command | getline);
  retval=$2;
  close(command);
  return retval;
}
function print_part(part,certfile){
  command="openssl x509 -noout -text -in "certfile;
  while(command | getline){
    if ($1 == part) {
      for(i=2;i<=NF;i++){
        if(i==NF) gsub(/\//,", ", $i)
        retval=retval""$i;
        if(i<NF) retval=retval" ";
      }
    }
  };
  close(command);
  return retval;
}
function print_cert(name,certfile){
  # Header
  #printf "# %s\n",certfile;
  while(getline < certfile){if(/^#/) print $0};
  close(certfile);
  printf "<%s>\n",name;
  while(getline < certfile){if(!/^#/) print $0};
  close(certfile);
  printf "</%s>\n",name;
}
{
  # Static part
  rest=$0;
  while(match(rest,/<[A-Z0-9_]+>/)) {
    matched=substr(rest,RSTART+1,RLENGTH-2);
    ##print "Matched:",matched;
    if (ENVIRON[matched]) gsub("<"matched">",ENVIRON[matched]);
    rest=substr(rest,RSTART+RLENGTH);
  }
  print $0;
}
END{
  # Dynamic part
  if(configtype=="client") {
    printf "remote-cert-tls server\n";
  } else {
    printf "remote-cert-tls client\n";
  }

  # TLS Auth
  print_cert("tls-auth",key_dir"/ta.key");
  printf "key-direction %d\n",(configtype=="client");
  printf "\n";

  print_cert("dh",key_dir"/dh4096.pem");
  printf "\n";

  # Ca Certificate
  if (configtype=="client") {
    printf "verify-x509-name \"%s\"\n",print_part("Subject:",key_dir"/"server".crt");
  }
  printf "verify-hash %s\n",print_fingerprint(key_dir"/ca.crt");
  print_cert("ca",key_dir"/ca.crt");
  printf "\n";

  # User Data
  if (configtype=="client") {
    print_cert("cert",key_dir"/"user".crt");
    printf "\n";
    print_cert("key",key_dir"/"user".key");
    printf "\n";
  } else {
    print_cert("cert",key_dir"/"server".crt");
    printf "\n";
    # key secret/<SERVER>.key is in template
  }
  #print ENVIRON["SERVER_NET"];
}' ${TEMPLATE}
ca@rzeasyrsa:~$ ./get_ovpn.sh --help
Options:
  -h|--help		                             This help
  -c|--config-type	Default: client              (client|server)
  -k|--key-dir		Default: OpenVPN-CA/keys     Directory where certificates and keys can be found
  -t|--template		Default: .ovpn  The template to use     
  -u|--user		                             User to create config for
  -s|--server		                             Servername for --config-type=server
  --what-ever=value	Replace <WHAT_EVER> in template with value e.g.: --server-net=... replaces <SERVER_NET> with the given value

OpenVPN Server

OpenVPN Server Template

  1. I am using the mysql-auth-plugin from https://github.com/chantra/openvpn-mysql-auth
  2. On the OpenVPN-Server the user openvpn has uid 1195 and gid 1195 and I have a TMP-dir for this user in the /etc/fstab like this:
none            /run/openvpn_tmp                 tmpfs           nodev,noexec,nosuid,size=5m,mode=0700,uid=1195,gid=1195 0 0


Example server.ovpn:

local <SERVER_IP>
port <SERVER_PORT>
tmp-dir /run/openvpn_tmp
management <MANAGEMENT_IP> <MANAGEMENT_PORT> /etc/openvpn/management-password
proto udp
dev tun
tun-mtu 1500
mssfix

topology subnet
server <SERVER_NET> <SERVER_NETMASK>
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS <DNS1>"
push "dhcp-option DNS <DNS2>"

push "route 192.168.18.0 255.255.255.0 net_gateway"
push "route 192.168.0.0 255.255.0.0"
push "route 10.0.0.0 255.0.0.0"
push "route 172.28.0.0 255.255.0.0"

client-to-client
duplicate-cn
keepalive 10 120
auth   SHA512
cipher AES-256-CBC
tls-cipher DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-RSA-AES128-SHA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA
reneg-sec 36000
comp-lzo adaptive
max-clients 25
user openvpn
group openvpn
persist-key
persist-tun

status /var/log/openvpn/<SERVER>-status.log 2
status-version 2
log-append  /var/log/openvpn/<SERVER>-openvpn.log
verb 3
plugin /usr/lib/openvpn/libopenvpn-mysql-auth.so -c /etc/openvpn/auth/<SERVER>_auth_mysql.conf

key secret/<SERVER>.key  # This file should be kept secret

remote-cert-tls client
username-as-common-name

Generate OpenVPN Config for server

ca@rzeasyrsa:~$ ./get_ovpn.sh  \
  --server openvpn \
  --config-type server \
  --server-ip=192.168.18.23 \
  --server-port=1234 \
  --server-net=10.214.60.128 \
  --server-netmask=255.255.255.128 \
  --management-ip=192.168.17.23 \
  --management-port=11234 \
  --dns1=192.168.0.50 \
  --dns2=192.168.0.30 \
  --template server.ovpn \
  --key-dir=OpenVPN-CA/keys

OpenVPN Client

OpenVPN client template

Example client.ovpn:

client
dev tun
proto udp
remote <SERVER_IP> <SERVER_PORT>
tls-client
ns-cert-type server
comp-lzo

auth-user-pass
auth   SHA512
cipher AES-256-CBC
tls-cipher DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-RSA-AES128-SHA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA
#tls-version-min 1.2

route-delay 5 30
persist-key
persist-tun
nobind
mssfix
push-peer-info
reneg-sec 0
tun-mtu 1500
verb 3
#auth-nocache

Generate OpenVPN Config for server

ca@rzeasyrsa:~$ ./get_ovpn.sh  \
  --config-type client \
  --server-ip   192.168.18.23 \
  --server-port 1234 \
  --template    client.ovpn \
  --key-dir     OpenVPN-CA/keys \
  --user        vpnclient