Lo standard de facto per realizzare i tunnel VPN è sicuramente IPSec. Tale protocollo è compatibile con dispositivi di vendor diversi (interoperabilità) e permette di creare dei tunnel altamente affidabili e robusti in termini di sicurezza. Per contro, però, esso risulta essere piuttosto complesso da configurare e proprio per questo motivo, soprattutto in ambito SOHO, si opta per soluzioni alternative. Una di queste è sicuramente OpenVPN, in grado di realizzare dei tunnel cifrati mediante i protocolli SSL/TLS.
Di seguito un breve howto in cui viene descritta la configurazione di OpenVPN per un bastion host dual-homed Linux.
Nello specifico, la rete locale è così definita:
Internet - Screened router - interfaccia UNTRUST del bastion - FW IPTABLES - interfaccia TRUST del bastion - LAN
Configurazione del server
Per prima cosa occorre installare l’applicativo in questione digitando il comando:
nightfly@nightbox:~$ sudo apt-get install openvpn
ad installazione completata, posizioniamoci nella directory /etc/openvpn e creiamo le subdir certificati e log:
nightfly@nightbox:/etc/openvpn$ sudo mkdir log
nightfly@nightbox:/etc/openvpn$ sudo mkdir certificati
Successivamente, creiamo i due file in cui verranno salvati i log:
nightfly@nightbox:/etc/openvpn$ cd log
nightfly@nightbox:/etc/openvpn/log$ sudo touch openvpn.log openvpn-status.log
A questo punto possiamo creare il file di configurazione:
nightfly@nightbox:/etc/openvpn$ sudo nano server.conf
il cui contenuto dovrà essere simile al seguente:
tls-server
port 5002
dev tun
ifconfig 192.168.110.1 192.168.110.2
persist-key
persist-tun
push "route 192.168.1.0 255.255.255.0"
#Percorsi dei certificati
ca certificati/ca.crt
cert certificati/server.crt
key certificati/server.key
dh certificati/dh1024.pem
tls-auth certificati/ta.key 0 # 0 per il server ed 1 per il client, essenziale per la generazione dell'hash HMAC nell'header TLS
cipher BF-CBC
comp-lzo
keepalive 10 120
#log and security
user nobody
group nogroup
status log/openvpn-status.log
log-append log/openvpn.log
verb 3
scrip-security 2
Mediante la direttiva tls-server sto imponendo al mio bastion host di fungere da server per le sessioni TLS.
Con port specifico su quale porta OpenVPN deve rimanere in ascolto, mentre con dev tun sto scegliendo la tipologia di interfaccia da realizzare. A tal proposito, occorre precisare che i tipi di interfaccia che può tirar su OpenVPN sono 2, ovvero:
1) tun, per le VPN routed (livello 3);
2) tap, per le VPN bridged (livello 2).
Con ifconfig specifico l’indirizzo IP del tunnel VPN lato server (192.168.110.1) e lato client (192.168.110.2). Per la natura delle interfacce tun, trattasi di un collegamento point-to-point (/30).
con push “route 192.168.1.0 255.255.255.0” sto iniettando la rotta per raggiungere la mia LAN (interfaccia TRUST del bastion-host) sul client VPN.
Con le direttive:
cipher BF-CBC
comp-lzo
sto definendo il tipo di cifratura (BlowFish) ed il tipo di compressione (LZO – Lempel-Ziv-Oberhumer) messe in atto nel tunnel VPN.
Con keeplive faccio in modo che il tunnel rimanga attivo anche in assenza di traffico, mentre nella sezione #log and security definisco (in quest’ordine) i permessi, i file di log, il verbosity (accuratezza dei log) ed il livello di sicurezza di questo file di configurazione.
Salviamo il file in questione e procediamo con la generazione delle chiavi e dei certificati. Lato server i comandi da lanciare sono i seguenti:
nightfly@nightbox:~$ cd /usr/share/doc/openvpn/examples/easy-rsa/2.0/
nightfly@nightbox:~$ sudo nano vars
che andrà editato customizzando i campi indicati
nightfly@nightbox:~$ source ./vars
nightfly@nightbox:~$ ./clean-all
nightfly@nightbox:~$ ./build-ca
per la generazione del certificato relativo alla CA
nightfly@nightbox:~$ ./build-dh
per lo scambio delle chiavi mediante l’algoritmo Diffie-Helman (leggasi premaster-key)
nightfly@nightbox:~$ ./build-key-server server
per la generazione della chiave privata associata al server, con relativa richiesta *.crt
nightfly@nightbox:~$ openvpn --genkey --secret ta.key
per la generazione della chiave segreta.
Una volta generate le chiavi ed i certificati copiamoli nella directory /etc/openvpn/certificati:
nightfly@nightbox:~$ sudo cp ca.crt server.crt server.key dh1024.pem ta.key /etc/openvpn/certificati
A questo punto possiamo avviare il demone OpenVPN:
nightfly@nightbox:~$ sudo service openvpn start
Verifichiamo che l’interfaccia tun0 sia attiva mediante il comando ifconfig:
nightfly@nightbox:~$ ifconfig
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
indirizzo inet:192.168.110.1 P-t-P:192.168.110.2 Maschera:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisioni:0 txqueuelen:100
Byte RX:0 (0.0 B) Byte TX:0 (0.0 B)
Configurazione di IPTABLES
Il bastion host ha DROP come azione di default per la chain FORWARD. Proprio per questo motivo, occorre consentire il transito del traffico dall’interfaccia tun0 a quella TRUST (eth0) e viceversa. Le regole da definire sono le seguenti:
iptables -A FORWARD -i tun0 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o tun0 -j ACCEPT
Configurazione del client
A questo punto è possibile installare e configurare il client, che però dovrà utilizzare lo stesso file ca.crt del server, la medesima chiave ta.key del server ma una propria chiave privata (client.key) ed un proprio certificato (client.crt).
Per ambienti Windows vi consiglio questo client Openvpn (se utilizzate Windows 7 fate riferimento a questa pagina per la procedura di installazione).
Quest’altro client, invece, evitatelo come la peste (in quanto bacatissimo, d’altronde è una versione alpha).
Ad installazione completata potrete utilizzare il seguente file di configurazione:
remote <indirizzo IP pubblico del server OpenVPN> 5002
client
tls-client
nobind
dev tun
ifconfig 192.168.110.2 192.168.110.1
pull
ca key/ca.crt
cert key/client.crt
key key/client.key
tls-auth key/ta.key 1
persist-key
persist-tun
cipher BF-CBC
comp-lzo
keepalive 10 120
scrip-security 2
verb 3
Da notare che gli algoritmi di compressione e cifratura devono essere i medesimi di quelli utilizzati dal server, pena l’impossibilità di connettersi allo stesso.
Diagnostica
A connessione VPN avvenuta, potete verificare la raggiungibilità attraverso il tunnel degli host della LAN mediante un seplice ping, ad esempio:
ping 192.168.1.2
Se il ping dovesse andare in timeout, provate a mettere in ascolto tcpdump sulle interfacce tun0 ed eth0 e controllate la tabella di routing del vostro bastion host (attraverso il comando route).
Verificate inoltre che la rotta verso la LAN sia stata correttamente iniettata sul client (Windows), digitando:
route print
Fine del post, bye.