Product SiteDocumentation Site

10.2. Rete privata virtuale (VPN)

Una rete privata virtuale (VPN in breve) è un modo per collegare due diverse reti locali attraverso Internet per mezzo di un tunnel che, per mantenere la riservatezza, di solito è criptato. Le VPN vengono spesso usate per integrare una macchina remota nella rete locale di un'azienda.
Esistono diversi strumenti utili a questo scopo. OpenVPN è una soluzione efficace, facile da implementare e gestire, basata su SSL/TLS. Un'altra possibilità è l'utilizzo di IPsec per cifrare il traffico IP tra due macchine; la cifratura è trasparente, il che significa che le applicazioni in esecuzione su questi host non devono essere modificate per tener conto della VPN. Può anche essere utilizzato SSH per realizzare una VPN, in aggiunta alle sue caratteristiche più convenzionali. Infine, una VPN può essere stabilita utilizzando il protocollo Microsoft PPTP. Esistono altre soluzioni, ma vanno oltre l'obiettivo di questo libro.

10.2.1. OpenVPN

OpenVPN è un software dedicato alla creazione di reti private virtuali. La sua configurazione prevede la creazione di interfacce di rete virtuali sul server VPN e sul/sui client; sono supportate entrambe le interfacce tun (per tunnel a livello IP) e tap (per tunnel a livello di Ethernet). In pratica, generalmente vengono utilizzate le interfacce tun tranne quando i client VPN vengono integrati nella rete locale del server per mezzo di un bridge (ponte) Ethernet.
OpenVPN si basa su OpenSSL per tutta la crittografia SSL/TLS e le funzioni associate (riservatezza, autenticazione, integrità, non rifiuto). Può essere configurato sia con una chiave privata condivisa che con certificati X.509 basati su un'infrastruttura a chiave pubblica. Quest'ultima configurazione è fortemente preferibile in quanto permette una maggiore flessibilità di fronte a un numero crescente di utenti in roaming che accedono alla VPN.

10.2.1.1. Infrastruttura a chiave pubblica: easy-rsa

