giovedì, Novembre 21, 2024

VPN con IPSec su OpenBSD in sei passi

1) In questo documento realizzeremo una VPN con IPSEC solamente con tool che siano presenti in una installazione di default di OpenBSD 3.2. Si può fare anche con versioni precedenti, ovviamente a scapito di minori features e probabilmente più bug noti non ancora risolti.

Ognuno dei computer, da cui eseguiremo gli esempi, ha un IP privato della classe 192.168.0.0/255.255.255.0. Non è importante ai fini dell’esempio conoscerli tutti, li vedremo mano a mano, useremo la classe 10.0.0.0/255.0.0.0 se ci serviranno altri indirizzi IP.

Ecco i computer utilizzati per l’esempio:

  • die0 -> Pentium 166 con OpenBSD 3.1
  • die1 -> Pentium 150 con OpenBSD 3.2
  • sparc -> Sun Sparcstation 10 con OpenBSD 3.2

2) PRIMA di configurare qualsiasi cosa, proviamo da Sparc ad effettuare un ping verso die1 e contemporaneamente da una terza macchina a fare sniffing del traffico.

[sparc.sick-net]# ping 192.168.0.8
PING 192.168.0.8 (192.168.0.8): 56 data bytes
64 bytes from 192.168.0.8: icmp_seq=0 ttl=255 time=1.962 ms
64 bytes from 192.168.0.8: icmp_seq=1 ttl=255 time=1.169 ms
64 bytes from 192.168.0.8: icmp_seq=2 ttl=255 time=1.104 ms
64 bytes from 192.168.0.8: icmp_seq=3 ttl=255 time=1.155 ms
64 bytes from 192.168.0.8: icmp_seq=4 ttl=255 time=1.164 ms
--- 192.168.0.8 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/std-dev = 1.104/1.310/1.962/0.329 ms
[sparc.sick-net]#

Ecco cosa vediamo facendo sniffing:

[die0.sick-net]# tcpdump -i fxp0 -s 1500 host 192.168.0.8 and host 192.168.0.17
tcpdump: listening on fxp0
13:44:39.628638 arp who-has die1.sick-net tell 192.168.0.17
13:44:39.628892 arp reply die1.sick-net is-at 0:50:fc:1:21:5f
13:44:39.629253 192.168.0.17 > die1.sick-net: icmp: echo request
13:44:39.629498 die1.sick-net > 192.168.0.17: icmp: echo reply
13:44:40.635745 192.168.0.17 > die1.sick-net: icmp: echo request
13:44:40.635982 die1.sick-net > 192.168.0.17: icmp: echo reply
13:44:41.645596 192.168.0.17 > die1.sick-net: icmp: echo request
13:44:41.645844 die1.sick-net > 192.168.0.17: icmp: echo reply
^C
949 packets received by filter
0 packets dropped by kernel
[die0.sick-net]#

Ogni pacchetto può essere visto e, con l’opzione -w, salvato su un file pcap analizzabile con tantissimi tool, anche grafici, o anche con un semplice hexdump o strings, il chè potrebbe permettere con estrema facilità la lettura di tutte password che passano su tale LAN: a meno che i pacchetti non siano criptati, magari con IPSec.

3) Abilitiamo i protocolli che dovremo usare nel kernel con sysctl (nel GENERIC ci sono già compilati, basta appunto abilitarli), abilitiamo anche il routing dei pacchetti, e facciamo in modo che vengano mantenute tali impostazioni anche al reboot:

Prima eseguiamo un backup di /etc/sysctl.conf con

cp /etc/sysctl.conf /etc/sysctl.conf.bak

.
In questo modo se dovessimo fare errori potremmo sempre ripristinare il file di sistema originale.

[die1.sick-net]# sysctl -w net.inet.esp.enable=1
net.inet.esp.enable: 1 -> 1
[die1.sick-net]# sysctl -w net.inet.ah.enable=1
net.inet.ah.enable: 1 -> 1
[die1.sick-net]# echo "net.inet.ah.enable=1" >> /etc/sysctl.conf <
[die1.sick-net]# echo "net.inet.esp.enable=1" >> /etc/sysctl.conf
[die1.sick-net]# sysctl -w net.inet.ip.forwarding=1
net.inet.ip.forwarding: 0 -> 1
[die1.sick-net]# sysctl -w net.inet6.ip6.forwarding=1
net.inet6.ip6.forwarding: 0 -> 1
[die1.sick-net]# echo "net.inet.ip.forwarding=1" >> /etc/sysctl.conf
[die1.sick-net]# echo "net.inet6.ip6.forwarding=1" >> /etc/sysctl.conf
[die1.sick-net]# sysctl -w net.inet.ipcomp.enable=1
net.inet.ipcomp.enable: 0 -> 1
[die1.sick-net]# echo "net.inet.ipcomp.enable=1" >> /etc/sysctl.conf

[sparc.sick-net]# sysctl -w net.inet.esp.enable=1
net.inet.esp.enable: 1 -> 1
[sparc.sick-net]# sysctl -w net.inet.ah.enable=1
net.inet.ah.enable: 1 -> 1
[sparc.sick-net]# echo "net.inet.ah.enable=1" >> /etc/sysctl.conf <
[sparc.sick-net]# echo "net.inet.esp.enable=1" >> /etc/sysctl.conf
[sparc.sick-net]# sysctl -w net.inet.ip.forwarding=1
net.inet.ip.forwarding: 0 -> 1
[sparc.sick-net]# sysctl -w net.inet6.ip6.forwarding=1
net.inet6.ip6.forwarding: 0 -> 1
[sparc.sick-net]# echo "net.inet.ip.forwarding=1" >> /etc/sysctl.conf
[sparc.sick-net]# echo "net.inet6.ip6.forwarding=1" >> /etc/sysctl.conf
[sparc.sick-net]# sysctl -w net.inet.ipcomp.enable=1
net.inet.ipcomp.enable: 0 -> 1
[sparc.sick-net]# echo "net.inet.ipcomp.enable=1" >> /etc/sysctl.conf

4) Creiamo su ogni macchina le chiavi e le SA (Security Associations), usando come convenzione A=die1=192.168.0.8/255.255.255.0 e B=sparc=192.168.0.17/255.255.255.0. Da questo punto in poi se dovessimo fare errori o semplicemente volessimo ricominciare da 0 senza bisogno di riavviare, potremmo semplicemente eseguire “

/sbin/ipsecadm flush

” resettando sia i flussi che le SA:

[die1.sick-net]# dd if=/dev/urandom bs=1024 count=1 | sha1
1+0 records in
1+0 records out
1024 bytes transferred in 0.062 secs (16466 bytes/sec)
4ae1fdd43524bb86d9298febc4b565ca4852664d
[die1.sick-net]# dd if=/dev/urandom bs=1024 count=1 | sha1
1+0 records in
1+0 records out
1024 bytes transferred in 0.069 secs (14762 bytes/sec)
f1381cdc084f64b1f13eed04cf682e840277e9ce

[die1.sick-net]# /sbin/ipsecadm new esp -src 192.168.0.8 -dst 192.168.0.17 -forcetunnel
-spi 1000 -enc blf -auth sha1 -key   4ae1fdd43524bb86d9298febc4b565ca4852664d -authkey f1381cdc084f64b1f13eed04cf682e840277e9ce
[die1.sick-net]# /sbin/ipsecadm new esp -src 192.168.0.17 -dst 192.168.0.8 -forcetunnel
-spi 1001 -enc blf -auth sha1 -key  4ae1fdd43524bb86d9298febc4b565ca4852664d -authkey f1381cdc084f64b1f13eed04cf682e840277e9ce

[sparc.sick-net]# /sbin/ipsecadm new esp -src 192.168.0.8 -dst 192.168.0.17 -forcetunnel -spi 1000 -enc blf
-auth sha1 -key  4ae1fdd43524bb86d9298febc4b565ca4852664d -authkey f1381cdc084f64b1f13eed04cf682e840277e9ce
[sparc.sick-net]# /sbin/ipsecadm new esp -src 192.168.0.17 -dst 192.168.0.8 -forcetunnel -spi 1001 -enc blf
-auth sha1 -key 4ae1fdd43524bb86d9298febc4b565ca4852664d -authkey f1381cdc084f64b1f13eed04cf682e840277e9ce

E’ necessario ricordarsi sempre di tenere *SEGRETE* queste chiavi. Non usare quelle dell’esempio ma crearne di nuove, inquanto queste ormai sono già state sicuramente lette.

5) Creiamo su ogni macchina i flussi di uscita e di ingresso per i pacchetti cryptati, sarebbero quindi 8 per ogni macchina, 4 di uscita e 4 di ingresso, 2 per ogni ip gestito, cioè quello pubblico su internet delle due macchine e quello privato sulla LAN interna, come ip “virtuali” per due eventuali interfacce di lan interna sui due lati della vpn useremo questi A=die1=10.0.1.1/255.255.255.0 e B=sparc=10.0.2.2/255.255.255.0, se ci si volesse limitare soltanto a riuscire a criptare il traffico tra le due macchine basterebbe configurare solamente i primi 2 flussi elencati sotto di ogni macchina.

[die1.sick-net]# /sbin/ipsecadm flow -dst 192.168.0.17 -proto esp -addr 192.168.0.8 255.255.255.255 192.168.0.17 255.255.255.255
-require  -out -src 192.168.0.8
[die1.sick-net]# /sbin/ipsecadm flow -dst 192.168.0.17 -proto esp -addr 192.168.0.17 255.255.255.255 192.168.0.8 255.255.255.255
-require -in  -src 192.168.0.8

[die1.sick-net]# /sbin/ipsecadm flow -dst 192.168.0.17 -proto esp -addr 10.0.1.0 255.255.255.0 10.0.2.0 255.255.255.0
-require -out -src 192.168.0.8
[die1.sick-net]# /sbin/ipsecadm flow -dst 192.168.0.17 -proto esp -addr 192.168.0.8 255.255.255.255 10.0.2.0 255.255.255.0
-require -out -src 192.168.0.8
[die1.sick-net]# /sbin/ipsecadm flow -dst 192.168.0.17 -proto esp -addr 10.0.1.0 255.255.255.0 192.168.0.17 255.255.255.255
-require -out -src 192.168.0.8
[die1.sick-net]# /sbin/ipsecadm flow -dst 192.168.0.17 -proto esp -addr 10.0.2.0 255.255.255.0 10.0.1.0 255.255.255.0
-require -in -src 192.168.0.8
[die1.sick-net]# /sbin/ipsecadm flow -dst 192.168.0.17 -proto esp -addr 192.168.0.17 255.255.255.255 10.0.1.0 255.255.255.0
-require -in -src 192.168.0.8
[die1.sick-net]# /sbin/ipsecadm flow -dst 192.168.0.17 -proto esp -addr 10.0.2.0 255.255.255.0 192.168.0.8 255.255.255.255
-require -in -src  192.168.0.8
***

***
[sparc.sick-net]# /sbin/ipsecadm flow -dst 192.168.0.8 -proto esp -addr 192.168.0.17 255.255.255.255 192.168.0.8 255.255.255.255
-require -out -src 192.168.0.17
[sparc.sick-net]# /sbin/ipsecadm flow -dst 192.168.0.8 -proto esp -addr 192.168.0.8 255.255.255.255 192.168.0.17 255.255.255.255
-require -in -src 192.168.0.17

[sparc.sick-net]# /sbin/ipsecadm flow -dst 192.168.0.8 -proto esp -addr 10.0.2.0 255.255.255.0 10.0.1.0 255.255.255.0
-require -out -src 192.168.0.17
[sparc.sick-net]# /sbin/ipsecadm flow -dst 192.168.0.8 -proto esp -addr 192.168.0.17 255.255.255.255 10.0.1.0 255.255.255.0
-require -out  -src 192.168.0.17
[sparc.sick-net]# /sbin/ipsecadm flow -dst 192.168.0.8 -proto esp -addr 10.0.2.0 255.255.255.0 192.168.0.8 255.255.255.255
-require -out -src 192.168.0.17
[sparc.sick-net]# /sbin/ipsecadm flow -dst 192.168.0.8 -proto esp -addr 10.0.1.0 255.255.255.0 10.0.2.0 255.255.255.0
-require -in -src 192.168.0.17
[sparc.sick-net]# /sbin/ipsecadm flow -dst 192.168.0.8 -proto esp -addr 192.168.0.8 255.255.255.255 10.0.2.0 255.255.255.0
-require -in -src  192.168.0.17
[sparc.sick-net]# /sbin/ipsecadm flow -dst 192.168.0.8 -proto esp -addr 10.0.1.0 255.255.255.0 192.168.0.17 255.255.255.255
-require -in -src 192.168.0.17
***

