在Linux路由器上,如何为所有主机设置下载配额?
这是与许多客人共享的 wifi 网络:
- 每位访客的下载配额一开始应为 150 Mb,无任何限制
- 达到配额后,下载速度应限制为 50 k/s
- 过滤必须基于 mac 地址,IP 地址可能会随着 dhcp 的变化而变化。
石像鬼router 实现了类似的功能,不幸的是,这里不能使用 gargoyle,我需要使用 tc 和 iptables 来实现。
这回答是一个很好的起点:
iptables -A INPUT -p tcp -s 192.168.0.2 -m quota --quota 13958643712 -j ACCEPT
iptables -A INPUT -p tcp -j CLASSIFY --set-class 1:12
让它使用 MAC 地址而不是 IP 很容易,但是它需要提前知道地址,但这里的情况并非如此。
答案1
经过一番研究后,我发现:
首先,一些配置:
# download quota (Mb)
dl_quota_mb=150
dl_quota=$(($dl_quota_mb * 1024 * 1024))
# max speed once overquota (k/s)
dl_cap_kb=50
dl_cap=$(($dl_cap_kb * 8))
# wifi interface
if_lan=wlan0
# lan subnet
lan=192.168.1
为每个ip创建tc类来限制下载速度:
TCA="tc class add dev $if_lan"
TQA="tc qdisc add dev $if_lan"
SFQ="sfq perturb 10"
$TQA root handle 1: htb
# over quota speed limits
for i in `seq 1 254`; do
$TCA parent 1: classid 1:$i htb rate ${dl_cap}kbit ceil ${dl_cap}kbit prio 2
$TQA parent 1:$i handle $i: $SFQ
done
为带有记帐功能的 lan ip 创建 ipset:
ipset create IP_QUOTA bitmap:ip range $lan.0/24 counters
ipset add IP_QUOTA $lan.1-$lan.254
使用 iptables 对超额 ips 数据包进行分类,以实施限制:
IPT="iptables -t mangle"
IPT_POST="iptables -t mangle -A POSTROUTING -o $if_lan"
$IPT -N overquota
$IPT_POST -m set --match-set IP_QUOTA dst --bytes-gt $dl_quota -j overquota
# classify packets
for i in `seq 1 254`; do
$IPT -A overquota --dst $lan.$i -j CLASSIFY --set-class 1:$i
done
这为我们提供了每个 IP 地址的下载配额。要获取每个 mac 地址的下载配额,一种方法是监视 mac/ip 对的更改并相应地设置/重置 IP 计数器。
我已经设置了一个项目在 github 上,它实现了 OpenWrt 的完整解决方案。
笔记:截至 2017 年 6 月,Gargoyle 的下载配额是按 IP 地址计算的。最终在 Gargoyle 中实现这样的东西会很高兴。