Script for user configurations generation and sending at Ubuntu OpenVPN server

2016-01-05
#openvpn #ubuntu #howto #script

Ubuntu has very detailed documentation about OpenVPN server configuration. The key feature of this note is a script for automatic generation of single-file client configurations (keys and certs are embedded) and sending them by email. Looks interesting? Read below!

§ Prerequisites

All commands in this section must be executed as the root user.

Update package list:

1apt-get update
2apt-get -y upgrade

Install the needed packages (easy-rsa must be installed explicitly on modern Ubuntu):

1apt-get install -y openvpn easy-rsa

§ Configure OpenVPN server on Ubuntu 14.04

Copy default configuration:

1cp -r /usr/share/easy-rsa /etc/openvpn/easy-rsa
2cd /etc/openvpn/easy-rsa

Edit the vars file in the /etc/openvpn/easy-rsa folder to correspond to your settings. Change the following lines to correspond to your options:

 1export KEY_SIZE=2048
 2
 3export KEY_COUNTRY="US"
 4export KEY_PROVINCE="State"
 5export KEY_CITY="BigCityName"
 6export KEY_ORG="OrganizationName"
 7export KEY_EMAIL="mail@organization.com"
 8export KEY_OU="vpn.organization.com"
 9
10export KEY_NAME="vpn.organization.com"
11
12export KEY_CN="vpn.organization.com"
13export KEY_ALTNAMES="vpn.organization.com"

Activate the saved settings:

1source vars

And generate server keys:

1./clean-all
2./build-ca
3./build-key-server vpn.organization.com
4./build-dh
5openvpn --genkey --secret keys/ta.key

Example of the server config (it must be placed into the /etc/openvpn folder):

 1# /etc/openvpn/server.conf
 2# Which TCP/UDP port should OpenVPN listen on
 3port 1594
 4
 5# Ip's
 6server 10.10.10.0 255.255.255.0
 7
 8# UDP server
 9proto udp
10
11# Create a routed IP tunnel
12dev tun
13
14# Root certificate, certificate, private key, DH key, SSL/TLS key
15ca       easy-rsa/keys/ca.crt
16cert     easy-rsa/keys/vpn.organization.com.crt
17key      easy-rsa/keys/vpn.organization.com.key
18dh       easy-rsa/keys/dh2048.pem
19tls-auth easy-rsa/keys/ta.key 0
20
21# Maintain a record of client <-> virtual IP address
22ifconfig-pool-persist ipp.txt
23
24# Allow different clients to be able to "see" each other
25client-to-client
26
27# Ping every 10 seconds, peer is down if no pong during a 120 seconds
28keepalive 10 120
29
30# Cryptographic cipher
31cipher AES-256-CBC
32
33# Enable compression on the VPN link
34comp-lzo
35
36# Reduce the OpenVPN daemon's privileges after initialization
37user nobody
38group nogroup
39
40# Avoid errors caused by the privilege downgrade
41persist-key
42persist-tun
43
44# Status file
45status openvpn-status.log
46
47# Set the appropriate level of log verbosity
48verb 3

Be sure that your keys ca.crt, vpn.organization.com.crt, vpn.organization.com.key, dh2048.pem, and ta.key are in the correct place, corresponding to the server config.

§ Client configuration

The client configuration must correspond to the server one. For the above server config, the client config is:

 1# /etc/openvpn/easy-rsa/client.conf
 2# Specify that it is a client
 3client
 4
 5# Use the same setting as on the server.
 6dev tun
 7proto udp
 8
 9# The hostname/IP and port of the server.
10remote vpn.organization.com 1594
11
12# Keep trying indefinitely to resolve the host name of the OpenVPN server
13resolv-retry infinite
14
15# Most clients don't need to bind to a specific local port number
16nobind
17
18# Downgrade privileges after initialization (non-Windows only)
19user nobody
20group nogroup
21
22# Try to preserve some state across restarts
23persist-key
24persist-tun
25
26# Verify server certificate
27ns-cert-type server
28
29# Enable compression on the VPN link
30comp-lzo
31
32# Set log file verbosity.
33verb 3
34
35# Set key direction for tls-auth
36key-direction 1
37
38# Cryptographic cipher
39cipher AES-256-CBC

§ Convenient autosending of client configurations

Save the following script into a folder:

 1#!/usr/bin/env bash
 2
 3CLIENT=$1
 4CLIENT_MAIL=$2
 5SERVER=vpn.dima.io
 6
 7cd /etc/openvpn/easy-rsa
 8
 9source vars
10
11mkdir -p bundles
12
13./build-key ${CLIENT}.at.${SERVER}
14
15cp client.conf bundles/${CLIENT}.at.${SERVER}.conf
16
17echo "<ca>"  >> bundles/${CLIENT}.at.${SERVER}.conf
18cat keys/ca.crt >> bundles/${CLIENT}.at.${SERVER}.conf
19echo "</ca>" >> bundles/${CLIENT}.at.${SERVER}.conf
20
21echo "<cert>"  >> bundles/${CLIENT}.at.${SERVER}.conf
22cat keys/${CLIENT}.at.${SERVER}.crt >> bundles/${CLIENT}.at.${SERVER}.conf
23echo "</cert>" >> bundles/${CLIENT}.at.${SERVER}.conf
24
25echo "<key>"  >> bundles/${CLIENT}.at.${SERVER}.conf
26cat keys/${CLIENT}.at.${SERVER}.key >> bundles/${CLIENT}.at.${SERVER}.conf
27echo "</key>" >> bundles/${CLIENT}.at.${SERVER}.conf
28
29echo "<tls-auth>"  >> bundles/${CLIENT}.at.${SERVER}.conf
30cat keys/ta.key >> bundles/${CLIENT}.at.${SERVER}.conf
31echo "</tls-auth>" >> bundles/${CLIENT}.at.${SERVER}.conf
32
33if [ -n "$CLIENT_MAIL" ]; then
34    echo -e "Hello, ${CLIENT}!\n\nConfiguration with embedded certificates is attached." > mail.txt
35    echo "If you use Windows system, rename configuration from *.conf to *.ovpn." >> mail.txt
36    echo "This mail is automatically generated. Please do not respond to it." >> mail.txt
37    echo "--"
38    echo "${SERVER} team."
39    cat mail.txt | mutt -s "Configuration for $CLIENT on $SERVER OpenVPN server" -a bundles/${CLIENT}.at.${SERVER}.conf -- $CLIENT_MAIL
40fi
41
42rm mail.txt

add-key

And make it executable:

1chmod +x add-key

You will have to install mutt (it is used for sending emails with attachments). Your server must have a full hostname like server.organization.com; otherwise sendmail may hang during the install, so change it before the mutt installation.

1apt-get install -y mutt

§ If you install in LXC container

If you install the VPN server in an LXC container, you have to take additional steps. First, add a rule for iptables in the host system (use the IP of your VPN container and the port from the VPN server config):

1iptables -t nat -A PREROUTING -i eth0 -p udp --dport 1594 -j DNAT --to 10.0.3.111:1594

To make it persistent, you may use iptables-persistent.

Second, configure the tun device for LXC.