Creare una VPN con OpenVPN, Server CA con Linux e Raspberry PI

Creare una connessione VPN utilizzando OpenVPN e un server di certificate authority - CA.

il
ICT - Manager, Collaboratore di IProgrammatori

Ormai in questo periodo particolare che stiamo vivendo, per qualcuno si è paventata la necessità di lavorare da casa in remoto. Realizzare questo contesto non è sempre facile se non adottando delle configurazioni particolari che ci dessero la possibillità reale di lavorare da casa come se stessimo effettivamente seduti nel nostro ufficio.

Le soluzioni da poter adottare sono diverse e nella maggioranza dei casi si riesce anche ad avere un adeguato sistema di protezione dei dati che vengono trasmessi inevitabilmente in rete. Uno tra questi è l’applicazione TeamViewer, capace di creare una connessione diretta con la nostra postazione dell’ufficio grazie all’ausilio di un programma che una volta eseguito crea una connessione sicura tra i due pc interessati.

Per molte aziende però, questa non è stata la soluzione migliore, in quanto per il corretto funzionamento, prevede che appunto il pc nel nostro ufficio sia acceso e collegato alla rete e quindi a termine della sessione lavorativa non si ha la possibilità di poterlo spegnere inquanto successivamente non avremo piu la possibilità di collegarci allo stesso perché spento.

Pertanto l’unica reale soluzione che effettivamente ci dia la facoltà di lavorare lontano dal nostro ufficio e allo stesso tempo creare una certa versatilità per l’azienda, che ne ha l’esigenza, è quello di usufruire di un servizio VPN (Virtual Private Network).

OpenVPN è una VPN TLS/SSL. Questo vuol dire che utilizza i certificati per crittografare il traffico tra il server e i client. Per tanto utilizzeremo l'ultima versione di EasyRSA per costruire la nostra infrastruttura a chiave pubblica CA (PKI).

Questo sistema, opportunamente configurato ci da la possibilità di accedere al nostro ufficio e in particolare alle risorse del NAS aziendale da qualsiasi parte del mondo e in assoluta sicurezza, dando la sensazione di essere effettivamente seduti dietro la nostra scrivania. Si conviene che in questo modo non ci sarà bisogno di avere i pc degli uffici accessi perennemente ma semplicemente basta avere il NAS aziendale in rete. In particolare come vedremo piu avanti questa soluzione ci garantirà di accedere alle risorse condivise della nostra azienda tramite la nostra VPN e non direttamente al NAS, in questo modo i dati aziendali non saranno mai esposti ai pericoli della rete.

Per usufruire di una VPN ci sono svariati modi e purtroppo quelli piu affidabili il più delle volte sono a pagamento e richiedono un canone mensile. Invece in questo articolo verrà preso in considerazione un tool free, OpenVPN, che una volta installato non necessita di alcun canone o altro.

Una configurazione molto valida che ho avuto modo di attuare in diversi contesti aziendali, mediamente strutturati tra i 30 e 50 client, prevede l’utilizzo di:

Raspberry PI come server per la nostra VPN utilizzando sul raspberry una versione di Ubuntu server

Server CA su macchina virtuale base linux con l’ausilio di virtualbox

Come indicato precedentemente faremo uso anche di un secondo server virtuale “Server CA”, certificate authority per costruire la nostra infrastruttura a chiave pubblica CA (PKI). Infatti ogni qualvolta un dipendente dovrà accedere alla rete aziendale userà sul suo pc un file di configurazione già pronto e compilato con i parametri necessari alla connessione e in più al suo interno sarà registrata la chiave pubblica RSA di crittografia, mentre la relativa chiave privata è installata sul server VPN. La generazione dei certificati e delle chiavi è devoluto al server di certificate authority

Sia per motivi di sicurezza che di funzionalità, questo server virtuale deve essere tenuto sempre spento e solo quando si ha la necessità di creare una nuova autorizzazione ad accedere alla VPN aziendale, si potrà utilizzarlo solo per generare i nuovi certificati.

Quindi per il normale funzionamento della nostra VPN non si dovrà tenere acceso il server di certificate authority

La nostra rete di esempio avrà questa configurazione:

• Rete 192.168.1.0/24
• Gateway 192.168.1.1
• Server VPN 192.168.1.2
• Server CA 192.168.1.3

1. Installiamo OpenVPN e EasyRSA su entrambi i server:

  • colleghiamoci al server VPN e installiamo OpenVPN e EasyRSA tramite SSH
ssh utente@192.168.1.2
apt update
apt install openvpn

quindi installiamo EasyRSA sia sul sever VPN che sul server CA

wget -P ~/ https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.5/EasyRSA-nix-3.0.5.tgz
cd ~
tar xvf EasyRSA-nix-3.0.5.tgz

A questo punto abbiamo completato l’installazione dei software necessari

2. Configurazione del server CA per i certificati

  • colleghiamoci al server CA sempre tramite SSH
ssh utente@192.168.1.3
cd ~/EasyRSA-3.0.5/

utilizziamo il file di esempio vars.example come base

cp vars.example vars

quindi apriamo il file e portiamoci nella sezione dei set_var

nano vars

...
#set_var EASYRSA_REQ_COUNTRY    "US"
#set_var EASYRSA_REQ_PROVINCE   "California"
#set_var EASYRSA_REQ_CITY       "San Francisco"
#set_var EASYRSA_REQ_ORG        "Copyleft Certificate Co"
#set_var EASYRSA_REQ_EMAIL      "me@example.net"
#set_var EASYRSA_REQ_OU         "My Organizational Unit"
...


de-commentiamo tutte le righe sopra che troviamo nel file e rispettivamente modifichiamo le voci a nostro piacimento avendo cura di non cancellare le virgolette
Al termine salviamo e chiudiamo

Dentro la cartella EasyRSA c’è uno script ‘easyrsa’ che lanciato con l’opzione init-pki avvierà la nostra infrastruttura a chiave pubblica sul server CA

./easyrsa init-pki

riceveremo questo messaggio:

. . .
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /home/TUO_NOME_UTENTE/EasyRSA-3.0.5/pki

a questo punto riutilizziamo lo stesso script ma questa volta passiamo come opzione build-ca. In questo modo il sistema creerà due importanti file ca.crt e ca.key che rappresentano la parte pubblica e privata del nostro certificato SSL.

Il file ca.crt rappresenta la parte pubblica del certificato ed esso verrà usato sia dal server VPN che dai client che utilizzano il servizio di VPN

Il file ca.key è l’importantissima chiave privata per firmare le chiavi e i certificati sia dei server che dei client e pertanto questo file va depositato esclusivamente sul server CA il quale come dicevamo prima va avviato, per motivi di sicurezza, solo per firmare i ceritificati di eventuali richieste.

./easyrsa build-ca

Il sistema vi chiederà prima di confermare un nome che per motivi di comodità sarà quello del server CA e quindi basta dare invio e dopodichè vi chiederà di creare una password che sarà importante inquanto verrà richiesta ogni volta quando si dovranno firmare le richieste per i nuovi cilent.

3. Creazione del certificato e della chiave per il server VPN

Questa fase della configurazione creerà una richiesta di certificato che successivamente verrà trasmessa la nostro server CA il quale firmerà tale richiesta creando le chiavi necessarie per l’autenticazione

  • Colleghiamoci al server VPN tramite SSH

apriamo la cartella EasyRSA e lanciamo sempre lo stesso script init-pki.

cd EasyRSA-3.0.5/
./easyrsa init-pki

A questo punto effettuiamo la nostra prima richiesta passando allo script due argomenti gen-req e un nome a nostro piacimento. Per la guida verrà usato server ma nel caso si voglia usare un altro nome si dovrà avere cura di sostituire il nome server nei file di configurazione riportati nel resto della guida

./easyrsa gen-req server

il sistema ci chiederà quindi di creare una password e dopodichè avremo creato la nostra chiave privata che andrà copiata nella cartella /etc/openvpn

sudo cp ~/EasyRSA-3.0.5/pki/private/server.key /etc/openvpn/

trasferiamo il file di richiesta del server VPN al server CA per la successiva firma

scp ~/EasyRSA-3.0.5/pki/reqs/server.req utente@192.168.1.3:/tmp

  • Colleghiamoci al server CA

quindi importiamo la richiesta usando lo script easyrsa import-req seguito dal path del file della nostra richiesta

cd EasyRSA-3.0.5/
./easyrsa import-req /tmp/server.req server

ora possiamo firmare la richiesta usando lo script easyrsa seguito dal tipo di richiesta, ovvero server se si tratta di un server e client se si tratta di un client seguito dal nome server nel nostro caso oppure dal nome scelto in precedenza:

./easyrsa sign-req server server

questo è l’output

You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.

Request subject, to be signed as a server certificate for 3650 days:

subject=
commonName = server

Type the word 'yes' to continue, or any other input to abort.
Confirm request details: 


scriviamo prima yes e confermiamo, dopodichè il sistema ci chiederà la password che abbiamo dato alla richiesta. Ottenuto quindi il certificato firmato lo dovremo trasferire sul nostro server VPN

scp pki/issued/server.crt utente@192.168.1.2:/tmp

trasferiremo anche il file ca.cert:

scp pki/ca.crt utente@192.168.1.2:/tmp
  • Colleghiamoci al server VPN

copiamo il file ca.cert e server.cert nella cartella /etc/openvpn

sudo cp /tmp/{server.crt,ca.crt} /etc/openvpn/

A questo punto creiamo una chiave Diffie-Hellman con relativa firma HMAC che avrà lo scopo di garantire l’autenticità della trasmissione e aumentare il livello di sicurezza tra client e server. Questo sistema è utile sia in termini di sicurezza per il trasferimento delle chiavi durante la procedura iniziale di three-way-handshake, sia in termini di funzionalità, infatti senza la nostra chiave Diffie-Hellman ogni tentativo fraudolento di connessione al server verrà subito scartato senza quindi sovraccaricare lo stesso inutilmente nel tentativo di riconoscimento di una chiave non autorizzata

la procedura potra richiedere molto tempo:

cd EasyRSA-3.0.5/
./easyrsa gen-dh
openvpn --genkey --secret ta.key

Quindi copiamo i due file nella directory /etc/openvpn

sudo cp ~/EasyRSA-3.0.5/ta.key /etc/openvpn/
sudo cp ~/EasyRSA-3.0.5/pki/dh.pem /etc/openvpn/

Tutti i certificati e le chiavi necessarie sono state create ed installate correttamente

4 Generiamo una coppia di chiavi e un certificato Client

  • Colleghiamoci al server VPN

Questa procedura va ripetuta per ogni client che si vorrà autorizzare all’utlizzo della VPN. Procediamo con la creazione delle chiavi e del certificato. Per comodità creiamo una cartella per contenere i file di chiave e il certificato

mkdir -p ~/client-configs/keys

diamogli i permessi al solo proprietario della cartella

chmod -R 700 ~/client-configs

Adesso generiamo la richiesta

cd ~/EasyRSA-3.0.5/
./easyrsa gen-req client1

confermiamo e impostiamo una password. Dopodichè copiamo i file nella cartella di archivio

cp pki/private/client1.key ~/client-configs/keys/

trasferiamo il file di richiesta al server CA per la firma

scp pki/reqs/client1.req utente@192.168.1.3:/tmp


  • Colleghiamoci al server CA
cd EasyRSA-3.0.5/
./easyrsa import-req /tmp/client1.req client1

firmiamo la richiesta passando come argomento client e non server come fatto in precedenza

./easyrsa sign-req client client1

confermare con yes e successivamente con la password usata in precedenza

Quindi trasferire il certificato firmato al server VPN

scp pki/issued/client1.crt utente@192.168.1.2:/tmp
  • Collegati al server VPN

Copia il certificato del client e il file ca.crt e ta.key nella cartella di archivio creata prima

sudo cp /tmp/client1.crt ~/client-configs/keys/
sudo cp ~/EasyRSA-3.0.5/ta.key ~/client-configs/keys/
sudo cp /etc/openvpn/ca.crt ~/client-configs/keys/

5.Ora procediamo con la configurazione del servizione OpenVPN Service

Copiamo il file di configurazione di esempio nella cartella /etc/openvpn

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

Quindi apriamo il file di configurazione del server

sudo nano /etc/openvpn/server.conf

quindi usando la combinazione di tasti ctrl+w apriamo il motore di ricerca di nano e digita HMAC. In questa sezione troviamo la riga tls-auth e nel caso sia commentata la decommentiamo e poi aggiungiamo il paramtero

tls-auth ta.key 0 # This file is secret key-direction 0
key-direction 0

poi troviamo la riga

cipher AES-256-CBC

e nel caso sia commentata la decommentiamo. Questa impostazione ci garantisce un buon livello di crittografia.Aggiungiamo anche l'algoritmo sha256

auth SHA256

ultima modifica essenziale è quella di decommentare le voci

user nobody
group nogroup

Salviamo e chiudiamo il file. Queste viste fino a questo punto sono modifiche essenziali al funzionamento del servizio openvpn. D'altronde esistono altre impostazioni utili a rendere il servizio piu sicuro e che io consiglio vivamente di applicare.La prima di queste riguarda il file server.conf che ci permetterà di instradare tutto il traffico nel tunnel della vpn inquanto si imporrà anche ai client di utilizzare determinati DNS. Quindi apriamo il file server.conf e togliamo ; alla direttiva riportata sotto

push "redirect-gateway def1 bypass-dhcp"

lo stesso facciamo alle righe che troviamo subito sotto

push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"

Sarà possibile cambiare anche la porta di default di openvpn e la tipologia di protocollo, ovvero TCP o UDP.

#opzionale
port 443

qui possiamo sostituire la 443 con una porta a nostro piacimento. Ricordati successivamente di attivare il port forwarding sul tuo router per la porta che scegli.

Lo stesso può cambiare questa impostazione scegliendo la tipologia di protocollo tra TCP o UDP. Nel caso si scelga il protocollo TCP ricordati di sostituire la seguente direttiva ovvero cambiare il suo valore da 1 a 0

#opzionale
proto tcp

#opzionale
explicit-exit-notify 0

Se si è modificato il nome del server durante il comando ./build-key-server utilizzato in precedenza allora bisogna cambiare anche le voci seguenti, altrimenti gia risltano correttamente inizializzate

cert server.crt
key server.key

Perfetto. Adesso salva e chiudi

Un aspetto molto importante per il corretto funzionamento della nostra VPN è sicuramente il IP-Forwording, ovvero la funzionalità che il nostro server dovrà espletare per instradare correttamente tutto il traffico. Qundi con il solito editor apriamo il file

sudo nano /etc/sysctl.conf

individuiamo la riga net.ipv4.ip_forward e cambiamo il suo valore da 0 a 1

net.ipv4.ip_forward=1

Salva e chiudi.

A questo punto continuiamo con le impostazioni necessarie a garantire il masquerading del nostro traffico. Innanzitutto individuiamo la nostra interfaccia di rete pubblica lanciando il comando:

ip route | grep default

la stringa che ci ritornerà il sistema conterrà la nostra stringa che dovrebbe essere dopo la parola dev:

default via 203.0.113.1 dev enp2s0 proto static

Apriamo il file /etc/ufw/before.rules per aggiungere la configurazione necessaria:

sudo nano /etc/ufw/before.rule

In questo file abbiamo la possibilità di inserire le regole necessarie al mascheramento e che verranno lette dal sistema prima delle regole impostate nel firewall UFW. Incolliamo quanto segue avendo cura di sostituire il nome della nostra interfaccia di rete che abbiamo ricavato prima;

#
# 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 enp2s0 (change to the interface you discovered!)
-A POSTROUTING -s 10.8.0.0/8 -o enp2s0 -j MASQUERADE
COMMIT
# END OPENVPN RULES

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

questa porzione di codice devve essere inserita all'inizio del file. Salviamo e chiudiamo.

Modifichiamo adesso all'interno del file /etc/default/ufw  la direttiva DEFAULT_FORWARD_POLICY con il valore ACCEPT anzichè DROP,

sudo nano /etc/default/ufw

modifichiamo la voce:

DEFAULT_FORWARD_POLICY="ACCEPT"

