
strongswan v6.1.0
strongSwan - VPN baseada em IPsec
Configuração do strongSwan
Visão Geral
O strongSwan é uma solução de VPN OpenSource baseada em IPsec.
Este documento é apenas uma breve introdução ao comando swanctl do strongSwan, que utiliza a moderna vici Versatile IKE Configuration Interface. O comando ipsec, obsoleto, que usa a interface de configuração stroke legada, é descrito aqui. Para informações mais detalhadas, consulte as páginas de manual, o novo site de documentação e o wiki legado.
Quickstart
Certificados para usuários, hosts e gateways são emitidos por uma CA strongSwan
fictícia. Em nossos cenários de exemplo, o certificado da CA strongswanCert.pem
precisa estar presente em todos os endpoints VPN para que os pares possam ser
autenticados. Para sua aplicação VPN específica, você pode usar certificados de
qualquer CA de terceiros ou gerar você mesmo as chaves privadas e certificados
necessários com a ferramenta pki do strongSwan, cujo uso será explicado em
uma das seções a seguir.
Caso Site a Site
Neste cenário, dois gateways de segurança, moon e sun, conectarão as duas sub-redes moon-net e sun-net entre si por meio de um túnel VPN estabelecido entre os dois gateways:
10.1.0.0/16 -- | 192.168.0.1 | === | 192.168.0.2 | -- 10.2.0.0/16
moon-net moon sun sun-net
Configuração no 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
}
}
}
}
Configuração no 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
}
}
}
}
As identidades locais e remotas usadas neste cenário são os subjectDistinguishedNames contidos nos certificados de entidade final. Os certificados e as chaves privadas são carregados no daemon charon com o comando
swanctl --load-creds
enquanto
swanctl --load-conns
carrega as conexões definidas em swanctl.conf. Com start_action = trap, a
conexão IPsec é estabelecida automaticamente com o primeiro pacote IP de payload
em texto claro que quiser passar pelo túnel.
Caso Host a Host
Esta é uma configuração entre dois hosts únicos que não possuem uma sub-rede atrás deles. Embora o modo de transporte IPsec fosse suficiente para conexões host a host, usaremos o modo túnel IPsec padrão.
| 192.168.0.1 | === | 192.168.0.2 |
moon sun
Configuração no 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
}
}
}
}
Configuração no 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
Este é um caso muito comum em que um gateway strongSwan atende a um número arbitrário de clientes VPN remotos, geralmente com endereços IP dinâmicos.
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x |
moon-net moon carol
Configuração no 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
}
}
}
}
Configuração no 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
}
}
}
}
Para remote_addrs, foi escolhido o nome de host moon.strongswan.org, que
será resolvido por DNS em tempo de execução para o endereço IP de destino
correspondente. Neste cenário, a identidade do roadwarrior carol é o endereço
de e-mail [email protected], que deve ser incluído como
subjectAlternativeName no certificado do roadwarrior carolCert.pem.
Caso Roadwarrior com IP Virtual
Os roadwarriors geralmente têm endereços IP dinâmicos atribuídos pelo ISP ao qual estão conectados no momento. Para simplificar o roteamento de moon-net de volta ao cliente de acesso remoto carol, seria desejável que o roadwarrior tivesse um endereço IP interno escolhido de um pool predefinido.
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x | -- 10.3.0.1
moon-net moon carol virtual IP
Em nosso exemplo, o endereço IP virtual é escolhido do pool de endereços
10.3.0.0/16, que pode ser configurado adicionando a seção
pools {
rw_pool {
addrs = 10.3.0.0/16
}
}
ao swanctl.conf do gateway, de onde são carregados no daemon charon usando
o comando
swanctl --load-pools
Para solicitar um endereço IP desse pool, um roadwarrior pode usar o mode config de IKEv1 ou os payloads de configuração de IKEv2. A configuração para ambos é a mesma
vips = 0.0.0.0
Configuração no 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
}
}
Configuração no 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 com Autenticação EAP
Este é um caso muito comum em que um gateway strongSwan atende a um número arbitrário de clientes VPN remotos que se autenticam por meio de um Extended Authentication Protocol baseado em senha, como por exemplo EAP-MD5 ou EAP-MSCHAPv2.
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x |
moon-net moon carol
Configuração no 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
}
}
O arquivo swanctl.conf contém adicionalmente uma seção secrets que define
todas as credenciais dos clientes
secrets {
eap-carol {
id = [email protected]
secret = Ar3etTnp
}
eap-dave {
id = [email protected]
secret = W7R0g3do
}
}
Configuração no 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 com Identidade EAP
Frequentemente, uma identidade EAP do cliente é trocada via EAP e difere da identidade IKEv2 externa. Neste exemplo, a identidade IKEv2 assume como padrão o endereço IPv4 do cliente.
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x |
moon-net moon carol
Configuração no 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
}
}
Configuração no 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
}
}
Geração de Certificados e CRLs
Esta seção não é um tutorial completo sobre como usar a ferramenta pki do strongSwan. Ela apenas lista alguns pontos relevantes se você quiser gerar seus próprios certificados e CRLs para uso com o strongSwan.
Geração de um Certificado de CA
A instrução pki
pki --gen --type ed25519 --outform pem > strongswanKey.pem
gera uma chave elíptica de curva de Edwards com uma força criptográfica de 128 bits. A chave pública correspondente é empacotada em um certificado de CA autoassinado com validade de 10 anos (3652 dias)
pki --self --ca --lifetime 3652 --in strongswanKey.pem \
--dn "C=CH, O=strongSwan, CN=strongSwan Root CA" \
--outform pem > strongswanCert.pem
que pode ser listado com o 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 você preferir que a chave privada da CA e o certificado X.509 estejam no
formato binário DER, basta omitir a opção --outform pem. O diretório
/etc/swanctl/x509ca contém todos os certificados de CA necessários, tanto no
formato binário DER quanto no formato Base64 PEM. Independentemente da extensão
do arquivo, o formato correto será determinado automaticamente pelo strongSwan.
Geração de um Certificado de Entidade Final de Host ou Usuário
Novamente, usamos o comando
pki --gen --type ed25519 --outform pem > moonKey.pem
para gerar uma chave privada Ed25519 para o host moon. Alternativamente, você
pode digitar
pki --gen --type rsa --size 3072 > moonKey.der
para gerar uma chave RSA tradicional de 3072 bits e armazená-la em formato binário DER. Como alternativa, um TPM 2.0 Trusted Platform Module disponível em toda plataforma Intel recente pode ser usado como um smartcard virtual para armazenar com segurança uma chave privada RSA ou ECDSA. Para detalhes, consulte o HOWTO sobre TPM 2.0.
Em uma próxima etapa, o 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
cria uma solicitação de certificado PKCS#10 que precisa ser assinada pela CA.
Por meio do uso [múltiplo] do parâmetro --san, qualquer número de
subjectAlternativeNames desejados pode ser adicionado à solicitação. Elas
podem ter a 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
Com base na solicitação de certificado, a CA emite um certificado de entidade final assinado com o seguinte comando
pki --issue --cacert strongswanCert.pem --cakey strongswanKey.pem \
--type pkcs10 --in moonReq.pem --serial 01 --lifetime 1826 \
--outform pem > moonCert.pem
Se o parâmetro --serial com um argumento hexadecimal for omitido, um número de
série aleatório será gerado. Alguns clientes VPN de terceiros exigem que um
certificado de gateway VPN contenha o flag TLS Server Authentication de
Extended Key Usage (EKU), que pode ser incluído com a seguinte opção
--flag serverAuth
Se você quiser usar o recurso de busca dinâmica de CRL descrito em uma das
seções a seguir, poderá incluir um ou vários crlDistributionPoints em seus
certificados de entidade final usando o parâmetro --crl
--crl http://crl.strongswan.org/strongswan.crl
--crl "ldap://ldap.strongswan.org/cn=strongSwan Root CA, o=strongSwan,c=CH?certificateRevocationList"
O certificado de host emitido pode ser listado com
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
Normalmente, um cliente VPN baseado em Windows, OSX, Android ou iOS precisa de sua chave privada, de seu certificado de host ou usuário e do certificado da CA. A maneira mais conveniente de carregar essas informações é colocar tudo em um contêiner PKCS#12:
openssl pkcs12 -export -inkey carolKey.pem \
-in carolCert.pem -name "carol" \
-certfile strongswanCert.pem -caname "strongSwan Root CA" \
-out carolCert.p12
A ferramenta pki do strongSwan atualmente não é capaz de criar contêineres PKCS#12, portanto, openssl deve ser usado.
Geração de uma CRL
Uma CRL vazia assinada pela CA pode ser gerada com o comando
pki --signcrl --cacert strongswanCert.pem --cakey strongswanKey.pem \
--lifetime 30 > strongswan.crl
Se você omitir a opção --lifetime, o valor padrão de 15 dias será usado.
As CRLs podem ser enviadas para um servidor HTTP ou LDAP ou colocadas em formato
binário DER ou Base64 PEM no diretório /etc/swanctl/x509crl, de onde são
carregadas no daemon charon com o comando
swanctl --load-creds### Revogando um Certificado ###
Um certificado de entidade final específico é revogado com o comando
pki --signcrl --cacert strongswanCert.pem --cakey strongswanKey.pem \
--lifetime 30 --lastcrl strongswan.crl \
--reason key-compromise --cert moonCert.pem > new.crl
Em vez do arquivo de certificado (no nosso exemplo, moonCert.pem), o número de
série do certificado a ser revogado pode ser indicado usando o parâmetro
--serial. O comando pki --signcrl --help documenta todas as razões de
revogação possíveis, mas o parâmetro --reason também pode ser omitido. O
conteúdo do novo arquivo CRL pode ser listado com o 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 Local de CRLs
A opção strongswan.conf
charon {
cache_crls = yes
}
ativa o cache local de CRLs que foram obtidos dinamicamente de um servidor
HTTP ou LDAP. As cópias em cache são armazenadas em /etc/swanctl/x509crl
usando um nome de arquivo exclusivo formado pelo subjectKeyIdentifier do
emissor e o sufixo .crl.
Com a cópia em cache, a CRL fica imediatamente disponível após a inicialização. Quando a cópia local fica desatualizada, uma CRL atualizada é automaticamente obtida de um dos pontos de distribuição de CRL definidos durante a próxima autenticação IKEv2.