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

L'algoritmo RSA è ampiamente utilizzato nella crittografia a chiave pubblica. Si tratta di una «coppia di chiavi», 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 in azienda una propria autorità di certificazione. A tal fine, OpenVPN fornisce lo strumento easy-rsa che serve come infrastruttura di certificazione X.509. Si tratta di un insieme di script che utilizzano il comando openssl; questi script si trovano in /usr/share/doc/openvpn/examples/easy-rsa/2.0/.
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 è il primo certificato da creare; a tal fine, gli amministratori copiano la directory che contiene easy-rsa in un luogo più appropriato, preferibilmente su una macchina non connessa alla rete, per ridurre il rischio di furto della chiave privata della CA.
$ cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 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"
$ . ./vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /home/rhertzog/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) []:
Common Name (eg, your name or your server's hostname) [Falcot Corp CA]:
Name []:
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) []:
Common Name (eg, your name or your server's hostname) [vpn.falcot.com]:
Name []:
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/rhertzog/pki-falcot/openssl.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'
commonName            :PRINTABLE:'vpn.falcot.com'
emailAddress          :IA5STRING:'admin@falcot.com'
Certificate is to be certified until Oct  9 13:57:42 2020 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) []:
Common Name (eg, your name or your server's hostname) [JoeSmith]:Joe Smith
Name []:
Email Address [admin@falcot.com]:joe@falcot.com
[…]
Now all certificates have been created, they need to be copied where appropriate: the root certificate's public key (keys/ca.crt) will be stored on all machines (both server and clients) as /etc/ssl/certs/Falcot_CA.crt. The server's certificate is installed only on the server (keys/vpn.falcot.com.crt goes to /etc/ssl/vpn.falcot.com.crt, and keys/vpn.falcot.com.key goes to /etc/ssl/private/vpn.falcot.com.key with restricted permissions so that only the administrator can read it), with the corresponding Diffie-Hellman parameters (keys/dh2048.pem) installed to /etc/openvpn/dh2048.pem. Client certificates are installed on the corresponding VPN client in a similar fashion.

10.2.1.2. Configurazione del server OpenVPN

By default, the OpenVPN initialization script tries starting all virtual private networks defined in /etc/openvpn/*.conf. Setting up a VPN server is therefore a matter of storing a corresponding configuration file in this directory. A good starting point is /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz, which leads to a rather standard server. Of course, some parameters need to be adapted: ca, cert, key and dh need to describe the selected locations (respectively, /etc/ssl/certs/Falcot_CA.crt, /etc/ssl/vpn.falcot.com.crt, /etc/ssl/private/vpn.falcot.com.key and /etc/openvpn/dh2048.pem). The server 10.8.0.0 255.255.255.0 directive defines the subnet to be used by the VPN; the server uses the first IP address in that range (10.8.0.1) and the rest of the addresses are allocated to clients.
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 /etc/init.d/openpvn start nome e /etc/init.d/openpvn stop nome (dove il nome della connessione corrisponde a quello definito in /etc/openvpn/nome.conf).
The network-manager-openvpn-gnome package contains an extension to Network Manager (see Sezione 8.2.4, «Automatizzare la configurazione della rete per gli utenti in movimento») that allows managing OpenVPN virtual private networks. This allows every user to configure OpenVPN connections graphically and to control them from the network management icon.

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:
The second method is more recent, and was introduced with OpenSSH 4.3; it is now possible for OpenSSH to create virtual network interfaces (tun*) on both sides of an SSH connection, and these virtual interfaces can be configured exactly as if they were physical interfaces. The tunneling system must first be enabled by setting PermitTunnel to “yes” in the SSH server configuration file (/etc/ssh/sshd_config). When establishing the SSH connection, the creation of a tunnel must be explicitly requested with the -w any:any option (any can be replaced with the desired tun device number). This requires the user to have administrator privilege on both sides, so as to be able to create the network device (in other words, the connection must be established as 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, despite being the standard in IP VPNs, is rather more involved in its implementation. The IPsec engine itself is integrated in the Linux kernel; the required user-space parts, the control and configuration tools, are provided by the ipsec-tools package. In concrete terms, each host's /etc/ipsec-tools.conf contains the parameters for IPsec tunnels (or Security Associations, in the IPsec terminology) that the host is concerned with; the /etc/init.d/setkey script provides a way to start and stop a tunnel (each tunnel is a secure link to another host connected to the virtual private network). This file can be built by hand from the documentation provided by the setkey(8) manual page. However, explicitly writing the parameters for all hosts in a non-trivial set of machines quickly becomes an arduous task, since the number of tunnels grows fast. Installing an IKE daemon (for IPsec Key Exchange) such as racoon, strongswan or openswan makes the process much simpler by bringing administration together at a central point, and more secure by rotating the keys periodically.
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

# PPP options used for a PPTP connection
lock
noauth
nobsdcomp
nodeflate

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

# vpn.falcot.com is the PPTP server
pty "pptp vpn.falcot.com --nolaunchpppd"
# the connection will identify as the "vpn" user
user vpn
remotename pptp
# encryption is needed
require-mppe-128
file /etc/ppp/options.pptp
ipparam falcot

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

# Create the route to the Falcot network
if [ "$6" = "falcot" ]; then
  # 192.168.0.0/24 is the (remote) Falcot network
  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

# Delete the route to the Falcot network
if [ "$6" = "falcot" ]; then
  # 192.168.0.0/24 is the (remote) Falcot network
  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
The last step involves registering the vpn user (and the associated password) in the /etc/ppp/chap-secrets file. Contrary to other instances where an asterisk (*) would work, the server name must be filled explicitly here. Furthermore, Windows PPTP clients identify themselves under the DOMAIN\\USER form, instead of only providing a user name. This explains why the file also mentions the FALCOT\\vpn user. It is also possible to specify individual IP addresses for users; an asterisk in this field specifies that dynamic addressing should be used.

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     *