Dopo aver fatto questo sui due host dovremmo avere una routing table simile a questa, controllabile con

netstat -nr

(non ci interessa risolvere i nomi, nè quello che c’è prima di Encap):

[die1.sick-net]# netstat -nr
Encap:
Source Port Destination Port Proto SA(Address/Proto/Type/Direction)
10.0.2/24 0 10.0.1/24 0 0 192.168.0.17/50/require/in
10.0.2/24 0 192.168.0.8/32 0 0 192.168.0.17/50/require/in
192.168.0.17/32 0 10.0.1/24 0 0 192.168.0.17/50/require/in
192.168.0.17/32 0 192.168.0.8/32 0 0 192.168.0.17/50/require/in
10.0.1/24 0 10.0.2/24 0 0 192.168.0.17/50/require/out
10.0.1/24 0 192.168.0.17/32 0 0 192.168.0.17/50/require/out
192.168.0.8/32 0 10.0.2/24 0 0 192.168.0.17/50/require/out
192.168.0.8/32 0 192.168.0.17/32 0 0 192.168.0.17/50/require/out

[sparc.sick-net]# netstat -nr
Encap:
Source Port Destination Port Proto SA(Address/Proto/Type/Direction)
10.0.1/24 0 10.0.2/24 0 0 192.168.0.8/50/require/in
10.0.1/24 0 192.168.0.17/32 0 0 192.168.0.8/50/require/in
192.168.0.8/32 0 10.0.2/24 0 0 192.168.0.8/50/require/in
192.168.0.8/32 0 192.168.0.17/32 0 0 192.168.0.8/50/require/in
10.0.2/24 0 10.0.1/24 0 0 192.168.0.8/50/require/out
10.0.2/24 0 192.168.0.8/32 0 0 192.168.0.8/50/require/out
192.168.0.17/32 0 10.0.1/24 0 0 192.168.0.8/50/require/out
192.168.0.17/32 0 192.168.0.8/32 0 0 192.168.0.8/50/require/out

6) Ora controlliamo se tra i 2 host iniziali la connessione avviene cryptata o meno, rifacendo la semplice prova con ping come al punto 2:

[die1.sick-net]# ping -c 3 192.168.0.17
PING 192.168.0.17 (192.168.0.17): 56 data bytes
64 bytes from 192.168.0.17: icmp_seq=0 ttl=255 time=5.382 ms
64 bytes from 192.168.0.17: icmp_seq=1 ttl=255 time=4.394 ms
64 bytes from 192.168.0.17: icmp_seq=2 ttl=255 time=4.321 ms
--- 192.168.0.17 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/std-dev = 4.321/4.699/5.382/0.483 ms
[die1.sick-net]#

[sparc.sick-net]# ping -c 3 192.168.0.8
PING 192.168.0.8 (192.168.0.8): 56 data bytes
64 bytes from 192.168.0.8: icmp_seq=0 ttl=255 time=5.091 ms
64 bytes from 192.168.0.8: icmp_seq=1 ttl=255 time=4.742 ms
64 bytes from 192.168.0.8: icmp_seq=2 ttl=255 time=4.730 ms
--- 192.168.0.8 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/std-dev = 4.730/4.854/5.091/0.176 ms
[sparc.sick-net]#

