OpenVpn: installazione e configurazione in modalità bridge

Quest’articolo, per fruibilità, l’ho diviso nelle seguenti parti:

L’intera guida è orientata verso un S.O. Debian e Debian-like.
Ho impiegato tre giorni per scrivere questa guida, il motivo per cui l’ho scritta e che in internet si trovano tantissime guide sull’argomento, ma nessuna specifica che spiega per bene come integrare il servizio openvpn, configurato come bridge, con il demone dhcp.
Inoltre molte guide sono obsolete o con informazioni alle volte contraddittorie, per cui spero che possa essere utile a qualcuno. 🙂

Installiamo dei pacchetti necessari

sudo su
apt-get install openvpn bridge-utils

Creare i certificati usando il tool easy-rsa

Eseguite una copia dei file del tool easy-rsa:

mkdir /etc/openvpn/easy-rsa/
cp -R /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa/

Settiamo il tool modificando il file vars:

nano /etc/openvpn/easy-rsa/vars

Modificare i campi:

export KEY_COUNTRY=""		# il vostro STATO
export KEY_PROVINCE=""		# la vostra PROVINCIA
export KEY_CITY=""		# la vostra città
export KEY_ORG=""		# la vostra organizzazione
export KEY_EMAIL=""		# il vostro indirizzo di posta elettronica
export KEY_SIZE=2048		# Diffie-Hellman
export KEY_NAME="server"        # X509 Subject Field

Certificati del Server

cd /etc/openvpn/easy-rsa/
source vars
./clean-all			# Cancella tutti i certificati e le chiavi presenti nella cartella /etc/openvpn/easy-rsa/keys
./build-ca			# Crea il certificato di ROOT della Certification Authority
./build-key-server server	# Crea il certificato e la chiave privata del server

Cambiate “server” con il nome che ritenete più opportuno.
All’esecuzione dell’ultimo comando vi verrà chiesto di inserire una password.
1. Inserite una password sicura e accertatevi di non perderla.
2. Alla richiesta di firmare il certificato rispondete di si.
3. Alla richiesta di eseguire il commit rispondete si.

Creiamo i parametri DIFFIE-HELLMAN necessari per il server per la connessione SSL/TSL

./build-dh

Tutti i certificati e le chiavi sono stati generati nella sottocartella “/etc/openvpn/vars/keys”
Se volete attivare il protocollo TSL dovete generare la key corrispondente:

openvpn --genkey --secret keys/ta.key

Wiki: http://it.wikipedia.org/wiki/Transport_Layer_Security

Mettiamo i file creati nella cartella del programma:

cp server.crt server.key ca.crt dh2048.pem ta.key /etc/openvpn/

Certificati del Client

sudo su
cd /etc/openvpn/vars
source vars
./build-key nome_del_pc_client

I certificati e le chiavi del client vengono sempre creati nella cartella “/etc/openvpn/easy-rsa/keys”

Il file che il client ha bisogno per effettuare la connessione con il server sono:

ca.crt				# Certificato di Root della CA
nome_del_pc_client.crt		# Certificato del client
nome_del_pc_client.key		# Chiave privata del client
ta.key				# TSL key

Copiate questi file all’interno della cartella /etc/openvpn/ del client.

Configurazione del server

tun (routing) o tap (bridging) ?

Il device TAP è una scheda di rete virtuale, mentre il dispositivo TUN è un collegamento IP virtuale da punto a punto (point-to-point).

Vantaggi e svantaggi: http://openvpn.net/index.php/open-source/faq/community-software-general/309-what-is-the-difference-between-bridging-and-routing.html

Se si utilizza bridging Ethernet (tap), è necessario utilizzare i parametri dev tap e server-bridge invece dei parametri dev tun e server.

Gli indirizzi utilizzati nella rete del server e nella rete locale del client non devono fare parte della stessa sottorete, altrimenti vi ritroverete con un loop nel routing dei pacchetti.

Es:

dev tap0
server-bridge

Altrimenti:

dev tun
server

L’istruzione server-bridge senza parametri, implica che il rilascio degli indirizzi ip per i client venga fornito dal demone dhcpd (isc-dhcp-server o dnsmasq) e non da openvpn.

