更新日期: 2015-04-02
介紹
當沒有 tc 時, Shorewall 預設的 qdisc: pfifo_fast <--- main tc-pfifo_fast )
pfifo_fast = 3 tc-pfifo (side by side) <--- man tc-prio
Not all three bands are dequeued simultaneously
(as long as lower bands have traffic, higher bands are never dequeued.)
(Additional packets coming in are not enqueued but are instead dropped.)
in: 有 tc 時, qdisc 將會是 flow --> sfq ----> prio
out: tbf ---> prio
man rx-prio
man tc-sfq
external: sent by a given IP address
internal: traffic being sent to a given IP address
簡易編
/etc/shorewall/shorewall.conf
有關設定
TC_ENABLED=Simple
CLEAR_TC=Yes
TC_PRIOMAP="2 3 3 3 2 3 1 1 2 2 2 2 2 2 2 2"
/etc/shorewall/tcinterfaces
# # OUT-BANDWIDTH (out_bandwidth) - [rate[:[burst][:[latency][:[peek][:[minburst]]]]]] # default burst is 10kb # #INTERFACE TYPE IN-BANDWIDTH OUT-BANDWIDTH eth0 External 50mbit:200kb 6.0mbit:100kb:200ms:100mbit:1516
/etc/shorewall/tcpri
#BAND PROTO PORT(S) ADDRESS INTERFACE HELPER COMMENT All DMZ traffic in band 3 by default 3 - - 70.90.191.124/31 COMMENT Bit Torrent is in band 3 3 ipp2p:all bit COMMENT But give a boost to DNS queries 2 udp 53 COMMENT And place echo requests in band 1 to avoid false line-down reports 1 icmp 8
TC (Traffic Control)
當在沒有任何 tc 的情況下, Linux-2.6 的所有 interface 都是用 pfifo_fast 去把 package 排隊的
pfifo_fast 是一種 qdisc (排隊方法) 來
pfifo_fast 是基於 package 的 tos 去把不同的 package 分入了三條隊中
H -----|tc-pfifo\ M tos -----|tc-pfifo| L -----|tc-pfifo/ ------->
- tos: Type of Service
- qdisc: queuing discipline
下面的隊會得到優先處理, 當下面的隊(tc-pfifo)未完成傳送前, 較高的隊(tc-pfifo)就不能傳送 !!
當 queue full 了後, package 就會被 drop ...
當用 shorewall 實現 tc 後, 系統會改用 HTB (Hierarchical Token Bucket ) 的
最處是支援很多條隊, 並且可以確保每條隊都有最低輸出
限速對象: Upload
在 Gateway 上一般來說只可以限制 Upload 速度
如果要限制 download 的速度, 那就要透過 IFB 去實施了
[internet] ---> (IFB)----> interface
- IFB: Intermediate Functional Block
Shorewall 設定檔:
啟動 tc 方法很簡單, 只要在 /etc/shorewall/shorewall.conf 修改
TC_ENABLED = Internal CLEAR_TC = Yes # 在 start, stop, restart Shorewall 時會重建 tc 的設定 # 為的是以免 tc 被外界影響
限速設定由以下3個檔案來完成
- /etc/shorewall/tcdevices
- /etc/shorewall/tcrules
- /etc/shorewall/tcfilters
我們可以在 /usr/share/doc/shorewall/default-config/ 找到相應的 template 檔
實例:
tcdevices
它是用來指定對那個 interface 限速
#INTERFACE IN-BANDWITH OUT-BANDWIDTH OPTIONS eth0 10mbps 2mbps
每個 interface 都會有一個 sequential number
第一個是1, 第二個是2
可用單位:
- kbps Kilobytes per second.
- mbps Megabytes per second.
- kbit Kilobits per second.
- mbit Megabits per second.
-
bps Bytes per second
接線方式:
Internet | | IN | V Server(eth0)
OPTIONS:
- hfsc <--- 更進階的掛隊方法, default 是用 htb
HFSC: Hierarchical Fair Service Curves
P.S.
- 不可以應用在 sub-interface 上, 比如 eth0:0
- 不可以用 "*", 比如 ppp*
tcfilters
用來設定不用 "MARK" 有不同速度
#INTERFACE MARK RATE CEIL PRIORITY OPTIONS eth0 1 10kbit 50kbit 1 tcp-ack,tos-minimize-delay eth0 2 300kbit full/2 2 eth0 3 300kbit full 2 eth0 4 90kbit 200kbit 3 default <----- unmarked traffic 就會被 mark 過這個
INTERFACE - interface[[:parent]:class]
Priority:
1 = highest priority
當同 class 時(MARK), 較高的 Priority 那個會得到"照顧"先, 而無視另一位的 "RATE" 設定
OPTIONS:
tcp-ack: tcp ack packets (size <=64 Bytes)
tos-minimize-delay: 當 tos 內的值是 minimize-delay 時, 就會 overrides 所有的 mark (無視 package 上已有的 mark)
flow= nfct-src / dst
flow=nfct-src
that means that we want to use the source IP address before SNAT
SFQ queuing discipline to each leaf HTB
SFQ ensures that each flow gets equal access to the interface
flow 的數量差不多是 Netfilter connection
fow 是由 Kernel Module(cls_flow) 所提供的功能來
tcrules
#MARK SOURCE DESTINATION PROTOCOL PORT(S) 22:T 192.168.1.0/24 0.0.0.0 tcp 22 # 由 192.168.123.0/24 到 0.0.0.0 的 ssh 全 Mark 22 #MARK SOURCE DESTINATION PROTOCOL PORT(S) 1 0.0.0.0/0 0.0.0.0/0 icmp echo-request 1 0.0.0.0/0 0.0.0.0/0 icmp echo-reply # 所有用ping有關的 mark 為 1
PORT(S) - Destination Ports
MARK 是由 1 至 255 的, 後面可以選擇接上 ":T/F/P"[C]
- F FORWARD
- P PREROUTING
- T POSTROUTING
- C Connection (有 packet 或 connection mark 之分的)
P.S.
- 當有 package 或 connection 中了 tcrules 內的幾條 rule 時, 那會以最尾一條為準
- 每個 class最多可以有 127 個 package 在排隊
Example 6.
Mark all ICMP echo traffic with packet mark 1. Mark all peer to peer traffic with packet mark 4.
This is a little more complex than otherwise expected. Since the ipp2p module is unable to determine all packets in a connection are P2P packets, we mark the entire connection as P2P if any of the packets are determined to match. We assume packet/connection mark 0 to means unclassified. Traffic originating on the firewall is not covered by this example.
#MARK SOURCE DESTINATION PROTOCOL PORT(S) CLIENT USER/ TEST # PORT(S) GROUP 1 0.0.0.0/0 0.0.0.0/0 icmp echo-request 1 0.0.0.0/0 0.0.0.0/0 icmp echo-reply RESTORE 0.0.0.0/0 0.0.0.0/0 all - - - 0 CONTINUE 0.0.0.0/0 0.0.0.0/0 all - - - !0 4 0.0.0.0/0 0.0.0.0/0 ipp2p:all SAVE 0.0.0.0/0 0.0.0.0/0 all - - - !0
The last four rules can be translated as:
"If a packet hasn't been classified (packet mark is 0), copy the connection mark to the packet mark. If the packet mark is set, we're done. If the packet is P2P, set the packet mark to 4. If the packet mark has been set, save it to the connection mark."
COMMENT 為 Netfilter 加上 comment "/* ... */"
SAVE: packet's mark ---> connection mark (要 Netfilter 支援 CONNMARK)
RESTORE: connection mark ---> packet's mark
TEST - [!]value[/mask][:C]
Optional - Defines a test on the existing packet or connection mark. The rule will match only if the test returns true.
shorewall refresh
查看與測試
shorewall:
- shorewall show tc
- shorewall show filters
原生指令(tc):
- tc qdisc show dev $DEV
- tc class show dev $DEV
- tc filter show dev $DEV
Other: