Intro to OpenVPN


VPNs what are they good for

VPNs allow you to connect to a system


Assumptions

  • OpenWRT is running on the server
  • You have SSH access to the machine running OpenWRT
  • The OpenWRT server is set to give out ips on its lan (i.e. on the 192.168../16 private address block).

Creating Certificates

First, let's create the certificates which the server and the clients will uses to authenticate one another. This step will not be done on the server so as to not have to load extra software on the server, to keep private keys off the server, and to speed up the proccess of generating the Diffie-Hellman key.


Install Certificate software

sudo dnf update # Use `apt` or 'opkg' update your box as nessesary sudo dnf install easy-rsa openvpn

I built this on Fedora so you will see the dnf command allot if you have apt installed or another package manager, use that.


Create CA Certificate

We will now setup the directory where easy-rsa will place its files when building the certificates and keys.

mkdir vpn-keys-certs cd vpn-keys-certs ./easyrsa clean-all ./easyrsa build-ca nopass

Security if you need an extra layer of security on top of the Diffie-Hellman key and control list then ommit nopass from the build-ca line and the gen-req lines to follow.


Generate Diffie-Hellman Key

This key will be our fist line of defense.

./easyrsa gen-dh # creates file dh.pem ./easyrsa gen-crl # creates file crl.pem

Generate Server Certificates

Next we create keys and certificats for the server and a few clients, Luke and Leia. Neither will have passwords assocciated with their keys.

./easyrsa gen-req <NAMEOFCert> nopass # Creates the .key file ./easyrsa sign-req server <NAMEOFCert> # Creates the .crt file

Gernerating Client Certificates

# Create the certs and keys for leia ./easyrsa gen-req <NameOfClientA> nopass ./easyrsa sign-req client <NameOfClientA> # Create the Certs and keys for luke ./easyrsa gen-req <NameOfClientB> nopass ./easyrsa sign-req client <NameOfClientB>

Verifing Certificats

Certificates can be verified using:

openssl verify -CAfile /path/to/ca.crt path/to/certificate.crt`

Revoking a Certificate

If a client certificate has been compermised and needs revoked so that the server will reject all attemps to it conneting we will update the crl.pem file.

./easyrsa revoke <NameOfClientToBeRevoked> ./easyrsa gen-crl

Thats it!!! Now just copy the new crl.pem file to the server and restart the system. Luke will nolonger be able to connect with the luke.key


TODO:

  • Create and revoke a certificate with duplicate names
  • Place the vpn-keys-certs in a git repository. See the Going Futher section at the bottom of the "Assorted Solutions" blog page.

The TLS authority

This key will be a shared secret used to verify the integrity of any UDP packet sent to the server. If a packet does not contain the HMAC signiture of the shared key the packet will be dropped emidiatly. Thus protecting againset DoS attacks, Port scanning, Buffer overflow and thus requires a machine to have both a valid .crt, and two .keys. The Hardening OpenVPN Security goes into a little more detail but here is the basics.


Generate the TLS key

openvpn --genkey --secret ta.key

Get the Server going


ssh into the router as root then:

opkg update opkg install openvpn

Make sure that there is a place to store the keys

mkdir /etc/openvpn/keys

Move the following keys to the server:

  • pki/ca.crt
  • pki/ta.key
  • pki/issued/republic.crt
  • pki/private/republic.key
  • pki/dh.pem
  • pki/crl.pem

Exit the ssh session and distribute the keys located in the pki/ folder

scp ca.crt ta.key issued/republic.crt private/republic.key dh.pem crl.pem root@openwrt.server.lan:/etc/openvpn/keys

Moving Keys to Client

Each client will get a set of certs. and keys

  • pki/ca.crt
  • pki/ta.key
  • pki/issued/personal.crt
  • pki/private/personal.key

Send these keys to their respective client's. NOTE: all four keys can live in the same folder.


Leia get's:

  • pki/ca.crt
  • pki/ta.key
  • pki/issued/leia.crt
  • pki/private/leia.key

And Luke get's:

  • pki/ca.crt
  • pki/ta.key
  • pki/issued/luke.crt
  • pki/private/luke.key

Server configuration file

Now that we have the keys, certificates and control list files on the server lets setup the configuration file.

ssh root@openwrt.server.lan touch /etc/config/openvpn.conf nano /etc/config/openvpn.conf

Paste in the following code taken from the OpenVPN sample config.

port 1194 proto udp dev tun ca /etc/openvpn/keys/ca.crt cert /etc/openvpn/keys/republic.crt key /etc/openvpn/keys/republic.key dh /etc/openvpn/keys/dh.pem tls-auth /etc/openvpn/keys/ta.key 0 server 10.8.0.0 255.255.255.0 # The 10.8.0.0 my be chaned to any 10... domain such as 10.88.0.0 route 192.168.20.0 255.255.255.0 # The 192.168.20.0 should match the ip domain of your server push "route 192.168.20.0 255.255.255.0" # Should also match the above line. push "dhcp-option DNS 192.168.20.1" topology subnet ifconfig-pool-persist ipp.txt keepalive 10 120 user nobody persist-key persist-tun status openvpn-status.log verb 3 explicit-exit-notify 1

----

> NOTE: you will need to change the following lines to point to your certificates and keys
> ```bash=
> ca /etc/openvpn/keys/ca.crt
> cert /etc/openvpn/keys/republic.crt
> key /etc/openvpn/keys/republic.key
> dh /etc/openvpn/keys/dh.pem
> tls-auth /etc/openvpn/keys/ta.key 0
>```

---

## Client Configuration File

Lets get back to the Client computer and get them set up to connect. The client configuration looks pretty similar to the server.

---

Create a file named `client.conf` on your system and paste the following code.

:::info
```bash=
# Client Configuration file

