Skip to content

OpenVPN Quickstart for Custom VLAN

jchappelow edited this page Aug 5, 2024 · 8 revisions

WARNING: This is a work in progress. Is currently just notes for a more formal document. Use with care. Also note that this is uses the simplified setup procedure where the CA issues all client keys as described on the OpenVPN wiki. To instead have the clients issue certificate requests, use a separate CA system.

In this setup, there will be one server that hosts the VPN. All clients will connect to that server to join the VPN. Upon connect, each client will have a new network interface (e.g. tun0) with an IP address assigned from the VPN subnet. In this example, the subnet is 10.9.0.0/23.

Install packages

Install openvpn and easy-rsa (v3) packages.

For Debian-based distros:

sudo apt update
sudo apt install openvpn easy-rsa

Prepare client/server identities

First Make a folder for your setup:

mkdir vpnsetup
cd vpnsetup

Initialize the certificate authority (CA):

make-cadir ./ca
cd ca

This creates a folder for a new CA, with a link to the easyrsa executable and a vars file:

drwx------ 2 user user 4096 Aug  5 11:17 ./
drwxrwxr-x 3 user user 4096 Aug  5 11:17 ../
lrwxrwxrwx 1 user user   27 Aug  5 11:17 easyrsa -> /usr/share/easy-rsa/easyrsa*
-rw-r--r-- 1 user user 4616 Aug  5 11:17 openssl-easyrsa.cnf
-rw-r--r-- 1 user user 8925 Aug  5 11:17 vars
lrwxrwxrwx 1 user user   30 Aug  5 11:17 x509-types -> /usr/share/easy-rsa/x509-types/

Edit the ca/vars file, adding configuration like the following after the point in the file that states # DO YOUR EDITS BELOW THIS POINT:

# edit ca/vars:
set_var EASYRSA_REQ_COUNTRY    "US"
set_var EASYRSA_REQ_PROVINCE   "TX"
set_var EASYRSA_REQ_CITY       "Austin"
set_var EASYRSA_REQ_ORG        "Kwil"
set_var EASYRSA_REQ_EMAIL      "[email protected]"
set_var EASYRSA_REQ_OU         "Kwil Engineering"
set_var EASYRSA_ALGO           "rsa"
set_var EASYRSA_KEY_SIZE       2048

Initialize the CA's public key infrastructure (pki):

./easyrsa init-pki

The output should be as follows:

init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /home/user/vpnsetup2/ca/pki

Complete the creation of the CA, providing a Common Name for the CA:

./easyrsa build-ca nopass

When prompted, enter the desired "Common Name" for the CA. Here we call it KwilVPN0:

Using SSL: openssl OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:KwilVPN0

CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/home/user/vpnsetup2/ca/pki/ca.crt

Create the identities for the server and each client.

./easyrsa build-server-full kwilsrv nopass
./easyrsa build-client-full client1 nopass
./easyrsa build-client-full client2 nopass
...

Create a folder for the server's config and data:

cd .. # to vpnsetup
mkdir -p server/ccd
cp ca/pki/ca.crt ./server
cp ca/pki/private/kwilsrv.key ./server
cp ca/pki/issued/kwilsrv.crt ./server

Create the server's Diffie Hellman parameters and TLS key:

# in vpnsetup/server
openssl dhparam -out server/dh.pem 2048 # this will take a few minutes
openvpn --genkey secret server/tls.auth

Create the server's config file:

# server/server.conf
proto udp
port 1194
tls-server
key kwilsrv.key
cert kwilsrv.crt
ca ca.crt
dh dh.pem
# tls-auth tls.auth 0
#remote-cert-eku "TLS Web Client Authentication"
data-ciphers-fallback AES-256-CBC
dev tun
topology subnet
#push "topology subnet"
server 10.9.0.0 255.255.254.0
# ifconfig 10.9.0.1 255.255.255.0
#push "route 10.9.0.0 255.255.254.0"
#push "route-gateway 10.9.0.1"
user nobody
group nogroup
client-config-dir ccd #client config files will go here
ccd-exclusive #Only allow clients with a config to connect
#route 10.9.0.0 255.255.254.0
ifconfig-pool-persist ipp.txt
allow-compression no
keepalive 60 180
verb 3
persist-key
persist-tun
status openvpn-status.log

Adjust the subnet definition in the above server config as needed. See OpenVPN's sample server config for details on each setting./

For static IP assignment, create a file for each client in the server/ccd folder. For example, to assign the IP address 10.9.0.2 to client1:

# server/ccd/client1
ifconfig-push 10.9.0.2 255.255.254.0

The vpnsetup/server folder should now look like:

server/
├── ca.crt
├── ccd
│   ├── client1
│   └── client2
├── dh.pem
├── kwilsrv.crt
├── kwilsrv.key
└── tls.auth

Create a folder for the each client's config:

# in vpnsetup folder
CLIENT=client1
mkdir -p ${CLIENT}
cp ca/pki/ca.crt ./${CLIENT}
cp ca/pki/private/${CLIENT}.key ./${CLIENT}
cp ca/pki/issued/${CLIENT}.crt ./${CLIENT}

Make a config file for each client:

# client1/client1.ovpn
client
dev tun
proto udp
remote <server's real IP or fqdn> 1194
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
ca ca.crt
cert client1.crt  # edit
key client1.key   # edit
remote-cert-tls server
cipher AES-256-CBC
verb 3

Prepare each client and distribute to each client machine.

Start the server, as root:

openvpn --config server.conf