OpenVPN (e fastweb)

Da Inc0Wiki.

Preambolo

Questa guida non è generica: a causa della configurazione del luogo per la quale è stata scritta, se decideste di copiare i file di configurazione senza capirli e senza capire le modifiche fatte agli altri dispositivi, probabilmente non funzionerà.
Faccio inoltre presente che questa guida è stata scritta per configurare due nodi su cui è installato un SO Linux: non viene trattato in alcun modo la configurazione per host/nodi windows
Vi prego quindi di leggere con attenzione TUTTA la guida o SMETTERE fin da ora.

Scopo

Configurare una rete VPN (lan-2-lan) tra un nodo con ip pubblico e dinamico ed un nodo interno a fastweb abch'esso con ip dinamico ma privato (proprio perch+ fastweb) per permettere agli hosts delle due lan di comunicare.

Come e perchè

In quanto uno dei due nodi è all'interno di fastweb, risulta impossibile raggiungerlo tramite internet: questo preclude la possibilità di poter iniziare delle connesioni con lui. La soluzione che ho trovato (e che quindi NON è l'unica ma la sola che mi è venuta alla mente fino ad ora) è quella di fare si che sia il nodo dentro fastweb (client) ad iniziare le connessioni verso il nodo con ip pubblico (server).
Si fa presente che la soluzione più facile sarebbe avere i due nodi della vpn (client e server) che fungano da gateway per le rispettive lan ovvero con 2 schede ethernet, una verso internet ed una verso la lan: sfortunatamente questa non è la situazione in cui ci troviamo.
In quanto intendiamo mettere in comunicazione due lan e non sappiamo quali dati verranno scambiati, la tecnica che permette di creare connessioni sicure attraverso reti insicure (internet) consiste nell'utilizzare un tunnel criptato attraverso il quale far transitare le nostre comunicazioni, rendendole di fatto invisibili all'esterno: nel nostro caso si è scelto di configurare la VPN con SSL/TLS.

Server VPN

La rete (VALHALLA) in cui risiede il server vpn (pribnowbox) è una lan il cui gateway (hellgate) è un router CISCO della serie 800: il server vpn è, quindi, un client della rete verso il quale viene eseguito un nat (dal gateway) della porta 1194/udp (openvpn).
La lan opera nella sottorete di classe C 192.168.1.0/24: il gateway ha ip 192.168.1.1, il server vpn ha ip 192.168.1.2 ed i client hanno ip dinamico assegnato tramite dhcp in un range che varia da 192.168.1.100 a 192.168.1.200.
Sul tale server è attiva alcuna regola di firewalling.

Client VPN

Il client vpn è anche il gateway (nosferatu) della lan (vampire) all'interno di fastweb: è dotato di due schede ethernet, l'eth2 è collegata all'hag Fastweb, l'eth0 è collegata ad uno switch al quale sono collegati altri pc. eth2 ha ip dinamico datogli dall'hag, eth0 ha ip fisso 192.168.51.2.
La lan opera nella sottorete di classe C 192.168.51.0/24: il gateway, come scritto poco fa, è 192.168.51.2 ed i client hanno ip dinamico assegnato tramite dhcp in un range che varia da 192.168.51.100 a 192.168.51.200.
Su tale server è attivo iptables che fa MASQUERADE per permettere ai client di accedere ai vari servizi (www, pop, imap, smtp, ecc.) in modo trasparente. Per facilità di configurazione le policy delle catene sono impostate su ACCEPT ma nulla vieta imporle più restrittive una volta che la VPN sarà attiva e funzionante: in questo modo si eliminano, almeno inialmente, difficoltà nella configurazione che potrebbero essere causare da fattori esterni.

ext_if="eth2"
int_if="eth0"
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv4/ip_dynaddr

$iptables -P INPUT   ACCEPT
$iptables -P FORWARD ACCEPT
$iptables -P OUTPUT  ACCEPT

