海运的博客

linux用tc给软件应用或ip做qos限制下载上传速度

发布时间:May 1, 2023 // 分类: // No Comments

tc只能对网卡出口(egress)方向限速,如果是单机限制下载速度需将入(ingress)定向到虚拟接口出,然后使用虚拟ifb接口对下载限速。
在限制上传速度时可以直接使用iptables mark数据包,但是下载的时候ingress在iptables mark之前,需要在出的时候对流量mark并save,tc在定向流量到虚拟接口的时候添加connmark。

#!/bin/bash
set -x
#上传限速,使用hfsc模式
tc qdisc del dev eth0 root
tc qdisc add dev eth0 root handle 1: hfsc default 20
tc class add dev eth0 parent 1:0 classid 1:20 hfsc sc rate 1000mbit ul rate 1000mbit
tc class add dev eth0 parent 1:0 classid 1:21 hfsc sc rate 40mbit ul rate 50mbit
#使用htb模式限速
#tc qdisc add dev eth0 root handle 1: htb default 20
#tc class add dev eth0 parent 1:0 classid 1:20 htb rate 1000mbit
#tc class add dev eth0 parent 1:20 classid 1:21 htb rate 40mbit ceil 50mbit
#给限速队列添加随机公平
#tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10
#tc qdisc add dev eth0 parent 1:21 handle 21: sfq perturb 10
#iptables mark 21使用class 1:21
tc filter add dev eth0 parent 1:0 prio 1 handle 21 fw flowid 1:21

#下载限速
modprobe ifb numifbs=1
ip link set dev ifb0 up
tc qdisc del dev eth0 ingress
tc qdisc add dev eth0 handle ffff: ingress
tc filter add dev eth0 parent ffff: u32 match u32 0 0 action connmark \
action mirred egress redirect dev ifb0
tc qdisc del dev ifb0 root
#tc qdisc add dev ifb0 root handle 2: hfsc default 20
#tc class add dev ifb0 parent 2:0 classid 2:20 hfsc sc rate 1000mbit ul rate 1000mbit
#tc class add dev ifb0 parent 2:0 classid 2:21 hfsc sc rate 80mbit ul rate 80mbit

tc qdisc add dev ifb0 root handle 2: htb default 20
tc class add dev ifb0 parent 2:0 classid 2:20 htb rate 1000mbit
tc class add dev ifb0 parent 2:0 classid 2:21 htb rate 80mbit

#直接使用tc限制特定ip,无需iptables mark
#tc filter add dev ifb0 parent 2:0 protocol ip prio 0 u32 match ip dst 192.168.1.2 flowid 2:21
#tc filter add dev ifb0 parent 2:0 protocol ipv6 prio 0 u32 match ip6 dst 2408::/16 flowid 2:21

tc filter add dev ifb0 parent 2:0 prio 0 handle 21 fw flowid 2:21

iptables -t mangle -F
iptables -t mangle -X
ip6tables -t mangle -F
ip6tables -t mangle -X

iptables -t mangle -A OUTPUT -m owner --uid-owner user -o eth0 -p tcp -m multiport --dport 80,443 -j RETURN
iptables -t mangle -A OUTPUT -m owner --uid-owner user -o eth0 -d 192.168.1.0/24 -j RETURN
iptables -t mangle -A OUTPUT -m owner --uid-owner user -o eth0 -j CONNMARK --restore-mark
iptables -t mangle -A OUTPUT -m owner --uid-owner user -o eth0 -m mark ! --mark 0 -j ACCEPT
iptables -t mangle -A OUTPUT -m owner --uid-owner user -o eth0 -j MARK --set-mark 21
iptables -t mangle -A OUTPUT -j CONNMARK --save-mark
ip6tables -t mangle -A OUTPUT -m owner --uid-owner user -o eth0 -j CONNMARK --restore-mark
ip6tables -t mangle -A OUTPUT -m owner --uid-owner user -o eth0 -m mark ! --mark 0 -j ACCEPT
ip6tables -t mangle -A OUTPUT -p tcp --dport 443 -j MARK --set-mark 21
ip6tables -t mangle -A OUTPUT -j CONNMARK --save-mark

查看:

tc -s qdisc show dev eth0
tc -s qdisc show dev eth0 root
tc -s qdisc show dev eth0 ingress
tc -s class show dev eth0 
tc -s filter show dev eth0 

参考:
https://blog.csdn.net/i_scream_/article/details/82776333

linux/openwrt清空iptables连接跟踪状态表conntrack

发布时间:April 19, 2023 // 分类: // No Comments

最近在用iptables mark后做qos,当规则更新后要先清空下conntrack,不然之前已建立连接的mark并不改变,影响后续的判断。
使用conntrack工具:

conntrack -F

openwrt可使用以下方法:

echo f > /proc/net/nf_conntrack

openwrt如有开启hnat需先关闭再清除conntrack,不然无效,如mtk/360t7闭源驱动:

echo 0 > /sys/kernel/debug/hnat/qos_toggle
echo 0 > /sys/kernel/debug/hnat/hook_toggle

https://forum.openwrt.org/t/mwan3-how-to-flush-firewall-conntrack-table/133776

Iptables数据包、连接标记模块MARK/CONNMARK使用

发布时间:November 7, 2012 // 分类:Iptables // No Comments

MARK标记用于将特定的数据包打上标签,供Iptables配合TCQOS流量限制或应用策略路由
看看和MARK相关的有哪些模块:

ls /usr/lib/iptables/|grep -i mark
libxt_CONNMARK.so
libxt_MARK.so
libxt_connmark.so
libxt_mark.so

其中大写的为标记模块,小写的为匹配模块,它们之间是相辅相成的。
MARK标记数据包:

#如将所有TCP数据包标记为1
iptables -t mangle -A PREROUTING -p tcp -j MARK --set-mark 1

mark匹配数据包:

#匹配标记1的数据并保存数据包中的MARK到连接中
iptables -t mangle -A PREROUTING -p tcp -m mark --mark 1 -j CONNMARK --save-mark
#将非空mark数据包保存到连接中
iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j CONNMARK --save-mark

CONNMARK标记连接:

iptables -j CONNMARK --help
--set-mark #标记连接
--save-mark #保存数据包中的MARK到连接中
--restore-mark #将连接中的MARK设置到同一连接的其它数据包中
iptables -t mangle -A PREROUTING -p tcp -j CONNMARK --set-mark 1

connmark匹配连接:

iptables -m connmark --help
--mark value #匹配连接的MARK的标记
#匹配连接标记1并将连接中的标记设置到数据包中
iptables -t mangle -A PREROUTING -p tcp -m connmark --mark 1 -j CONNMARK --restore-mark

应用案例:Iptables标记数据策略路由多WAN带宽叠加并负载均衡

其它可参考:
https://blog.csdn.net/bytxl/article/details/7918403
https://blog.csdn.net/dog250/article/details/78301259

ROS标记中的mark-connection和mark-packet区别

发布时间:November 7, 2012 // 分类:ROS // No Comments

之前有记录使用ROS做QOS的一些心得,关于使用mark-connection和mark-packet还有一些疑问,mark-connection和mark-packet有什么区别,为什么要用mark-connection?下面是个人的一些理解:
1.标记mark-connection和mark-packet主要区别:

#https://www.haiyun.me
mark-connection应用到同一连接中的所有数据包,容易识别上传、下载数据包;
mark-packet仅标记单一数据包,识别上传、下载需双向标记所有数据包。

2.标记mark-connection和mark-packet性能分析,数据包标记mark-packet示例:

/ip firewall mangle
add chain=prerouting action=mark-packet new-packet-mark=HTTP protocol=tcp dst-port=80 in-interface=bridge-local
add chain=prerouting action=mark-packet new-packet-mark=HTTP protocol=tcp dst-port=80 in-interface=pppoe-out1
#这样Mangle对经过的每个数据包都要进行mark-packet,数据包是否TCP协议?目标端口是否80?进入网络端口是?

连接标记mark-connection示例:

add chain=prerouting action=mark-connection new-connection-mark=HTTP protocol=tcp dst-port=80 in-interface=bridge-local
add chain=prerouting action=mark-packet new-packet-mark=HTTP in-interface=bridge-local connection-mark=HTTP
#这样在Mangle链只需进行以下判断,是否新连接?是否有连接标记?