Un motivo valido per cui si vuole usare dhcpd del proprio server piuttosto che openvpn e la possibilità che il proprio server abbia un dns (bind) installato e che il demone dhcp annunci i nuovi pc che si collegano alla rete al dns.

Questo aspetto è poco documentato e le informazioni al riguardo sono contraddittorie:

http://openvpn.net/index.php/open-source/faq/community-software-server/323-i-want-to-set-up-an-ethernet-bridge-on-the-1921681024-subnet-existing-dhcp.html

ATTENZIONE: La direttiva “server” con “dev tap” non deve essere usata come è suggerito dalla faq del sito openvpn, usate “server-bridge”:

  1. senza parametri se volete che sia il vostro server dhcp a rilasciare gli indirizzi
  2. con parametri opportunamente settati se volete che la gestione degli indirizzi ip sia lasciata al server openvpn.
    In questo caso c’è molta documentazione valida a riguardo.

Tuttavia è importante fare notare che il server dhcp non deve fornire ai client vpn il gateway di default della rete in cui è presente il server openvpn, pena la perdita di connessione da parte dei client remoti ad internet.

1. Creare un bridge su server

Configurazione di esempio della mia macchina (file: /etc/network/interfaces)

iface eth0 inet manual
iface eth1 inet manual
iface eth2 inet manual
iface eth3 inet manual
iface eth4 inet manual
iface wlan0 inet manual

auto br0
iface br0 inet static
	bridge_ports eth0 eth1 eth2 eth3 eth4 wlan0 tap0
	address 172.16.0.10
	netmask 255.255.0.0
	network 172.16.0.0
	broadcast 172.16.255.255
	gateway 172.16.0.1
	# dns-* options are implemented by the resolvconf package, if installed
	dns-nameservers 172.16.0.10 172.16.0.1 8.8.8.8
	dns-search example.org

Le istruzioni:

iface br0 inet static
	bridge_ports eth0 eth1 eth2 eth3 eth4 wlan0 tap0

permettono la creazione di un bridge di rete di nome br0, con configurazione di rete statica, di cui fanno parte le periferiche fisiche:

eth0 eth1 eth2 eth3 eth4 wlan0

e la periferica virtuale

tap0

L’indirizzo di rete del bridge e le varie altre impostazioni vengono settate dalle istruzioni successive.

Una volta modificata la vostra configurazione di rete in relazione alle vostre esigenze potete riavviare il servizio di networking col comando:

sudo /etc/init.d/networking restart

2. Configurare il demone dhcpd, nel caso specifico “isc-dhcp-server”.

Questo è un cat parziale del mio file del mio file di configurazione /etc/dhcp/dhcpd.conf del mio server:

...

# Definizioni delle classi

class "local" {
	match pick-first-value (option dhcp-client-identifier, hardware);
}

class "ospiti" {
	match pick-first-value (option dhcp-client-identifier, hardware);
}

class "vpn" {	
	match if (substring(hardware, 1, 2) = 00:FF );
}

# MAC address delle macchine

subclass "ospiti" 1:00:01:AA:BB:CC:DD;
subclass "ospiti" 1:00:02:AA:BB:CC:DD;

subclass "local" 1:00:03:AA:BB:CC:DD;
subclass "local" 1:00:04:AA:BB:CC:DD;

# Definizione della subnet

subnet 172.16.0.0 netmask 255.255.0.0 {
    allow duplicates;
    default-lease-time 86400;
    max-lease-time 86400;				# 24h
    option domain-name "example.org";
    option subnet-mask 255.255.0.0;
    option broadcast-address 172.16.255.255;
    option domain-name-servers 172.16.0.10;
    option ntp-servers 172.16.0.10;

    # Local					172.16.0.50-89
    pool {
	allow members of "local";
	range 172.16.0.50 172.16.0.89;
	option routers 172.16.0.1;		# gateway della rete locale
	ddns-updates on;
    }

    # Ospiti					172.16.10.0/24
    pool {
        allow members of "ospiti";
       	range 172.16.10.1 172.16.10.254;
	default-lease-time 43200;
	max-lease-time 43200;			# 12h
	option routers 172.16.0.1;		# gateway della rete locale
	ddns-updates on;
    }

    # VPN					172.16.20.0/24
    pool {
	allow members of "vpn";
	range 172.16.20.1 172.16.20.254;
	ddns-updates on;
    }
}

