# OpenVPN server on Ubuntu 18.06

## Setup server

### Leverage an AWS instance

Leverage an instance with:

* "Source/Destination Check" disabled.
* Firewall open on port 1194/UDP.

### Configure IP forward

Run:

```bash
nano /etc/sysctl.conf
```

Enable net.ipv4.ip\_forward:

```bash
net.ipv4.ip_forward=1
```

Apply changes:

```bash
sysctl -p
```

#### If you are using ufw\...

Get your default network card:

```bash
ip route | grep default
```

Output example:

```
default via 172.31.0.1 dev eth0 proto dhcp src 172.31.10.197 metric 100
```

Edit ufw config:

```bash
nano /etc/ufw/before.rules
```

Add the block `START OPENVPN RULES` and `END OPENVPN RULES`:

```bash
#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
#   ufw-before-input
#   ufw-before-output
#   ufw-before-forward
#

# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0] 
# Allow traffic from OpenVPN client to wlp11s0 (change to the interface you discovered!)
-A POSTROUTING -s 10.22.0.0/16 -o eth0 -j MASQUERADE
-A POSTROUTING -s 3.4.3.0/8 -o eth0 -j MASQUERADE
COMMIT
# END OPENVPN RULES

# Don't delete these required lines, otherwise there will be errors
*filter

```

Edit ufw default config:

```bash
nano /etc/default/ufw
```

Allow forward:

```bash
 DEFAULT_FORWARD_POLICY="ACCEPT"
```

Allow openvpn and SSH:

```bash
ufw allow 1194/udp
ufw allow OpenSSH
```

### Install Openvpn

Run:

```bash
apt update
apt install openvpn
```

Download EasyRSA:

```bash
wget -P ~/ https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.4/EasyRSA-3.0.4.tgz
tar xvf EasyRSA-3.0.4.tgz
```

Copy and edit vars:

```bash
cd ~/EasyRSA-3.0.4/
cp vars.example vars
nano vars
```

Uncomment and change the following config:

```
set_var EASYRSA_REQ_COUNTRY     "AU"
set_var EASYRSA_REQ_PROVINCE    "New South Wales"
set_var EASYRSA_REQ_CITY        "Sydney"
set_var EASYRSA_REQ_ORG         "Your Company"
set_var EASYRSA_REQ_EMAIL       "hostmaster@yourcompany.com"
set_var EASYRSA_REQ_OU          "Your Company"
```

Initiate the public key:

```bash
./easyrsa init-pki
```

Build CA certificate. Keep the default Common Name and hit enter:

```bash
./easyrsa build-ca nopass
```

Create a private key for the server and a certificate request:

```bash
./easyrsa gen-req server nopass
```

Copy the server key to the /etc/openvpn/ directory:

```bash
cp ~/EasyRSA-3.0.4/pki/private/server.key /etc/openvpn/
```

Sign the request. Input yes when prompted:

```bash
./easyrsa sign-req server server
```

Sign the request. Input yes when prompted:

```bash
./easyrsa sign-req server server
```

Copy certificates to openvpn dir:

```bash
cp ./pki/issued/server.crt /etc/openvpn/
cp ./pki/ca.crt /etc/openvpn/
```

Create a strong Diffie-Hellman key to use during key exchange (may take a few minutes to complete):

```bash
./easyrsa gen-dh
```

Generate an HMAC signature to strengthen the server's TLS integrity verification capabilities:

```bash
openvpn --genkey --secret ta.key
```

Copy the files to openvpn dir:

```bash
sudo cp ~/EasyRSA-3.0.4/ta.key /etc/openvpn/
sudo cp ~/EasyRSA-3.0.4/pki/dh.pem /etc/openvpn/
```

### Configuring the OpenVPN Service

Copy sample config:

```bash
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
sudo gzip -d /etc/openvpn/server.conf.gz
```

Edit server config:

```bash
nano /etc/openvpn/server.conf
```

Double check tls-auth and add key-direction:

```bash
tls-auth ta.key 0
key-direction 0

```

Double check cipher and add auth:

```bash
cipher AES-256-CBC
auth SHA256
```

Change dh:

```bash
#dh dh2048.pem
dh dh.pem
```

Enable user and group:

```bash
user nobody
group nogroup
```

Enable client-to-client:

```bash
client-to-client
```

Start and enable service:

```bash
systemctl enable openvpn@server
systemctl restart openvpn@server
systemctl status openvpn@server
```

### Setup client config

Run:

```bash
mkdir -p ~/client-configs/keys
mkdir -p ~/client-configs/files
chmod -R 700 ~/client-configs
cp ~/EasyRSA-3.0.4/ta.key ~/client-configs/keys/
cp ~/EasyRSA-3.0.4/pki/ca.crt ~/client-configs/keys/
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf
nano ~/client-configs/base.conf
```

Config remote server:

