Назад | Перейти на главную страницу

Iptables u32 соответствие nat

В настоящее время я настраиваю IPtables для перенаправления определенных полезных данных UDP в свое приложение.

Вот пример того, над чем я работал до сих пор:

iptables -t nat -I PREROUTING -p udp -d {IPDST} --dport 27055 -m u32 --u32  '0>>22&0x3C@8=0xFFFFFFFF && 0>>22&0x3C@12=0x54536F75 && 0>>22&0x3C@16=0x72636520 && 0>>22&0x3C@20=0x456E6769 && 0>>22&0x3C@24=0x6E652051 && 0>>22&0x3C@28=0x75657279' -j REDIRECT --to-port 21015

Это работает, он перенаправит пакеты, содержащие полезную нагрузку:

FFFFFFFF54536F7572636520456E67696E6520517565727900

с одного порта на мое приложение на другом.

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

ffffffff55ffffffff

Однако иногда пакет может выглядеть так:

ffffffff55fa0cf40f

Я пробовал что-то вроде этого:

iptables -t nat -I PREROUTING -p udp -d {IPDST} --dport 27055 -m u32 --u32  '0>>22&0x3C@8=0xFFFFFFFF && 0>>22&0x3C@12=0x55' -j REDIRECT --to-port 21015

Я предполагаю, что проблема в том, что я пытаюсь сопоставить 2 байта, а не 4, как обычно? Вышеупомянутое не является ошибкой, но также не перенаправляет пакеты.

Это было бы для вашего удобства (в одну строку, но мне пришлось отобразить это так, чтобы работать жирным шрифтом):

iptables -t nat -I PREROUTING -p udp -d {IPDST} --dport 27055 -m u32 --u32 '0>>22&0x3C@8=0xFFFFFFFF && 0>>22&0x3C@12>>24=0x55' -j REDIRECT --to-port 21015

или

iptables -t nat -I PREROUTING -p udp -d {IPDST} --dport 27055 -m u32 --u32 '0>>22&0x3C@8=0xFFFFFFFF && 0>>22&0x3C@12&0xFF000000=0x55000000' -j REDIRECT --to-port 21015

В обоих случаях вы удаляете из уравнения ту часть, которую не хотите сравнивать, либо сдвигая 3 байта вправо и оставляя только 1-й, либо используя маску, которая сохранит в уравнении только 1-й байт. Второй более гибкий.

Есть пример в man iptables-extensions аналогично первому варианту:

... 0 >> 22 & 0x3C @ 0 >> 24 = 0 "

[...]

Это первые 4 байта полезной нагрузки ICMP, из которых байт 0 является типом ICMP. Поэтому мы просто сдвигаем значение 24 вправо, чтобы отбросить все, кроме первого байта, и сравнить результат с 0.

Также обратите внимание, что, поскольку это таблица nat, если порт источника не меняется, будет рассматриваться только первый пакет UDP. После этого conntrack будет обрабатывать поток, и ваше правило не увидит другие пакеты. Поэтому, если каждый пакет независим, убедитесь, что исходный порт изменился, и вам, возможно, придется использовать nfct инструмент вместе с -j CT --timeout правило, чтобы сократить "память" conntrack и избежать заполнения его таблиц.