Ви запускаєте tcpdump на зовнішньому інтерфейсі шлюзу IPsec під Linux і бачите дві речі одразу: вхідні кадри ESP і, відразу за ними, розшифровані внутрішні пакети. На виході видно лише ESP. Природний висновок — відповіді не надсилаються або IPsec шифрує один напрямок і забуває інший. Ні те, ні інше не є правдою.

Те, що ви бачите, — це точка захоплення. Ядро перетворює вихідні пакети до того, як шлях передавання пристрою передасть їх сокету пакетів, тому сокет ніколи не бачить внутрішню форму на виході. На вході пакет спершу захоплюється як ESP, а декапсульована копія стає видимою, коли він знову входить у стек. Той самий трафік, два різні вікна спостереження.

Точка захоплення вирішує, що ви бачите

На звичайному інтерфейсі сокет AF_PACKET розташований біля рівня пристрою. Пакети, що залишають хост, спершу проходять обробку виходу IPsec, яка перетворює внутрішній сегмент TCP у датаграму ESP або UDP-4500, і лише потім досягають цього рівня. Пакети, що надходять, копіюються в сокет у момент виходу з кабелю, ще зашифрованими, а розшифрований результат стає видимим пізніше, коли стек доставляє його локально або пересилає далі.

Цей порядок повністю пояснює асиметрію. Це не доказ про напрямок, політику чи поведінку застосунку, і якщо ставитися до нього так, люди починають гнатися за відповіддю, яка весь час надсилалася правильно. Це одна з небагатьох мережевих загадок, де аномалію створює інструмент, а не мережа.

Узгодьте фільтр із рівнем, який маєте на увазі

Вираз на кшталт tcp port 443 вибирає внутрішнє з'єднання TCP. На виході це з'єднання вже стало ESP на момент звернення до сокета, тому фільтр ні з чим не збігається. Якщо ви хочете рахувати захищений трафік, фільтруйте за зовнішньою формою: протокол 50 для необробленого ESP або порт UDP 4500, коли використовується обхід NAT. Обидва фільтри дають кількість пакетів, яку можна порівняти між двома сторонами, що зазвичай і є причиною підрахунку. Жоден з них не каже, чи отримав внутрішній запит відповідь.

Не ставтеся до числа UDP 4500 як до кількості пакетів ESP. IKE також використовує цей порт для повідомлень підтримання NAT-T і для інкапсульованого обміну, тому число включає трафік, який не є тими даними, що ви хотіли виміряти. Початковий обмін IKE на UDP 500 потребує власного фільтра, якщо питання саме в цьому. Число, що змішує керівний трафік з даними, також робить будь-яку оцінку пропускної здатності хибною на невідому величину. Окремі підрахунки відповідають на окремі питання.

Запишіть фільтр поруч із питанням, на яке він відповідає. «Скільки ESP залишило коробку» і «чи залишив вебзапит коробку» — це різні вимірювання з різними фільтрами, і один захват не може вирішити обидва. Без цієї нотатки двоє людей порівнюватимуть числа, які ніколи не рахували одне й те саме.

Спостерігайте до перетворення, а не після

Якщо потрібно побачити вихідний відкритий текст, перемістіть точку спостереження раніше, до обробки виходу IPsec. NFLOG дає вам гачок Netfilter, де правило може копіювати вибрані пакети в сокет у просторі користувача, який tcpdump уміє читати. Посібник strongSwan зі скидання трафіку документує цей підхід саме з цієї причини.

Збіг із політикою обмежує правило трафіком, що ось-ось увійде в тунель. Саме -m policy --pol ipsec --dir out робить правило конкретним, а не записує кожен пакет, який надсилає коробка. Потім читайте групу журналу з обмеженим захопленням: невелика кількість знімків і обмеження розміру не дають діагностиці перетворитися на архів трафіку. Обмежений захват також легше передати рецензентові, не тягнучи зайвий вантаж. Вирішіть число до початку, а не після того, як побачите, скільки надійшло.

iptables -I OUTPUT 1 -d 10.83.0.44/32 -p tcp --dport 8443 -m policy --pol ipsec --dir out -j NFLOG --nflog-group 5
tcpdump -ni nflog:5 -s 128 -c 20 'host 10.83.0.44 and tcp port 8443'

Виберіть гачок відповідно до потоку. OUTPUT охоплює трафік, який породжує сам шлюз; транзит від клієнта LAN проходить ланцюгом FORWARD, і правило на OUTPUT ніколи його не побачить. Адреса й порт вище — заповнювачі для схваленого тестового призначення.

Що доводить спостереження

NFLOG — це ціль журналювання, а не рішення про пропуск. Пакет, що з'явився там, показує, що він дістався гачка і збігся з правилом. Він не показує, що пізніший фільтр пропустив його, що пристрій передав його або що інша сторона щось отримала.

Порожній журнал такий самий неоднозначний. Перевірте лічильник пакетів правила, підтвердьте напрямок, підтвердьте, що потік справді збігся з політикою IPsec, і підтвердьте призначення. Лише збіжний лічильник на обох сторонах перетворює спостереження на висновок. Потім порівняйте лічильники асоціації безпеки на обох сторонах для тієї самої контрольованої спроби, бо лічильники SA — це авторитетний запис про те, що було захищено й надіслано.

Ще одна пастка: «відкритий текст» тут означає поза рівнем шифрування IPsec. Внутрішній сеанс HTTPS усе ще має власний TLS. Захоплення декапсульованого пакета не розшифровує TLS застосунку, а читабельний HTTP там означає, що застосунок ніколи не використовував HTTPS.

Приберіть і порівняйте обидва кінці

Видаліть саме те правило, яке ви вставили, за його власником, щойно спостереження завершиться. Залишене правило журналювання коштує процесорного часу на кожному відповідному пакеті й тихо створює проблему збереження даних. Видаляйте, повторюючи правило з -D, а не очищуючи ланцюг, який вам не належить.

iptables -D OUTPUT -d 10.83.0.44/32 -p tcp --dport 8443 -m policy --pol ipsec --dir out -j NFLOG --nflog-group 5

Якщо розгортання використовує IPsec у просторі користувача, інтерфейс XFRM або апаратне розвантаження, точки спостереження зміщуються, і цей рецепт може взагалі не підійти. У разі libipsec документоване місце для спостереження за внутрішнім трафіком — пристрій TUN. Спершу визначте шлях, потім виберіть точку, що відповідає на питання, і очікуйте, що два напрямки виглядатимуть по-різному лише тоді, коли ви дивитеся на неправильний бік перетворення.

Схожі статті