Назад к обновлениям
New releaseSep 8, 2026

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.

Категории