Site-to-site IPsec на Linux: как я соединил три офиса строительной компании за две недели
Этот материал — не учебник, а пересказ боевого проекта. Меня зовут Семёнов Евгений Сергеевич, я директор АйТи Фреш. В прошлом году к нам обратилась строительная компания: головной офис в Москве, филиалы в Санкт-Петербурге и Казани, 150 сотрудников, 1С и ERP в центральной серверной. Сотрудники филиалов работали через RDP поверх открытого интернета — медленно, небезопасно, с регулярными разрывами. Мы развернули IPsec site-to-site на strongSwan и закрыли задачу за две недели. Ниже — ровно те шаги, которые я проходил, с конфигурациями и ошибками.
Что было в начале
На первой встрече я увидел типичную картину: файлы проектной документации гоняются по почте, пароли к 1С у всех одинаковые, Wi-Fi в казанском офисе вообще без шифрования. У руководства болит голова не от VPN, а от того, что проектировщики из Казани жалуются на тормоза.
Аудит показал: три офиса живут отдельными мирами, между ними нет защищённой связности, в каждом стоит свой Windows Server с локальным доменом, нет общего файлообменника. Моё предложение — объединить всё в одну сеть через IPsec, вынести ERP в московский DMZ и открыть доступ только через туннель.
Архитектура, которую я нарисовал
Full-mesh на трёх узлах — это три туннеля: МСК—СПб, МСК—Казань, СПб—Казань. Не hub-and-spoke, потому что нагрузка на московский шлюз с мешем была бы слишком неравномерной, а full-mesh распределяет трафик.
| Офис | WAN | LAN | Железо шлюза |
|---|---|---|---|
| Москва (HQ) | 2 провайдера, статика | 10.10.0.0/24 + 10.11.0.0/24 VLAN серверов | Dell PowerEdge R350, Debian 12 |
| СПб | Static IP | 10.20.0.0/24 | Intel NUC i5, Debian 12 |
| Казань | За NAT провайдера, dynamic | 10.30.0.0/24 | Intel NUC i5, Debian 12 |
Бюджет на железо для двух филиалов — 72 000 рублей. В Москве шлюзом выступила уже стоявшая виртуалка на ProxMox — дополнительных затрат не было.
Создание PKI
Отдельная машина — наш технический ноутбук с Debian — служит корневым CA. Никогда не ставлю CA на тот же шлюз, который сам шифрует трафик.
cd /etc/ipsec.d
# Корневой CA на 10 лет
ipsec pki --gen --type rsa --size 4096 --outform pem > private/ca-key.pem
ipsec pki --self --ca --lifetime 3650 \
--in private/ca-key.pem \
--dn "C=RU, O=Stroy, CN=Stroy VPN CA" \
--outform pem > cacerts/ca-cert.pem
# Шаблон подписи для шлюза Москвы
ipsec pki --gen --type rsa --size 4096 --outform pem > private/gw-msk-key.pem
ipsec pki --pub --in private/gw-msk-key.pem | \
ipsec pki --issue --lifetime 1825 \
--cacert cacerts/ca-cert.pem --cakey private/ca-key.pem \
--dn "C=RU, O=Stroy, CN=gw-msk.stroy.local" \
--san gw-msk.stroy.local --san 203.0.113.10 \
--flag serverAuth --flag ikeIntermediate \
--outform pem > certs/gw-msk-cert.pem
Аналогично подписал сертификаты gw-spb и gw-kzn. Затем скопировал ключи на соответствующие шлюзы через SCP на тот момент, когда был физически рядом с каждой машиной. Удалённо через незашифрованный канал я приватные ключи никогда не передаю.
Базовая настройка шлюзов
Для экономии времени начал с PSK-варианта — проверить связность до перехода на сертификаты. Конфигурация Москвы:
# /etc/ipsec.conf — GW-MSK, первый этап с PSK
config setup
charondebug="ike 2, knl 2, cfg 2"
uniqueids=yes
conn %default
keyexchange=ikev2
ikelifetime=24h
lifetime=8h
dpdaction=restart
dpddelay=30s
dpdtimeout=150s
keyingtries=%forever
ike=aes256-sha256-modp2048!
esp=aes256gcm16-sha256!
conn msk-spb
auto=start
authby=secret
left=203.0.113.10
leftsubnet=10.10.0.0/24,10.11.0.0/24
leftid=@gw-msk.stroy.local
right=198.51.100.5
rightsubnet=10.20.0.0/24
rightid=@gw-spb.stroy.local
conn msk-kzn
auto=start
authby=secret
left=203.0.113.10
leftsubnet=10.10.0.0/24,10.11.0.0/24
leftid=@gw-msk.stroy.local
right=%any
rightid=@gw-kzn.stroy.local
rightsubnet=10.30.0.0/24
На стороне СПб и Казани — зеркальные файлы. PSK-секрет — длинная строка из /dev/urandom, 40 символов. Для тестов этого хватает, для продакшена — нет.
Переход на сертификаты
Когда все три туннеля поднялись и прошёл ping — начал менять на pubkey-аутентификацию. Фрагмент конфига Москвы после перехода:
conn msk-spb
auto=start
authby=pubkey
ike=aes256gcm16-sha384-ecp384!
esp=aes256gcm16-sha384!
left=203.0.113.10
leftsubnet=10.10.0.0/24,10.11.0.0/24
leftid=@gw-msk.stroy.local
leftcert=gw-msk-cert.pem
leftsendcert=always
right=198.51.100.5
rightsubnet=10.20.0.0/24
rightid=@gw-spb.stroy.local
rightca="C=RU, O=Stroy, CN=Stroy VPN CA"
Файл ipsec.secrets — одна строка: : RSA gw-msk-key.pem. Права 600, владелец root. И никаких PSK-строк больше не осталось.
Казанский офис за NAT
Самая весёлая история — казанский офис. Провайдер выдавал серый IP через карьерный NAT, никаких статических адресов за деньги не продавал. Пришлось играть от имени клиента.
# /etc/ipsec.conf на gw-kzn
conn to-msk
auto=start
authby=pubkey
left=%defaultroute
leftsubnet=10.30.0.0/24
leftid=@gw-kzn.stroy.local
leftcert=gw-kzn-cert.pem
leftfirewall=yes
right=203.0.113.10
rightsubnet=10.10.0.0/24,10.11.0.0/24,10.20.0.0/24
rightid=@gw-msk.stroy.local
forceencaps=yes
ike=aes256gcm16-sha384-ecp384!
esp=aes256gcm16-sha384!
forceencaps = yes — критичная строка. Без неё провайдерский NAT ломал ESP. С ней весь трафик ушёл в UDP 4500 и прошёл как миленький.
Маршрутизация и DHCP
Внутри каждого офиса на маршрутизаторах добавил статические маршруты на удалённые подсети через VPN-шлюз. Это простая часть. Но клиенту хотелось, чтобы маршруты раздавались по DHCP автоматически — на случай если появится новый филиал и придётся переписывать сотни ПК. Я настроил DHCP Option 121 (classless static routes):
# /etc/dhcp/dhcpd.conf на маршрутизаторе МСК
option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;
subnet 10.10.0.0 netmask 255.255.255.0 {
range 10.10.0.100 10.10.0.200;
option routers 10.10.0.1;
option rfc3442-classless-static-routes
24, 10, 20, 0, 10, 10, 0, 1,
24, 10, 30, 0, 10, 10, 0, 1;
}
Windows и Linux-клиенты оба подхватывают эту опцию, и при каждом обновлении лизы маршруты актуализируются. macOS имеет свои причуды — но в офисе стройки яблок почти не было.
Failover через второго провайдера
Московский офис был самой важной точкой, туда сходится весь трафик. Под неё мы добавили резервный канал от второго провайдера. Две конфигурации — primary и backup. Скрипт переключает трафик, если основной не отвечает 60 секунд:
#!/bin/bash
# /usr/local/bin/vpn-failover.sh
REMOTE=10.20.0.1
PRIMARY=msk-spb-primary
BACKUP=msk-spb-backup
if ! ping -c3 -W2 "$REMOTE" >/dev/null 2>&1; then
if ! ipsec status | grep -q "$BACKUP.*ESTABLISHED"; then
ipsec down "$PRIMARY"
sleep 2
ipsec up "$BACKUP"
logger -t vpn "failover: switched to backup channel"
fi
else
if ipsec status | grep -q "$BACKUP.*ESTABLISHED"; then
ipsec down "$BACKUP"
sleep 2
ipsec up "$PRIMARY"
logger -t vpn "recovery: switched back to primary"
fi
fi
Проверка — раз в 60 секунд через systemd timer. За год работы два реальных переключения: один раз провайдер делал обслуживание узла, второй — физически порвали магистраль на стройке возле офиса.
Мониторинг и уведомления
Подключил Zabbix-агент к каждому шлюзу, написал простой item, который парсит ipsec statusall и отдаёт количество ESTABLISHED-SA. При падении любого SA — алерт в Telegram техническому директору клиента и мне.
# UserParameter для Zabbix
UserParameter=vpn.established,ipsec status | grep -c ESTABLISHED
# Триггер: если меньше 3 — алерт
{gw-msk:vpn.established.last()}<3
За 8 месяцев до истечения проекта было 11 алертов, 9 разобрались сами за 3–10 минут (DPD подтянул туннель), два потребовали нашего вмешательства — оба раза виноваты провайдеры.
Что получил клиент в итоге
- Три офиса в единой защищённой сети, AES-256-GCM на всём трафике.
- Файловый сервер в Москве доступен по SMB из СПб и Казани, задержки 20–40 мс.
- Отказ от RDP через интернет — больше никаких жалоб на тормоза 1С.
- Автоматический failover в Москве и скрипты мониторинга на всех шлюзах.
- Обучение админа клиента — два четырёхчасовых созвона с демонстрацией логов и процедур восстановления.
Смета проекта: железо двух филиалов 72 000 руб., работы и документация 195 000 руб., итого 267 000 руб. По сравнению с коммерческими VPN-шлюзами вроде Fortinet экономия для клиента составила около 380 000 руб. на железе и примерно 60 000 руб./год на лицензиях.
Типовые ошибки, с которыми я столкнулся
- Несовпадение времени на шлюзах. У филиала время ушло на 9 минут вперёд, сертификаты «ещё не действительны». NTP обязателен.
- MTU. Казанский провайдер режет пакеты больше 1440. Пришлось включать MSS clamping на forward-цепочке.
- Iptables MASQUERADE поверх VPN. Старое правило в /etc/rc.local маскировало VPN-подсети под внешний IP. Туннель жил, но пакеты улетали в никуда. Исправил добавлением исключения сверху.
- 1С не видит сервер по имени. DNS филиала не ресолвил внутренние домены Москвы. Развернули условный DNS-форвардинг в BIND.
Соберу VPN-сеть для ваших филиалов
Проектирую, строю, документирую. Для объединения двух-пяти офисов срок обычно 7–14 рабочих дней. Железо подбираем под бюджет — от Intel NUC до Dell PowerEdge. После сдачи — обучение вашего админа и 30 дней бесплатной поддержки.
Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш
FAQ — частые вопросы по site-to-site IPsec
- Сколько времени у меня заняло объединение трёх офисов?
- Чистое внедрение — 8 рабочих дней: три дня PKI и сбор шлюзов, два дня установка в Москве, по дню на СПб и Казань, и финальный день на failover и мониторинг. Весь проект с документацией и обучением админа клиента уместился в две недели.
- Почему я не выбрал WireGuard для этой задачи?
- Потому что в казанском офисе стоял Cisco ISR, который отдавать и менять клиент не хотел. Cisco умеет IKEv2 IPsec, но не знает WireGuard. strongSwan идеально вставал и туда, и на Debian, и на Mikrotik.
- Что делать, если филиал сидит за NAT провайдера?
- Ставим на филиале left=%defaultroute и forceencaps=yes. На NAT-маршрутизаторе пробрасываем UDP 500, UDP 4500 и протокол ESP (IP 50) — но если есть forceencaps, ESP не нужен.
- PSK или сертификаты?
- Сертификаты X.509. Всегда. PSK для site-to-site — это дыра, которую рано или поздно найдут. У каждой стороны должен быть свой приватный ключ, это азы.
- Выдержит ли 1С через такой VPN?
- Выдержит, и неплохо. В нашем проекте скорость работы 1С через VPN выросла в 3–4 раза по сравнению с предыдущим RDP-через-интернет. Главное — обеспечить минимум 10–20 Мбит/с симметричного канала и следить за MTU.