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.