IPsec IKEv2 на strongSwan: рабочая схема для объединения филиалов 20–50 РМ
Сидишь, смотришь в ipsec.conf, и думаешь — кто вообще придумал этот синтаксис? Я каждый раз смеюсь, когда на новом проекте приходится поднимать IPsec с нуля. Меня зовут Семёнов Евгений Сергеевич, я директор АйТи Фреш, и за последние годы мы развернули более тридцати site-to-site-туннелей на strongSwan — для торговых сетей, производств, бухгалтерских ассоциаций. Ниже — не перевод документации, а мой рабочий конспект: какие команды я пишу, какие ошибки жду заранее, и что проверяю перед сдачей клиенту.
Когда вообще нужен IPsec, а не WireGuard или OpenVPN
У меня три критерия. Если в офисе уже есть железный Cisco или FortiGate — IPsec, потому что с ним всё совместимо без бубна. Если клиенту важна сертифицированная крипта или регулятор требует AES-256-CBC с ГОСТ-обвязкой — тоже IPsec. А если нужна максимальная простота и пропускная способность — ухожу в WireGuard. OpenVPN оставляю для случаев, когда надо пробиться через хитрый китайский файрвол по TCP 443.
Для задачи «соединить три офиса российского юрлица» в 90% случаев выбираю strongSwan с IKEv2. Это зрелая, бесплатная, стабильная реализация. Шпарит на 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. Если шлюз одновременно и роутер — для LAN-трафика не накладывайте MASQUERADE поверх защищённых префиксов. Это ломает 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
Для автоматического контроля я ставлю скрипт, который ping-ает удалённый шлюз и перезапускает туннель при потере. Результат пишет в 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
Запускаю раз в 5 минут через systemd timer. На проекте для сети кофеен — 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.
Бэкап конфигурации
Если вас поднимут в три ночи и попросят восстановить шлюз — иметь бэкап жизненно важно. Я делаю его скриптом:
#!/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 раз в сутки в хранилище клиента и в наш дата-центр МТС. За последние три года тянули из бэкапа ровно дважды — оба раза на железе, которое внезапно умерло.
Поднимем IPsec-туннели между офисами под ключ
Проектирую, ставлю, документирую и мониторю. Типовой срок для трёх филиалов — 5–8 рабочих дней. Оборудование можно использовать имеющееся или собрать бюджетные Intel NUC. Для клиентов на аутсорсинге VPN включён в базовый тариф.
Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш
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 честно пишет, что именно не совпало.