```bash
#remote my-server-1 1194
remote YOUR-VPN-SERVER-DOMAIN 1194
```

Double check proto:

```bash
proto udp
```

Enable user and group:

```bash
user nobody
group nogroup
```

Comment out certificates (they are provided in the .ovpn file):

```bash
#ca ca.crt
#cert client.crt
#key client.key
```

Double check cipher and add auth:

```bash
cipher AES-256-CBC
auth SHA256
```

Add these lines in the end of the file. The last ones are commented out (only need to enable them for Linux clients that ship with an /etc/openvpn/update-resolv-conf file):

```bash
key-direction 1
# script-security 2
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf
```

Create a script to compile the base config:

```bash
nano ~/client-configs/make_config.sh
```

Add:

```bash
#!/bin/bash

# First argument: Client identifier

KEY_DIR=~/client-configs/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-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

```

Set permissions:

```bash
chmod 700 ~/client-configs/make_config.sh
```

### Add client certificate

Generate certificate:

```bash
cd ~/EasyRSA-3.0.4
./easyrsa gen-req client2 nopass
./easyrsa sign-req client client2
cp pki/private/client2.key ~/client-configs/keys/
cp pki/issued/client2.crt ~/client-configs/keys/
cd ~/client-configs
./make_config.sh client2
ls files/client2.ovpn
```

### References

<https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-18-04>

<https://hackernoon.com/using-a-vpn-server-to-connect-to-your-aws-vpc-for-just-the-cost-of-an-ec2-nano-instance-3c81269c71c2>

## Revoke certificate

Run EasyRsa revoke command. Type yes when prompted:

```bash
cd /root/EasyRSA-3.0.4
./easyrsa revoke client2
```

Create a certificate revocation list (CRL):

```bash
./easyrsa gen-crl
```

Copy the CRL to the server config folder:

```bash
cp pki/crl.pem /etc/openvpn
```

Edit server config:

```bash
nano /etc/openvpn/server.conf
```

Add the following line to the end of the file:

```bash
crl-verify crl.pem
```

Restart server:

```bash
sudo systemctl restart openvpn@server
```

### References

<https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-18-04>

## Multi instances

Copy your current server config:

```bash
cd /etc/openvpn/
cp server.conf server2.conf
```

Edit the new file:

```bash
nano server2.conf
```

Change the following config:

```bash
port XXXX
server X.X.X.0 255.255.255.0
```

Start the server:

```bash
systemctl start openvpn@server2.service
systemctl enable openvpn@server2.service
```

### References

<https://www.hugeserver.com/kb/openvpn-multiple-ports/>

## Fixed IP for clients

Edit servers config:

```bash
nano /etc/openvpn/server.conf
```

Uncomment the following line:

```bash
client-config-dir ccd
```

Create the dir:

```bash
mkdir /etc/openvpn/ccd/
```

Create a file with **same CN name used in the certificate**:

```bash
nano /etc/openvpn/ccd/client-cn-name
```

Define the static IP:

```bash
ifconfig-push 10.8.0.2 255.255.0.0
```

Restart server:

```bash
systemctl restart openvpn@server
```

### References

<https://www.itsfullofstars.de/2018/09/openvpn-assign-static-ip-to-client/>

<https://serverfault.com/questions/826560/how-to-set-a-static-ip-client-side-in-openvpn>

## Restrict Client-to-client

Edit server config:

```bash
nano server-cluster.conf
```

Make sure the option **client-to-client** is **disabled**:

```bash
;client-to-client
```

Add the following line in the end of the file to route all traffic to the VPN server:

```bash
push "route 10.8.0.0 255.255.0.0"
```

Configure iptables:

```bash
# Allow all traffic from 10.22.0.100 (K8s master)
iptables -A FORWARD -s 10.22.0.100 -j ACCEPT

# Allow all traffic to 10.22.0.100 (K8s master)
iptables -A FORWARD -d 10.22.0.100 -j ACCEPT

# Allow all traffic between two nodes
iptables -A FORWARD -s 10.22.0.101 -d 10.22.0.102 -j ACCEPT
iptables -A FORWARD -s 10.22.0.102 -d 10.22.0.101 -j ACCEPT

# Drop everything else
iptables -A FORWARD -j DROP
```

### References

<https://backreference.org/2010/05/02/controlling-client-to-client-connections-in-openvpn/>

## Debug

Check service:

```bash
systemctl status openvpn@server.service
```

Monitor packets on interface tun0:

```bash
tcpdump -i tun0 -nn -s0 -v
tcpdump -i tun0 -nn -s0 -v port 6805
```

Monitor ping on interface vpn-cluster with buffer size 512 (it is not set, the “packets dropped by kernel” will always be zero):

```bash
tcpdump -i vpn-cluster -B 4096 -n icmp
```

Check open port:

```bash
netstat -a |grep 1194
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.devops.buzz/public/openvpn/openvpn-server-on-ubuntu-18.06.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
