LINUX.ORG.RU
решено ФорумAdmin

Обрезка UDP-пакета

 , ,


1

5

Есть тупая железка, которая шлёт клиентские запросы NTPv1 на 20 байт длиннее (68 вместо 48, 20 байт в конце просто забиты нулями), из-за чего chronyd сносит башку (он думает, что это аутентифицированные пакеты, видит неправильный Key-MAC и дропает их).

Хочу этой тупой железке попробовать сделать обрезание таких UDP-пакетов. Пока что с NFQUEUE не заморачивался, хочу чего-то попроще.

Вопрос: как? Пробовал tc-pedit:

#!/usr/bin/env bash

LAN=enp3s2

case "$1" in
        start)
                tc qdisc add dev ${LAN} handle ffff: ingress
                tc filter add dev ${LAN} parent ffff: protocol ip flower src_ip 192.168.1.55 ip_proto udp dst_port 123 action pedit munge offset 2 u16 set 0x30 pipe csum ip and udp
                ;;
        stop)
                tc qdisc del dev ${LAN} handle ffff: ingress
                ;;
esac

но сломал мозг (то, что я написал выше, не работает).

Железка подключена через сеть за enp3s2, пакеты идут через линуксовый роутер, на котором, собственно, и нужно провернуть трюк.

@mky @vel

Ответ на: комментарий от vel

А в udp кто будет длину пакета менять?

Об этом не подумал, думал, что csum будет делать magic. С другой стороны, я как бы и не знаю, на каком offset’е UDP, потому что могут быть опции IP.

Я бы в udp заголовке только длину исправлял.

А почему только в нём? Получается, по-хорошему, длину нужно трижды менять.

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

post-factum ★★★★★ ()
Ответ на: комментарий от mky

Не уверен, что pedit может менять размер пакета, там же тогда нужно менять размер skbuf. Нужно код смотреть…

Я вот тоже не уверен ☹.

Как именно не работает?

Хиты по фильтру вижу, а дальше ничего не происходит.

post-factum ★★★★★ ()

@vel @mky

Похоже, что вот так фурычит:

tc filter add dev ${LAN} parent ffff: protocol ip flower src_ip 192.168.1.55 ip_proto udp dst_port 123 action pedit munge offset 24 u16 set 0x38 pipe csum ip and udp

Если допустить, что опций IP нет, то длина UDP будет по offset’у 24.

Что думаете? Случайно заработало, или я правильно высчитал?

# tc -s filter ls dev enp3s2 ingress
filter parent ffff: protocol ip pref 49152 flower chain 0
filter parent ffff: protocol ip pref 49152 flower chain 0 handle 0x1
  eth_type ipv4
  ip_proto udp
  src_ip 192.168.1.55
  dst_port 123
  not_in_hw
        action order 1:  pedit action pipe keys 1
         index 1 ref 1 bind 1 installed 252 sec used 15 sec firstused 252 sec
         key #0  at 24: val 00380000 mask 0000ffff
        Action statistics:
        Sent 480 bytes 5 pkt (dropped 0, overlimits 0 requeues 0)
        backlog 0b 0p requeues 0

        action order 2: csum (iph, udp) action pass
        index 1 ref 1 bind 1 installed 252 sec used 15 sec firstused 252 sec
        Action statistics:
        Sent 480 bytes 5 pkt (dropped 0, overlimits 0 requeues 0)
        backlog 0b 0p requeues 0
post-factum ★★★★★ ()
Последнее исправление: post-factum (всего исправлений: 1)

Обрезать пакет – это много чего сделать надо: и обрезать, и длину ip и tcp поменять, и чексуммы пересчитать. eBPF Вам в помощь. Хелперы bpf_skb_change_tail, bpf_l3_csum_replace и так далее.

Наговнокодить сейчас не в силах за неимением ума, памяти, воли, и условий для тестов.

i586 ★★ ()
Ответ на: комментарий от post-factum

Смещение высчитали правильно, получили ip-пакет, в котором часть данных не пренадлежат udp пакета. Я бы на месте ядра дропал бы такие подозрительные пакеты :)

Возможно нет смысла пересчитывать контрольную сумму ip, меняется ведь только udp-пакет.

mky ★★★★★ ()
Ответ на: комментарий от mky

Я бы на месте ядра дропал бы такие подозрительные пакеты :)

Я бы тоже, только вот почему-то не дропает.

Возможно нет смысла пересчитывать контрольную сумму ip, меняется ведь только udp-пакет.

Да, скорее всего.

post-factum ★★★★★ ()
Ответ на: комментарий от mky

Смещение высчитали правильно, получили ip-пакет, в котором часть данных не пренадлежат udp пакета. Я бы на месте ядра дропал бы такие подозрительные пакеты :)

Похоже, что вот так тоже работает:

tc filter add dev ${LAN} parent ffff: protocol ip flower src_ip 192.168.1.55 ip_proto udp dst_port 123 action pedit munge offset 2 u16 set 0x4c pipe pedit munge offset 24 u16 set 0x38 pipe csum ip and udp

На skb, наверное, это всё равно не влияет.

post-factum ★★★★★ ()
Ответ на: комментарий от vel

«ping -R» такие умеет вызывать

Ну, «идея вопроса» (хаха) в том, что порядочный пакет опции на себя не нацепит.

Заложенная в протокол возможность расширения фактически оказалась востребована только для проверки реализаций протокола на вшивость и атаки на педикулёзные реализации.

Т.е. пост-фактумовское решение обобщается на аналогичные проблемы, а про опции можно не беспокоиться. Вероятность того, что какое-то работоспособное/полезное приложение не только шлёт «немножко неправильные» пакеты, но ещё и балуется опциями практически неотличима от нуля.

//Комментарий опубликован в рамках программы «Начни утро с капитанства»

frob ★★★★★ ()