$iptables -t nat -A POSTROUTING -s 192.168.51.0/24 -o $ext_if -j MASQUERADE

Mappa

Di seguito un'immagine che spero sia esplicativa per permettere una più facile comprensione della rete:
VPN.png

Pacchetti Necessari

openvpn - in base alla configurazione agisce come client o server
openssl - necessario per SSL/TLS
iptables - nel nostro caso indispensabile sul client ma non sul server

Configurazione

Come detto in precedenza intendiamo costruire la VPN con SSL/TLS quindi, per prima cosa dobbiamo preparare i certificati sia per il server vpn che per il client vpn.

Certificati Server VPN

In quanto successivamente i client dovranno essere autorizzati a collegarsi al server vpn, creiamo la CA (Certificate Authority) sul server così da poter essere direttamente noi a validare le richieste dei client.

Certificate Authority

Prepariamo i certificati della CA:

# openssl genrsa -out ca.key

Abbiamo la chiave della CA, creiamo la richiesta per il certificato (compilate la parte seguente a vostra scelta):

# openssl req -new -key ca.key -out rich.ca

Facciamo quindi firmare la richiesta e la rendiamo valida per circa 10 anni (nulla vi vieta di farlo per un lasso di tempo inferiore o superiore):

openssl x509 -req -in rich.ca -signkey ca.key -days 3650 –out ca.cert

A questo punto avremo 3 files:
- ca.key = La chiave
- rich.ca = La richiesta della CA
- ca.cert = Il certificato della CA

Certificati Lato Server

E' giunto finalmente il momento di creare i certifcati del server vpn. Creiamo la chiave dei certificati del server:

# openssl genrsa -out server.key