client

auth-nocache

dev tun

proto udp

remote 192.168.124.201 1194

resolv-retry infinite

nobind

user nobody
group nobody

persist-key
persist-tun

mute-replay-warnings

ca /home/cde/.vpn/erghos/ca.crt
cert /home/cde/.vpn/erghos/erghos.crt
key /home/cde/.vpn/erghos/erghos.key

remote-cert-tls server

tls-auth /home/cde/.vpn/erghos/ta.key 1

cipher BF-CBC

verb 3

mute 20
:::

You will again need to change the following lines

ca /home/cde/.vpn/erghos/ca.crt cert /home/cde/.vpn/erghos/erghos.crt key /home/cde/.vpn/erghos/erghos.key ... tls-auth /home/cde/.vpn/erghos/ta.key 1

To point to the location on your system.


OpenWRT setup

Let's get back to the OpenWRT server and finish up the confirmation by sshing into the server.


Earlier we created the openvpn.conf in the /etc/config/ directory now we will link to it in the /etc/config/openvpn file.

nano /etc/config/openvpn

Now we will add the lines so that openvpn knows to use our custom configuration file.

config openvpn myvpn option enabled 1 option config /etc/config/openvpn.conf

Now lets restart the service

service openvpn restart

The Interface

We will handle the rest of the setup through the LuCI web GUI on OpenWRT.


TODO: Add screen shots to this section.


  1. Goto Networking
  2. -> Interfaces
  3. Click Add new interface...

Name: VPN
Protocol: Unmanaged
Interface Ethernet Adapter: "tun0" (VPN)

Save & Apply


The Firewall settings

The Zone

  1. Goto Networking
  2. -> Firewall
  3. Click Add

Name: vpn
Input: accept
Output: accept
Forward: reject
Coverd networks: VPN

Save & Apply


The Traffic Rules

  1. Goto Network
  2. -> Firewall
  3. -> Traffic Rules

Add

Name: Allow-OpenVPN
Protocol: UDP
Source zone: WAN
Source port: 1194
Destination zone: Device (input)
Destination port: 1194

Save


If you want your server to only accept vpn connections and ignore all other requests to all the other ports remove the Source port: 1194 from the Allow-OpenVPN Firewall Traffic Rules.


Add

Name: VPN->LAN
Source: VPN
Destination: LAN

Save


Add

Name: LAN->VPN
Source: LAN
Destination: VPN

Save

Save & Apply

You should now be able to connect to the VPN from a client's machine.


CLI VPN connection

On the client machine:

sudo openvpn /path/to/config.conf

If successful you should see out put similar to:

[sudo] password for user: Mon Feb 1 10:55:27 2021 OpenVPN 2.4.10 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Dec 9 2020 Mon Feb 1 10:55:27 2021 library versions: OpenSSL 1.1.1i FIPS 8 Dec 2020, LZO 2.10 ... Mon Feb 1 11:08:57 2021 /sbin/ip route add 192.168.22.0/24 via 10.88.0.1 Mon Feb 1 11:08:57 2021 GID set to nobody Mon Feb 1 11:08:57 2021 UID set to nobody Mon Feb 1 11:08:57 2021 Initialization Sequence Completed

Verifing connection

You can now open up a second terminal and try and ping one of the machines or the server through the internal 192.168.. network

ping 192.168.20.1 PING 192.168.22.1 (192.168.22.1) 56(84) bytes of data. 64 bytes from 192.168.22.1: icmp_seq=1 ttl=64 time=3.04 ms 64 bytes from 192.168.22.1: icmp_seq=2 ttl=64 time=2.71 ms 64 bytes from 192.168.22.1: icmp_seq=3 ttl=64 time=3.17 ms ^C --- 192.168.22.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 2.705/2.970/3.169/0.195 ms

Troubleshooting


Cannot ioctl TUNSETIFF tun

Problem:

If you get ERROR: Cannot ioctl TUNSETIFF tun: Operation not permitted (errno=1) when running openvpn /dir/to/client.conf

Solution:

Run as admin i.e. sudo openvpn /dir/containing/client.conf


SSH connection/tunnel freezes

Problem:
If after starting the openvpn server.conf your SSH connection is lost you may be able to connect using openvpn.

Solution:
Check to see if you can ping 192.168.2.1 or the ip of your router. If so use a internet browser to open the OpenWRT LuCI interface and goto the Firewall setting


GUI Fails to connect

Problem:
On linux with SELinux I found that the GUI interface was having problems accessing the key files and was giving the error: AVC avc: denied { open } for pid=9040 comm="openvpn" path="/home/cde/...

Solution:

After some searching I found a stackover flow post with the solution.

sudo chcon -t home_cert_t ~/path/to/keys/*

Can't find a machine using it's name

Problem:

I can open a web browser and type in 192.168.2.1 and get the LuCI interface but typing is't name i.e. http://mindover.lan does not work.

Solution:

NoKnown current soulint to this problem and it seems to be seratic.


OpenVPN Server on an OpenWrt Router

Become A Certificate Authority with Easy-RSA 3

2x HOW TO

Hardening OpenVPN Security

OpenVPN Community Wiki and Tracker

OpenVPN Client Configuration file

OpenVPN Server Configuration File