3.在QOS中使用mark-connection还是mark-packet?

使用队列限速要时上传、下载要分开,所以只能识别mark-packet;
标记单向数据包使用mark-packet,如小数据包、TCP标志(SYN)优先之类的;
标记双向数据包mark-packet和mark-connection都可实现,通过上面例子使用mark-connection更优。

4.在多线带宽叠加和策略路由时要先标记数据再标记路由,这个时候就要用mark-connection了,因为同一连接不同数据包最好从同一出口发出。

ip firewall mangle add chain=prerouting action=mark-connection new-connection-mark=www.haiyun.me \
protocol=tcp dst-port=80 connection-state=new 
ip firewall mangle add chain=prerouting action=mark-routing new-routing-mark=www.haiyun.me \
connection-mark=www.haiyun.me 

一个实例:ROS单线ADSL使用、HTB、PCQ做流量控制

ROS下单线ADSL使用HTB+PCQ限速

发布时间:October 18, 2012 // 分类:ROS // 7 Comments

单线ADSL带宽4M,线路损耗后实际速度3.5M左右,上传350k左右,由于ADSL满速下载、上传速度会变慢,配置ROS最高上传、下载不得超过总带宽90%,QOS配置如下:
首先分类标记上传、下载数据:

#https://www.haiyun.me
/ip firewall mangle
#小数据
add chain=prerouting action=mark-connection new-connection-mark=Small-conn passthrough=yes protocol=icmp comment=Small
add chain=prerouting action=mark-connection new-connection-mark=Small-conn passthrough=yes protocol=udp dst-port=53
add chain=postrouting action=mark-connection new-connection-mark=Small-conn passthrough=yes protocol=udp dst-port=53
add chain=prerouting action=mark-connection new-connection-mark=Small-conn passthrough=yes protocol=udp dst-port=123
add chain=postrouting action=mark-packet new-packet-mark=Small-up passthrough=no out-interface=pppoe-out1 connection-mark=Small-conn 
add chain=prerouting action=mark-packet new-packet-mark=Small-up passthrough=no in-interface=bridge-local connection-mark=Small-conn 
add chain=prerouting action=mark-packet new-packet-mark=Small-down passthrough=no in-interface=pppoe-out1 connection-mark=Small-conn 
#SSH及VPN
add chain=prerouting action=mark-connection new-connection-mark=SSH-conn passthrough=yes protocol=tcp dst-port=22 comment=SSH
add chain=prerouting action=mark-connection new-connection-mark=SSH-conn passthrough=yes protocol=tcp dst-port=23
add chain=prerouting action=mark-packet new-packet-mark=SSH-up passthrough=no in-interface=bridge-local connection-mark=SSH-conn 
add chain=prerouting action=mark-packet new-packet-mark=SSH-down passthrough=no in-interface=pppoe-out1 connection-mark=SSH-conn 
#网页数据
add chain=prerouting action=mark-connection new-connection-mark=HTTP-conn passthrough=yes protocol=tcp dst-port=80 comment=HTTP
add chain=prerouting action=mark-connection new-connection-mark=HTTP-conn passthrough=yes protocol=tcp dst-port=443
add chain=prerouting action=mark-packet new-packet-mark=HTTP-up passthrough=no in-interface=bridge-local connection-mark=HTTP-conn 
add chain=prerouting action=mark-packet new-packet-mark=HTTP-down passthrough=no in-interface=pppoe-out1 connection-mark=HTTP-conn 
#其它
add chain=prerouting action=mark-connection new-connection-mark=Other-conn passthrough=yes comment=Other
add chain=prerouting action=mark-packet new-packet-mark=Other-up passthrough=no in-interface=bridge-local connection-mark=Other-conn 
add chain=prerouting action=mark-packet new-packet-mark=Other-down passthrough=no in-interface=pppoe-out1 connection-mark=Other-conn

新建队列类型为PCQ

