LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Server
User Name
Password
Linux - Server This forum is for the discussion of Linux Software used in a server related context.

Notices


Reply
  Search this Thread
Old 08-01-2009, 10:18 AM   #1
alexxxutz
LQ Newbie
 
Registered: Mar 2009
Posts: 19

Rep: Reputation: 0
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

}

case "$1" in

start)

echo -n "Starting bandwidth shaping: "
start
echo "done"
;;

stop)

echo -n "Stopping bandwidth shaping: "
stop
echo "done"
;;

restart)

echo -n "Restarting bandwidth shaping: "
restart
echo "done"
;;

show)

echo "Bandwidth shaping status for $IF:"
show
echo ""
;;

*)

pwd=$(pwd)
echo "Usage: tc.bash {start|stop|restart|show}"
;;

esac

exit 0

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!
 
Old 08-01-2009, 10:51 AM   #2
vishesh
Member
 
Registered: Feb 2008
Distribution: Fedora,RHEL,Ubuntu
Posts: 661

Rep: Reputation: 66
Does htb implemented on ethernet interface
I mean ouput of
#ip a

I implemented htb for internet bandwidth sharing and it worked perfectly

thanks
 
Old 08-01-2009, 11:27 AM   #3
alexxxutz
LQ Newbie
 
Registered: Mar 2009
Posts: 19

Original Poster
Rep: Reputation: 0
and how can i implement it? i have done just the steps i described
 
Old 08-01-2009, 12:04 PM   #4
vishesh
Member
 
Registered: Feb 2008
Distribution: Fedora,RHEL,Ubuntu
Posts: 661

Rep: Reputation: 66
There can be two possiblities
1. htb algorithm not get implemented on interface or
2. htb implemented successfully but not working according to aspectation

thats why i asked you about output of

#ip a


Thanks
 
Old 08-01-2009, 01:06 PM   #5
alexxxutz
LQ Newbie
 
Registered: Mar 2009
Posts: 19

Original Poster
Rep: Reputation: 0
Here is the #ip a output
Quote:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:50:56:b5:3d:4b brd ff:ff:ff:ff:ff:ff
inet 94.24.x.x/24 brd 94.24.x.255 scope global eth0
inet 94.24.x.y/24 brd 94.24.x.255 scope global secondary eth0
inet 94.24.x.z/24 brd 94.24.x.255 scope global secondary eth0
inet6 fe80::250:56ff:feb5:3d4b/64 scope link
valid_lft forever preferred_lft forever
3: sit0: <NOARP> mtu 1480 qdisc noop
link/sit 0.0.0.0 brd 0.0.0.0
x,y,z are the last 2 blocks of my ip, but i have not written them here for security reasons

Last edited by alexxxutz; 08-01-2009 at 01:07 PM. Reason: forgot to specify something
 
Old 08-02-2009, 08:26 AM   #6
alexxxutz
LQ Newbie
 
Registered: Mar 2009
Posts: 19

Original Poster
Rep: Reputation: 0
so the htb is implemented or not? what i must do to enable it?
 
Old 08-03-2009, 03:20 AM   #7
alexxxutz
LQ Newbie
 
Registered: Mar 2009
Posts: 19

Original Poster
Rep: Reputation: 0
well?
 
Old 08-03-2009, 05:03 AM   #8
vishesh
Member
 
Registered: Feb 2008
Distribution: Fedora,RHEL,Ubuntu
Posts: 661

Rep: Reputation: 66
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000

So its clear that pfifo_fast is working over your eth0 interface not htb.

Your program is not working properly .

Is there any error message appear when try to execute your script ?
#./tc.bash start

thanks
 
Old 08-04-2009, 06:33 AM   #9
alexxxutz
LQ Newbie
 
Registered: Mar 2009
Posts: 19

Original Poster
Rep: Reputation: 0
no...

Quote:
[root@tolgyi-alexandru ~]# ./tc.bash start
Starting bandwidth shaping: done
[root@tolgyi-alexandru ~]#
 
Old 08-04-2009, 06:45 AM   #10
alexxxutz
LQ Newbie
 
Registered: Mar 2009
Posts: 19

Original Poster
Rep: Reputation: 0
now it's working, but it limits the global speed on the server. how to limit only the rule marked by:
Quote:
iptables -t mangle -A OUTPUT -p tcp -m owner --uid-owner test -j MARK --set-mark 1
 
Old 08-04-2009, 07:35 AM   #11
vishesh
Member
 
Registered: Feb 2008
Distribution: Fedora,RHEL,Ubuntu
Posts: 661

Rep: Reputation: 66
according to your script you are limiting data coming or going from ip 216.3.128.12. There is no criteria for user test.

replace following
U32="$TC filter add dev $IF protocol ip parent 1:0 prio 1 u32"
and
start()
{
...
$U32 match ip dst $IP/32 flowid 1:1
$U32 match ip src $IP/32 flowid 1:2
}
with
start()
{
$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 filter add dev $IF protocol ip parent 1:0 prio 1 handle 1 fw flowid 1:1
}


I think that may work to control download speed and same logic to control upload speed

Thanks
www.linuxinterviews.blogspot.com might also help you.

Last edited by vishesh; 08-04-2009 at 08:07 AM.
 
Old 08-04-2009, 08:28 AM   #12
jomen
Senior Member
 
Registered: May 2004
Location: Leipzig/Germany
Distribution: Arch
Posts: 1,687

Rep: Reputation: 55
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.
 
Old 08-04-2009, 08:41 AM   #13
alexxxutz
LQ Newbie
 
Registered: Mar 2009
Posts: 19

Original Poster
Rep: Reputation: 0
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

Last edited by alexxxutz; 08-04-2009 at 08:53 AM.
 
Old 08-04-2009, 08:55 AM   #14
jomen
Senior Member
 
Registered: May 2004
Location: Leipzig/Germany
Distribution: Arch
Posts: 1,687

Rep: Reputation: 55
...but the "owner" may not quite work the way you think it does... [this line added/edited]

if you give me 20 I'll write the script
Please look at vishesh's post again - it has been edited with regard to the mark (last line)

Last edited by jomen; 08-04-2009 at 08:58 AM.
 
Old 07-04-2010, 03:24 PM   #15
rakib_sarder
LQ Newbie
 
Registered: Jul 2010
Posts: 1

Rep: Reputation: 0
but mine does not work ........
whenever i run the command
#bash tc.bash

it shows......

#'c.bash: line 23: synax error near unexpected token '{
'c.bash: line 23: 'start()

please help me......
 
  


Reply

Tags
bandwidth, iptables, limiting, linux, tc, user



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
"iptables tc" limiting bandwidth for specific port maxut Linux - Enterprise 1 12-16-2015 09:43 PM
Limiting bandwidth per user v8hadas Linux - Server 1 01-29-2008 06:07 AM
Bandwidth limiting using iptables kripz Linux - Networking 3 12-04-2007 08:11 PM
Using iptables for something very specific - bandwidth based on user/day/time koobi Linux - Networking 3 10-05-2007 02:29 AM
Limiting bandwidth on a linux router <Ol>Origy Linux - Networking 6 01-26-2005 04:06 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Server

All times are GMT -5. The time now is 03:20 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration