A few weeks back I build a OpenVPN server, which was a bit of a struggle to get everything working. So I decided to share my setup. Maybe someone finds this usefull.
This is a short summery and configuration example.
Scenario:
I have a router that's running Gentoo (of course!).
My router handles the internet connection for my LAN and WLAN.
I want remote clients to connect to my local LAN via OpenVPN.
All machines in the LAN should be able to see each other.
As network protocol I use UDP. UDP because I want the clients to access a TeamSpeak server located in my local LAN. The clients should also be able to play old LAN games together that often use UDP.
Step 1:
Build a bridge of the routers LAN device and a TAP device to be used by OpenVPN.
Kernel config:
Code: Select all
CONFIG_BRIDGE=yYour going to loose your SSH-session at this point if your access the router from local LAN!
Code: Select all
rc-service stop enp3s0Code: Select all
ip link add br0 type bridge
ip link set dev enp3s0 master br0
ip link set dev tap0 master br0
ln -s /etc/init.d/net.lo /etc/init.d/net.tap0
ln -s /etc/init.d/net.lo /etc/init.d/net.br0
Code: Select all
#bridge configuration
tuntap_tap0="tap"
config_tap0="null"
config_enp3s0="null"
bridge_br0="enp3s0 tap0"
config_br0="<static router ip address>/24"
bridge_forward_delay_br0=0
bridge_hello_time_br0=1000
depend_br0() {
need net.enp3s0
need net.tap0
}
Code: Select all
rc-update del net.enp3s0 default
rc-update add net.tap0 default
rc-update add net.br0 default
Step 2:
OpenVPN server configuration:
Code: Select all
port <myOpenVPN port>
proto udp
dev tap0
# keys configuration, use generated keys
askpass <myOpenVPN>/<myOpenVPN>.pass
ca <myOpenVPN>/ca.crt
cert <myOpenVPN>/<myOpenVPN>.crt
key <myOpenVPN>/<myOpenVPN>.key
dh <myOpenVPN>/dh.pem
# optional tls-auth key to secure identifying
tls-auth <myOpenVPN>/<myOpenVPN>_tls.key 0
# OpenVPN 'virtual' network information, network and mask
server-bridge
mode server
tls-server
push "route-gateway dhcp"
push "explicit-exit-notify 3"
# persistent device and key settings
persist-key
persist-tun
cipher AES-256-GCM
data-ciphers AES-256-GCM
data-ciphers-fallback AES-256-CBC
auth SHA512
auth-nocache
tls-version-min 1.2
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384
tun-mtu 1500
mssfix 1104
# connection
keepalive 10 120
max-clients 50
user nobody
group nobody
# logging
status openvpn-status.log
log /var/log/openvpn.log
verb 3
Generate root certificate.
I used Easy-RSA to create the server certificate and keypairs.
Here is the link to the OpenVPN-Wiki that I used to get the CA and keypairs: EasyRSA3-OpenVPN-Howto
Easy-RSA can be found here: Easy-RSA
Remember to also generate keys for the clients.
Code: Select all
./easyrsa build-client-full <client1>Code: Select all
openvpn --genkey --secret <myOpenVPN>.keyCode: Select all
cd /etc/openvpn
mkdir <myOpenVPN>
cp <Easy-RSA>/pki/ca.crt <myOpenVPN>
cp <Easy-RSA>/pki/<myOpenVPN>.key <myOpenVPN>
cp <Easy-RSA>/pki/dh.pem <myOpenVPN>
cp <Easy-RSA>/pki/issued/<myOpenVPN>.crt <myOpenVPN>
cp <Easy-RSA>/pki/issued/<client1>.crt <myOpenVPN>
cp <Easy-RSA>/pki/private/<client1>.key <myOpenVPN>
OpenVPN client config.
Code: Select all
client
proto udp
dev tap0
key-direction 1
persist-key
persist-tun
cipher AES-256-GCM
data-ciphers AES-256-GCM
auth SHA512
remote <myOpenVPN public adress> <myOpenVPN port>
remote-cert-tls server
float
auth-nocache
<ca>
...
</ca>
<cert>
...
</cert>
<key>
...
</key>
<tls-auth>
...
</tls-auth>
Code: Select all
#!/bin/sh
# Default Variable Declarations
DEFAULT="client.conf"
FILEEXT=".ovpn"
CRT=".crt"
KEY=".key"
CA="ca.crt"
TA="<myOpenVPN>.key"
kPath="/etc/openvpn/<myOpenVPN>/"
#Ask for a Client name
echo "Please enter an existing Client Name:"
read NAME
ovpnName=$NAME$FILEEXT
#echo "Please enter an Name for the output file"
#read ovpnName
#1st Verify that client's Public Key Exists
if [ ! -f $kPath$NAME$CRT ]; then
echo "[ERROR]: Client Public Key Certificate not found: $kPath$NAME$CRT"
exit
fi
echo "Client's cert found: $kPath$NAME$CRT"
#Then, verify that there is a private key for that client
if [ ! -f $kPath$NAME$KEY ]; then
echo "[ERROR]: Client 3des Private Key not found: $kPath$NAME$KEY"
exit
fi
echo "Client's Private Key found: $kPath$NAME$KEY"
#Confirm the CA public key exists
if [ ! -f $kPath$CA ]; then
echo "[ERROR]: CA Public Key not found: $kPath$CA"
exit
fi
echo "CA public Key found: $kPath$CA"
#Confirm the tls-auth ta key file exists
if [ ! -f $kPath$TA ]; then
echo "[ERROR]: tls-auth Key not found: $kPath$TA"
exit
fi
echo "tls-auth Private Key found: $kPath$TA"
#Ready to make a new .opvn file - Start by populating with the
cat $DEFAULT > $ovpnName
#Now, append the CA Public Cert
echo "<ca>" >> $ovpnName
cat $kPath$CA | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' >> $ovpnName
echo "</ca>" >> $ovpnName
#Next append the client Public Cert
echo "<cert>" >> $ovpnName
cat $kPath$NAME$CRT | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' >> $ovpnName
echo "</cert>" >> $ovpnName
#Then, append the client Private Key
echo "<key>" >> $ovpnName
cat $kPath$NAME$KEY >> $ovpnName
echo "</key>" >> $ovpnName
#Finally, append the TA Private Key
echo "<tls-auth>" >> $ovpnName
cat $kPath$TA >> $ovpnName
echo "</tls-auth>" >> $ovpnName
echo "Done! $ovpnName Successfully Created."
Code: Select all
proto udp
dev tap0
key-direction 1
persist-key
persist-tun
cipher AES-256-GCM
data-ciphers AES-256-GCM
auth SHA512
remote <myOpenVPN public adress> <myOpenVPN port>
remote-cert-tls server
float
auth-nocacheStep 5:
Start the OpenVPN-Server.
Create a link that matches your server config file name '/etc/openvpn/<myOpenVPN>.conf':
Code: Select all
ln -s /etc/init.d/openvpn /etc/init.d/openvpn.<myOpenVPN>
rc-service openvpn.<myOpenVPN> start
Monitor your log file:
Code: Select all
watch -cn 15 tail -n 40 /var/log/openvpn.logClient service.
In my setup the client machines are running Windows.
And since this config uses TAP as network device i use the OpenVPN community client you can find here:
OpenVPN 2.6.8
I won't go into Windows firewall setup here. Therefore just a hint:
Setting the TAP device on the Windows client to 'private network' makes it more easy to configure the firewall on the client machine. Also enabling 'ping' helps with trouble shooting.
Have fun!




