VPNs allow you to connect to a system
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.
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 haveapt
installed or another package manager, use that.
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 thebuild-ca
line and thegen-req
lines to follow.
This key will be our fist line of defense.
./easyrsa gen-dh # creates file dh.pem
./easyrsa gen-crl # creates file crl.pem
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
# 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>
Certificates can be verified using:
openssl verify -CAfile /path/to/ca.crt path/to/certificate.crt`
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
vpn-keys-certs
in a git repository. See the Going Futher section at the bottom of the "Assorted Solutions" blog page.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 .key
s. The Hardening OpenVPN Security goes into a little more detail but here is the basics.
openvpn --genkey --secret ta.key
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:
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
Each client will get a set of certs. and keys
Send these keys to their respective client's. NOTE: all four keys can live in the same folder.
Leia get's:
And Luke get's:
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.
Let's get back to the OpenWRT server and finish up the confirmation by ssh
ing 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
We will handle the rest of the setup through the LuCI web GUI on OpenWRT.
Networking
Interfaces
Add new interface...
Name: VPN
Protocol: Unmanaged
Interface Ethernet Adapter: "tun0" (VPN)
Save & Apply
Networking
Firewall
Add
Name: vpn
Input: accept
Output: accept
Forward: reject
Coverd networks: VPN
Save & Apply
Network
Firewall
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.
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
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
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
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
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/*
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
OpenVPN Community Wiki and Tracker