User Tools

Site Tools


links:openvpn

OpenVPN config examples

Links to local pages:

These are examples of OpenVPN (http://openvpn.net/) 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.

static.key

You need to create a static key with command:

Example:

openvpn --genkey --secret static.key

Then copy this key to both client/server.

server-static.conf

# 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 10.4.0.1 10.4.0.2 # first Tunnel-IP is local, 2nd Tunnel-IP is remote
verb 3
secret static.key # openvpn --genkey --secret static.key
keepalive 10 60
persist-tun
persist-key
persist-local-ip
comp-lzo

client-static.conf

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

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

Server TLS mode no-client-auth

Pros:

  • 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

Cons:

  • 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.

server-tls.conf

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

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

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

server 10.4.0.0 255.255.255.0 # the server Tunnel-IP will be .1

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

#route 10.4.0.0 255.255.255.0 # 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
persist-tun
persist-key
persist-local-ip
comp-lzo

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)
#client-to-client

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

# end of "server-tls.conf"

client-tls.conf

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

proto udp #default
dev tun   #default
client
remote 172.24.2.60 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

nobind
verb 3
keepalive 10 60
comp-lzo
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/
tmp-ca.key
tmp-ca.crt
dh1024.pem
server.key
server.crt
client.key
client.crt

Manually create certs/keys using OpenSSL

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

Set the paramters first

# personalize these exports:

export tls_projectname="projectname"
export tls_cert_dir="/etc/openvpn/$tls_projectname"
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="email@domain.com"
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/generate_openssl_cnf.sh"
#!/bin/sh
# 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 = 1024
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 ]
basicConstraints=CA:FALSE
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always

[ server ]
basicConstraints=CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always

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

[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
basicConstraints = CA:true

[ crl_ext ]
authorityKeyIdentifier=keyid:always,issuer:always
HERE

# end of "generate_openssl_cnf.sh"

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

chmod +x generate_openssl_cnf.sh
./generate_openssl_cnf.sh

Generate CA cert/key

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 \
  -batch
/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 \
  -batch
/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 10.4.0.0/24 -d 10.4.0.1 -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -i tun104 -s 10.4.0.0/24 -d 10.4.0.1 -p tcp -m tcp --dport 2221 -j ACCEPT
-A INPUT -i tun104 -j DROP
-A FORWARD -i tun104 -o tun104 -s 10.4.0.0/24 -d 10.4.0.0/24 -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A FORWARD -i tun104 -o tun104 -s 10.4.0.0/24 -d 10.4.0.0/24 -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.

server-tls-auth.conf

# Add to above: server-tls.conf

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

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

client-tls-auth.conf

# add to above client-tls.conf

auth-user-pass
links/openvpn.txt · Last modified: 23:22 17-11-2010 (external edit)