Linux tc 過濾器 u32 在數據包數據有效負載上匹配的不一致 - 有人可以解釋一下嗎?
我只是想對此有所了解,因為我真的不明白-為什麼-會這樣。
再往下是當一個正常的 GET 請求向它發出時,網路伺服器給出的“HTTP”響應的 TCPDUMP 輸出(tcpdump -s0 -XXnni eth0 tcp 埠 80)。我想要做的是使用 Linux u32 tc 過濾器來匹配 TCP ack 數據包的內容,尋找字元串’HTTP/1.
$$ 01 $$TCP ack 數據包的數據負載中的 200’(換句話說,尋找典型的 ‘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”部分開始的偏移點(數據包數據有效負載)在兩種情況下都不同。為什麼是這樣?什麼會導致它?
提前感謝任何可以向我解釋這個謎團的人。
找到了答案。啟用 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
我發現這可以解決問題。
http://linux-tc-notes.sourceforge.net/tc/doc/cls_u32.txt
標題偏移量
IP 標頭(和其他標頭)是可變長度的。如果您嘗試使用“匹配”來查看後面的標題中的值,這會產生問題 - 您不知道它在哪裡。這不是一個不可能的問題,因為 IP 數據包中的每個標頭都包含一個長度欄位。u32 的“標頭偏移”功能允許您從數據包中提取該長度,然後將其添加到“匹配”選項中指定的偏移量。
下面是它的工作原理。回想一下 match 選項如下所示:
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
match 表達式選擇 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.