Режим trap в strongSwan: почему туннель IPsec ждёт трафика
Неактивный IPsec-туннель по требованию не показывает CHILD SA, пока пакет не совпадёт с его политикой trap. Прочитайте состояние, проверьте триггер и знайте, когда подходит start.
В выводе статуса не появляется CHILD SA, туннель выглядит мёртвым, и тут ping в удалённую подсеть поднимает его. В настройке IPsec по требованию эта последовательность и есть замысел, а не неисправность. Политика trap устанавливает селектор и ждёт, и именно первый подходящий пакет запускает IKE и согласование CHILD SA.
Часть путаницы в словаре: «up» используется для двух разных состояний. Конфигурация загружена, и политика ядра существует, а ассоциация данных — нет. Монитор, считающий только активные SA, будет показывать здоровый сайт как недоступный, пока никто не отправляет туда трафик.
У простаивающего туннеля по требованию нет CHILD SA для показа
Запись trap сама по себе ничего не аутентифицирует. Она просит ядро держать политику для выбранного трафика и поднимать acquisition, когда пакету нужна эта политика. Демон получает acquisition, сопоставляет его с определением child и ведёт переговоры оттуда. До этого момента показывать нечего и из IKE SA, поэтому оба списка могут быть пусты одновременно.
Именно этот порядок делает журналы читаемыми. Сначала приходит acquisition, затем IKE_SA_INIT и IKE_AUTH, затем CHILD SA. Если журнал заканчивается сразу после acquisition, триггер сработал. Согласование не удалось, и следующий вопрос — об учётных данных, предложениях или доступности, а не о trap.
С бэкендом ядра Linux вы можете увидеть политику до появления любого SA. Выполните ip xfrm policy и найдите селектор с направлением out и шаблоном, указывающим на соединение. Эта запись и есть состояние по требованию, и её наличие — первое, что нужно подтвердить.
start_action решает, будет ли вообще что-то ждать
Каждое child в swanctl.conf несёт start_action. start запускается при загрузке конфигурации, trap устанавливает политику и ждёт, а none оставляет запуск чему-то другому. Только trap создаёт описанное выше поведение «ping — и он поднимается».
children {
office-lan {
local_ts = 192.168.50.0/24
remote_ts = 192.168.70.0/24
start_action = trap
}
}
Два селектора трафика определяют, что считается интересным, и пакет с хоста вне этих префиксов не запускает trap; он маршрутизируется как обычно. Расширение селекторов ради более охотного триггера расширяет и область, которую туннель заявляет как защищаемую, поэтому выводите их из трафика, который действительно хотите шифровать.
Справочник swanctl.conf перечисляет принимаемые значения вместе с отдельными действиями close и DPD, которые определяют, что происходит после появления SA.
Выясните, сработал ли триггер вообще
Начните с swanctl --list-conns и убедитесь, что child загружен с задуманным действием. Затем отправьте один пакет с хоста внутри local_ts на адрес внутри remote_ts и наблюдайте за swanctl --list-sas. Если вывод не меняется, ни один acquisition не дошёл до демона.
Две обычные причины тихого trap: пакет прошёл source-NAT до попадания в политику и больше не соответствует local_ts, или соединение вообще не загрузилось из-за синтаксической ошибки или ошибки учётных данных. Запустите заново swanctl --load-all и прочитайте вывод, прежде чем трогать селекторы. Соединение, которое не загрузилось, не устанавливает политику, поэтому трафику нечего запускать.
Направление тоже важно: trap, установленный для исходящего трафика, не запускается входящим пакетом. Если удалённая сторона должна поднимать туннель, ей нужен собственный trap, либо этой стороне нужен start.
Ожидание первого пакета не всегда правильный обмен
Интерактивные сеансы чувствуют стоимость настройки. Первый запрос платит за обмен IKE и согласование CHILD, и клиент с коротким сроком может сдаться до появления SA. Проактивный start убирает эту задержку первого пакета. Но держит туннель поднятым для трафика, который может никогда не прийти.
Три факта решают выбор: как часто используется путь, есть ли у первого запроса жёсткий срок и доступен ли партнёр при загрузке. Случайный пакетный трафик и партнёр, который может быть офлайн при загрузке, оба говорят за trap. Клиент, чувствительный к задержкам, и всегда доступный партнёр говорят за start. Если обе стороны могут инициировать, договоритесь, кому принадлежит триггер, чтобы не было дублирующихся согласований.
Установленная политика тоже не гарантия от утечек. Если требование fail-closed, межсетевой экран должен отбрасывать трафик без SA, и это правило живёт вне определения child.
Запишите три строки, которые завершат следующий спор
Запишите селекторы, действие при запуске и вывод команды, показывающий политику без SA. Эти три строки отделяют «по требованию и бездействует» от «не загружается» в следующий раз, когда кто-то сообщит, что туннель не работает. Их фиксация занимает минуту. Без них то же расследование начинается с нуля.
Проверяйте с хоста, который действительно находится внутри селектора. Ping с самого маршрутизатора часто идёт другим путём и ничего не доказывает о политике, защищающей подсеть за ним.