一、環境設定
| 介面 | 方向 | 說明 |
|---|---|---|
eth0 | 外網(WAN) | 連接 Internet(例如 PPPoE、NAT 出口) |
eth1 | 內網(LAN) | 內部使用者連線的網卡,例如 192.168.10.0/24 |
| Gateway | Linux 主機 | 同時負責路由與 NAT |
| 目標 | 控制內部使用者上 / 下行頻寬與分類(Web/Mail/FTP/VoIP) |
二、邏輯說明
流量方向定義:
| 類型 | 封包方向 | 實際控制介面 |
|---|---|---|
| 上傳 | LAN → WAN | 控制 eth0 的 egress |
| 下載 | WAN → LAN | 控制 eth1 的 ingress(轉發前)→ 用 IFB 重導再整形 |
因此:
- 出口(上傳)HTB 掛在
eth0 - 入口(下載)封包從
eth0 ingress→ redirect 到ifb0→ 控制
重點:雖然下載的流量「進入 eth0」再被轉送到 eth1,但我們控制的是「eth0 的 ingress」,不是 eth1 的 egress。
三、網路基礎設定
IP 與 NAT
# 假設內網是 192.168.10.0/24
ip addr add 192.168.10.1/24 dev eth1
ip link set eth0 up
ip link set eth1 up
# 啟用 NAT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sysctl -w net.ipv4.ip_forward=1
四、HTB 雙向控制範例(完整腳本)
以下以內網主機 192.168.10.50 為例:
限制上傳 / 下載頻寬,並依服務分類(Web/Mail/FTP/VoIP)分配。
#!/usr/bin/env bash
set -e
WAN=eth0 # 外網
LAN=eth1 # 內網
IFB=ifb0
HOST=192.168.10.50
# === 清理舊設定 ===
tc qdisc del dev $WAN root 2>/dev/null || true
tc qdisc del dev $WAN ingress 2>/dev/null || true
ip link del $IFB 2>/dev/null || true
iptables -t mangle -F
# === 上傳(內網 → 外網)===
echo "[+] 設定上傳 HTB on $WAN"
tc qdisc add dev $WAN root handle 1: htb default 130
tc class add dev $WAN parent 1: classid 1:1 htb rate 20Mbit ceil 20Mbit
# Web / Mail / FTP / VoIP / Default
tc class add dev $WAN parent 1:1 classid 1:110 htb rate 2Mbit ceil 20Mbit prio 2
tc class add dev $WAN parent 1:1 classid 1:120 htb rate 1.5Mbit ceil 20Mbit prio 3
tc class add dev $WAN parent 1:1 classid 1:140 htb rate 2Mbit ceil 20Mbit prio 4
tc class add dev $WAN parent 1:1 classid 1:150 htb rate 1Mbit ceil 20Mbit prio 1
tc class add dev $WAN parent 1:1 classid 1:130 htb rate 5Mbit ceil 20Mbit prio 5
# 對應 fwmark
tc filter add dev $WAN parent 1: protocol ip handle 11 fw flowid 1:110
tc filter add dev $WAN parent 1: protocol ip handle 12 fw flowid 1:120
tc filter add dev $WAN parent 1: protocol ip handle 13 fw flowid 1:140
tc filter add dev $WAN parent 1: protocol ip handle 14 fw flowid 1:150
tc filter add dev $WAN parent 1: protocol ip handle 19 fw flowid 1:130
# 封包標記
iptables -t mangle -A POSTROUTING -s $HOST -p tcp -m multiport --dports 80,443 -j MARK --set-mark 11
iptables -t mangle -A POSTROUTING -s $HOST -p tcp -m multiport --dports 25,465,587,110,995,143,993 -j MARK --set-mark 12
iptables -t mangle -A POSTROUTING -s $HOST -p tcp -m multiport --dports 20,21 -j MARK --set-mark 13
iptables -t mangle -A POSTROUTING -s $HOST -p udp -m multiport --dports 5060,5061 -j MARK --set-mark 14
iptables -t mangle -A POSTROUTING -s $HOST -p udp --dport 10000:20000 -j MARK --set-mark 14
iptables -t mangle -A POSTROUTING -s $HOST -j MARK --set-mark 19
# === 下載(外網 → 內網)===
echo "[+] 設定下載 HTB on $IFB"
modprobe ifb
ip link add $IFB type ifb
ip link set dev $IFB up
# 把 eth0 的 ingress 流量導向 ifb0
tc qdisc add dev $WAN handle ffff: ingress
tc filter add dev $WAN parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev $IFB
# ifb0 的 HTB
tc qdisc add dev $IFB root handle 2: htb default 230
tc class add dev $IFB parent 2: classid 2:1 htb rate 100Mbit ceil 100Mbit
tc class add dev $IFB parent 2:1 classid 2:210 htb rate 20Mbit ceil 100Mbit prio 2
tc class add dev $IFB parent 2:1 classid 2:220 htb rate 10Mbit ceil 100Mbit prio 3
tc class add dev $IFB parent 2:1 classid 2:240 htb rate 15Mbit ceil 100Mbit prio 4
tc class add dev $IFB parent 2:1 classid 2:250 htb rate 2Mbit ceil 100Mbit prio 1
tc class add dev $IFB parent 2:1 classid 2:230 htb rate 40Mbit ceil 100Mbit prio 5
tc filter add dev $IFB parent 2: protocol ip handle 21 fw flowid 2:210
tc filter add dev $IFB parent 2: protocol ip handle 22 fw flowid 2:220
tc filter add dev $IFB parent 2: protocol ip handle 23 fw flowid 2:240
tc filter add dev $IFB parent 2: protocol ip handle 24 fw flowid 2:250
tc filter add dev $IFB parent 2: protocol ip handle 29 fw flowid 2:230
# 標記下載流量(目的地是 LAN)
iptables -t mangle -A PREROUTING -d $HOST -p tcp -m multiport --sports 80,443 -j MARK --set-mark 21
iptables -t mangle -A PREROUTING -d $HOST -p tcp -m multiport --sports 25,465,587,110,995,143,993 -j MARK --set-mark 22
iptables -t mangle -A PREROUTING -d $HOST -p tcp -m multiport --sports 20,21 -j MARK --set-mark 23
iptables -t mangle -A PREROUTING -d $HOST -p udp -m multiport --sports 5060,5061 -j MARK --set-mark 24
iptables -t mangle -A PREROUTING -d $HOST -p udp --sport 10000:20000 -j MARK --set-mark 24
iptables -t mangle -A PREROUTING -d $HOST -j MARK --set-mark 29
echo "=== HTB QoS 啟用完成 ==="
五、測試與驗證
檢查 HTB 狀態
tc -s qdisc show dev eth0
tc -s class show dev eth0
tc -s qdisc show dev ifb0
tc -s class show dev ifb0
檢查封包標記
iptables -t mangle -L -v -n
當不同服務的流量出現時,對應的 class 傳輸量 (Sent bytes) 會增加。
六、實務建議
🧱 1. 多使用者環境
- 若要針對整個 LAN 控制,可改:
-s 192.168.10.0/24 - 若要每個使用者獨立限速,可依 IP 建立多組
classid與fwmark。
⚙️ 2. FTP 被動模式
FTP 的被動連線會使用高埠(ex: 21000–21050),
請在伺服器設定中固定範圍,再加入 iptables 標記。
☎️ 3. VoIP 流量
VoIP 對延遲敏感,請給予 最高優先權 (prio 1),
固定 SIP 埠(5060–5061)與 RTP 範圍(10000–20000/udp)。
🧩 4. 調試建議
若發現限速效果不穩,可暫時關閉硬體卸載功能:
ethtool -K eth0 gro off gso off tso off
七、結語
在這樣的 Linux Gateway 架構中,
HTB + iptables + IFB 提供了完整的流量控制能力:
- ✅ 上行:限制內網用戶對外的上傳頻寬
- ✅ 下行:限制外部流量進入內網的下載速率
- ✅ 依服務分類:Web、Mail、FTP、VoIP 各自分流
- ✅ 可擴展:可延伸至多台主機、多群組使用者
這套架構不但能應用於企業網關,也非常適合用在 測試環境、家庭寬頻 QoS、VPN Gateways 等場合。