Skip to content

Instantly share code, notes, and snippets.

@kremalicious
Last active August 20, 2019 15:38
Show Gist options
  • Save kremalicious/75d4f9e91c9b44acbacd1432fad4ae91 to your computer and use it in GitHub Desktop.
Save kremalicious/75d4f9e91c9b44acbacd1432fad4ae91 to your computer and use it in GitHub Desktop.
Hardened OpenVPN server on Ubuntu including client configuration script
#
# Hardened OpenVPN server on Ubuntu 16.04
# repeatable config generation script at end
#
# TOC
# ----
# 1. SERVER
# 2. NETWORKING
# 3. CLIENTS
# 3.1. REPEAT FOR EACH CLIENT
# 4. SERVER STATUS
#
#####################################
# 1. SERVER
#####################################
# install
sudo apt update
sudo apt install openvpn easy-rsa
# create CA in home folder
make-cadir ~/openvpn-ca && cd ~/openvpn-ca
# adjust variables used for each key generation
vi vars
source vars
./clean-all
./build-ca
# build server key pair and HMAC signature
./build-key-server SERVERNAME
./build-dh
openvpn --genkey --secret keys/ta.key
# generate stronger Diffie-Hellman PEM
openssl dhparam 4096 > keys/dh4096.pem
# copy everything server-related over to OpenVPN dir
cd ~/openvpn-ca/keys
sudo cp ca.crt ca.key SERVERNAME.crt SERVERNAME.key ta.key dh4096.pem /etc/openvpn
# create isolated user for OpenVPN daemon to run under
adduser --system --shell /usr/sbin/nologin --no-create-home openvpn_server
# configure OpenVPN
gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/SERVERNAME.conf
sudo vi /etc/openvpn/SERVERNAME.conf
ca ca.crt
cert SERVERNAME.crt
key SERVERNAME.key
# redirect everything through VPN
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"
tls-auth ta.key 0 # This file is secret
key-direction 0
cipher AES-256-CBC
auth SHA512
user openvpn_server
group nogroup
# strong TLS cyphers only
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-128-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA
#####################################
# 2. NETWORKING
#####################################
sudo vi /etc/sysctl.conf
net.ipv4.ip_forward=1
sudo sysctl -p
# Client masquerading
# get public network interface
ip route | grep default
# it's the one directly following 'dev'
# adjust firewall, here ufw
sudo vi /etc/ufw/before.rules
# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to eth0
-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
COMMIT
# END OPENVPN RULES
sudo vi /etc/default/ufw
DEFAULT_FORWARD_POLICY="ACCEPT"
sudo ufw allow 1194/udp
sudo ufw allow OpenSSH
# restart to load all changes
sudo ufw disable && sudo ufw enable
# START THE OPENVPN SERVER
sudo systemctl start openvpn@SERVERNAME && sudo systemctl status openvpn@SERVERNAME
sudo systemctl enable openvpn@SERVERNAME
#####################################
# 3. CLIENTS
#####################################
# create directory for storing configs
mkdir ~/openvpn-configs && chmod 700 ~/openvpn-configs && cd ~/openvpn-configs
# create a base config
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/openvpn-configs/base.conf
vi base.conf
remote SERVER_IP 1194
proto udp
user nobody
group nogroup
# keys/certs will be embedded in file later on
# so comment out here
#ca ca.crt
#cert client.crt
#key client.key
#tls-auth ta.key 1
key-direction 1
# use and uncomment if using OpenVPN below v2.4
#tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-128-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA
cipher AES-256-CBC
auth SHA512
# create a config generation script
vi make_config.sh
#!/bin/bash
# First argument: Client identifier
KEY_DIR=~/openvpn-ca/keys
OUTPUT_DIR=~/openvpn-configs
BASE_CONFIG=~/openvpn-configs/base.conf
cat ${BASE_CONFIG} \
<(echo -e '<ca>') \
${KEY_DIR}/ca.crt \
<(echo -e '</ca>\n<cert>') \
${KEY_DIR}/${1}.crt \
<(echo -e '</cert>\n<key>') \
${KEY_DIR}/${1}.key \
<(echo -e '</key>\n<tls-auth>') \
${KEY_DIR}/ta.key \
<(echo -e '</tls-auth>') \
> ${OUTPUT_DIR}/${1}.ovpn
# make executable
chmod 700 make_config.sh
# -----------------------------------
# 3.1. REPEAT FOR EACH CLIENT
# -----------------------------------
# generate client certificate and key pair
cd ~/openvpn-ca
source vars
./build-key CLIENTNAME
# generate client configs
cd ~/openvpn-configs
./make_config.sh CLIENTNAME
mv CLIENTNAME.ovpn SERVERNAME-CLIENTNAME.ovpn
#####################################
# 4. SERVER STATUS
#####################################
sudo systemctl status openvpn*.service
sudo journalctl -f | grep vpn
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment