Domenico Iezzi
VPN (Virtual Private Network) è un insieme di tool che permette la connessione di più reti private in maniera sicura, attraverso una rete pubblica.
virtuale: utenti possono comunicare tra di loro come se fossero connessi in una LAN
privata: accessibile in maniera sicura solo dagli utenti autorizzati
Primo standard per il networking sicuro (1995)
Progetto open source sviluppato da James Yonan nel 2001 come alternativa ad IPSec.
OpenVPN può utilizzare due protocolli per il trasporto dei dati: TCP o UDP.
Il protocollo TCP è un protocollo affidabile che utilizza un network non sempre affidabile. In caso un pacchetto non arrivi a destinazione, viene ritrasmesso con un timeout che aumenta esponenzialmente ad ogni retry
Non è considerato una buona opzione per una VPN in quanto
Considerato un protocollo più adatto per una VPN, in quanto
Interfaccia di rete virtuale, cioè non associata direttamente ad un'interfaccia di rete fisica, ma astratta dal kernel.
Dati in arrivo su tale interfaccia vengono inviati al demone OpenVPN che si occupa di cifrare e incapsulare questi dati nel protocollo scelto
Due tipologie principali sono supportate dal kernel linux:
TAP viene utilizzato con il layer 2, quindi si comporta come una vera e propia scheda di rete
Svantaggi:
TUN invece opera in layer 3 e permette il transito di pacchetti IPV4/6
Svantaggi:
OpenVPN implementa due metodi per cifrare la connessione:
OpenVPN è in grado di generare una chiave statica per cifrare la connessione.
openvpn --genkey --secret secret.key
Un file di configurazione minimale per il server:
dev tun
ifconfig 10.8.0.1 10.8.0.2
secret static.key
Semplice e veloce, comodo per fare testing ma in generale sconsigliato per motivi di sicurezza (more)
La modalità TLS consiste in una autenticazione bidirezionale tramite certificato. Una volta autenticati, client e server possono scambiarsi chiavi in maniera sicura
Vantaggi di questo approccio:
Gli autori di openvpn hanno sviluppato un comodo tool per permettere il setup di una PKI, la generazione e la firma di certificati, chiamato EasyRSA
EasyRSA 3 è la versione più recente. La versione presente nei repository delle maggiori distro GNU/Linux potrebbe essere piuttosto datata (ad esempio 2.2.2 in Ubuntu 16.04), tuttavia è possibile clonare il repository git e utilizzare direttamente il tool senza dover installare nulla
git clone https://github.com/OpenVPN/easy-rsa.git
cd easy-rsa/easyrsa3
Inizializziamo la PKI:
./easyrsa init-pki
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /your/path/to/easyrsa3/pki
Creiamo il root certificate:
./easyrsa build-ca
Enter New CA Key Passphrase:
Re-Enter New CA Key Passphrase:
Generating RSA private key, 2048 bit long modulus
[..]
CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/your/path/to/easyrsa3/pki/ca.crt
Creiamo un certificato per il nostro server:
./easyrsa build-server-full server
Generating a 2048 bit RSA private key
writing new private key to '/path/to/your/easyrsa3/pki/private/pre.key.o4vxT8HKMX'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
[..]
The Subject's Distinguished Name is as follows
commonName :ASN.1 12:'server'
Certificate is to be certified until Mar 27 17:33:28 2028 GMT (3650 days)
Write out database with 1 new entries
Data Base Updated
Analogamente usiamo ./easyrsa build-client-full client
per creare un certificato per il client
Concludiamo creando i parametri per lo scambio di chiavi Diffie-Helman
./easyrsa gen-dh
[..]
DH parameters of size 2048 created at /your/path/to/easyrsa3/pki/dh.pem
pki
|-- ca.crt
|-- dh.pem
|-- issued
| |-- client.crt
| `-- server.crt
`-- private
|-- ca.key
|-- client.key
`-- server.key
E' possibile configurare il demone OpenVPN tramite parametri a riga di comando:
Fortunatamente è possibile specificare le opzioni in un comodo file di configurazione. La directory di default utilizzata per i file di
configurazione e certificati è /etc/openvpn
.
Inoltre è possibile specificare una subdirectory per ogni configurazione. Ad esempio in Debian 9 avremo due subdirectory di default:
/etc/openvpn/client
/etc/openvpn/server
Dopo aver installato openvpn dai repository della propria distro, è possibile trovare degli esempi di configurazione ben documentati nei seguenti path:
/usr/share/doc/openvpn/examples/
/usr/share/openvpn/examples/
Questi file costituiscono un ottimo punto di partenza per la configurazione del proprio client/server OpenVPN.
Copiamo i file precedentemente creati tramite EasyRSA nella directory openvpn
# cp pki/issued/server.crt pki/dh.pem pki/ca.crt pki/private/server.key /etc/openvpn/
Copiamo il file di configurazione di esempio:
# cd /etc/openvpn/server
# gzip -dck /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > server.conf
# vim server.conf
Oppure creiamone uno da zero
# cd /etc/openvpn
# vim server.conf
Innanzitutto specifichiamo la porta su cui restare in ascolto (default 1194), protocollo e tipo di interfaccia virtuale da utilizzare
port 1194
proto udp
dev tun
Specifichiamo i file contenenti chiavi e certificati
ca ca.crt
cert server.crt
key server.key
dh dh.pem
N.B. sono stati utilizzati path relativi in quanto abbiamo copiato tutti i file necessari nella working directory di OpenVPN
Crea un pool di indirizzi ip da assegnare ai client che si connettono
server 192.168.2.0 255.255.255.0
server-ipv6 fd00::/64
Push permette di inviare impostazioni ai client che si connettono, in questo modo si possono comunicare informazioni su:
N.B.: i client che si connettono devono avere l'opzione pull
(o client
) per ricevere le configurazioni tramite push
push "route 192.168.0.0 255.255.255.0"
redirect-gateway: è una direttiva che redirige tutto il traffico sulla vpn, questo lo fa in 3 passi:
Abilitare la compressione permette di risparmiare banda aggiungendo dell'overhead e sacrificando un po' di RAM e CPU
Utilizzare l'opzione comp-lzo
(deprecata) se si utilizzano client la cui versione è minore di 2.4
Altrimenti le opzioni consigliate sono
compress lz4-v2
push "compress lz4-v2"
server 10.11.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "route 192.168.20.0 255.255.255.0"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
compress lz4-v2
push "compress lz4-v2"
messaggio tipo ping da client a server ogni 10 secondi. Niente risposta in 120s = offline.
keepalive 10 120
Configurazione TLS consigliata
tls-version-min 1.2
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-128-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA
cipher AES-256-CBC
auth SHA512
La chiave statica utilizzata per il setup "easy" può essere utilizzata per aggiungere una firma HMAC ad ogni pacchetto. Ogni pacchetto che non presenta una firma HMAC corretta verrà droppato. Può essere generata tramite comando
# openvpn --genkey --secret /etc/openvpn/server/ta.key
Sulla configurazione inseriremo (0 se configurazione server, 1 se configurazione client)
tls-auth ta.key 0
N.B. usare lo stesso file su server e tutti i client
Permette ai client connessi alla VPN di poter comunicare tra loro
client-to-client
Mantenere un record client - virtual address. Se un client si riconnette, gli verrà assegnato l'IP precedente
ifconfig-pool-persist ipp.txt
Ridurre privilegi del demone openvpn
user nobody
group nogroup
Se il vostro server è protetto da firewall, è necessario aggiungere delle regole per il corretto forwarding dei pacchetti tra le varie interfacce.
Abilitare pacchetti UDP in input nella porta scelta
# iptables -A INPUT -p udp --dport 1194 -j ACCEPT
Abilitare il forwarding tra l'interfaccia virtuale e quella fisica
# iptables -A FORWARD -i tun0 -o eth0 -j ACCEPT
# iptables -A FORWARD -i eth0 -o tun0 -j ACCEPT
NAT
# iptables -t nat -A POSTROUTING -s 10.11.0.0/24 -o eth0 -j MASQUERADE
In genere il pacchetto OpenVPN presente in tutte le distro contiene anche il relativo service file di systemd. In caso avessimo utilizzato una subdirectory, possiamo lanciare il demone con:
sudo systemctl start openvpn-(client|server)@<conf-file-name>.service
In caso avessimo copiato i file direttamente in /etc/openvpn
:
sudo systemctl start openvpn@<conf-file-name>.service
Nel nostro caso:
sudo systemctl start openvpn-server@server.service
La configurazione client è molto simile a quella server. In questo caso chiameremo il nostro file di configurazione client.conf
,
e sposteremo tutti i file necessari nella directory /etc/openvpn/client
. Per connetterci al nostro server sono necessarie le
seguenti opzioni
client
remote myvpnserver.com 1194
ca ca.crt
cert client.crt
key client.key
tls-auth ta.key 1
comp-lzo # se lo avete abilitato su server
auth SHA512 # se lo avete specificato su server
cipher AES-256-CBC # se lo avete specificato su server
Per connetterci alla VPN:
sudo systemctl start openvpn-client@client.service
E' possibile concatenare il file di configurazione con i relativi certificati/chiavi client in un unico file tramite il tool ovpngen
# ls
ca.crt client.crt client.key ta.key
# /path/to/ovpngen myvpnhost.com ca.crt client.crt client.key ta.key > client.ovpn
# vim client.ovpn
Una volta generato è possibile importare il profile nelle app OpenVPN di vari OS, in modo da potersi connettere senza dover configurare nulla