nftables: как сопоставить встроенный IP-адрес источника в ICMP-поле времени истечения, чтобы отличить ответы трассировки от виртуальной машины и хоста.

Вопрос или проблема

Я пытаюсь изменить ответы на запросы traceroute (тип 11) пакетов ICMP time-exceeded, но только когда это ответы на запросы с конкретной виртуальной машины (VM). Моя настройка следующая:

  • ОС хоста на Ubuntu с nftables
  • Гостевая VM на Ubuntu, подключенная через интерфейс моста “spod”
  • IP-адреса интерфейса моста: хост 137.205.192.1, VM 137.205.192.5
  • Интернет-интерфейс хоста: wlo1 (192.168.110.187), шлюз 192.168.110.1
  • Трафик VM замаскирован через хост

Текущие рабочие правила (но они изменяют ВСЕ пакеты типа 11, а не только те, что для VM):

nft add table ip icmp_mod
nft add chain ip icmp_mod prerouting { type filter hook prerouting priority -300; }
nft add rule ip icmp_mod prerouting ip protocol icmp icmp type time-exceeded ip saddr 192.168.110.1 counter snat ip to 146.97.180.159
nft add rule ip icmp_mod prerouting ip protocol icmp icmp type time-exceeded ip saddr 192.168.62.1 counter snat ip to 146.97.35.246
nft add rule ip icmp_mod prerouting ip protocol icmp icmp type time-exceeded ip saddr 45.235.255.73 counter snat ip to 146.97.35.18
nft add rule ip icmp_mod prerouting ip protocol icmp icmp type time-exceeded ip saddr 181.191.189.66 counter snat ip to 146.97.35.197

Когда я выполняю traceroute как с хоста, так и из VM на 1.1.1.1, ответы ICMP типа 11 выглядят одинаково в цепочке prerouting. Однако, просматривая журналы ядра, я вижу, что оригинальный исходный IP (137.205.192.5 VM) вставлен в нагрузку ICMP в ответах, предназначенных для VM.

Мне нужно изменить эти правила, чтобы они соответствовали и изменяли только пакеты ICMP типа 11, которые являются ответами на запросы traceroute с четкой VM, а не с хоста. Какой правильный синтаксис nftables для изучения и сопоставления оригинального исходного IP в нагрузке ICMP?

Ответ или решение

Для решения вашей задачи необходимо использовать nftables для фильтрации ICMP сообщений типа "time-exceeded" (тип 11) таким образом, чтобы они модифицировались только в ответ на трассировку от виртуальной машины (VM), а не хоста.

Теория

Используя nftables, вы можете анализировать содержимое ICMP пакетов и принимать решения на основе этих данных. В ICMP сообщении "time-exceeded" полезная нагрузка (payload) содержит оригинальный заголовок IP пакета, что в вашем случае означает, что вы можете извлечь и проверить исходный IP-адрес пакета, чтобы определить, был ли он отправлен VM или хостом. Это возможно благодаря анализу структуры пакета: когда ICMP "time-exceeded" генерируется маршрутизатором, в тело сообщения включается заголовок пакета, который вызвал истекание TTL (Time to Live).

Пример

Предположим, вы имеете следующее рабочее окружение:

  • ОС хоста Ubuntu использует nftables.
  • Виртуальная машина управляет Ubuntu и подключена через мостовой интерфейс “spod” с IP адресом 137.205.192.5.
  • Хост имеет IP 192.168.110.187 через интерфейс wlo1 и выход в интернет через шлюз 192.168.110.1.
  • Трафик VM замаскирован через хост.

Ваши текущие правила модифицируют все пакеты типа 11, без дифференциации источника:

nft add table ip icmp_mod
nft add chain ip icmp_mod prerouting { type filter hook prerouting priority -300; }
nft add rule ip icmp_mod prerouting ip protocol icmp icmp type time-exceeded ip saddr 192.168.110.1 counter snat ip to 146.97.180.159
nft add rule ip icmp_mod prerouting ip protocol icmp icmp type time-exceeded ip saddr 192.168.62.1 counter snat ip to 146.97.35.246
nft add rule ip icmp_mod prerouting ip protocol icmp icmp type time-exceeded ip saddr 45.235.255.73 counter snat ip to 146.97.35.18
nft add rule ip icmp_mod prerouting ip protocol icmp icmp type time-exceeded ip saddr 181.191.189.66 counter snat ip to 146.97.35.197

Применение

Чтобы различать ICMP сообщения, относящиеся к VM, необходимо извлечь оригинальный IP-адрес источника из полезной нагрузки ICMP пакета и выполнить сравнение. В nftables это может быть достигнуто путем прямого обращения к байтам полезной нагрузки.

К сожалению, nftables в текущем состоянии не предоставляет встроенные возможности для анализа вложенных заголовков пакетов. Однако вы можете использовать приемы в виде прямого адресации в полезной нагрузки пакета (англ. payload offset). Вам понадобится знать позицию IP-адреса источника в полезной нагрузке, чтобы написать правильные условия для фильтрации.

Пример правила в nftables, которое адресует подобный запрос:

nft add table ip icmp_mod
nft add chain ip icmp_mod prerouting { type filter hook prerouting priority -300\; }
nft add rule ip icmp_mod prerouting ip protocol icmp icmp type time-exceeded @nh,40,4 == 137.205.192.5 counter snat ip to 146.97.180.159

В этом примере @nh,40,4 — это указание на полезную нагрузку (nh – next header), начиная с 40-го байта, продолжительностью в 4 байта, которое как предполагается, содержит IP-адрес источника пакета. Проверка, если это соответствует адресу VM. Пожалуйста, обратите внимание, что смещения и специфика работы могут варьироваться в зависимости от версии nftables и структуры пакетов, поэтому рекомендуется тщательно протестировать ваши правила.

В итоге, подход основан на извлечении нужного сегмента из полезной нагрузки пакета, анализе этих данных и принятии решения о модификации пакета.

Безусловно, предлагаемые решения требуют высокой квалификации и тщательного тестирования, наличие резервных копий конфигураций перед применением любых изменений, а также понимание возможных последствий изменения сетевых правил на работающую систему.

Оцените материал
Добавить комментарий

Капча загружается...