IPsec IKEv2 на strongSwan: рабочая схема для объединения филиалов 20–50 РМ
Иногда смотришь в ipsec.conf и думаешь: ну кто, кто придумал такой синтаксис? Признаюсь честно, мне каждый раз смешно, когда на новом проекте мы с командой поднимаем IPsec с нуля. Я, Семёнов Евгений Сергеевич, директор ITFresh. Знаете, за последние годы мы развернули более тридцати 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! Раз в сутки он отправляет резервную копию и в хранилище клиента, и, для нашей страховки, в дата-центр МТС. На практике? За последние три года нам приходилось "тянуть" данные из бэкапа всего дважды. И оба раза это было, когда "железо" внезапно решило закончить свой жизненный путь.
Поднимем 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 честно пишет, что именно не совпало.
