Hi,
I would like to limit bandwidth for some devices. I am aware that SQM default take care of fairness usage so that no single device take over the whole network. But this is not I am looking for. I want to on purpose being unfair and limit internet usage for some devices.
For the why: eg: limit internet to non-video and stream based usage.
What is the best approach ? Can SQM do unfair traffic shaping per IP (or MAC) ? iptables with some packet drop rate ?
Currently using OpenWrt 21.02.2 on ASUS RT-AC58U
https://forum.openwrt.org/search?q=bandwidth%20limit%20per%20ip
Yup. Been there. If you look at the search results:
Use luci-app-nft-qos: obsolete package that don't work anymore. I installed it, configured and nothing happe (yes, I rebooted the router)
Use SQM to limit a whole interface : I tried that and it works. But I am looking to do per IP
Most of the post are deadend
Yes and no. SQM is both a set of scripts implementing what we consider sane and generally useful traffic-sharing policies and a framework to handle such scrpits to play nicely with OpenWrt. The former is not helping, but the latter is something you might be able to harness. If you want to write your own script simple.qos is a decent starting point, just ann more specific HTB instances and filters (and AQMs) for each device to be throttled. Keep in mind though that for the default ifb-ingress on WAN qdisc internal IP addresses are not available, so you might want to instantiate your throttle-me-this script on the LAN side instead.
pavelgl
February 14, 2023, 8:26am
5
Definitely not the best approach, but it can be used if you don't have high expectations.
opkg update; opkg install iptables-mod-hashlimit
iptables -A forwarding_rule -d 192.168.1.100/32 -m hashlimit --hashlimit-above 128kb/sec --hashlimit-burst 256kb --hashlimit-name user100dl --hashlimit-mode dstip -j DROP
iptables -A forwarding_rule -d 192.168.1.101/32 -m hashlimit --hashlimit-above 128kb/sec --hashlimit-burst 256kb --hashlimit-name user101dl --hashlimit-mode dstip -j DROP
iptables -A forwarding_rule -d 192.168.1.102/32 -m hashlimit --hashlimit-above 128kb/sec --hashlimit-burst 256kb --hashlimit-name user102dl --hashlimit-mode dstip -j DROP
The limits aren't precise at all, so you'll have to play around with the values if you decide to use it.
These rules only limit the download speed.
https://manpages.debian.org/jessie/iptables/iptables-extensions.8.en.html#hashlimit
The openNDS package can do this, but usually via some login, where upload and download quotas and rates are specified.
But if you have a list of mac addresses to be restricted you can add a dnsmasq dhcpscript option that runs a custom script whenever a device is allocated an ip address. This will authenticate devices on the list with specified quotas and rates, and devices not on the list getting full access or some default predefined allocation.
iptables -A forwarding_rule -d 192.168.1.100/32 -m hashlimit --hashlimit-above 128kb/sec --hashlimit-burst 256kb --hashlimit-name user100dl --hashlimit-mode dstip -j DROP
Where should I put this rule ?
I put it in the firewall.user ( Firewall - Custom Rules) and restart the firewall with /etc/init.d/firewall restart
But the speedtest show that there is no limit on the device.
Edit:
I can see that the rule been added with iptables -L
:
Chain forwarding_rule (1 references)
target prot opt source destination
DROP all -- anywhere phone.lan limit: above 50kb/s burst 100kb mode dstip
pavelgl
February 14, 2023, 9:56am
8
Yes, it should be inserted into /etc/firewall.user
, but run it from the command line first to make sure it doesn't return errors.
Check the rule for hits running iptables -nvL forwarding_rule
root@OpenWrt:~# iptables -nvL forwarding_rule
Chain forwarding_rule (1 references)
pkts bytes target prot opt in out source destination
19461 1523K DROP all -- * * 0.0.0.0/0 192.168.92.85 limit: above 128kb/s burst 256kb mode dstip
root@asus:/etc/config# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere /* !fw3 */
input_rule all -- anywhere anywhere /* !fw3: Custom input rule chain */
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED /* !fw3 */
syn_flood tcp -- anywhere anywhere tcp flags:FIN,SYN,RST,ACK/SYN /* !fw3 */
zone_lan_input all -- anywhere anywhere /* !fw3 */
zone_wan_input all -- anywhere anywhere /* !fw3 */
zone_guestZone_input all -- anywhere anywhere /* !fw3 */
zone_trusted_input all -- anywhere anywhere /* !fw3 */
Chain FORWARD (policy DROP)
target prot opt source destination
forwarding_rule all -- anywhere anywhere /* !fw3: Custom forwarding rule chain */
FLOWOFFLOAD all -- anywhere anywhere /* !fw3: Traffic offloading */ ctstate RELATED,ESTABLISHED FLOWOFFLOAD
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED /* !fw3 */
zone_lan_forward all -- anywhere anywhere /* !fw3 */
zone_wan_forward all -- anywhere anywhere /* !fw3 */
zone_guestZone_forward all -- anywhere anywhere /* !fw3 */
zone_trusted_forward all -- anywhere anywhere /* !fw3 */
reject all -- anywhere anywhere /* !fw3 */
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere /* !fw3 */
output_rule all -- anywhere anywhere /* !fw3: Custom output rule chain */
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED /* !fw3 */
zone_lan_output all -- anywhere anywhere /* !fw3 */
zone_wan_output all -- anywhere anywhere /* !fw3 */
zone_guestZone_output all -- anywhere anywhere /* !fw3 */
zone_trusted_output all -- anywhere anywhere /* !fw3 */
Chain forwarding_guestZone_rule (1 references)
target prot opt source destination
Chain forwarding_lan_rule (1 references)
target prot opt source destination
Chain forwarding_rule (1 references)
target prot opt source destination
DROP all -- anywhere phone.lan limit: above 50kb/s burst 100kb mode dstip
Chain forwarding_trusted_rule (1 references)
target prot opt source destination
Chain forwarding_wan_rule (1 references)
target prot opt source destination
Chain input_guestZone_rule (1 references)
target prot opt source destination
Chain input_lan_rule (1 references)
target prot opt source destination
Chain input_rule (1 references)
target prot opt source destination
Chain input_trusted_rule (1 references)
target prot opt source destination
Chain input_wan_rule (1 references)
target prot opt source destination
Chain output_guestZone_rule (1 references)
target prot opt source destination
Chain output_lan_rule (1 references)
target prot opt source destination
Chain output_rule (1 references)
target prot opt source destination
Chain output_trusted_rule (1 references)
target prot opt source destination
Chain output_wan_rule (1 references)
target prot opt source destination
Chain reject (6 references)
target prot opt source destination
REJECT tcp -- anywhere anywhere /* !fw3 */ reject-with tcp-reset
REJECT all -- anywhere anywhere /* !fw3 */ reject-with icmp-port-unreachable
Chain syn_flood (1 references)
target prot opt source destination
RETURN tcp -- anywhere anywhere tcp flags:FIN,SYN,RST,ACK/SYN limit: avg 25/sec burst 50 /* !fw3 */
DROP all -- anywhere anywhere /* !fw3 */
Chain zone_guestZone_dest_ACCEPT (3 references)
target prot opt source destination
ACCEPT all -- anywhere anywhere /* !fw3 */
Chain zone_guestZone_dest_REJECT (1 references)
target prot opt source destination
reject all -- anywhere anywhere /* !fw3 */
Chain zone_guestZone_forward (1 references)
target prot opt source destination
forwarding_guestZone_rule all -- anywhere anywhere /* !fw3: Custom guestZone forwarding rule chain */
zone_wan_dest_ACCEPT all -- anywhere anywhere /* !fw3: Zone guestZone to wan forwarding policy */
ACCEPT all -- anywhere anywhere ctstate DNAT /* !fw3: Accept port forwards */
zone_guestZone_dest_REJECT all -- anywhere anywhere /* !fw3 */
Chain zone_guestZone_input (1 references)
target prot opt source destination
input_guestZone_rule all -- anywhere anywhere /* !fw3: Custom guestZone input rule chain */
ACCEPT tcp -- anywhere anywhere tcp dpt:domain /* !fw3: guestDnsDhcp */
ACCEPT tcp -- anywhere anywhere tcp dpt:bootps /* !fw3: guestDnsDhcp */
ACCEPT tcp -- anywhere anywhere tcp dpt:bootpc /* !fw3: guestDnsDhcp */
ACCEPT udp -- anywhere anywhere udp dpt:domain /* !fw3: guestDnsDhcp */
ACCEPT udp -- anywhere anywhere udp dpt:bootps /* !fw3: guestDnsDhcp */
ACCEPT udp -- anywhere anywhere udp dpt:bootpc /* !fw3: guestDnsDhcp */
ACCEPT all -- anywhere anywhere ctstate DNAT /* !fw3: Accept port redirections */
zone_guestZone_src_REJECT all -- anywhere anywhere /* !fw3 */
Chain zone_guestZone_output (1 references)
target prot opt source destination
output_guestZone_rule all -- anywhere anywhere /* !fw3: Custom guestZone output rule chain */
zone_guestZone_dest_ACCEPT all -- anywhere anywhere /* !fw3 */
Chain zone_guestZone_src_REJECT (1 references)
target prot opt source destination
reject all -- anywhere anywhere /* !fw3 */
Chain zone_lan_dest_ACCEPT (5 references)
target prot opt source destination
ACCEPT all -- anywhere anywhere /* !fw3 */
Chain zone_lan_forward (1 references)
target prot opt source destination
forwarding_lan_rule all -- anywhere anywhere /* !fw3: Custom lan forwarding rule chain */
zone_trusted_dest_ACCEPT tcp -- anywhere base-address.mcast.net/4 /* !fw3: multicast */
zone_trusted_dest_ACCEPT udp -- anywhere base-address.mcast.net/4 /* !fw3: multicast */
zone_wan_dest_ACCEPT all -- anywhere anywhere /* !fw3: Zone lan to wan forwarding policy */
zone_guestZone_dest_ACCEPT all -- anywhere anywhere /* !fw3: Zone lan to guestZone forwarding policy */
zone_trusted_dest_ACCEPT all -- anywhere anywhere /* !fw3: Zone lan to trusted forwarding policy */
ACCEPT all -- anywhere anywhere ctstate DNAT /* !fw3: Accept port forwards */
zone_lan_dest_ACCEPT all -- anywhere anywhere /* !fw3 */
Chain zone_lan_input (1 references)
target prot opt source destination
input_lan_rule all -- anywhere anywhere /* !fw3: Custom lan input rule chain */
ACCEPT all -- anywhere anywhere ctstate DNAT /* !fw3: Accept port redirections */
zone_lan_src_ACCEPT all -- anywhere anywhere /* !fw3 */
Chain zone_lan_output (1 references)
target prot opt source destination
output_lan_rule all -- anywhere anywhere /* !fw3: Custom lan output rule chain */
zone_lan_dest_ACCEPT all -- anywhere anywhere /* !fw3 */
Chain zone_lan_src_ACCEPT (1 references)
target prot opt source destination
ACCEPT all -- anywhere anywhere ctstate NEW,UNTRACKED /* !fw3 */
Chain zone_trusted_dest_ACCEPT (4 references)
target prot opt source destination
ACCEPT all -- anywhere anywhere /* !fw3 */
Chain zone_trusted_dest_REJECT (1 references)
target prot opt source destination
reject all -- anywhere anywhere /* !fw3 */
Chain zone_trusted_forward (1 references)
target prot opt source destination
forwarding_trusted_rule all -- anywhere anywhere /* !fw3: Custom trusted forwarding rule chain */
zone_guestZone_dest_ACCEPT all -- anywhere anywhere /* !fw3: Zone trusted to guestZone forwarding policy */
zone_lan_dest_ACCEPT all -- anywhere anywhere /* !fw3: Zone trusted to lan forwarding policy */
zone_wan_dest_ACCEPT all -- anywhere anywhere /* !fw3: Zone trusted to wan forwarding policy */
ACCEPT all -- anywhere anywhere ctstate DNAT /* !fw3: Accept port forwards */
zone_trusted_dest_REJECT all -- anywhere anywhere /* !fw3 */
Chain zone_trusted_input (1 references)
target prot opt source destination
input_trusted_rule all -- anywhere anywhere /* !fw3: Custom trusted input rule chain */
ACCEPT all -- anywhere anywhere ctstate DNAT /* !fw3: Accept port redirections */
zone_trusted_src_ACCEPT all -- anywhere anywhere /* !fw3 */
Chain zone_trusted_output (1 references)
target prot opt source destination
output_trusted_rule all -- anywhere anywhere /* !fw3: Custom trusted output rule chain */
zone_trusted_dest_ACCEPT all -- anywhere anywhere /* !fw3 */
Chain zone_trusted_src_ACCEPT (1 references)
target prot opt source destination
ACCEPT all -- anywhere anywhere ctstate NEW,UNTRACKED /* !fw3 */
Chain zone_wan_dest_ACCEPT (4 references)
target prot opt source destination
DROP all -- anywhere anywhere ctstate INVALID /* !fw3: Prevent NAT leakage */
ACCEPT all -- anywhere anywhere /* !fw3 */
Chain zone_wan_dest_REJECT (1 references)
target prot opt source destination
reject all -- anywhere anywhere /* !fw3 */
Chain zone_wan_forward (1 references)
target prot opt source destination
forwarding_wan_rule all -- anywhere anywhere /* !fw3: Custom wan forwarding rule chain */
zone_lan_dest_ACCEPT esp -- anywhere anywhere /* !fw3: Allow-IPSec-ESP */
zone_lan_dest_ACCEPT udp -- anywhere anywhere udp dpt:isakmp /* !fw3: Allow-ISAKMP */
ACCEPT all -- anywhere anywhere ctstate DNAT /* !fw3: Accept port forwards */
zone_wan_dest_REJECT all -- anywhere anywhere /* !fw3 */
Chain zone_wan_input (1 references)
target prot opt source destination
input_wan_rule all -- anywhere anywhere /* !fw3: Custom wan input rule chain */
ACCEPT udp -- anywhere anywhere udp dpt:bootpc /* !fw3: Allow-DHCP-Renew */
ACCEPT icmp -- anywhere anywhere icmp echo-request /* !fw3: Allow-Ping */
ACCEPT igmp -- anywhere anywhere /* !fw3: Allow-IGMP */
ACCEPT all -- anywhere anywhere ctstate DNAT /* !fw3: Accept port redirections */
zone_wan_src_REJECT all -- anywhere anywhere /* !fw3 */
Chain zone_wan_output (1 references)
target prot opt source destination
output_wan_rule all -- anywhere anywhere /* !fw3: Custom wan output rule chain */
zone_wan_dest_ACCEPT all -- anywhere anywhere /* !fw3 */
Chain zone_wan_src_REJECT (1 references)
target prot opt source destination
reject all -- anywhere anywhere /* !fw3 */
But nothing seems to be dropped:
root@asus:/etc/config# iptables -nvL forwarding_rule
Chain forwarding_rule (1 references)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * * 0.0.0.0/0 192.168.1.10 limit: above 50kb/s burst 100kb mode dstip
Is it because I have multiple interface ? I have the right IP I am sure.
pavelgl
February 14, 2023, 10:10am
10
No, the rule is created at the beginning of the FORWARD chain (before any other rules) and works based on the IP address.
Try
iptables -I FORWARD ...
but it shouldn't make a difference.
Tried with a second device:
iptables -I FORWARD -d 192.168.1.10/32 -m hashlimit --hashlimit-above 50kb/sec --hashlimit-burst 100kb --hashlimit-name user10dl --hashlimit-mode dstip -j DROP
iptables -I FORWARD -d 192.168.1.222/32 -m hashlimit --hashlimit-above 50kb/sec --hashlimit-burst 100kb --hashlimit-name user22dl --hashlimit-mode dstip -j DROP
But no luck :
root@asus:/etc/config# iptables -nvL FORWARD
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * * 0.0.0.0/0 192.168.1.222 limit: above 50kb/s burst 100kb mode dstip
0 0 DROP all -- * * 0.0.0.0/0 192.168.1.10 limit: above 50kb/s burst 100kb mode dstip
110 22509 forwarding_rule all -- * * 0.0.0.0/0 0.0.0.0/0 /* !fw3: Custom forwarding rule chain */
38 4288 FLOWOFFLOAD all -- * * 0.0.0.0/0 0.0.0.0/0 /* !fw3: Traffic offloading */ ctstate RELATED,ESTABLISHED FLOWOFFLOAD
38 4288 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED /* !fw3 */
72 18221 zone_lan_forward all -- br-lan * 0.0.0.0/0 0.0.0.0/0 /* !fw3 */
0 0 zone_wan_forward all -- eth1 * 0.0.0.0/0 0.0.0.0/0 /* !fw3 */
0 0 zone_guestZone_forward all -- wlan0-2 * 0.0.0.0/0 0.0.0.0/0 /* !fw3 */
0 0 zone_trusted_forward all -- br-trusted * 0.0.0.0/0 0.0.0.0/0 /* !fw3 */
0 0 reject all -- * * 0.0.0.0/0 0.0.0.0/0 /* !fw3 */
Edit :
root@asus:/etc/config# iptables --version
iptables v1.8.7 (legacy)
pavelgl
February 14, 2023, 11:15am
12
Run these commands.
fw3 restart
iptables -I FORWARD -d 192.168.1.10/32 -j DROP
iptables -I FORWARD -s 192.168.1.10/32 -j DROP
iptables -I FORWARD -d 192.168.1.10/32 -m hashlimit --hashlimit-upto 50kb/sec --hashlimit-burst 100kb --hashlimit-name user10dl --hashlimit-mode dstip -j ACCEPT
iptables -I FORWARD -s 192.168.1.10/32 -m hashlimit --hashlimit-upto 50kb/sec --hashlimit-burst 100kb --hashlimit-name user10dl --hashlimit-mode srcip -j ACCEPT
If you still don't see any hits (and the IP address is correct), the traffic doesn't traverse the FORWARD chain (like if it's a dumbAP)
Working !!
Bandwidth limited !
root@asus:/etc/config# iptables -nvL FORWARD
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
2007 191K ACCEPT all -- * * 192.168.1.10 0.0.0.0/0 limit: up to 50kb/s burst 100kb mode srcip
1906 860K ACCEPT all -- * * 0.0.0.0/0 192.168.1.10 limit: up to 50kb/s burst 100kb mode dstip
0 0 DROP all -- * * 192.168.1.10 0.0.0.0/0
0 0 DROP all -- * * 0.0.0.0/0 192.168.1.10
492 81347 forwarding_rule all -- * * 0.0.0.0/0 0.0.0.0/0 /* !fw3: Custom forwarding rule chain */
164 23012 FLOWOFFLOAD all -- * * 0.0.0.0/0 0.0.0.0/0 /* !fw3: Traffic offloading */ ctstate RELATED,ESTABLISHED FLOWOFFLOAD
164 23012 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED /* !fw3 */
327 58252 zone_lan_forward all -- br-lan * 0.0.0.0/0 0.0.0.0/0 /* !fw3 */
0 0 zone_wan_forward all -- eth1 * 0.0.0.0/0 0.0.0.0/0 /* !fw3 */
1 83 zone_guestZone_forward all -- wlan0-2 * 0.0.0.0/0 0.0.0.0/0 /* !fw3 */
0 0 zone_trusted_forward all -- br-trusted * 0.0.0.0/0 0.0.0.0/0 /* !fw3 */
0 0 reject all -- * * 0.0.0.0/0 0.0.0.0/0 /* !fw3 */
Limiting ACCEPT works. But not dropping ?
What happening to the packet that are above the accept threshold ?? I don't see them in the Drop rule ....
pavelgl
February 14, 2023, 11:58am
14
The logical explanation - no such packets.
This would also explain why you don't see any dropped packets using the opposite approach.
Try lowering the limits even more.
BTW, I have made a copy/paste error.
Change --hashlimit-name
of the second rule (limiting uploads).
iptables -I FORWARD -s 192.168.1.10/32 -m hashlimit --hashlimit-upto 50kb/sec --hashlimit-burst 100kb --hashlimit-name user10upl --hashlimit-mode srcip -j ACCEPT
So I tried DROP with rate down to 1kb/s : not working. My phone just go full bandwidth.
Play a bit around and found that when using the approach ACCEPT with limited rate, the DROP rule is not needed. The below setup will limit the bandwidth:
root@asus:~# iptables -nvL FORWARD
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
2056 893K ACCEPT all -- * * 0.0.0.0/0 192.168.1.10 limit: up to 600kb/s burst 1mb mode dstip
2819 250K ACCEPT all -- * * 192.168.1.10 0.0.0.0/0 limit: up to 600kb/s burst 1mb mode srcip
603 99569 forwarding_rule all -- * * 0.0.0.0/0 0.0.0.0/0 /* !fw3: Custom forwarding rule chain */
329 52907 FLOWOFFLOAD all -- * * 0.0.0.0/0 0.0.0.0/0 /* !fw3: Traffic offloading */ ctstate RELATED,ESTABLISHED FLOWOFFLOAD
329 52907 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED /* !fw3 */
270 46451 zone_lan_forward all -- br-lan * 0.0.0.0/0 0.0.0.0/0 /* !fw3 */
0 0 zone_wan_forward all -- eth1 * 0.0.0.0/0 0.0.0.0/0 /* !fw3 */
4 211 zone_guestZone_forward all -- wlan0-2 * 0.0.0.0/0 0.0.0.0/0 /* !fw3 */
0 0 zone_trusted_forward all -- br-trusted * 0.0.0.0/0 0.0.0.0/0 /* !fw3 */
0 0 reject all -- * * 0.0.0.0/0 0.0.0.0/0 /* !fw3 */
So only ACCEPT matter. Which kind of explain why setting a DROP rate do not have any effect.
But why the behavior is reversed compare to @pavelgl ??
And also both -s
and -d
ACCEPT rule is needed. If it's only one of them, the bandwidth is not limited.