В настоящее время я настраиваю 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. "и избегайте заполнения его таблиц.