Linux

使用 tc 過濾器和 u32 匹配限制給定埠上的輸入

  • October 24, 2015

我正在嘗試對埠 8128-8191 上的所有傳入流量進行速率限制。我已經閱讀了我找到的所有內容,檢查了所有內容十次,它仍然無法正常工作。

命令:

tc qdisc del dev eth0 root

tc qdisc add dev eth0 root handle 1: htb default 1
tc class add dev eth0 parent 1:0 classid 1:1 htb rate 1kbit ceil 1kbit
tc filter add dev eth0 parent 1:0 prio 1 protocol ip u32 match ip dport 8128 0xFFC0 classid 1:1  

這就是我計算遮罩的方式:

expected = lowest port  = 0b_0001_1111_1100_0000 = 0x1FC0 = 8128d
   mask = highest port = 0b_1111_1111_1100_0000 = 0xFFC0 
          highest port = 0b_0001_1111_1111_1111 = 0x1FFF = 8191d

輸出:

#tc -s class show dev eth0
class htb 1:1 root prio 0 rate 1000bit ceil 1000bit burst 1600b cburst 1600b
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
lended: 0 borrowed: 0 giants: 0
tokens: 200000000 ctokens: 200000000

# tc filter show dev eth0
filter parent 1: protocol ip pref 1 u32
filter parent 1: protocol ip pref 1 u32 fh 800: ht divisor 1
filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1
 match 00001fc0/0000ffc0 at 20

我從我的工作站發送字節流:

cat /dev/urandom | pv -L 3k | nc -nvv ${SERVER_ADDRESS} 8128

在伺服器上,我收到它們:

nc -nvvl -p 8128 > /dev/null

我用出色的 iptraf 檢查了 eth1 的使用情況,吞吐量保持在 3 kbit/s 或更高,並且class htb 1:1.

我相信我對面具很好。我還嘗試了一些更簡單的方法dport 8128 0xFFFF,但沒有更多結果。

顯示過濾器時,at 20似乎是正確的,因為 IP 標頭是 20 字節長。源埠和目的埠是前 4 個字節,所以 32 位匹配是正確的。我不明白其他價值觀。

我正在使用 Debian 7:

# uname -a
Linux node-1 3.2.0-4-amd64 #1 SMP Debian 3.2.68-1+deb7u5 x86_64 GNU/Linux

在嘗試上述操作之前,我還清除了 iptables 中的所有內容。

也許我把過濾器連接到類的方式搞砸了。也許有一些我忘記啟動的核心選項。

有什麼見解嗎?

tc1)使用標準 linux 核心很難限制(整形)輸入流量。您可以為您的核心嘗試 IMQ 更新檔http://www.linuximq.net/ 。您也需要修補 iptables。然後,您可以“標記”數據包以轉到 IMQ 設備,並tcimq0設備上根據需要調整流量。

  1. 另一個簡單但不准確的解決方案是使用 iptables,但它基於數據包計數(您需要為您的協議/連接估計平均數據包大小)
iptables -A INPUT -p tcp --dport 8128:8191 -m limit --limit 5/seconds -j ACCEPT
iptables -A INPUT -p tcp --dport 8128:8191 -j DROP

您需要這兩行,首先將每秒接受所有 ip 的前 5 個數據包,然後丟棄所有內容。

引用自:https://serverfault.com/questions/729897