VPN con IPSec su OpenBSD in sei passi
mercoledì 6 dicembre, 2006Autore: Autore da inserire
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.
