Salviamo e chiudiamo.

Ora si potrà inserire come di consueto con il comando ufw l'attivazione del traffico sulla nostra porta del server VPN che abbiamo scelto nella fase iniziale della guida:

sudo ufw allow 443/tcp
sudo ufw disable
sudo ufw enable

  • Attiviamo e poi Avviamo il servizio OpenVPN

Utilizziamo il comando systemctl per avviare il servizio passando come argomento il file di configurazione del nostro server che si trova nella cartella /etc/openvpn/server.conf:

sudo systemctl start openvpn@server

Controlliamo lo stato del servizio:

sudo systemctl status openvpn@server

Dovrebbe risultare active dall'output del comando. Per abilitare invece il servizio in modo automatico ogni qual volta si avvia il server, diamo il comando:

sudo systemctl enable openvpn@server

La configurazione lato server è completata. Bisogna ora configurare il metodo per la creazione del file di configurazione che userà effettivamente il client per potersi cosi collegare al server:

Criamo una directroy sul server OpenVPN:

mkdir -p ~/client-configs/files

per iniziare partiamo da un esempio di file di configurazione e poi modificheremo secondo le nostre esigenze il tutto:

cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf

Apriamo il file

nano ~/client-configs/base.conf

Individuiamo la direttiva remote che indicherà al client l'indirizzo pubblico del nostro server che noi abbiamo gia impostato in fase di configurazione. Qualora inizialmente si è deciso di cambiare la porta del server OpenVPN questa deve essere indicata anche in questa direttiva:

remote your_server_ip 443

decommentiamo, rimuovendo il simbolo ; , le direttive usergroup, probabilmente già risulteranno decommentate

user nobody
group nogroup

commentiamo invece le direttive ca, cert e key:

#ca ca.crt
#cert client.crt
#key client.key

in modo analogo commentiamo anche le direttive ta.key e tls-auth:

#tls-auth ta.key 1

Aggiungere o modificare i parametri cipher e auth nel file /etc/openvpn/server.conf:

cipher AES-256-CBC
auth SHA256

Aggiungiamo adesso la direttiva key-direction 1 alla fine del file

key-direction 1

Infine le righe seguenti vanno aggiunte in coda al file e devono restare commentate qualora il client che utilizzarrà la nostra VPN abbia come sistema operativo WINDOWS altrimenti vanno  decommentate se il sistema operativo è LINUX:

# script-security 2
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf

salviamo e chiudiamo.

Successivamente, creiamo uno script che compilerà la configurazione di base con i relativi certificati, chiavi e file di crittografia e quindi inserirà la configurazione creata nella directory ~/client-configs/files.

Apri un nuovo file chiamato make_config.sh nella directory ~/client-configs:

nano ~/client-configs/make_config.sh

il contenuto sarà

#!/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

Salviamo e chiudiamo.

Rendiamo eseguibile il file:

chmod 700 ~/client-configs/make_config.sh 

In questo modo avremo ina copia del nostro file base.conf con all'interno i nostri certificati e le nostre chiavi, aggiunge una copia del tutto nella directory dei file di configurazione e genera un file con estensione ovpn che dovra essere usato direttamente sul client. Si nota quindi, che ogni volta che vogliamo autorizzare un nuovo client al nostro server VPN basterà lanciare questo script per creare la configurazione necessaria. Non bisogna però dimenticare che per ogni client va creata una coppia di chiavi e certificati con la procedura vista in precedenza:

cd ~/client-configs
sudo ./make_config.sh client1

abbiamo il nostro file ovpn

ls ~/client-configs/files

Trasferito questo file direttamente sul client possiamo finalmente collegarci alla nostra VPN.

Nel caso di client con sistema operativo LINUX basterà andare nella cartetla dove abbiamo trasferito il file di configurazione e lanciare il comando

openvpn --configure client.ovpn

Nel caso invece si tratti di un client con sistema operativo WINDOWS, una volta installato il client OpenVPN, troveremo una cartella chiamata config nella cartella principale dell'utente \User\[nome utente]\config, qui copieremo il file ovpn. In questo modo il servizio riconoscerà direttamente la configurazioneda noi caricata