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

Несоответствия с Linux tc filter u32 сопоставлением полезной нагрузки пакетных данных - может кто-нибудь объяснить?

Я просто хотел бы кое-что проинформировать об этом, поскольку я действительно не понимаю - почему - это так.

Ниже находится вывод TCPDUMP (tcpdump -s0 -XXnni eth0 tcp port 80) ответа HTTP, который веб-сервер дает, когда к нему отправляется обычный запрос GET. Я пытаюсь использовать фильтр Linux u32 tc для сопоставления содержимого пакета TCP ack, ища строку HTTP / 1. [01] 200 'в полезных данных пакета подтверждения TCP (другими словами, поиск типичного ответа «HTTP / 1.0 200 OK» или «HTTP / 1.1 200 OK».

Вот фрагмент команды tc filter - это, вероятно, поможет разобраться в контексте:

tc filter add dev eth0 parent ffff: protocol ip u32 \
  match ip protocol 6 0xff \
  match ip sport 80 0xffff \
  match u8 0x10 0xff at 33 \
  match u32 0x48545450 0xffffffff at 52 \
  match u32 0x2f312e31 0xfffffffe at 56 \
  match u32 0x20323030 0xffffffff at 60 \
<do something>

Последние 3 строки 'match u32' будут соответствовать 'HTTP / 1.0 200' или 'HTTP / 1.1 200', в то время как строка u8 соответствует флагу TCP ack, а остальные соответствуют исходному порту 80 протокола TCP.

У меня такой вопрос - почему на двух разных Linux-системах мне нужно менять числа 52, 56 и 60 на 40, 44 и 48? (вычтите 12 из смещения). Он прикреплен к моему серверу Slackware Linux дома, я должен использовать 52, 56 и 60, а, как и на сервере RedHat / CentOS, я должен использовать 40, 44 и 48.

Причина этого проста; сравните эти два TCPDUMP с каждого сервера:

Slackware: 0x0000:  0040 63c9 c3a0 0018 7d05 dd11 0800 4500  .@c.....}.....E.
           0x0010:  05be d41c 0000 3606 9ea2 4266 0963 c0a8  ......6...Bf.c..
           0x0020:  000a 0050 a278 e948 dcdb fa41 ac84 8010  ...P.x.H...A....
           0x0030:  0059 3cb2 0000 0101 080a 9380 9172 0008  .Y<..........r..
           0x0040:  3bea 4854 5450 2f31 2e31 2032 3030 204f  ;.HTTP/1.1.200.O

RedHat or: 0x0000:  0016 3e32 3fcf 0010 dbff 2050 0800 4500  ..>2?......P..E.
CentOs:    0x0010:  0554 cf64 0000 3706 e08b 4266 0969 0a64  .T.d..7...Bf.i.d
           0x0020:  7881 0050 b316 c917 2062 b4a8 cff4 5018  x..P.....b....P.
           0x0030:  005a a17f 0000 4854 5450 2f31 2e31 2034  .Z....HTTP/1.1.4
           0x0040:  3034 204e 6f74 2046 6f75 6e64 0d0a 436f  04.Not.Found..Co

Как видите, точка смещения, в которой начинается часть «HTTP» (полезная нагрузка пакетных данных), различна в обоих случаях. Почему это? И что могло вызвать это?

Заранее спасибо всем, кто может объяснить мне эту тайну.

Я обнаружил, что это может решить проблему.

http://linux-tc-notes.sourceforge.net/tc/doc/cls_u32.txt

Смещения заголовка


Заголовок IP (и другие заголовки) имеют переменную длину. Это создает проблему, если вы пытаетесь использовать «совпадение» для просмотра значения в следующем заголовке - вы не знаете, где оно находится. Это не невозможная проблема, потому что каждый заголовок в IP-пакете содержит поле длины. Функция «смещения заголовка» в u32 позволяет вам извлечь эту длину из пакета, а затем добавить ее к смещению, указанному в опции «совпадение».

Вот как это работает. Напомним, что вариант соответствия выглядит так:

match u32 VALUE MASK at OFFSET

Ранее я сказал, что OFFSET сообщает ядру, какое слово в пакете сравнивать со значением VALUE. Это заявление было упрощением. Два других значения могут быть добавлены к OFFSET, чтобы определить, какое слово использовать. Оба этих значения начинаются с 0, но они могут быть изменены, когда опция «ссылка» вызывает другой список фильтров. Любая сделанная модификация применяется только во время выполнения списка вызываемых фильтров, поскольку старые значения восстанавливаются, если вызываемый список фильтров не может классифицировать пакет. Вот два значения и имена, которые я их называю:

permoff     This value is unconditionally added to every OFFSET
        that is done in the destination link, ie that one
    that is called.  This includes calculations of new
    permoff's and tempoff's.  Permoff's are cumulative
    in that if the destination link calls another link
    and calculates a new permoff, the result is added to
    this one.

tempoff A "match" option in the destination link can
        optionally add this value its OFFSET.  Tempoff's are
    temporary, in that it does not apply to any links the
    destination link calls.  It also does not effect the
    calculation of OFFSET's for new permoff's and
    tempoff's.

Время для примера. Рассмотрим эту команду:

# tc filter add dev eth0 parent 999:0 protocol ip prio 99 u32 \
    link 1: offset at 0 mask 0f00 shift 6 plus 0 eat \
match ip protocol 6 ff

Выражение соответствия выбирает пакеты TCP (это протокол IP 6). Если у нас есть протокол 6, мы выполняем фильтр 1: 0. Теперь что касается остального:

offset  This signals that we want to modify permoff or tempoff
        if the link is executed.  If this is not present,
    neither permoff nor tempoff are effected - in other
    words the target of the link inherits the current
    permoff and tempoff.

at 0    This says the 16 bit word that contains the value we
        are going to use to calculate permoff or tempoff lives
    offset 0 the IP packet - ie at the start of the packet.
    This offset must be even.  If not specified 0 is used.

mask 0f00   This mask (which is in hex) is bit-wise anded with the
        16 bit word extracted from the packet header.  It
    isolates the header length from the rest of the
    information in the word.  If not specified 0 is used
    for the extracted value.

shift 6 This says the word extracted is to be divided by 64
        after being masked.  If not present the value is not
    shifted.

plus 0  After extracting the word, masking it and dividing it by
        64, this value is now added to it.  If not present is
    assumed to be 0.

eat     If this is present we are calculating permoff, and the
        result of the calculation above is added to it.  Tempoff
    is set to 0 in this case.  If this is not present we are
    calculating tempoff, and the result of the calculation
    becomes tempoff's new value.  Permoff is not altered in
    this case.

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

Вы можете включить / выключить их в Linux, выполнив следующие действия:

echo 0 > /proc/sys/net/ipv4/tcp_timestamps
echo 1 > /proc/sys/net/ipv4/tcp_timestamps

Также проверьте, включены ли они или нет, выполнив:

cat /proc/sys/net/ipv4/tcp_timestamps