· 14 мин чтения

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 поверх голого интернета.

Грабли, которые я стабильно нахожу у клиентов

Бэкап конфигурации

Если вас поднимут в три ночи и попросят восстановить шлюз — иметь бэкап жизненно важно. Я делаю его скриптом:

#!/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 честно пишет, что именно не совпало.

Подпишитесь на рассылку ITfresh

Раз в неделю — практические гайды для руководителя IT и сисадмина: безопасность, 1С, миграции, резервные копии, лайфхаки из реальных проектов.

Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.