IPTABLES and TC for limiting bandwidth per linux user
Linux - ServerThis forum is for the discussion of Linux Software used in a server related context.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
IPTABLES and TC for limiting bandwidth per linux user
I discovered that i can use TC and IPTABLES for limiting bandwidth on SSH per linux user.
First i added the command:
Quote:
iptables -t mangle -A OUTPUT -p tcp -m owner --uid-owner test -j MARK --set-mark 1
to mark packet.
Then i used this script to limit bandwidth:
Quote:
#!/bin/bash
#
# tc uses the following units when passed as a parameter.
# kbps: Kilobytes per second
# mbps: Megabytes per second
# kbit: Kilobits per second
# mbit: Megabits per second
# bps: Bytes per second
# Amounts of data can be specified in:
# kb or k: Kilobytes
# mb or m: Megabytes
# mbit: Megabits
# kbit: Kilobits
# To get the byte figure from bits, divide the number by 8 bit
#
#
# Name of the traffic control command.
TC=/sbin/tc
# The network interface we're planning on limiting bandwidth.
IF=eth0 # Interface
# Download limit (in mega bits)
DNLD=1mbit # DOWNLOAD Limit
# Upload limit (in mega bits)
UPLD=1mbit # UPLOAD Limit
# IP address of the machine we are controlling
IP=216.3.128.12 # Host IP
# Filter options for limiting the intended interface.
U32="$TC filter add dev $IF protocol ip parent 1:0 prio 1 u32"
start() {
# We'll use Hierarchical Token Bucket (HTB) to shape bandwidth.
# For detailed configuration options, please consult Linux man
# page.
$TC qdisc add dev $IF root handle 1: htb default 30
$TC class add dev $IF parent 1: classid 1:1 htb rate $DNLD
$TC class add dev $IF parent 1: classid 1:2 htb rate $UPLD
$U32 match ip dst $IP/32 flowid 1:1
$U32 match ip src $IP/32 flowid 1:2
# The first line creates the root qdisc, and the next two lines
# create two child qdisc that are to be used to shape download
# and upload bandwidth.
#
# The 4th and 5th line creates the filter to match the interface.
# The 'dst' IP address is used to limit download speed, and the
# 'src' IP address is used to limit upload speed.
}
stop() {
# Stop the bandwidth shaping.
$TC qdisc del dev $IF root
}
restart() {
# Self-explanatory.
stop
sleep 1
start
}
show() {
# Display status of traffic control status.
$TC -s qdisc ls dev $IF
But no luck... The speed is unlimited.
I tried to use this script:
Quote:
iptables -t mangle -A OUTPUT -p tcp -m owner --uid-owner test -j REJECT
to see if it rejects the packets created by "test" user, and it works. It rejects all the packets. Now the problem is what i have done wrong in the part of bandwidth limiting? I didn't marked correctly the packets, or my script is wrong? Please help me!
There can be two possiblities
1. htb algorithm not get implemented on interface or
2. htb implemented successfully but not working according to aspectation
vishesh: I was writing while you posted - but mine is a little different
alexxxutz:
You should probably take the POSTROUTING chain instead of OUTPUT (see: man iptables)
Are you sure that the -m owner --uid-owner is really what you want?
from man iptables:
Quote:
--uid-owner userid[-userid]
Matches if the packet socket's file structure (if it has one) is owned by the given user. You may also specify a numerical UID, or an UID range.
So: it is not really about a username as such.
You want to control ssh? Then you can use its port (22) in the match, instead of the "-m owner" match.
Or use "-m layer7" to match for ssh traffic...
generally, if you want to use iptables and its marks for filtering:
Code:
# you create a new rule in the mangle table
$PRIO="123" #some number
IPT="$IPTABLES -t mangle"
$IPT -N myfilter
# you add it to the POSTROUTING chain
$IPT -A POSTROUTING -j myfilter
# if conntrack is used - restore a mark and allow the packets, which already have been marked, through - no need to check again
$IPT -A myfilter -p tcp -j CONNMARK --restore-mark
$IPT -A myfilter -m mark --mark $PRIO -j ACCEPT
# you add to it your matching rule
$IPT -A myfilter -p tcp -m owner --uid-owner test -j MARK --set-mark $PRIO
# you conntrack it optionally, so not every packet has to be rematched
$IPT -A myfilter -j CONNMARK --save-mark
# you use that mark in a tc filter rule
$TC qdisc add dev $IF root handle 1: htb default 30
$TC class add dev $IF parent 1: classid 1:1 htb rate $your_rate
# add an SFQ qdisc to the end - to which you then attach the actual filter
$TC qdisc add dev $IF parent 1:1 sfq perturb 10
$TC filter add dev $IF parent 1:1 prio 1 handle $PRIO fw flowid 1:1
It is not a working example - but shows the concept.
ok. now all seems to be ok, but now the speed still unlimited on any user i set... so the mark don't works... i have a tunneling service via ssh (port forwarding) and i want to limit the speed for each client. for example 1 euro = 64kB/s 2 euro = 128kB/s. so i want to make 2 groups. one for 1 euro packet speed and other for the 2 euro packet. for that reason i need to use owner
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.