
strongswan v6.1.0
strongSwan - VPN basata su IPsec
Configurazione di strongSwan
Panoramica
strongSwan è una soluzione VPN OpenSource basata su IPsec.
Questo documento è solo una breve introduzione al comando swanctl di strongSwan, che usa la moderna vici Versatile IKE Configuration Interface. Il comando ipsec deprecato, che usa l'interfaccia di configurazione legacy stroke, è descritto qui. Per informazioni più dettagliate consultare le pagine man, il nostro nuovo sito di documentazione e la wiki legacy.
Avvio rapido
I certificati per utenti, host e gateway sono emessi da una fittizia CA
strongSwan. Negli scenari di esempio, il certificato CA strongswanCert.pem
deve essere presente su tutti gli endpoint VPN per poter autenticare i peer.
Per la vostra specifica applicazione VPN potete usare certificati di una
qualsiasi CA di terze parti oppure generare voi stessi le chiavi private e i
certificati necessari con lo strumento pki di strongSwan, il cui utilizzo
verrà spiegato in una delle sezioni seguenti.
Caso Site-to-Site
In questo scenario due security gateway moon e sun collegano tra loro le due sottoreti moon-net e sun-net attraverso un tunnel VPN instaurato tra i due gateway:
10.1.0.0/16 -- | 192.168.0.1 | === | 192.168.0.2 | -- 10.2.0.0/16
moon-net moon sun sun-net
Configurazione sul gateway moon:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem
/etc/swanctl/swanctl.conf:
connections {
net-net {
remote_addrs = 192.168.0.2
local {
auth = pubkey
certs = moonCert.pem
}
remote {
auth = pubkey
id = "C=CH, O=strongSwan, CN=sun.strongswan.org"
}
children {
net-net {
local_ts = 10.1.0.0/16
remote_ts = 10.2.0.0/16
start_action = trap
}
}
}
}
Configurazione sul gateway sun:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/sunCert.pem
/etc/swanctl/private/sunKey.pem
/etc/swanctl/swanctl.conf:
connections {
net-net {
remote_addrs = 192.168.0.1
local {
auth = pubkey
certs = sunCert.pem
}
remote {
auth = pubkey
id = "C=CH, O=strongSwan, CN=moon.strongswan.org"
}
children {
net-net {
local_ts = 10.2.0.0/16
remote_ts = 10.1.0.0/16
start_action = trap
}
}
}
}
Le identità locali e remote usate in questo scenario sono i subjectDistinguishedNames contenuti nei certificati end entity. I certificati e le chiavi private vengono caricati nel demone charon con il comando
swanctl --load-creds
mentre
swanctl --load-conns
carica le connessioni definite in swanctl.conf. Con start_action = trap
la connessione IPsec viene stabilita automaticamente al primo pacchetto IP in
chiaro che vuole attraversare il tunnel.
Caso Host-to-Host
Questa è una configurazione tra due singoli host che non hanno una sottorete alle loro spalle. Sebbene la modalità transport IPsec sarebbe sufficiente per le connessioni host-to-host, useremo la modalità tunnel IPsec predefinita.
| 192.168.0.1 | === | 192.168.0.2 |
moon sun
Configurazione sull'host moon:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem
/etc/swanctl/swanctl.conf:
connections {
host-host {
remote_addrs = 192.168.0.2
local {
auth=pubkey
certs = moonCert.pem
}
remote {
auth = pubkey
id = "C=CH, O=strongSwan, CN=sun.strongswan.org"
}
children {
net-net {
start_action = trap
}
}
}
}
Configurazione sull'host sun:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/sunCert.pem
/etc/swanctl/private/sunKey.pem
/etc/swanctl/swanctl.conf:
connections {
host-host {
remote_addrs = 192.168.0.1
local {
auth = pubkey
certs = sunCert.pem
}
remote {
auth = pubkey
id = "C=CH, O=strongSwan, CN=moon.strongswan.org"
}
children {
host-host {
start_action = trap
}
}
}
}
Caso Roadwarrior
Questo è un caso molto comune in cui un gateway strongSwan serve un numero arbitrario di client VPN remoti, che in genere hanno indirizzi IP dinamici.
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x |
moon-net moon carol
Configurazione sul gateway moon:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem
/etc/swanctl/swanctl.conf:
connections {
rw {
local {
auth = pubkey
certs = moonCert.pem
id = moon.strongswan.org
}
remote {
auth = pubkey
}
children {
net-net {
local_ts = 10.1.0.0/16
}
}
}
}
Configurazione sul roadwarrior carol:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/carolCert.pem
/etc/swanctl/private/carolKey.pem
/etc/swanctl/swanctl.conf:
connections {
home {
remote_addrs = moon.strongswan.org
local {
auth = pubkey
certs = carolCert.pem
id = [email protected]
}
remote {
auth = pubkey
id = moon.strongswan.org
}
children {
home {
local_ts = 10.1.0.0/16
start_action = start
}
}
}
}
Per remote_addrs è stato scelto il nome host moon.strongswan.org, che verrà
risolto dal DNS in fase di esecuzione nel corrispondente indirizzo IP di
destinazione. In questo scenario l'identità del roadwarrior carol è
l'indirizzo email [email protected], che deve essere incluso come
subjectAlternativeName nel certificato roadwarrior carolCert.pem.
Caso Roadwarrior con IP Virtuale
I roadwarrior di solito hanno indirizzi IP dinamici assegnati dall'ISP a cui sono attualmente collegati. Per semplificare il routing da moon-net verso il client di accesso remoto carol, sarebbe desiderabile che il roadwarrior avesse un indirizzo IP interno scelto da un pool predefinito.
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x | -- 10.3.0.1
moon-net moon carol virtual IP
Nel nostro esempio l'indirizzo IP virtuale viene scelto dal pool di indirizzi
10.3.0.0/16, che può essere configurato aggiungendo la sezione
pools {
rw_pool {
addrs = 10.3.0.0/16
}
}
al swanctl.conf del gateway, da dove vengono caricati nel demone charon
usando il comando
swanctl --load-pools
Per richiedere un indirizzo IP da questo pool, un roadwarrior può usare la mode config IKEv1 o i configuration payload IKEv2. La configurazione per entrambi è la stessa
vips = 0.0.0.0
Configurazione sul gateway moon:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem
/etc/swanctl/swanctl.conf:
connections {
rw {
pools = rw_pool
local {
auth = pubkey
certs = moonCert.pem
id = moon.strongswan.org
}
remote {
auth = pubkey
}
children {
net-net {
local_ts = 10.1.0.0/16
}
}
}
}
pools {
rw_pool {
addrs = 10.30.0.0/16
}
}
Configurazione sul roadwarrior carol:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/carolCert.pem
/etc/swanctl/private/carolKey.pem
/etc/swanctl/swanctl.conf:
connections {
home {
remote_addrs = moon.strongswan.org
vips = 0.0.0.0
local {
auth = pubkey
certs = carolCert.pem
id = [email protected]
}
remote {
auth = pubkey
id = moon.strongswan.org
}
children {
home {
local_ts = 10.1.0.0/16
start_action = start
}
}
}
}
Caso Roadwarrior con Autenticazione EAP
Questo è un caso molto comune in cui un gateway strongSwan serve un numero arbitrario di client VPN remoti che si autenticano tramite un Extended Authentication Protocol basato su password, come ad esempio EAP-MD5 o EAP-MSCHAPv2.
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x |
moon-net moon carol
Configurazione sul gateway moon:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem
/etc/swanctl/swanctl.conf:
connections {
rw {
local {
auth = pubkey
certs = moonCert.pem
id = moon.strongswan.org
}
remote {
auth = eap-md5
}
children {
net-net {
local_ts = 10.1.0.0/16
}
}
send_certreq = no
}
}
Il file swanctl.conf contiene inoltre una sezione secrets che definisce
tutte le credenziali dei client
secrets {
eap-carol {
id = [email protected]
secret = Ar3etTnp
}
eap-dave {
id = [email protected]
secret = W7R0g3do
}
}
Configurazione sul roadwarrior carol:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/swanctl.conf:
connections {
home {
remote_addrs = moon.strongswan.org
local {
auth = eap
id = [email protected]
}
remote {
auth = pubkey
id = moon.strongswan.org
}
children {
home {
local_ts = 10.1.0.0/16
start_action = start
}
}
}
}
secrets {
eap-carol {
id = [email protected]
secret = Ar3etTnp
}
}
Caso Roadwarrior con Identità EAP
Spesso un'identità EAP del client viene scambiata tramite EAP e differisce dall'identità IKEv2 esterna. In questo esempio l'identità IKEv2 predefinita è l'indirizzo IPv4 del client.
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x |
moon-net moon carol
Configurazione sul gateway moon:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem
/etc/swanctl/swanctl.conf:
connections {
rw {
local {
auth = pubkey
certs = moonCert.pem
id = moon.strongswan.org
}
remote {
auth = eap-md5
eap_id = %any
}
children {
net-net {
local_ts = 10.1.0.0/16
}
}
send_certreq = no
}
}
secrets {
eap-carol {
id = carol
secret = Ar3etTnp
}
eap-dave {
id = dave
secret = W7R0g3do
}
}
Configurazione sul roadwarrior carol:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/swanctl.conf:
connections {
home {
remote_addrs = moon.strongswan.org
local {
auth = eap
eap_id = carol
}
remote {
auth = pubkey
id = moon.strongswan.org
}
children {
home {
local_ts = 10.1.0.0/16
start_action = start
}
}
}
}
secrets {
eap-carol {
id = carol
secret = Ar3etTnp
}
}
Generazione di Certificati e CRL
Questa sezione non è un tutorial completo su come usare lo strumento pki di strongSwan. Elenca solo alcuni punti rilevanti se si desidera generare i propri certificati e CRL da usare con strongSwan.
Generazione di un Certificato CA
L'istruzione pki
pki --gen --type ed25519 --outform pem > strongswanKey.pem
genera una chiave ellittica Edwards-Curve con una forza crittografica di 128 bit. La corrispondente chiave pubblica viene inserita in un certificato CA autofirmato con una validità di 10 anni (3652 giorni)
pki --self --ca --lifetime 3652 --in strongswanKey.pem \
--dn "C=CH, O=strongSwan, CN=strongSwan Root CA" \
--outform pem > strongswanCert.pem
che può essere visualizzato con il comando
pki --print --in strongswanCert.pem
subject: "C=CH, O=strongSwan, CN=strongSwan Root CA"
issuer: "C=CH, O=strongSwan, CN=strongSwan Root CA"
validity: not before May 18 08:32:06 2017, ok
not after May 18 08:32:06 2027, ok (expires in 3651 days)
serial: 57:e0:6b:3a:9a:eb:c6:e0
flags: CA CRLSign self-signed
subjkeyId: 2b:95:14:5b:c3:22:87:de:d1:42:91:88:63:b3:d5:c1:92:7a:0f:5d
pubkey: ED25519 256 bits
keyid: a7:e1:6a:3f:e7:6f:08:9d:89:ec:23:92:a9:a1:14:3c:78:a8:7a:f7
subjkey: 2b:95:14:5b:c3:22:87:de:d1:42:91:88:63:b3:d5:c1:92:7a:0f:5d
Se preferite che la chiave privata della CA e il certificato X.509 siano in
formato binario DER, basta omettere l'opzione --outform pem. La directory
/etc/swanctl/x509ca contiene tutti i certificati CA richiesti, sia in formato
DER binario che in formato PEM Base64. Indipendentemente dall'estensione del
file, il formato corretto verrà determinato automaticamente da strongSwan.
Generazione di un Certificato End Entity per Host o Utente
Anche qui usiamo il comando
pki --gen --type ed25519 --outform pem > moonKey.pem
per generare una chiave privata Ed25519 per l'host moon. In alternativa
potete digitare
pki --gen --type rsa --size 3072 > moonKey.der
per generare una tradizionale chiave RSA da 3072 bit e salvarla in formato DER binario. In alternativa, un TPM 2.0 Trusted Platform Module disponibile su ogni piattaforma Intel recente potrebbe essere usato come smartcard virtuale per archiviare in modo sicuro una chiave privata RSA o ECDSA. Per i dettagli, fare riferimento al HOWTO TPM 2.0.
In un passaggio successivo, il comando
pki --req --type priv --in moonKey.pem \
--dn "C=CH, O=strongswan, CN=moon.strongswan.org" \
--san moon.strongswan.org --outform pem > moonReq.pem
crea una richiesta di certificato PKCS#10 che deve essere firmata dalla CA.
Grazie all'uso [multiplo] del parametro --san, è possibile aggiungere alla
richiesta un numero qualsiasi di subjectAlternativeNames desiderate. Queste
possono essere della forma
--san sun.strongswan.org # fully qualified host name
--san [email protected] # RFC822 user email address
--san 192.168.0.1 # IPv4 address
--san fec0::1 # IPv6 address
Sulla base della richiesta di certificato, la CA emette un certificato end entity firmato con il seguente comando
pki --issue --cacert strongswanCert.pem --cakey strongswanKey.pem \
--type pkcs10 --in moonReq.pem --serial 01 --lifetime 1826 \
--outform pem > moonCert.pem
Se il parametro --serial con un argomento esadecimale viene omesso, viene
generato un numero di serie casuale. Alcuni client VPN di terze parti
richiedono che il certificato del gateway VPN contenga il flag TLS Server
Authentication Extended Key Usage (EKU), che può essere incluso con la
seguente opzione
--flag serverAuth
Se si desidera utilizzare la funzionalità di recupero dinamico delle CRL
descritta in una delle sezioni seguenti, è possibile includere uno o più
crlDistributionPoints nei propri certificati end entity usando il parametro
--crl
--crl http://crl.strongswan.org/strongswan.crl
--crl "ldap://ldap.strongswan.org/cn=strongSwan Root CA, o=strongSwan,c=CH?certificateRevocationList"
Il certificato host emesso può essere visualizzato con
pki --print --in moonCert.pem
subject: "C=CH, O=strongSwan, CN=moon.strongswan.org"
issuer: "C=CH, O=strongSwan, CN=strongSwan Root CA"
validity: not before May 19 10:28:19 2017, ok
not after May 19 10:28:19 2022, ok (expires in 1825 days)
serial: 01
altNames: moon.strongswan.org
flags: serverAuth
CRL URIs: http://crl.strongswan.org/strongswan.crl
authkeyId: 2b:95:14:5b:c3:22:87:de:d1:42:91:88:63:b3:d5:c1:92:7a:0f:5d
subjkeyId: 60:9d:de:30:a6:ca:b9:8e:87:bb:33:23:61:19:18:b8:c4:7e:23:8f
pubkey: ED25519 256 bits
keyid: 39:1b:b3:c2:34:72:1a:01:08:40:ce:97:75:b8:be:ce:24:30:26:29
subjkey: 60:9d:de:30:a6:ca:b9:8e:87:bb:33:23:61:19:18:b8:c4:7e:23:8f
Di solito, un client VPN basato su Windows, OSX, Android o iOS necessita della propria chiave privata, del proprio certificato host o utente e del certificato CA. Il modo più comodo per caricare queste informazioni è inserire tutto in un contenitore PKCS#12:
openssl pkcs12 -export -inkey carolKey.pem \
-in carolCert.pem -name "carol" \
-certfile strongswanCert.pem -caname "strongSwan Root CA" \
-out carolCert.p12
Lo strumento pki di strongSwan attualmente non è in grado di creare contenitori PKCS#12, quindi è necessario usare openssl.
Generazione di una CRL
Una CRL vuota firmata dalla CA può essere generata con il comando
pki --signcrl --cacert strongswanCert.pem --cakey strongswanKey.pem \
--lifetime 30 > strongswan.crl
Se si omette l'opzione --lifetime, viene usato il valore predefinito di 15
giorni. Le CRL possono essere caricate su un server HTTP o LDAP oppure inserite
in formato DER binario o PEM Base64 nella directory /etc/swanctl/x509crl, da
dove vengono caricate nel demone charon con il comando
swanctl --load-creds### Revoca di un certificato ###
Un certificato di entità finale specifico viene revocato con il comando
pki --signcrl --cacert strongswanCert.pem --cakey strongswanKey.pem \
--lifetime 30 --lastcrl strongswan.crl \
--reason key-compromise --cert moonCert.pem > new.crl
Invece del file del certificato (nel nostro esempio moonCert.pem), è possibile indicare il numero di serie del certificato da revocare utilizzando il parametro --serial. Il comando pki --signcrl --help documenta tutte le possibili ragioni di revoca, ma il parametro --reason può anche essere omesso. Il contenuto del nuovo file CRL può essere elencato con il comando
pki --print --type crl --in new.crl
issuer: "C=CH, O=strongSwan, CN=strongSwan Root CA"
update: this on May 19 11:13:01 2017, ok
next on Jun 18 11:13:01 2017, ok (expires in 29 days)
serial: 02
authKeyId: 2b:95:14:5b:c3:22:87:de:d1:42:91:88:63:b3:d5:c1:92:7a:0f:5d
1 revoked certificate:
01: May 19 11:13:01 2017, key compromise
Cache locale delle CRL
L'opzione di strongswan.conf
charon {
cache_crls = yes
}
attiva la memorizzazione locale nella cache delle CRL recuperate dinamicamente da un server HTTP o LDAP. Le copie memorizzate nella cache vengono salvate in /etc/swanctl/x509crl utilizzando un nome file univoco composto dal subjectKeyIdentifier dell'emittente e dal suffisso .crl.
Con la copia memorizzata nella cache, la CRL è immediatamente disponibile dopo l'avvio. Quando la copia locale diventa obsoleta, una CRL aggiornata viene recuperata automaticamente da uno dei punti di distribuzione delle CRL definiti durante la successiva autenticazione IKEv2.