OpenBSD ipsec vpn advanced Scenario: 192.168.1.0/24--ne3[FRW1]rl0--vr0[FRW2]rl0--192.168.2.0/24 Rete privata con subnet 192.168.1.0/24 Firewall 1 (FRW1) nic ne3: 192.168.1.1 (interfaccia interna) nic rl0: 10.0.0.1 (interfaccia esterna) Firewall 2 (FRW2) nic vr0: 10.0.0.2 (interfaccia esterna) nic rl0: 192.168.2.1 (interfaccia interna) Rete privata con subnet 192.168.2.0/24 Il firewall FRW1 protegge la rete privata 192.168.1.0/24 ed effettua la nat degli indirizzi interni Il firewall FRW2 protegge la rete privata 192.168.2.0/24 ed effettua la nat degli indirizzi interni I due firewall comunicano tra loro su una linea dedicata con le due interfaccie di rete che condividono la stessa subnet 10.0.0.0/24 I dati scambiati dalle due reti private sulla linea dedicata sono protette da ipsec Utilizzando ipsec/ipsecctl, un certificato X509 per l'autenticazione e scegliendo gli algoritmi di crittografia indispensabili ai demoni isakmpd si configuri una vpn tra le due reti private ipsecctl aiuta a semplificare la configurazione di ipsec 1. Assicurarsi che le tre subnet 192.168.1.0/24, 192.168.2.0/24 e 10.0.0.0/24 comunichino tra loro eventualmente aggiornando le rispettive tabelle di routing e abilitando l'ip forwarding nei due router firewall FRW1: route add 192.168.2.0/24 10.0.0.2 route show -inet Togliere il commento # alla seguente riga di /etc/sysctl.conf: net.inet.ip.forwarding=1 firewall FRW2: route add 192.168.1.0/24 10.0.0.1 route show -inet Togliere il commento # alla seguente riga di /etc/sysctl.conf: net.inet.ip.forwarding=1 generico pc della subnet 192.168.1.0/24: route add 10.0.0.0/24 192.168.1.1 route add 192.168.2.0/24 192.168.1.1 route show -inet generico pc della subnet 192.168.2.0/24: route add 10.0.0.0/24 192.168.2.1 route add 192.168.1.0/24 192.168.2.1 route show -inet 2. Abilitare nei due firewall/router i protocolli di ipsec togliendo i commenti # alle seguenti righe di /etc/sysctl.conf: net.inet.esp.enable=1 net.inet.ah.enable=1 3. Configurazione del firewall FRW1 in pf.conf ext_if = "rl0" int_if = "ne3" set skip on { lo0 $int_if } nat on $ext_if from ! ($ext_if) -> ($ext_if:0) block in pass out keep state 4. Configurazione del firewall FRW2 in pf.conf ext_if = "vr0" int_if = "rl0" set skip on { lo0 $int_if } nat on $ext_if from ! ($ext_if) -> ($ext_if:0) block in pass out keep state 5. Per l'autenticazione utilizzo un certificato X509 Come descritto in isakmpd(8) uso openssl(1) per creare un Certificate Signing Request (CSR) interpretabile dal Certificate Authority (CA) La Certificate Authority (CA) e' usata per autenticare gli host certificates 5.1 Creo il self-signed root Certificate Authority (CA, ca.crt) e la sua chiave privata ca.key: # openssl req -x509 -days 365 -newkey rsa:1024 \ -keyout /etc/ssl/private/ca.key \ -out /etc/ssl/ca.crt Sono richieste alcune informazioni che verranno inglobate nel certificato (per lasciare un campo vuoto usare il punto '.') 5.2 Creo il Certificate Signing Requests (CSRs) per ogni peer IKE utilizzando una chiave esistente (5.2.1) oppure creando una nuova chiave (5.2.2) 5.2.1 I CSR vengono autenticati da una chiave privata pre-generata # openssl req -new -key /etc/isakmpd/private/local.key \ -out /etc/isakmpd/private/10.0.0.1.csr 5.2.2 # cd /etc/ssl # openssl genrsa -out 10.0.0.1.key 1024 # openssl req -new -key 10.0.0.1.key \ -out 10.0.0.1.csr 5.3 Utilizzando la CSR e la CA si puo' ottenere il certificato .crt: # env CERTIP=10.0.0.1 openssl x509 -req \ -days 365 -in 10.0.0.1.csr \ -CA /etc/ssl/ca.crt -CAkey /etc/ssl/private/ca.key \ -CAcreateserial -extfile /etc/ssl/x509v3.cnf \ -extensions x509v3_IPAddr -out 10.0.0.1.crt 5.4 Gli step 5.2 e 5.3 vanno ripetuti anche per il peer 10.0.0.2 5.5 Il certificato CA /etc/ssl/ca.crt deve essere spostato in /etc/isakmpd/ca/ I certificati 10.0.0.1.crt e 10.0.0.2 devono essere spostati nella directory locale /etc/isakmpd/certs/ Se sono state create le nuove chiavi 10.0.0.1.key e 10.0.0.2 in /etc/isakmpd/private di ogni singolo host devono essere rinominate come local.key e il file deve essere leggibile solo dal root chmod 0400 local.key 6. Come descritto nella sezione CRYPTO TRANSFORMS nella man page di ipsec.conf e' possibile scegliere tra differenti algoritmi di cifratura per l'autenticazione/crittografia e group-size durante le due fasi di scambio delle chiavi tra i due demoni isakmpd In questo documento ho scelto i seguenti algoritmi: fase 1 autenticazione: hmac-sha2-384 crittografia: blowfish group-size: modp1024 fase 2 autenticazione: hmac-sha2-512 crittografia: 3des group-size: modp1024 6.1 Sul firewall FRW1 si modifichi /etc/ipsec.conf: ike esp from 192.168.1.0/24 to 192.168.2.0/24 peer 10.0.0.2 \ main auth hmac-sha2-384 enc blowfish group modp1024 \ quick auth hmac-sha2-512 enc 3des group modp1024 Quando non e' specificato (come in questo caso, vedi ipsec.conf man page) avremo: active mode: la negoziazione tra i due demoni isakmpd inizia automaticamente encap esp: protocollo esp tmode tunnel: tunnel mode perfetto per creare una vpn 6.2 Sul firewall FRW2 si modifichi /etc/ipsec.conf: ike esp from 192.168.2.0/24 to 192.168.1.0/24 peer 10.0.0.1 \ main auth hmac-sha2-384 enc blowfish group modp1024 \ quick auth hmac-sha2-512 enc 3des group modp1024 7. Consentire il passaggio di ipsec attraverso il firewall FRW1 modificando pf.conf linea da aggiungere: pass quick on $ext_if from 10.0.0.2 linea da modificare: set skip on { lo0 $int_if enc0 } 8. Consentire il passaggio di ipsec attraverso il firewall FRW2 modificando pf.conf linea da aggiungere: pass quick on $ext_if from 10.0.0.1 linea da modificare: set skip on { lo0 $int_if enc0 } 9. Verificare nei due firewall in /etc/rc.conf che pf sia attivo e che ipesec non lo sia pf=YES ipsec=NO 10. Avviare la vpn in modalita' debug su entrambi i firewall isakmpd -Kdv ipsecctl -f /etc/ipsec.conf -d: usata per far funzionare il demone in foreground facendo loggare allo stderr -v: abilita il logging verbose (logga il completamento della fase 1 (Main) e la fase 2 (Quick)) 061615.279787 Default isakmpd: phase 1 done: initiator id 0a000001: 10.0.0.1, responder id 0a000002: 10.0.0.2, src: 10.0.0.1 dst: 10.0.0.2 061615.347568 Default isakmpd: quick mode done: src: 10.0.0.1 dst: 10.0.0.2 11. Effettuare un ping da 192.168.1.* a 192.168.2.* e viceversa 12. Per controllare che effettivamente i pacchetti siano crittografati usare, ad esempio, tcpdump sul firewall FRW1 e effettuare un ping dal pc 192.168.1.2 al pc 192.168.2.2 tcpdump -i rl0 -s 1500 host 10.0.0.1 tcpdump: listening on rl0, link-type EN10MB 06:26:55.921081 esp 10.0.0.1 > 10.0.0.2 spi 0x21B834B2 seq1 len 116 06:26:55.924659 esp 10.0.0.2 > 10.0.0.1 spi 0x2EFF2D20 seq1 len 116 13. Per conosce lo stato dei flows e delle associazioni: ipsecctl -sa FLOWS: flow esp in from 192.168.2.0/24 to 192.168.1.0/24 peer 10.0.0.2 srcid 10.0.0.1/32 dstid 10.0.0.2/32 type use flow esp out from 192.168.1.0/24 to 192.168.2.0/24 peer 10.0.0.2 srcid 10.0.0.1/32 dstid 10.0.0.2/32 type require SAD: esp tunnel from 10.0.0.1 to 10.0.0.2 spi 0x21b834b2 auth hmac-sha2-512 enc 3des-cbc esp tunnel from 10.0.0.2 to 10.0.0.1 spi 0x2eff2d20 auth hmac-sha2-512 enc 3des-cbc 14. Rendere definitive le modifiche Cambiare la seguente linea in /etc/rc.conf isakmpd_flags=''-K'' Aggiungere inoltre la seguente riga a rc.local: ipsecctl -f /etc/ipsec.conf 15. Miglioriamo le regole dei firewall partendo da PACKET FILTERING di ipsec.conf man page Il traffico IPsec appare non crittografato all'interfaccia enc e' puo' essere filtrato con pf proto udp port 500 traffico ISAKMP sull'interfaccia esterna per lo scambio delle chiavi proto ah | esp Traffico IPsec encapsulated sull'interfaccia esterna 15.1 Configurazione del firewall FRW1 in pf.conf ext_if = "rl0" int_if = "ne3" set skip on { lo0 $int_if enc0 } nat on $ext_if from ! ($ext_if) -> ($ext_if:0) block on $ext_if pass in on $ext_if proto udp from 10.0.0.2 to 10.0.0.1 port 500 pass out on $ext_if proto udp from 10.0.0.1 to 10.0.0.2 port 500 pass in on $ext_if proto esp from 10.0.0.2 to 10.0.0.1 pass out on $ext_if proto esp from 10.0.0.1 to 10.0.0.2 15.2 Configurazione del firewall FRW2 in pf.conf ext_if = "vr0" int_if = "rl0" set skip on { lo0 $int_if enc0 } nat on $ext_if from ! ($ext_if) -> ($ext_if:0) block on $ext_if pass in on $ext_if proto udp from 10.0.0.1 to 10.0.0.2 port 500 pass out on $ext_if proto udp from 10.0.0.2 to 10.0.0.1 port 500 pass in on $ext_if proto esp from 10.0.0.1 to 10.0.0.2 pass out on $ext_if proto esp from 10.0.0.2 to 10.0.0.1 10.07 rev.0 Giuseppe Reale jscrat@libero.it reference: ipsec, ipsec.conf man pages IPSec done BSD way - therek