IPsec IKEv2 на strongSwan: рабочая схема для объединения филиалов 20–50 РМ
За последние годы мы развернули больше тридцати site-to-site-туннелей на strongSwan — торговым сетям, производствам, бухгалтерским ассоциациям. Это не пересказ документации, а рабочий конспект: какие команды использую, какие подводные камни жду, что проверяю перед сдачей.
Когда вообще нужен IPsec, а не WireGuard или OpenVPN
Как я выбираю VPN-технологию? У меня есть три главных правила. Первое: если у клиента уже стоит 'железка' вроде Cisco или FortiGate, почти всегда беру IPsec. С ним всё дружит буквально 'без бубна'. Второе: когда критически важна сертифицированная крипта — например, регулятор требует AES-256-CBC с ГОСТ-обвязкой — тут тоже, извините, без вариантов, только IPsec. И третье: нужна максимальная простота вместе с очень высокой пропускной способностью? Тогда я однозначно иду в WireGuard. Ну а OpenVPN? Его приберегаю для самых хитрых кейсов, когда, скажем, нужно пробиться через какой-нибудь особо 'злой' китайский файрвол по TCP 443. Вот такой расклад.
Нужно 'соединить три офиса российского юрлица' — в 90% случаев мой выбор падает на strongSwan с IKEv2. Это зрелая, проверенная годами технология: бесплатная и стабильная реализация. strongSwan отлично работает на AES-NI, почти не нагружает CPU, дружит с сертификатами X.509. Плюс у него есть MOBIKE для тех, кто постоянно в движении. Вариант надёжный и беспроигрышный.
Типичная топология, которую я разворачиваю
Как правило, мы предпочитаем классическую схему hub-and-spoke. Что это значит? Есть центральный офис, например, у нас он часто бывает в Москве. К нему подключаются два-три филиала. Каждый филиал держит свой отдельный туннель до 'головы', то есть до HQ. А если филиалам нужно обменяться трафиком между собой? Всё просто: он идёт транзитом через этот самый центральный узел. Это невероятно удобно! Мы здорово экономим на конфигурациях и, что важно, значительно упрощаем весь мониторинг.
# Пример адресации для торговой сети
HQ (Москва) : 203.0.113.10 / LAN 10.10.0.0/24
Branch-SPB : 198.51.100.5 / LAN 10.20.0.0/24
Branch-Rostov : 192.0.2.17 / LAN 10.30.0.0/24
А что, если филиалов уже не два-три, а больше пяти, да ещё и трафик между ними бешеный? В таком случае я уже перехожу на full-mesh. Или другой вариант — строю route-based VPN, используя VTI-интерфейсы с OSPF. Впрочем, это уже материал для совсем другой статьи.
Установка и базовая подготовка
Мы чаще всего работаем на Debian 12. Почему? Система стабильная, проверенная. И главное, strongSwan там всегда свежий, что для нас критично. Какие пакеты ставим?
sudo apt update
sudo apt install strongswan strongswan-pki libcharon-extra-plugins \
libcharon-extauth-plugins libstrongswan-extra-plugins
# включаем форвардинг
cat <<'EOF' | sudo tee /etc/sysctl.d/90-vpn.conf
net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv6.conf.all.forwarding = 1
EOF
sudo sysctl --system
# файрвол
sudo ufw allow 500/udp
sudo ufw allow 4500/udp
sudo ufw allow proto esp
И очень важный момент: не пропустите NAT! Если ваш шлюз работает ещё и как роутер, ни в коем случае не накладывайте MASQUERADE для LAN-трафика поверх защищённых префиксов. Сделаете так — и всё, VPN сломан. А диагностировать подобную проблему, поверьте, дико тяжело.
Поднимаем корпоративный CA
PSK? Я использую его только для тестов. В 'продакшене' мой выбор однозначен — всегда сертификаты. Как мы это делаем? Создаю отдельный CA на нашей управляющей машине. Оттуда уже подписываю сертификаты для всех шлюзов. И вот тут внимание: после всех операций ключи CA я обязательно уношу в холодный бэкап. Это принципиально. Доступ к ним должен быть исключён полностью.
# Корневой центр
pki --gen --type rsa --size 4096 --outform pem > ca-key.pem
pki --self --ca --lifetime 3650 \
--in ca-key.pem \
--dn "C=RU, O=ITfresh Demo, CN=VPN Corp Root CA" \
--outform pem > ca-cert.pem
# Сертификат HQ
pki --gen --type rsa --size 2048 --outform pem > hq-key.pem
pki --req --type priv --in hq-key.pem \
--dn "C=RU, O=ITfresh Demo, CN=vpn-hq.itfresh.local" \
--san vpn-hq.itfresh.local --san 203.0.113.10 \
--outform pem > hq.csr
pki --issue --cacert ca-cert.pem --cakey ca-key.pem \
--in hq.csr --lifetime 730 \
--flag serverAuth --flag ikeIntermediate \
--outform pem > hq-cert.pem
Файлы раскладываем так, чтобы всё было по swanctl. ca-cert летит в /etc/swanctl/x509ca/, публичный сертификат — в /etc/swanctl/x509/. А ключ? Он у нас лежит в /etc/swanctl/private/, конечно же, с правами 600. Никак иначе.
Конфигурация HQ — hub
Знаете, я уже давным-давно попрощался с устаревшим ipsec.conf. Полностью перешёл на современный swanctl.conf. Почему? Ну, во-первых, его синтаксис куда чище и понятнее. А во-вторых, он сейчас поддерживается намного, намного активнее. Разница колоссальная.
# /etc/swanctl/swanctl.conf на HQ
connections {
spb {
version = 2
local_addrs = 203.0.113.10
remote_addrs = 198.51.100.5
proposals = aes256-sha256-modp2048
dpd_delay = 30s
rekey_time = 24h
local {
auth = pubkey
certs = hq-cert.pem
id = vpn-hq.itfresh.local
}
remote {
auth = pubkey
id = vpn-spb.itfresh.local
}
children {
spb-net {
local_ts = 10.10.0.0/24
remote_ts = 10.20.0.0/24
esp_proposals = aes256gcm128-sha256-modp2048
start_action = start
close_action = restart
dpd_action = restart
}
}
}
}
Где хранятся секреты? Они могут быть в /etc/swanctl/swanctl.conf, в секции secrets, или же в отдельном файле swanctl.d/secrets.conf. Я лично всегда выношу их в отдельный файл. Так, знаете ли, гораздо проще управлять доступом к ним. Безопасность прежде всего.
Конфигурация филиала
Что по конфигурации на филиале? Она, по сути, почти зеркальная. Но есть один важный нюанс. Если IP динамический, нам придётся поменять local_addrs на %any. И что крайне важно, обязательно добавляем forceencaps — это нужно для обхода NAT. Выглядит это примерно так:
# /etc/swanctl/swanctl.conf на Branch-SPB
connections {
to-hq {
version = 2
local_addrs = %any
remote_addrs = 203.0.113.10
encap = yes
proposals = aes256-sha256-modp2048
local {
auth = pubkey
certs = spb-cert.pem
id = vpn-spb.itfresh.local
}
remote {
auth = pubkey
id = vpn-hq.itfresh.local
}
children {
hq-net {
local_ts = 10.20.0.0/24
remote_ts = 10.10.0.0/24,10.30.0.0/24
esp_proposals = aes256gcm128-sha256-modp2048
start_action = start
close_action = restart
dpd_action = restart
}
}
}
}
Здесь обратите внимание на remote_ts. Я всегда сразу прописываю там две вещи: и центральную подсеть, и подсеть второго филиала. Зачем это нужно? Да просто так трафик между, скажем, Ростовом и СПб пойдёт через HQ, и нам не придётся городить дополнительные туннели. Удобно же!
Мониторинг и отказоустойчивость
Проверка состояния:
sudo swanctl --load-all
sudo swanctl --list-sas
sudo swanctl --list-conns
sudo journalctl -u strongswan -f
Чтобы всё было под контролем автоматически, я устанавливаю небольшой скрипт. Он постоянно пингует удалённый шлюз. А если связь вдруг пропадает, туннель тут же перезапускается. Результаты? Они автоматически пишутся прямо в Zabbix. Смотрите:
#!/bin/bash
# /usr/local/bin/vpn-watchdog.sh
set -u
REMOTE=10.20.0.1
CHILD=spb-net
if ! ping -c3 -W2 "$REMOTE" >/dev/null 2>&1; then
logger -t vpn-watchdog "tunnel $CHILD down, restarting"
swanctl --terminate --child "$CHILD" >/dev/null 2>&1
sleep 2
swanctl --initiate --child "$CHILD"
fi
Запускаем его через systemd timer, каждые 5 минут — не просто так. На проекте для сети кофеен (4 города, 11 точек) этот скрипт за 8 месяцев сам поднял туннели 43 раза. Ни одного ручного обращения в саппорт не потребовалось.
Реальный кейс: сеть магазинов 4 городов
Март 2025 года. К нам обратилась крупная торговая сеть — 4 филиала (Москва-HQ, Питер, Казань, Новосибирск) и 11 точек продаж. Их главная головная боль — RDP-доступ к кассовому ПО через «голый» интернет: ПО было арендованным и крутилось на терминальном сервере в Москве. Из Новосибирска всё дико тормозило, сессии регулярно зависали.
Мы немедленно взялись за дело! Развернули strongSwan-туннели, связав все филиалы в единую надёжную сеть. Для безопасности использовали PKI на мощных 4096-битных RSA-ключах, а IKE-шифрование доверили AES-256-GCM. Что стало основой? Для каждого филиала мы поставили отдельный Debian-шлюз, используя Intel NUC i5 — вышло и дёшево, и очень сердито, всего 35 000 рублей за одну железку! Весь проект, включая монтаж, ювелирную настройку, подготовку детальной документации и обучение местного админа, занял у нас 8 рабочих дней. А стоило это 142 000 рублей. Результат? За целый год работы туннели "падали" всего дважды, и оба раза это был, к сожалению, обрыв у провайдера в Новосибирске. Зато знаете что? Скорость 1С через наш VPN выросла в целых 3 раза! Это же просто космос по сравнению с тем, как она "плелась" через RDP по "голому" интернету. Разве это не прекрасно?
Грабли, которые я стабильно нахожу у клиентов
- Несовпадение алгоритмов. Классика: HQ шпарит AES-256-GCM, филиал — AES-128-CBC. Туннель не поднимается, в журнале честно написано «no proposal chosen». Приводите к одному списку.
- Разные ID сторон. Если id на одной стороне «vpn-hq.example.ru», а на другой записано «@vpn-hq.example.ru» — это разные вещи. Я всегда пишу через @ или FQDN без @ — но одинаково на обеих сторонах.
- Забытый NAT-T. Филиал за NAT провайдера, forceencaps не включён — пакеты ESP фильтруются, туннель держится 20 секунд и падает. Лечится encap = yes на filial-е.
- MTU. Если у вас AES-256 в туннельном режиме, overhead около 60 байт. Я ставлю MSS clamping:
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -m policy --dir in --pol ipsec -j TCPMSS --set-mss 1360. - Не отозвали сертификат уволенного филиала. Был случай в 2024: расформировали офис, железку подарили бывшему админу. Через месяц VPN-туннель с неизвестного IP. Всегда отзывайте сертификат и публикуйте CRL.
Бэкап конфигурации
Глубокая ночь, 3 утра, звонок — нужно срочно поднять «упавший» шлюз. В такой ситуации спасает только свежий, надёжный бэкап. Именно для таких случаев я использую вот этот скрипт:
#!/bin/bash
DEST=/var/backups/strongswan
mkdir -p "$DEST"
tar czf "$DEST/swanctl-$(hostname)-$(date +%Y%m%d).tgz" \
/etc/swanctl /etc/strongswan.d /etc/ipsec.secrets 2>/dev/null
find "$DEST" -mtime +30 -delete
А дальше что? rsync! Раз в сутки он отправляет резервную копию и в хранилище клиента, и, для нашей страховки, в дата-центр МТС. На практике? За последние три года нам приходилось "тянуть" данные из бэкапа всего дважды. И оба раза это было, когда "железо" внезапно решило закончить свой жизненный путь.
FAQ — частые вопросы
- Почему я выбираю IKEv2, а не IKEv1?
- IKEv2 на фазе установления обменивается меньшим количеством сообщений, умеет MOBIKE для бесшовного переключения IP, имеет встроенную поддержку NAT-T. IKEv1 я применяю только когда на другом конце стоит старое оборудование, которое не умеет ничего лучше.
- Можно ли обойтись без PKI и использовать PSK?
- Для двух узлов — можно, и я иногда так и делаю при быстром pilot-запуске. Но как только филиалов становится три и больше, PSK превращается в ад — любая утечка требует переезда. Сертификаты с собственным CA проще поддерживать в долгую.
- Что делать, если у филиала динамический IP?
- На стороне HQ указывайте remote_addrs=%any и аутентифицируйте по сертификату. При смене IP MOBIKE обновит туннель без разрыва сессии. На филиале обязательно forceencaps=yes, если провайдер делает NAT.
- Какая производительность ждёт меня на обычном сервере?
- С AES-NI на Xeon или Ryzen strongSwan спокойно выдаёт 2–5 Гбит/с на ядро для AES-256-GCM. Узким местом у нас в офисах почти всегда был провайдерский канал, а не шифрование.
- Как отлаживать туннель, если он не поднимается?
- Смотреть swanctl --list-sas и journalctl. Поднимать charondebug до уровня 2–3. В 80% случаев проблема в несовпадении ID, сроков жизни SA или крипто-предложений — strongSwan честно пишет, что именно не совпало.

