Миграция 15 site-to-site туннелей на IKEv2: StrongSwan, AES-256-GCM и Ansible-аудит cipher suite
Переводим site-to-site IPsec с IKEv1 на IKEv2 в StrongSwan: AES-256-GCM, ECDH P-256 вместо DH group 2/5, PFS в каждом SA, аудит cipher suite через Ansible.
Рост числа филиалов на удалёнке в 2020 стимулирует переход на современные IPsec IKEv2 конфигурации
К середине осени у одного из наших managed-клиентов собралось пятнадцать site-to-site IPsec-туннелей. Часть из них живёт со времён «когда настраивал тот подрядчик» и работает на IKEv1 с DH group 2 (1024-bit MODP) и 3DES. Работает - в смысле трафик идёт, туннели поднимаются. Проблема появилась, когда безопасники клиента попросили предоставить список cipher suite по всем туннелям для внутреннего аудита. Мы полезли смотреть и обнаружили картину, которая объясняет, почему аудиты вообще нужны.
Из пятнадцати туннелей семь использовали DH group 2, три - DH group 5 (1536-bit MODP), два держались на 3DES-CBC в ESP, и только три были настроены более-менее по-человечески с AES-128 и SHA-1. IKEv2 не использовал никто. PFS был включён формально на части туннелей, но с теми же слабыми DH-группами - что делает его скорее декоративным.
Что меняем и почему
DH group 2 и 5 - это 1024 и 1536 бит MODP. Слабость 1024-bit DH задокументирована, NIST от неё отказался, и ряд современных реализаций уже отказывается согласовывать её по умолчанию. Оставлять их в production в 2020 - риск, который сложно обосновать.
IKEv1 добавляет сложность без пользы. Main mode, Aggressive mode, xauth - всё это багаж, которого в IKEv2 нет. IKEv2 проще в реализации, лучше обрабатывает переустановку SA, имеет встроенный dead peer detection и поддерживает MOBIKE. С точки зрения операционной работы переход с IKEv1 на IKEv2 убирает, а не добавляет сложность.
AES-256-GCM вместо AES-CBC + SHA. GCM - это AEAD, аутентификация встроена в шифрование, отдельный HMAC не нужен. Быстрее на современном железе с AES-NI и меньше поверхность для ошибок реализации.
ECDH P-256 для PFS. Группа 19 по RFC 5114 - 256-bit elliptic curve. Эквивалентная стойкость примерно в 128 бит при ключе в 32 байта. Быстрее классического DH на тех же параметрах безопасности.
Новая конфигурация туннеля
Для каждого соединения в StrongSwan конфиг /etc/ipsec.conf меняется так:
conn site-branch-01
keyexchange=ikev2
ike=aes256gcm16-prfsha256-ecp256!
esp=aes256gcm16-ecp256!
left=<gw-ip>
leftsubnet=10.0.0.0/24
right=<branch-ip>
rightsubnet=192.168.10.0/24
authby=psk
auto=start
dpdaction=restart
dpddelay=30s
dpdtimeout=120s
closeaction=restart
keyingtries=%forever
Знак ! после proposal - это принципиальный момент. Без него StrongSwan будет добавлять свои дефолтные proposals и может согласовать что-то менее желаемое с удалённой стороной. С ! - только то, что написано, либо нет соединения.
prfsha256 в IKE-предложении - это PRF (pseudo-random function) для генерации ключевого материала. В AEAD-режиме integrity отдельно не нужна, поэтому proposal выглядит как три компонента вместо четырёх.
Удалённая сторона: не всегда StrongSwan
Пятнадцать туннелей - это пятнадцать разных удалённых площадок. Там стоит всякое: Cisco ASA, MikroTik, Cisco IOS, один FortiGate и несколько таких же StrongSwan. С некоторыми сразу договорились о параметрах, с другими пришлось подбирать совместимость.
Типичная проблема: удалённый FortiGate не поддерживал ecp256 в старой прошивке - пришлось использовать modp2048 (DH group 14) как компромисс. group 14 - это 2048-bit MODP, она намного лучше group 2 и 5, в RFC 3526 используется как минимально приемлемый вариант. Не ECDH, но уже не 1024-bit.
Для MikroTik важен порядок proposals: RouterOS согласовывает первый подходящий сверху, поэтому если поставить более слабый вариант первым - он его и возьмёт. Проверять нужно через ipsec statusall и смотреть, что реально согласовалось.
Ansible-плейбук для аудита cipher suite
Проблема с пятнадцатью туннелями не в том, чтобы их настроить - это дело нескольких часов. Проблема в том, что через три месяца кто-то вручную поменяет один туннель, чтобы «просто починить», и конфигурация снова разойдётся с baseline. Нам нужен автоматический аудит.
Написали плейбук, который проверяет актуальные параметры согласованных SA через ipsec statusall и сравнивает с разрешённым списком:
---
- name: Audit IPsec cipher suites
hosts: vpn_gateways
gather_facts: false
vars:
allowed_ike_enc: ["AES_CBC_256", "AES_GCM_16_256"]
allowed_ike_dh: ["ECP_256", "MODP_2048"]
allowed_esp_enc: ["AES_CBC_256", "AES_GCM_16_256"]
forbidden_any: ["3DES", "DES", "MD5", "MODP_1024", "MODP_1536"]
tasks:
- name: Get ipsec statusall
command: ipsec statusall
register: ipsec_status
changed_when: false
- name: Check for forbidden algorithms
set_fact:
violations: >-
{{
forbidden_any
| select('in', ipsec_status.stdout)
| list
}}
- name: Fail if forbidden algorithms present
fail:
msg: "Forbidden algorithms in use: {{ violations }}"
when: violations | length > 0
Плейбук запускается по расписанию через Jenkins ночью и отправляет результат в Slack-канал команды. Если есть нарушение - pipeline падает, уходит алерт. Если всё чисто - тихо пишет в лог.
Реальный вывод ipsec statusall для StrongSwan содержит строки вида IKE proposal: AES_GCM_16_256/PRF_HMAC_SHA2_256/ECP_256 - парсить их через grep достаточно, полный ASN-парсинг не нужен.
Про работу с Ansible Collections на продакшне, включая прогон плейбуков через Nexus-прокси без прямого доступа в Galaxy, мы писали в посте про Ansible Collections.
Как шла миграция
Миграцию делали туннель за туннелем, не одновременно. Схема простая:
- Договориться с другой стороной о параметрах и окне обслуживания.
- Обновить конфиг на обеих сторонах, перезапустить соединение.
- Убедиться через
ipsec statusall, что согласовалось именно то, что планировалось. - Дать туннелю поработать сутки под нагрузкой, проверить переустановку SA по rekeying.
Несколько туннелей потребовали двух итераций - удалённая сторона не могла сразу обновить прошивку или конфиг, согласовывались промежуточные параметры лучше старых, но не идеальные.
Где сейчас
Двенадцать из пятнадцати туннелей переведены на IKEv2 с AES-256-GCM. Три ждут обновления прошивки на удалённой стороне - там пока modp2048 на IKEv2, что уже сильно лучше исходного состояния. DH group 2 и 3DES убраны везде.
Ansible-аудит работает с первой недели и уже один раз поймал туннель, который переподнялся после сбоя с согласованным SHA-1 вместо SHA-256 - удалённая сторона предложила более слабый вариант, StrongSwan без ! его принял бы. С ! туннель просто не поднялся и ушёл алерт. Это и есть смысл строгих proposals.
В рамках managed-сопровождения теперь аудит cipher suite входит в стандартную еженедельную проверку наравне с мониторингом доступности туннелей. Про отказоустойчивость самих шлюзов через BGP мы разбирали в отдельном посте.