
strongswan v6.1.0
strongSwan - VPN на основе IPsec
Конфигурация strongSwan
Обзор
strongSwan — это VPN-решение с открытым исходным кодом на основе IPsec.
Этот документ — лишь краткое введение в команду swanctl из strongSwan, которая использует современный vici Versatile IKE Configuration Interface. Устаревшая команда ipsec, использующая старый интерфейс конфигурации stroke, описана здесь. Более подробную информацию можно найти в man-руководствах, на нашем новом сайте документации и на старом вики.
Быстрый старт
Сертификаты для пользователей, хостов и шлюзов выпускаются вымышленным
центром сертификации (CA) strongSwan. В наших примерах сертификат CA strongswanCert.pem
должен присутствовать на всех VPN-узлах, чтобы можно было аутентифицировать
пиров. Для вашего конкретного применения VPN вы можете либо использовать сертификаты от
любого стороннего CA, либо самостоятельно сгенерировать необходимые закрытые ключи и сертификаты
с помощью инструмента pki из strongSwan, использование которого будет объяснено в одном из
следующих разделов.
Сценарий «сеть-сеть»
В этом сценарии два шлюза безопасности moon и sun соединяют две подсети moon-net и sun-net друг с другом через VPN-туннель, установленный между двумя шлюзами:
10.1.0.0/16 -- | 192.168.0.1 | === | 192.168.0.2 | -- 10.2.0.0/16
moon-net moon sun sun-net
Конфигурация на шлюзе 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
}
}
}
}
Конфигурация на шлюзе 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
}
}
}
}
Используемые в этом сценарии локальная и удалённая идентичности — это subjectDistinguishedNames, содержащиеся в сертификатах конечных объектов. Сертификаты и закрытые ключи загружаются в демон charon с помощью команды
swanctl --load-creds
тогда как
swanctl --load-conns
загружает соединения, определённые в swanctl.conf. При start_action = trap
IPsec-соединение автоматически устанавливается при первом IP-пакете с полезной нагрузкой
в открытом виде, который должен пройти через туннель.
Сценарий «хост-хост»
Это настройка между двумя отдельными хостами, за которыми нет подсети. Хотя для соединений «хост-хост» было бы достаточно транспортного режима IPsec, мы будем использовать режим туннеля IPsec по умолчанию.
| 192.168.0.1 | === | 192.168.0.2 |
moon sun
Конфигурация на хосте 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
}
}
}
}
Конфигурация на хосте 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
}
}
}
}
Сценарий Roadwarrior
Это очень распространённый случай, когда шлюз strongSwan обслуживает произвольное число удалённых VPN-клиентов, обычно имеющих динамические IP-адреса.
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x |
moon-net moon carol
Конфигурация на шлюзе 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
}
}
}
}
Конфигурация на удалённом клиенте 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
}
}
}
}
Для remote_addrs было выбрано имя узла moon.strongswan.org, которое будет
разрешено через DNS во время выполнения в соответствующий IP-адрес назначения.
В этом сценарии идентичность удалённого клиента carol — это адрес электронной почты
[email protected], который должен быть включён как subjectAlternativeName в
сертификат удалённого клиента carolCert.pem.
Сценарий Roadwarrior с виртуальным IP-адресом
Клиенты Roadwarrior обычно имеют динамические IP-адреса, назначаемые интернет-провайдером, к которому они в данный момент подключены. Чтобы упростить маршрутизацию от moon-net обратно к клиенту удалённого доступа carol, желательно, чтобы roadwarrior имел внутренний IP-адрес, выбранный из предопределённого пула.
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x | -- 10.3.0.1
moon-net moon carol virtual IP
В нашем примере виртуальный IP-адрес выбирается из пула адресов
10.3.0.0/16, который можно настроить, добавив раздел
pools {
rw_pool {
addrs = 10.3.0.0/16
}
}
в swanctl.conf шлюза, откуда они загружаются в демон charon
с помощью команды
swanctl --load-pools
Чтобы запросить IP-адрес из этого пула, клиент Roadwarrior может использовать IKEv1 mode config или IKEv2 configuration payloads. Конфигурация для обоих случаев одинакова:
vips = 0.0.0.0
Конфигурация на шлюзе 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
}
}
Конфигурация на удалённом клиенте 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
}
}
}
}
Сценарий Roadwarrior с аутентификацией EAP
Это очень распространённый случай, когда шлюз strongSwan обслуживает произвольное число удалённых VPN-клиентов, которые аутентифицируются с помощью основанного на пароле протокола Extended Authentication Protocol, например EAP-MD5 или EAP-MSCHAPv2.
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x |
moon-net moon carol
Конфигурация на шлюзе 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
}
}
Файл swanctl.conf дополнительно содержит раздел secrets, определяющий все
учётные данные клиентов
secrets {
eap-carol {
id = [email protected]
secret = Ar3etTnp
}
eap-dave {
id = [email protected]
secret = W7R0g3do
}
}
Конфигурация на удалённом клиенте 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
}
}
Сценарий Roadwarrior с идентификатором EAP
Часто идентификатор EAP клиента передаётся через EAP и отличается от внешней идентичности IKEv2. В этом примере идентичность IKEv2 по умолчанию равна IPv4-адресу клиента.
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x |
moon-net moon carol
Конфигурация на шлюзе 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
}
}
Конфигурация на удалённом клиенте 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
}
}
Генерация сертификатов и CRL
Этот раздел не является полноценным руководством по использованию инструмента pki из strongSwan. В нём перечислены лишь несколько моментов, актуальных, если вы хотите сгенерировать собственные сертификаты и CRL для использования с strongSwan.
Генерация сертификата CA
Команда pki
pki --gen --type ed25519 --outform pem > strongswanKey.pem
создаёт эллиптический ключ на кривой Эдвардса с криптографической стойкостью 128 бит. Соответствующий открытый ключ помещается в самоподписанный сертификат CA со сроком действия 10 лет (3652 дня)
pki --self --ca --lifetime 3652 --in strongswanKey.pem \
--dn "C=CH, O=strongSwan, CN=strongSwan Root CA" \
--outform pem > strongswanCert.pem
который можно просмотреть командой
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
Если вы предпочитаете, чтобы закрытый ключ CA и сертификат X.509 хранились в двоичном формате DER,
просто опустите параметр --outform pem. Каталог /etc/swanctl/x509ca
содержит все необходимые сертификаты CA либо в двоичном DER, либо в формате Base64 PEM.
Независимо от расширения файла правильный формат будет определён
strongSwan автоматически.
Генерация сертификата конечного объекта для хоста или пользователя
Снова используем команду
pki --gen --type ed25519 --outform pem > moonKey.pem
для генерации закрытого ключа Ed25519 для хоста moon. В качестве альтернативы можно
выполнить
pki --gen --type rsa --size 3072 > moonKey.der
чтобы сгенерировать традиционный 3072-битный ключ RSA и сохранить его в двоичном формате DER. Как альтернатива, TPM 2.0 Trusted Platform Module (доверенный платформенный модуль), доступный на каждой современной платформе Intel, может использоваться как виртуальная смарт-карта для безопасного хранения закрытого ключа RSA или ECDSA. Подробности см. в руководстве по TPM 2.0 HOWTO.
На следующем шаге команда
pki --req --type priv --in moonKey.pem \
--dn "C=CH, O=strongswan, CN=moon.strongswan.org" \
--san moon.strongswan.org --outform pem > moonReq.pem
создаёт запрос на сертификат PKCS#10, который должен быть подписан центром сертификации.
Благодаря [многократному] использованию параметра --san в запрос можно добавить любое количество
желаемых subjectAlternativeNames. Они могут быть следующего
вида:
--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
На основе запроса на сертификат центр сертификации выпускает подписанный сертификат конечного объекта следующей командой
pki --issue --cacert strongswanCert.pem --cakey strongswanKey.pem \
--type pkcs10 --in moonReq.pem --serial 01 --lifetime 1826 \
--outform pem > moonCert.pem
Если параметр --serial с шестнадцатеричным аргументом опущен, генерируется случайный
серийный номер. Некоторые сторонние VPN-клиенты требуют, чтобы сертификат VPN-шлюза
содержал флаг TLS Server Authentication расширенного использования ключа
(EKU), который можно добавить с помощью следующего параметра:
--flag serverAuth
Если вы хотите использовать функцию динамической загрузки CRL, описанную в одном из
следующих разделов, вы можете включить один или несколько crlDistributionPoints
в сертификаты конечных объектов с помощью параметра --crl:
--crl http://crl.strongswan.org/strongswan.crl
--crl "ldap://ldap.strongswan.org/cn=strongSwan Root CA, o=strongSwan,c=CH?certificateRevocationList"
Выпущенный сертификат хоста можно просмотреть командой
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
Обычно VPN-клиенту на Windows, OSX, Android или iOS требуются его закрытый ключ, сертификат хоста или пользователя и сертификат CA. Самый удобный способ загрузить эту информацию — поместить всё в контейнер PKCS#12:
openssl pkcs12 -export -inkey carolKey.pem \
-in carolCert.pem -name "carol" \
-certfile strongswanCert.pem -caname "strongSwan Root CA" \
-out carolCert.p12
Инструмент pki из strongSwan в настоящее время не умеет создавать контейнеры PKCS#12, поэтому необходимо использовать openssl.
Генерация CRL
Пустой CRL, подписанный центром сертификации, можно сгенерировать командой
pki --signcrl --cacert strongswanCert.pem --cakey strongswanKey.pem \
--lifetime 30 > strongswan.crl
Если опустить параметр --lifetime, будет использовано значение по умолчанию — 15 дней.
CRL можно либо загрузить на HTTP- или LDAP-сервер, либо поместить в двоичном формате DER или
Base64 PEM в каталог /etc/swanctl/x509crl, откуда они
загружаются в демон charon с помощью команды
swanctl --load-creds### Отзыв сертификата ###
Конкретный сертификат конечного субъекта отзывается следующей командой
pki --signcrl --cacert strongswanCert.pem --cakey strongswanKey.pem \
--lifetime 30 --lastcrl strongswan.crl \
--reason key-compromise --cert moonCert.pem > new.crl
Вместо файла сертификата (в нашем примере moonCert.pem) можно указать серийный номер
отзываемого сертификата с помощью параметра --serial.
Команда pki --signcrl --help описывает все возможные причины отзыва,
но параметр --reason также можно опустить. Содержимое нового
файла CRL можно вывести командой
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
Локальное кэширование CRL
Параметр strongswan.conf
charon {
cache_crls = yes
}
активирует локальное кэширование CRL, которые динамически загружаются с
HTTP- или LDAP-сервера. Кэшированные копии сохраняются в /etc/swanctl/x509crl с
уникальным именем файла, образованным из subjectKeyIdentifier издателя и
суффикса .crl.
Благодаря кэшированной копии CRL становится доступен сразу после запуска. Когда локальная копия устаревает, обновлённый CRL автоматически загружается из одной из заданных точек распространения CRL во время следующей аутентификации IKEv2.