Questa è la definizione del mio pool di indirizzi nel mio server.

Per la sottoclasse VPN l’opzione “option routers 172.16.0.10;” è mancante ne è presente nella definizione generale del range:

subnet 172.16.0.0 netmask 255.255.0.0 {
	...

Tanto basta per evitare che venga fornito ai client vpn un gateway che incasini l’instradamento di default dei client vpn verso internet.
Tuttavia è d’obbligo indicare l’opzione “option routers 172.16.0.10;” in tutti gli altri pool della subnet.

Per assicurarsi che tutti i client vpn finiscano nel pool corretto bisogna indicare come regola “allow members of “vpn”;” nel pool e creare una classe con questa regola qui:

class "vpn" {
        match if (substring(hardware, 1, 2) = 00:FF );
}

La regola funziona perché ogni client che si collega tramite openvpn avrà sempre come MAC address iniziale i valori: 00:FF
Tutti gli altri pool definiti nella subnet hanno regole differenti che non coincidono con la regola della classe vpn.

E’ importante accertarsi che nessuno dei client vpn possa finire in un pool di indirizzi in cui è definita la regola “option routers”, sopratutto se in quest’ultima regola è definito il gateway della rete del server vpn.

E’ possibile instradare tutto il traffico del client vpn verso la rete del server, ma in quel caso bisogna specificare come indirizzo ip quello del server vpn. Es:

option routers 172.16.0.10

Gli altri valori del MAC Address dei client vpn varieranno casualmente ad ogni connessione a meno che non si specificano esplicitamente tramite l’istruzione:

lladdr 00:ff:00:00:00:0d

per le macchine linux e nelle proprietà del device tap0 per le macchine windows.
Nelle macchine windows l’istruzione “lladdr 00:ff:00:00:00:0d” non è riconosciuta.

3. Configurazione del servizio OpenVpn

Nella cartella di configurazione del demone openvpn non sono presenti i file di configurazione per cui bisogna metterceli a mano:

cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
gzip -d /etc/openvpn/server.conf.gz
rm /etc/openvpn/server.conf.gz

Una configurazione di esempio del file del server.conf è la seguente:

# Quale indirizzo ip dovrebbe rimanere in ascolto OpenVPN?
local 172.16.0.10		# Indirizzo ip del bridge br0

port 1194			# Porta
proto udp			# Protocollo

dev tap0
server-bridge

ca		ca.crt		# Certificato di Root della CA
cert		server.crt	# Certificato del Server
key		server.key	# Chiave privata del Server
dh		dh2048.pem	# Diffie Hellman parameters
tls-auth	ta.key 0	# This file is secret (0 = server)

comp-lzo			# algoritmo di compressione per la connessione
client-to-client
keepalive 10 120

user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log

daemon
verb 3
chroot jail

Anche qui ho omesso i commenti presenti nel file di configurazione di esempio.

Configurazione di un client

Il client ha anche lui bisogno del suo file di configurazione per cui, se non ne avete uno già pronto potete copiare quello di default:

cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/

Esempio di configurazione per un client linux.
E’ stata omessa la documentazione presente nel file di configurazione di esempio.

script-security 2

client
dev tap
proto tcp

remote vpn.example.org 1194	# Indirizzo del vostro server vpn

lladdr 00:ff:00:00:00:0d	# Indirizzo MAC del client

resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun

ca ca.crt			# Certificato radice della CA
cert client.crt			# certificato del client
key client.key			# chiave privata del client

ns-cert-type server

tls-auth ta.key 1		# File condiviso con il server (1 = client)
comp-lzo
verb 3

chroot

Per maggiorni informazioni in merito al chroot si può controllare questa pagina della wiki http://it.wikipedia.org/wiki/Chroot

mkdir /etc/openvpn/jail
nano /etc/openvpn/server.conf

Alla fine del file aggiungere l’istruzione:

chroot jail

e salvare.

chroot jail e syslog

Il problema è semplice, alla rotazione giornaliera dei log del sistema il servizio rsyslog viene riavviato dalla macchina facendo perdere la connessione alla socket “/dev/log” da parte del servizio openvpn.
Infatti la socket AF_UNIX “/dev/log” viene terminata e ricreata al riavvio del servizio rsyslog.
Il servizio openvnp, essendo bloccato dentro la cartella “/etc/openvpn/jail” non può più accedere alla socket del demone rsyslog che si torva fuori dalla cartella “jail” (ovvero “/dev/log”).

Per ovviare al problema bisogna creare la cartella dev dentro jail:

mkdir /etc/openvpn/jail/dev

e modificare la configurazione del demone rsyslog creando un nuovo file dentro la cartella “/etc/rsyslog.d” e aggiungere lì la configurazione del nuovo socket per il demone openvpn. Ovvero:

nano /etc/rsyslog.d/openvpn.conf

E aggiungere la seguente istruzione:

$AddUnixListenSocket /etc/openvpn/jail/dev/log

e salvare e riavviare il servizio.

service rsyslog restart

3 pensieri su “OpenVpn: installazione e configurazione in modalità bridge

  1. Ciao e complimenti per la guida.
    Ho sempre dei dubbi come configurare la rete br0…mi puoi dare una dritta?
    Tieni presente che la rete dove sto installando OpenVPN è la classica 192.168.1.xx dove il pc, raspberry, ha come indirizzo 192.168.1.44 e gateway 192.168.1.1
    Non voglio che il server DHCP assegni l’indirizzo ma che decida io l’indirizzo da dare.
    Altra considerazione, che non so se cambia oppure no, la rete da dove mi connetto è configurata nello stesso modo, sempre 192.168.1.xx

    Grazie

  2. Ciao e grazie per i complimenti.
    Dunque… “, la rete da dove mi connetto è configurata nello stesso modo, sempre 192.168.1.xx”
    Come già detto nell’articolo…
    Gli indirizzi utilizzati nella rete del server e nella rete locale del client non devono fare parte della stessa sottorete, altrimenti vi ritroverete con un loop nel routing dei pacchetti.

    Per cui se il server openvpn e i client vpn sono configurati nella stessa sotto-rete non funzionerà nulla.

    Motivo: il client vpn cercherà di contattare i servizi (pc, stampanti, ecc.), una volta stabilita la connessione con il server vpn, della rete remota vpn cercandoli nella propria rete locale. Ovvero il client non sarà in grado di capire se l’indirizzo (192.168.1.xx) che deve contattare sia nella propria rete locale o in quella remota.

    Devi configurare il server su una sotto-rete diversa dalle sotto-reti di tutti i client. Es:
    192.168.50.xxx netmask 255.255.255.0, il gateway del raspeberry deve essere nella stessa sotto-rete del raspberry, per cui se cambi la sottorete del raspberry devi cambiare anche la sotto-rete del router/gateway.
    In questo modo, eviterai di modificare la configurazione delle reti dei client.

    Per quanto riguarda gli indirizzi statici per i client… sono generalmente contrario ad assegnare indirizzi statici preferisco che siano risolti con un server dns (bind o dnsmasq). Se non ricordo male cambiando la configurazione del server openvpn un poco è possibile configurare il servizio in modo che sia lui a rilasciare gli indirizzi ip, evitando cosi dhcpd o dnsmasq.

    Oppure, cosa che nell’articolo è accennata, si può fissare staticamente il mac address dei client vpn, (istruzione lladdr da aggiungere nel file di configurazione del client per le macchine linux; proprietà di rete per le macchine winzoz) e specificare nel file di configurazione del servizio dhcpd che quel mac address deve avere rilasciato sempre uno specifico indirizzo. (man dhcpd.conf se non ricordo male)

    Il motivo per cui bisogna specificare a mano l’indirizzo mac del client vpn è che ogni qual volta il servizio vpn sul client viene avviato il mac di questo cambia in modo causale.

    Comunque l’argomento è vasto e mi devi perdonare se non approfondisco ma ho 38 di febbre e non sono lucido per un ciufolo…

  3. Bell’articolo, molto completo. Passi dalle basi ai meccanismi collegati in modo davvero fluido.
    Complimenti.
    Sto lavorando per far dialogare due reti intere via VPN e qualcosa del tuo splendido articolo può tornarmi utile.

    Grazie

I commenti sono chiusi.