[die0.sick-net]# tcpdump -i fxp0 -s 1500 host 192.168.0.8 and host 192.168.0.17
tcpdump: listening on fxp0
12:00:27.237979 esp die1.sick-net > 192.168.0.17 spi 0x00001000 seq 13 len 116
12:00:27.241112 esp 192.168.0.17 > die1.sick-net spi 0x00001001 seq 13 len 116
12:00:28.240834 esp die1.sick-net > 192.168.0.17 spi 0x00001000 seq 14 len 116
12:00:28.243783 esp 192.168.0.17 > die1.sick-net spi 0x00001001 seq 14 len 116
12:00:29.250609 esp die1.sick-net > 192.168.0.17 spi 0x00001000 seq 15 len 116
12:00:29.253543 esp 192.168.0.17 > die1.sick-net spi 0x00001001 seq 15 len 116
12:00:38.039461 esp 192.168.0.17 > die1.sick-net spi 0x00001001 seq 16 len 116
12:00:38.040698 esp die1.sick-net > 192.168.0.17 spi 0x00001000 seq 16 len 116
12:00:39.048395 esp 192.168.0.17 > die1.sick-net spi 0x00001001 seq 17 len 116
12:00:39.049592 esp die1.sick-net > 192.168.0.17 spi 0x00001000 seq 17 len 116
12:00:40.058269 esp 192.168.0.17 > die1.sick-net spi 0x00001001 seq 18 len 116
12:00:40.059413 esp die1.sick-net > 192.168.0.17 spi 0x00001000 seq 18 len 116
^C
417 packets received by filter
0 packets dropped by kernel
[die0.sick-net]#

Perfetto. Tutti i pacchetti sono di tipo spi e sono quindi criptati, ma non solo. Adesso proviamo a pingare i 2 host “virtuali” tra loro, che altro non sarebbero che le due LAN ruotate attraverso la nostra vpn appena creata:

[die1.sick-net]# ping -c 3 10.0.2.2
PING 10.0.2.2 (10.0.2.2): 56 data bytes
64 bytes from 10.0.2.2: icmp_seq=0 ttl=255 time=4.577 ms
64 bytes from 10.0.2.2: icmp_seq=1 ttl=255 time=4.343 ms
64 bytes from 10.0.2.2: icmp_seq=2 ttl=255 time=4.438 ms
--- 10.0.2.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/std-dev = 4.343/4.452/4.577/0.123 ms
[die1.sick-net]#

[sparc.sick-net]# ping -c 3 10.0.1.1
PING 10.0.1.1 (10.0.1.1): 56 data bytes
64 bytes from 10.0.1.1: icmp_seq=0 ttl=255 time=6.613 ms
64 bytes from 10.0.1.1: icmp_seq=1 ttl=255 time=4.679 ms
64 bytes from 10.0.1.1: icmp_seq=2 ttl=255 time=4.700 ms
--- 10.0.1.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/std-dev = 4.679/5.330/6.613/0.910 ms
[sparc.sick-net]#

[die0.sick-net]# tcpdump -i fxp0 -s 1500 host 192.168.0.8 and host 192.168.0.17
tcpdump: listening on fxp0
12:02:23.346286 esp 192.168.0.17 > die1.sick-net spi 0x00001001 seq 19 len 116
12:02:23.347548 esp die1.sick-net > 192.168.0.17 spi 0x00001000 seq 19 len 116
12:02:24.358961 esp 192.168.0.17 > die1.sick-net spi 0x00001001 seq 20 len 116
12:02:24.360089 esp die1.sick-net > 192.168.0.17 spi 0x00001000 seq 20 len 116
12:02:25.368772 esp 192.168.0.17 > die1.sick-net spi 0x00001001 seq 21 len 116
12:02:25.369932 esp die1.sick-net > 192.168.0.17 spi 0x00001000 seq 21 len 116
12:02:28.538368 esp die1.sick-net > 192.168.0.17 spi 0x00001000 seq 22 len 116
12:02:28.541439 esp 192.168.0.17 > die1.sick-net spi 0x00001001 seq 22 len 116
12:02:29.547144 esp die1.sick-net > 192.168.0.17 spi 0x00001000 seq 23 len 116
12:02:29.550085 esp 192.168.0.17 > die1.sick-net spi 0x00001001 seq 23 len 116
12:02:30.556963 esp die1.sick-net > 192.168.0.17 spi 0x00001000 seq 24 len 116
12:02:30.559968 esp 192.168.0.17 > die1.sick-net spi 0x00001001 seq 24 len 116
^C
228 packets received by filter
0 packets dropped by kernel
[die0.sick-net]#

Benissimo. Non solo vengono cryptati i flussi di dati, ma vengono anche incapsulati gli header IP dei pacchetti tra le due LAN, così dall’esterno non è possibile vedere quali sono gli ip delle LAN private dietro i router IPSec.

Articoli correlati

Noleggia una Tesla per il tuo evento ICT!

Categorie