Creiamo la richiesta del certificato del server (alla richiesta del CN o Common Name, prediligo utilizzare l'hostname della macchina ma nulla vi vieta di fare diversamente a condizione che poi sappiate chi è chi):

# openssl req -new -key server.key -out rich.ser

A questo punto abbiamo altri 2 files:
- server.key = La chiave
- rich.ser = La richiesta del server
Possiamo procedere facendo firmare la richiesta del server alla CA per ottenere il certificato del server (valida per un periodo lievemente inferiore a quello della CA):

openssl x509 -req -in rich.ser -days 3640 -CA ca.cert -CAkey ca.key -CAcreateserial -out ser.cert

Ora abbiamo anche il file ser.cert.
Non resta altro che creare anche il Diffie-Hellman:

# openssl dhparam -out dh.pem 1024

il cui nome è dh.pem.

Certificati Lato Client

Ora creiamo i certificati sul client:

# openssl genrsa -out client.key

Creiamo la richiesta del certificato del client (anche qui, alla richiesta del CN io prediligo utilizzare l'hostname della macchina ma nulla vi vieta di usare un altro nome):

#  openssl req -new -key client.key -out rich.cli

A questo punto abbiamo:
- client.key = La chiave
- rich.cli = La richiesta del client
Spediamo la richiesta alla CA e facciamola firmare come abbiamo fatto per il server ed indichiamo un periodo di validità anche per questo certificato:

openssl x509 -req -in rich.cli -days 3630 -CA ca.cert -CAkey ca.key -CAcreateserial -out cli.cert

A questo punto spediamo il certificato del client (cli.cert) e il certificato della CA (ca.cert) al client.

Routing VS Bridging

OpenVPN crea ed usa un device (tun o tap a seconda di come lo si configura) per mettere in comunicazione i due nodi: la comunicazione tra i nodi può essere realizzata tramite routing o bridging. Se intendete fare routing dovrete usare tun (è il caso di questa guida) e potrete mettere in comunicazione svariati nodi ognuno dei quali potrà avere una sottorete distinta; se intendete fare bridgin (ed in questa guida NON viene spiegato) dovrete usare tap e se vorreste mettere in comunicazioni dei nodi sarete vincolati al fatto che tali nodi dovranno essere sulla stessa sottorete.

File di configurazione

OpenVPN salva i suoi file di configurazione in /etc/openvpn, per comodità andiamo a creare una cartella all'interno di openvpn (sia sul client che sul server) all'interno della quale metteremo i certificati e le chiavi. Sul server, inoltre, creiamo anche la cartella ccd/.

Configurazione server OpenVPN - /etc/openvpn/srvTLS.conf

# Vogliamo fare IP Routing quindi usiamo tap
# Specifichiamo il nome del device che dovrà sempre essere usato
dev tun0

# Per la vpn intendiamo usare il protocollo udp
proto udp

# Il server sarà in ascolto sulla porta 1194/udp
port 1194

# L'interfaccia di amministrazione (testuale) sarà in ascolto sulla porta 1195 solo sull'interfaccia 127.0.0.1
management localhost 1195

# Abilitiamo la compressione del traffico sull'interfaccia vpn
comp-lzo

# Specifichiamo la sottorete usata per mettere in comunicaizone i nodi:
# il server, avrà mask 255.255.255.0 e sarà per default 10.0.0.1
server 10.0.0.0 255.255.255.0

# Eseguiamo un ping ogni 30 secondi, se dopo 300 secondi non riceviamo risposta consideriamo l'host morto.
keepalive 30 300

# Evitiamo i tentativi di accesso a certe risorse che al riavvio potrebbero non essere più accessibili
# oer via di un downgrade dei privilegi.
persist-key
persist-tun

# Solitamente i client delle lan sono in grado di raggiungere solo il server,
# questa direttiva permette ai client di vedersi reciprocamente.
client-to-client

# Specifichiamo che noi siamo il server-tls
tls-server

# All'interno di /etc/openvpn/TLS ho posizionato i file creati durante la prepazione dell'ambiante per la connessione TLS
# Il file con il Diffie-Hellman
dh /etc/openvpn/TLS/dh.pem
# Il certificato della CA
ca /etc/openvpn/TLS/ca.cert
# Il certificato del server
cert /etc/openvpn/TLS/ser.cert
# La chiave del server
key /etc/openvpn/TLS/server.key

# OpenVPN supporta ogni cifratura supportata dalla libreria OpenSSL: openvpn -–show-ciphers per avere una lista.
# Per la nostra vpn usiamo una cifratura con chiave a 192bit.
cipher DES-EDE3-CBC

# Cartella contenente i file di configurazione di ogni client
client-config-dir /etc/openvpn/ccd

# Quando la vpn viene attivata, abilitiamo il routing verso le varie sottoreti a cui siamo connessi
route 192.168.51.0 255.255.255.0

# Salviamo un file contenente la corrispondenza client <-> virtual IP address in modo che, sa la vpn dovesse cadere o dovesse essere restartata
# quanto i client si ricollegano gli viene assegnato lo stesso ip che avevano in precedenza.
ifconfig-pool-persist /etc/openvpn/TLS/ipp.txt

# Livello di accuratezza dei log
verb 4

# File di log: se la vpn viene restartata il file non viene sovrascritto ma la scrittura continua dalla fine.
log-append /var/log/openvpn/server.log

Configurazione server OpenVPN - /etc/openvpn/ccd/nosferatu

I file contenuti in questa cartella, uno per ogni possibile nodo della vpn, contengono le informazioni da passare all'omonimo client. nosferatu, come indicato nella mappa è il nome indicato nel CN del client al momento della creazione del certificato, nonchè l'hostname del server su gira openvpn.

######### ccd/nosferatu #########
# Ignoriamo eventuali configurazione passate tramite "push" nel file di configurazione globale del server.
push-reset

# Assegnamo l'ip fisso 10.0.0.51 al client che si collega e si presenta come "nosferatu"
ifconfig-push 10.0.0.51 10.0.0.1

# Indichiamo al nostro server che nosferatu fa routing per la rete 192.168.51.0/24
iroute 192.168.51.0 255.255.255.0

# Diciamo a nosferatu che il server VPN a cui si è collegato fa routing per la rete 192.168.1.0/24
push "route 192.168.1.0 255.255.255.0"
######### end #########


Configurazione client OpenVPN - /etc/openvpn/inc0TLS.conf

In /etc/openvpn creiamo la cartella inc0TLS all'interno della quale posiazioniamo le chiavi ed i certificati per la connessione in SSL/TSL.

# Nella vpn, noi siamo client
client

# Specifichiamo il nome del device che dovrà sempre essere usato
# Il device tun51 non è un obbligo, per scelta è stato preso dall'indirizzo della sottorete 192.168.51.0
dev tun51

# Per la vpn intendiamo usare il protocollo udp
proto udp

# Porta alla quale collegarsi
port 1194

# Non è necessario bindare sul client una porta specifica
nobind

# Nome internet del server openvpn
remote incubus.homelinux.net

# In caso di fallimenti, cercare di risolvere e collegarsi al server vpn all'infinito
resolv-retry infinite

# Per evitare la caduta della vpn
ping 10
ping-restart 60

# Abilitiamo la compressione del traffico vpn
comp-lzo

# Siamo client
tls-client
# Certificato della CA
ca /etc/openvpn/inc0TLS/inc0ca.cert
# Certificato del client
cert /etc/openvpn/inc0TLS/loop.cert
# Chiave del client
key /etc/openvpn/inc0TLS/loop.key

# Per la nostra vpn usiamo una cifratura con chiave a 192bit.
cipher DES-EDE3-CBC

# Livello di accuratezza dei log
verb 3

# File di log: se la vpn viene restartata il file non viene sovrascritto ma la scrittura continua dalla fine.
log-append  /var/log/openvpn/vpn.log

/etc/init.d/openvpn

Prepariamo ora la vpn affinchè client e server vengano eseguiti all'avvio del sistema: come per ogni altro demone basta crare un link simbolico in /etc/rcX.d/ (con X corrispondente al runlever nel quale parte il vostro sistema). Lo script contenuto all'interno di /etc/init.d è predisposto per controllare quale vpn (nel caso ne abbiate configurata più di una) lanciare: questo viene fatto controllando il nome del link simbolico che avete posizionato in /etc/rcX.d, ad esempio: se il nome del link è openvpn.srtTLS, lo script di init avvierà openVPN prendendo il file di configurazione da /etc/openvpn chiamato srvTLS.conf; se il nome del link è openvpn.inc0TLS, lo script di init avvierà openVPN prendendo il file di configurazione da /etc/openvpn chiamato inc0TLS.conf.

Routing

Avviamo ora server e client della vpn e controlliamo i log: assicuriamoci che la connessione avvenga senza problemi: per prima prova pinghiamo dal server (10.0.0.1) il client (10.0.0.51) per assicurarci che la connessione sia avvenuta. Se il precedente ping è andato a buon fine, tentiamo una connessione ssh dal server al client: logghiamoci ed eseguiamo un ping da 10.0.0.51 a 10.0.0.1 e verifichiamo che vada a buon fine. A questo punto abbiamo la sicurezza che i due nodi della vpn sono connessi: è giunto il momento di mettere in comunicazione i client delle rispettive reti.

Server VPN

Come detto inizialmente, il server vpn non è il gateway della lan: è quindi necessario impostare N(+1) nuove rotte sul gateway stesso per redirigere i pacchetti al server vpn:
- N: tante rotte quante le lan (192.168.X.0/netmask) che il nostro server vpn mette in comunicazione
- +1: (non indispensabile) rotta per la sottorete (10.0.0.0) usata nella vpn
In questo modo anche i client della vostra sottorete non dovranno essere configurati e potranno raggiungere gli hosts delle altre sottoreti. Di seguito sono riportate le tabelle di routing del gateway:

Hellgate#show ip route
Codes: C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route

Gateway of last resort is 0.0.0.0 to network 0.0.0.0

     82.0.0.0/32 is subnetted, 1 subnets
C    82.54.115.106 is directly connected, Dialer0
     10.0.0.0/24 is subnetted, 1 subnets
S    10.0.0.0 [1/0] via 192.168.1.2
S    192.168.51.0/24 [1/0] via 192.168.1.2
C    192.168.1.0/24 is directly connected, Vlan1
     192.168.100.0/32 is subnetted, 1 subnets
C    192.168.100.1 is directly connected, Dialer0
S*   0.0.0.0/0 is directly connected, Dialer0
Hellgate#

e del server vpn:

pribnowbox incubus # route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.0.0.2        0.0.0.0         255.255.255.255 UH    0      0        0 tun0
10.0.0.0        10.0.0.2        255.255.255.0   UG    0      0        0 tun0
192.168.51.0    10.0.0.2        255.255.255.0   UG    0      0        0 tun0
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0
127.0.0.0       0.0.0.0         255.0.0.0       U     0      0        0 lo
0.0.0.0         192.168.1.1     0.0.0.0         UG    0      0        0 eth0
pribnowbox incubus #

L'ultima operazione che resta da fare è l'abilitazione del mascheramento dei pacchetti tramite iptables: mascheriamo tutti i pacchetti che provengono dalla sottorete 10.0.0.0/24 (quella usata dai nodi della vpn) e che vogliono uscire sull'interfaccia eth0 (che, nel caso del server) è quella che lo collega alla lan 192.168.1.0/24:

# iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE

Client VPN

Ricordiamo che il client VPN è il gateway per la lan fastweb, ha 2 interfacce eth attive e iptables. Ora, con la vpn attiva, c'è la nuova interfaccia tun51: tale server deve essere in grado di redirigere i pacchetti alla giusta destinazione:

nosferatu incubus # route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.0.0.1        0.0.0.0         255.255.255.255 UH    0      0        0 tun51
192.168.51.0    0.0.0.0         255.255.255.0   U     0      0        0 eth0
192.168.1.0     10.0.0.1        255.255.255.0   UG    0      0        0 tun51
2.239.104.0     0.0.0.0         255.255.248.0   U     0      0        0 eth2
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 eth0
0.0.0.0         2.239.104.1     0.0.0.0         UG    100    0        0 eth2
nosferatu incubus #

Tutto questo viene fatto automaticamente dalla vpn e dalla configurazione impostasta nel file contenuto all'interno della cartella ccd/ presente sul server e passato al client quando lo stesso si collega.

Test Conclusivi

Per verificare che tutto funzioni a dovere si può procedere facendo dei traceroute da un client di una lan verso l'altra e vice versa:

C:\Users\Incubus>tracert 192.168.51.3

Traccia instradamento verso TZMISCE [192.168.51.3]
su un massimo di 30 punti di passaggio:

  1    <1 ms    <1 ms    <1 ms  pb.valhalla.lan [192.168.1.2]
  2   304 ms   466 ms   293 ms  NOSFERATU [10.0.0.51]
  3   254 ms   262 ms   283 ms  TZMISCE [192.168.51.3]

Traccia completata.

C:\Users\Incubus>ping 192.168.51.3

Esecuzione di Ping 192.168.51.3 con 32 byte di dati:
Risposta da 192.168.51.3: byte=32 durata=266ms TTL=62
Risposta da 192.168.51.3: byte=32 durata=168ms TTL=62
Risposta da 192.168.51.3: byte=32 durata=195ms TTL=62
Risposta da 192.168.51.3: byte=32 durata=260ms TTL=62

Statistiche Ping per 192.168.51.3:
    Pacchetti: Trasmessi = 4, Ricevuti = 4,
    Persi = 0 (0% persi),
Tempo approssimativo percorsi andata/ritorno in millisecondi:
    Minimo = 168ms, Massimo =  266ms, Medio =  222ms

C:\Users\Incubus>

Credits

Autore: Incubus

E-Mail: theincubus (at) gmail (dot) com