Si tratta di una «coppia di chiavL'algoritmo RSA è ampiamente utilizzato nella crittografia a chiave pubblica. i», formata da una chiave privata e una chiave pubblica. Le due chiavi sono strettamente legate l'una all'altra, e le loro proprietà matematiche sono tali che un messaggio cifrato con la chiave pubblica può essere decifrato solo da qualcuno a conoscenza della chiave privata, garantendone la riservatezza. Al contrario, un messaggio cifrato con la chiave privata può essere decodificato da chiunque conosca la chiave pubblica, il che permette di autenticare l'origine di un messaggio in quanto solo una persona con accesso alla chiave privata lo avrebbe potuto generare. Quando è associato ad una funzione hash digitale (MD5, SHA1 o una variante più recente), si ottiene un meccanismo di firma che può essere applicato a qualsiasi messaggio.
Tuttavia, chiunque può creare una coppia di chiavi, archiviarvi qualsiasi identità, e fingere di essere l'identità da lui scelta. Una soluzione implica il concetto di Autorità di certificazione (CA: «Certification Authority» ), formalizzato dallo standard X.509. Questo termine si riferisce a un soggetto che detiene una coppia di chiavi fidate conosciuto come certificato principale. Questo certificato viene utilizzato solamente per firmare altri certificati (coppie di chiavi), dopo che sono state adottate misure adeguate per controllare l'identità memorizzata nella coppia di chiavi. Le applicazioni che utilizzano X.509 possono quindi controllare i certificati presentati, se ne conoscono i certificati principali attendibili.
OpenVPN segue questa regola. Dal momento che le CA pubbliche emettono solamente certificati in cambio di un (costoso) pagamento, è possibile creare un'autorità di certificazione privata all'interno dell'azienda. Il pacchetto easy-rsa fornisce gli strumenti che servono come infrastruttura di certificazione X.509, offrendo un insieme di script utilizzando il comando openssl.
Gli amministratori della Falcot Corp utilizzano questo strumento per creare i certificati richiesti, sia per il server che per i client. Questo permette una configurazione simile di tutti i client, dato che dovranno essere impostati solo per considerare attendibili i certificati provenienti dalla CA locale di Falcot. Questa CA crea il primo certificato; a tal fine, gli amministratori impostano in un luogo appropriato la directory con i file richiesti per la CA, preferibilmente su una macchina non connessa alla rete, per ridurre il rischio di furto della chiave privata della CA.
$ make-cadir pki-falcot
$ cd pki-falcot
Successivamente salvano i parametri richiesti nel file vars, specialmente quelli denominati con un prefisso KEY_; queste variabili vengono poi integrate nell'ambiente:
$ vim vars
$ grep KEY_ vars
export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`
export KEY_DIR="$EASY_RSA/keys"
echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR
export KEY_SIZE=2048
export KEY_EXPIRE=3650
export KEY_COUNTRY="FR"
export KEY_PROVINCE="Loire"
export KEY_CITY="Saint-Étienne"
export KEY_ORG="Falcot Corp"
export KEY_EMAIL="admin@falcot.com"
export KEY_OU="Certificate authority"
export KEY_NAME="Certificate authority for Falcot Corp"
# If you'd like to sign all keys with the same Common Name, uncomment the KEY_CN export below
# export KEY_CN="CommonName"
$ . ./vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /home/roland/pki-falcot/keys
$ ./clean-all
Il passo successivo è la creazione della coppia di chiavi della CA stessa (le due parti della coppia di chiavi vengono memorizzate nei file keys/ca.crt e keys/ca.key durante questa fase):
$ ./build-ca
Generating a 2048 bit RSA private key
...................................................................+++
...+++
writing new private key to 'ca.key'
-----
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.
-----
Country Name (2 letter code) [FR]:
State or Province Name (full name) [Loire]:
Locality Name (eg, city) [Saint-Étienne]:
Organization Name (eg, company) [Falcot Corp]:
Organizational Unit Name (eg, section) [Certificate authority]:
Common Name (eg, your name or your server's hostname) [Falcot Corp CA]:
Name [Certificate authority for Falcot Corp]:
Email Address [admin@falcot.com]:
Il certificato per il server VPN può essere creato, così come i parametri Diffie-Hellman necessari dal lato server per una connessione SSL/TLS. Il server VPN è identificato dal suo nome DNS vpn.falcot.com; questo nome viene riutilizzato per i file chiave generati (keys/vpn.falcot.com.crt per il certificato pubblico, keys/vpn.falcot.com.key per la chiave privata):
$ ./build-key-server vpn.falcot.com
Generating a 2048 bit RSA private key
.....................................................................................................................+++
...........+++
writing new private key to 'vpn.falcot.com.key'
-----
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.
-----
Country Name (2 letter code) [FR]:
State or Province Name (full name) [Loire]:
Locality Name (eg, city) [Saint-Étienne]:
Organization Name (eg, company) [Falcot Corp]:
Organizational Unit Name (eg, section) [Certificate authority]:
Common Name (eg, your name or your server's hostname) [vpn.falcot.com]:
Name [Certificate authority for Falcot Corp]:
Email Address [admin@falcot.com]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /home/roland/pki-falcot/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'FR'
stateOrProvinceName   :PRINTABLE:'Loire'
localityName          :T61STRING:'Saint-\0xFFFFFFC3\0xFFFFFF89tienne'
organizationName      :PRINTABLE:'Falcot Corp'
organizationalUnitName:PRINTABLE:'Certificate authority'
commonName            :PRINTABLE:'vpn.falcot.com'
name                  :PRINTABLE:'Certificate authority for Falcot Corp'
emailAddress          :IA5STRING:'admin@falcot.com'
Certificate is to be certified until Mar  6 14:54:56 2025 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
$ ./build-dh
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
[…]
Il passo seguente crea i certificati per i client VPN, è richiesto un certificato per ogni computer o persona autorizzata ad usare la VPN:
$ ./build-key JoeSmith
Generating a 2048 bit RSA private key
................................+++
..............................................+++
writing new private key to 'JoeSmith.key'
-----
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.
-----
Country Name (2 letter code) [FR]:
State or Province Name (full name) [Loire]:
Locality Name (eg, city) [Saint-Étienne]:
Organization Name (eg, company) [Falcot Corp]:
Organizational Unit Name (eg, section) [Certificate authority]:Development unit
Common Name (eg, your name or your server's hostname) [JoeSmith]:Joe Smith
[…]
Ora che sono stati creati tutti i certificati, bisogna copiarli dove è appropriato: la chiave pubblica del certificato principale (keys/ca.crt) verrà memorizzata su tutte le macchine (sia server che client) come /etc/ssl/certs/Falcot_CA.crt. Il certificato del server è installato solo sul server (keys/vpn.falcot.com.crt va in /etc/ssl/vpn.falcot.com.crt, e keys/vpn.falcot.com.key va in /etc/ssl/private/vpn.falcot.com.key con permessi limitati in modo che solo l'amministratore possa leggerlo), con i corrispondenti parametri Diffie-Hellman (keys/dh2048.pem) installati in /etc/openvpn/dh2048.pem. I certificati client vengono installati in modo simile nel corrispondente client VPN.

10.2.1.2. Configurazione del server OpenVPN

Per impostazione predefinita, lo script di inizializzazione di OpenVPN cerca di avviare tutte le reti private virtuali definite in /etc/openvpn/*.conf. Per configurare un server VPN basta quindi memorizzare il corrispondente file di configurazione in questa directory. Un buon punto di partenza è /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz, che porta ad un server abbastanza standard. Naturalmente, alcuni parametri devono essere adattati: ca, cert, key e dh devono descrivere le posizioni scelte (rispettivamente, /etc/ssl/certs/Falcot_CA.crt, /etc/ssl/vpn.falcot.com.crt, /etc/ssl/private/vpn.falcot.com.key e /etc/openvpn/dh2048.pem). La direttiva server 10.8.0.0 255.255.255.0 definisce la sottorete utilizzata dalla VPN; il server utilizza il primo indirizzo IP in quell'intervallo (10.8.0.1) ed il resto degli indirizzi viene assegnato ai client.
Con questa configurazione, l'avvio di OpenVPN crea l'interfaccia di rete virtuale solitamente con il nome tun0. Tuttavia, i firewall sono spesso configurati contemporaneamente alle interfacce di rete reali, e questo avviene prima dell'avvio di OpenVPN. Le buone pratiche raccomandano pertanto la creazione di una interfaccia di rete virtuale persistente e di configurare OpenVPN ad utilizzare questa interfaccia preesistente. Questo permette inoltre di scegliere il nome per questa interfaccia. A tal fine, il comando openvpn --mktun --dev vpn --dev-type tun crea una interfaccia di rete virtuale denominata vpn di tipo tun; questo comando può essere facilmente integrato nello script di configurazione del firewall, o in una direttiva up del file /etc/network/interfaces. Il file di configurazione di OpenVPN deve essere aggiornato di conseguenza, con le direttive dev vpn e dev-type tun.
Salvo ulteriori modifiche, i client VPN possono accedere solo al server VPN stesso attraverso l'indirizzo 10.8.0.1. Per fornire ai client l'accesso alla rete locale (192.168.0.0/24) è necessario aggiungere una direttiva push route 192.168.0.0 255.255.255.0 nella configurazione di OpenVPN, in questo modo i client VPN ottengono automaticamente un percorso di rete che gli consente di raggiungere questa rete attraverso la VPN. Inoltre, le macchine sulla rete locale devono anche essere informate che il percorso verso la VPN passa attraverso il server VPN (questo funziona automaticamente quando il server VPN è installato sul gateway). In alternativa, il server VPN può essere configurato per eseguire il mascheramento IP in modo che le connessioni provenienti dai client VPN figurino invece come provenienti dal server VPN (vedere la Sezione 10.1, «Gateway»).

10.2.1.3. Configurazione del client OpenVPN

Anche l'impostazione di un client OpenVPN richiede la creazione di un file di configurazione in /etc/openvpn/. Una configurazione standard può essere ottenuta usando /usr/share/doc/openvpn/examples/sample-config-files/client.conf come punto di partenza. La direttiva remote vpn.falcot.com 1194 indica l'indirizzo e la porta del server OpenVPN. Le direttive ca, cert e key devono essere modificate per indicare le posizioni dei file di chiave.
Se la VPN non deve essere avviata automaticamente all'avvio, impostare la direttiva AUTOSTART su none nel file /etc/default/openvpn. L'avvio o l'arresto di una determinata connessione VPN è sempre possibile con i comandi service openvpn@name start e service openvpn@nome stop (dove il nome della connessione corrisponde a quello definito in /etc/openvpn/nome.conf).
Il pacchetto network-manager-openvpn-gnome contiene un'estensione per Network Manager (vedere la Sezione 8.2.4, «Automatizzare la configurazione della rete per gli utenti in movimento») che consente la gestione delle reti private virtuali di OpenVPN. Questo permette ad ogni utente di configurare le connessioni OpenVPN graficamente e di controllarle tramite l'icona di gestione della rete.

10.2.2. Rete privata virtuale con SSH

In realtà ci sono due modi per creare una rete privata virtuale con SSH. La versione storica richiede la creazione di uno strato di PPP sul collegamento SSH. Questo metodo è descritto in un documento HOWTO:
Il secondo metodo è più recente, ed è stato introdotto con OpenSSH 4.3. OpenSSH ora può creare interfacce di rete virtuali (tun*) su entrambi i lati di una connessione SSH, e queste interfacce virtuali possono essere configurate esattamente come se fossero interfacce fisiche. Il sistema di tunneling deve essere prima abilitato impostando PermitTunnel a «yes» nel file di configurazione del server SSH (/etc/ssh/sshd_config). Nello stabilire la connessione SSH, la creazione di un tunnel deve essere esplicitamente richiesta con l'opzione -w any:any (any può essere sostituito con il numero desiderato per il dispositivo tun). Questo richiede che l'utente disponga dei privilegi di amministratore su entrambi i lati, così da poter creare il dispositivo di rete (in altre parole, la connessione deve essere stabilita come root).
Entrambi i metodi, permettono di implementare facilmente la creazione di una rete privata virtuale su SSH. Tuttavia, non nella maniera più efficiente: in particolare le VPN che forniscono non sono adatte per elevati livelli di traffico.
La spiegazione è che quando uno stack TCP/IP è incapsulato all'interno di una connessione TCP/IP (per SSH), il protocollo TCP viene utilizzato per due volte: una per la connessione SSH ed una all'interno del tunnel. Questo comporta problemi, soprattutto per il modo in cui TCP si adatta alle condizioni della rete variando i ritardi di timeout. Sul sito riportato di seguito viene descritto il problema in modo più dettagliato: . Le VPN su SSH dovrebbero pertanto essere limitate unicamente a tunnel temporanei senza vincoli di prestazioni.

10.2.3. IPSec

IPsec, pur rappresentando lo standard nelle VPN IP, è molto più difficile da implementare. Il motore di IPsec è integrato nel kernel di Linux; il pacchetto ipsec-tools fornisce i componenti necessari nello spazio utente, gli strumenti di controllo e configurazione. In termini concreti, in ogni host è presente un file /etc/ipsec-tools.conf che contiene i parametri per i tunnel IPsec (o, nella terminologia IPsec, Security Association) che riguardano l'host; lo script /etc/init.d/setkey fornisce un modo per avviare e arrestare un tunnel (ogni tunnel è un collegamento sicuro ad un altro host collegato alla rete privata virtuale). Questo file può essere costruito a mano a partire dalla documentazione fornita dalla pagina di manuale setkey(8). Tuttavia, scrivere esplicitamente i parametri per tutti gli host in un insieme non piccolo di macchine diventa rapidamente un compito arduo, in quanto il numero di tunnel cresce velocemente. L'installazione di un demone IKE (per IPsec Key Exchange) come racoon o strongswan rende il processo molto più semplice rendendo la'mministrazione centralizzata, e più sicura ruotando le chiavi periodicamente.
A dispetto del suo status di riferimento, la complessità della configurazione di IPsec limita il suo utilizzo nella pratica. Soluzioni basate su OpenVPN verranno generalmente preferite quando i tunnel richiesti non sono né troppi né troppo dinamici.

10.2.4. PPTP

PPTP (protocollo di tunneling punto a punto: Point to Point Tunneling Protocol) utilizza due canali di comunicazione, uno per i dati di controllo e uno per i dati di traffico; quest'ultimo utilizza il protocollo GRE (incapsulamento generico di instradamento: Generic Routing Encapsulation). Un collegamento PPP standard viene poi stabilito sopra il canale di scambio dei dati.

10.2.4.1. Configurazione del client

Il pacchetto pptp-linux contiene un client PPTP facilmente configurabile per Linux. Le seguenti istruzioni trovano ispirazione nella documentazione ufficiale:
Gli amministratori della Falcot hanno creato diversi file: /etc/ppp/options.pptp, /etc/ppp/peers/falcot, /etc/ppp/ip-up.d/falcot e /etc/ppp/ip-down.d/falcot.

Esempio 10.2. Il file /etc/ppp/options.pptp

# Opzioni PPP usate per una connessione PPTP
lock
noauth
nobsdcomp
nodeflate

Esempio 10.3. Il file /etc/ppp/peers/falcot

# vpn.falcot.com e' il server PPTP
pty "pptp vpn.falcot.com --nolaunchpppd"
# la connessione si identifichera' come utente 'vpn'
user vpn
remotename pptp
# e' necessaria la cifratura
require-mppe-128
file /etc/ppp/options.pptp
ipparam falcot

Esempio 10.4. Il file /etc/ppp/ip-up.d/falcot

# Creare l'instradamento per la rete Falcot
if [ "$6" = "falcot" ]; then
  # 192.168.0.0/24 e' la rete Falcot (remota)
  route add -net 192.168.0.0 netmask 255.255.255.0 dev $1
fi

Esempio 10.5. Il file /etc/ppp/ip-down.d/falcot

# Eliminare l'instradamento alla rete Falcot
if [ "$6" = "falcot" ]; then
  # 192.168.0.0/24 e' la rete Falcot (remota)
  route del -net 192.168.0.0 netmask 255.255.255.0 dev $1
fi

10.2.4.2. Configurazione del server

pptpd è il server PPTP per Linux. Il file di configurazione principale, /etc/pptpd.conf, richiede pochissime modifiche: localip (indirizzo IP locale) e remoteip (indirizzo IP remoto). Nell'esempio riportato di seguito, il server PPTP utilizza sempre l'indirizzo 192.168.0.199 e i client PPTP ricevono gli indirizzi IP da 192.168.0.200 a 192.168.0.250.

Esempio 10.6. Il file /etc/pptpd.conf

# TAG: speed
#
#       Specifies the speed for the PPP daemon to talk at.
#
speed 115200

# TAG: option
#
#       Specifies the location of the PPP options file.
#       By default PPP looks in '/etc/ppp/options'
#
option /etc/ppp/pptpd-options

# TAG: debug
#
#       Turns on (more) debugging to syslog
#
# debug

# TAG: localip
# TAG: remoteip
#
#       Specifies the local and remote IP address ranges.
#
#       You can specify single IP addresses separated by commas or you can
#       specify ranges, or both. For example:
#
#               192.168.0.234,192.168.0.245-249,192.168.0.254
#
#       IMPORTANT RESTRICTIONS:
#
#       1. No spaces are permitted between commas or within addresses.
#
#       2. If you give more IP addresses than MAX_CONNECTIONS, it will
#          start at the beginning of the list and go until it gets
#          MAX_CONNECTIONS IPs. Others will be ignored.
#
#       3. No shortcuts in ranges! ie. 234-8 does not mean 234 to 238,
#          you must type 234-238 if you mean this.
#
#       4. If you give a single localIP, that's ok - all local IPs will
#          be set to the given one. You MUST still give at least one remote
#          IP for each simultaneous client.
#
#localip 192.168.0.234-238,192.168.0.245
#remoteip 192.168.1.234-238,192.168.1.245
#localip 10.0.1.1
#remoteip 10.0.1.2-100
localip 192.168.0.199
remoteip 192.168.0.200-250
La configurazione PPP utilizzata da un server PPTP richiede anche alcuni cambiamenti in /etc/ppp/pptpd-options. I parametri importanti sono il nome del server (pptp), il nome di dominio (falcot.com) e gli indirizzi IP per i server DNS e WINS.

Esempio 10.7. Il file /etc/ppp/pptpd-options

## turn pppd syslog debugging on
#debug

## change 'servername' to whatever you specify as your server name in chap-secrets
name pptp
## change the domainname to your local domain
domain falcot.com

## these are reasonable defaults for WinXXXX clients
## for the security related settings
# The Debian pppd package now supports both MSCHAP and MPPE, so enable them
# here. Please note that the kernel support for MPPE must also be present!
auth
require-chap
require-mschap
require-mschap-v2
require-mppe-128

## Fill in your addresses
ms-dns 192.168.0.1
ms-wins 192.168.0.1

## Fill in your netmask
netmask 255.255.255.0

## some defaults
nodefaultroute
proxyarp
lock
L'ultimo passaggio prevede la registrazione dell'utente vpn (e la sua password associata) nel file /etc/ppp/chap-secrets. Contrariamente alle altre istanze dove un asterisco (*) potrebbe funzionare, il nome del server deve essere inserito qui in modo esplicito. Inoltre, i client Windows PPTP si identificano con la forma DOMINIO\\UTENTE, anziché fornire il solo nome utente. Questo spiega perché il file cita anche l'utente FALCOT\vpn. È anche possibile specificare i singoli indirizzi IP per gli utenti; un asterisco in questo campo specifica che devono essere utilizzati gli indirizzi dinamici.

Esempio 10.8. Il file /etc/ppp/chap-secrets

# Secrets for authentication using CHAP
# client        server  secret      IP addresses
vpn             pptp    f@Lc3au     *
FALCOT\\vpn     pptp    f@Lc3au     *