#pcq-rate为每个了数据流最大速度,0为按数据流数公平分配带宽,pcq-limit为每一数据流队列长度;
#pcq-total-limit不能小于内网主机数*pcq-limit。
/queue type 
add name="Small-down" kind=pcq pcq-rate=0 pcq-limit=50 pcq-classifier=dst-address pcq-total-limit=2000 
add name="Small-up" kind=pcq pcq-rate=50k pcq-limit=50 pcq-classifier=src-address pcq-total-limit=2000 
add name="SSH-down" kind=pcq pcq-rate=0 pcq-limit=50 pcq-classifier=dst-address pcq-total-limit=2000 
add name="SSH-up" kind=pcq pcq-rate=50k pcq-limit=50 pcq-classifier=src-address pcq-total-limit=2000 
add name="HTTP-down" kind=pcq pcq-rate=0 pcq-limit=50 pcq-classifier=dst-address pcq-total-limit=2000 
add name="HTTP-up" kind=pcq pcq-rate=80k pcq-limit=50 pcq-classifier=src-address pcq-total-limit=2000 
add name="Other-down" kind=pcq pcq-rate=0 pcq-limit=50 pcq-classifier=dst-address pcq-total-limit=2000 
add name="Other-up" kind=pcq pcq-rate=30k pcq-limit=50 pcq-classifier=src-address pcq-total-limit=2000 

添加队列树调用之前标记的数据包设置优先级,队列类型设置为之前新建的PCQ类型。

/queue tree
add name="Parent-up" parent=global-out limit-at=330k max-limit=330k
add name="Parent-down" parent=global-in limit-at=3300k max-limit=3300k
add name=Small-up parent=Parent-up packet-mark=Small-up limit-at=70k max-limit=150k queue=Small-up priority=1
add name=Small-down parent=Parent-down packet-mark=Small-down limit-at=500k max-limit=1000k queue=Small-down priority=1
add name=SSH-up parent=Parent-up packet-mark=SSH-up limit-at=70k max-limit=200k queue=SSH-up priority=2
add name=SSH-down parent=Parent-down packet-mark=SSH-down limit-at=500k max-limit=1000k queue=SSH-down priority=2
add name=HTTP-up parent=Parent-up packet-mark=HTTP-up limit-at=150k max-limit=200k queue=HTTP-up priority=3
add name=HTTP-down parent=Parent-down packet-mark=HTTP-down limit-at=2000k max-limit=3000k queue=HTTP-down priority=3
add name=Other-up parent=Parent-up packet-mark=Other-up limit-at=20k max-limit=80k queue=Other-up priority=4
add name=Other-down parent=Parent-down packet-mark=Other-down limit-at=200k max-limit=2000k queue=Other-down priority=4

ros+htb+pcq限速.png
ROS路由设置HTB+PCQ流量控制的一些注意事项

1.WAN限制上传,按源地址分组;LAN限制下载,按目标地址分组;
2.passthrough是否继续向下匹配此链接,选择yes会向下匹配,下面规则如有匹配标记会改变;
3.在HTB首先满足Limit At,在父级有剩余带宽的前提下才会Max Limit,优先级高的队列优先获得Max Limit;
4.mark-connection的数据包是双向的,然后通过mark-pack区分上传和下载;
5.global-in在DNAT后,global-out在SNAT前,分别可匹配目标地址和源地址。

ROS数据包流程图:
ros数据包流程图.png
ROS防火墙处理数据包流程.png

分类
最新文章
最近回复
  • opnfense: 谢谢博主!!!解决问题了!!!我之前一直以为内置的odhcp6就是唯一管理ipv6的方式
  • liyk: 这个方法获取的IPv6大概20分钟之后就会失效,默认路由先消失,然后Global IPV6再消失
  • 海运: 不好意思,没有。
  • zongboa: 您好,請問一下有immortalwrt設定guest Wi-Fi的GUI教學嗎?感謝您。
  • 海运: 恩山有很多。
  • swsend: 大佬可以分享一下固件吗,谢谢。
  • Jimmy: 方法一 nghtp3步骤需要改成如下才能编译成功: git clone https://git...
  • 海运: 地址格式和udpxy一样,udpxy和msd_lite能用这个就能用。
  • 1: 怎么用 编译后的程序在家里路由器内任意一台设备上运行就可以吗?比如笔记本电脑 m参数是笔记本的...
  • 孤狼: ups_status_set: seems that UPS [BK650M2-CH] is ...