[Techtalk] My son is a network hog -- limiting usage on one computer (fedora 15)?
Chris Wilson
chris+linuxchix at aptivate.org
Sat Dec 3 18:40:12 UTC 2011
Hi Gwen,
On Sun, 4 Dec 2011, Gwen Morse wrote:
> I do *not* want to monitor the specifics of what he's doing. He's 19 and
> can do what he likes (within legal reason). I want all of us to stop
> being throttled because one person in the house is a network pig. I've
> talked to my son repeatedly but he still keeps going over the limit.
>
> What I'd like is to know what I can use to set a nice round limit (say 1
> gig a month) and have it monitor his usage and then throttle him on his
> laptop if he goes over that limit. After a month it would reset and
> start all over again.
>
> Many/most ISPs use linux (or unix) for their servers and I was wondering
> what package I could use to do something like this?
>
> I've looked at some traffic shaping software but I'm not sure that's
> what I want. I don't want to prioritize certain traffic. I just want to
> (almost) cut him off once he goes over a predetermined limit.
I use pmacct to log network traffic by local source address into a MySQL
database, and a heavily customised version of the WonderShaper QoS script
which executes a SQL query to calculate the number of bytes used within a
given time frame, and if any user exceeds that limit, to completely block
their Internet access. It's quite easy to change this from a block to
placing all their traffic in a heavily throttled QoS class. It also
prioritises VOIP and interactive SSH over web traffic and backups, to
allow them to remain usable.
Script and pmacct config attached.
Cheers, Chris.
--
Aptivate | http://www.aptivate.org | Phone: +44 1223 760887
The Humanitarian Centre, Fenner's, Gresham Road, Cambridge CB1 2ES
Aptivate is a not-for-profit company registered in England and Wales
with company number 04980791.
-------------- next part --------------
!
! pmacctd configuration example
!
! Did you know CONFIG-KEYS contains the detailed list of all configuration keys
! supported by 'nfacctd' and 'pmacctd' ?
!
! debug: true
!
interface: eth0
daemonize: true
plugins: mysql[inbound], mysql[outbound], mysql[summary]
syslog: daemon
pcap_filter: not (src and dst net 192.168.0.0/24)
aggregate[inbound]: dst_host, src_mac, dst_mac
aggregate_filter[inbound]: dst net 192.168.0.0/24
aggregate[outbound]: src_host, src_mac, dst_mac
aggregate_filter[outbound]: src net 192.168.0.0/24
aggregate[summary]: sum_net
sql_db: pmacct
sql_table: acct_v7
sql_table[summary]: acct_v7_summary
sql_table_version: 7
sql_passwd: XXXXXXXX
sql_user: pmacct
sql_refresh_time: 60
! sql_optimize_clauses: true
sql_history: 1m
sql_history_roundoff: m
! sql_preprocess: qnum=1000, minp=5
sql_dont_try_update: true
networks_file: /etc/pmacctd.networks
! ports_file: ./ports.example
! sampling_rate: 10
! sql_trigger_time: 1h
! sql_trigger_exec: /home/paolo/codes/hello.sh
-------------- next part --------------
#!/bin/bash
# Wonder Shaper
# please read the README before filling out these values
#
# Set the following values to somewhat less than your actual download
# and uplink speed. In kilobits. Also set the device that is to be shaped.
DOWNLINK=120 # known good
# DOWNLINK=150
# DOWNLINK=200
# DOWNLINK=250 # ok when throttled
# DOWNLINK=300 # not ok when throttled
# DOWNLINK=350
# DOWNLINK=400 # known good
# DOWNLINK=600 # known OK most of the time, not when throttled
# DOWNLINK=800
# DOWNLINK=1200 # known OK most of the time
# DOWNLINK=1400 # known OK most of the time
# DOWNLINK=1500 # known OK most of the time
# DOWNLINK=900 # sopmetimes slow
# DOWNLINK=1000 # known slow (sometimes)
# DOWNLINK=1500
# DOWNLINK=1800
#DOWNLINK=2000 # known slow when throttled, otherwise ok
DOWNLINK=9000 # known slow when throttled, otherwise ok
DOWNLINK=18000 # maybe OK after upgrade
# UPLINK=80 # known good
# UPLINK=100
UPLINK=100 # seems to be OK even when throttled
UPLINK=110
# UPLINK=130 # seems to be OK, not when throttled
# UPLINK=140
# UPLINK=200
#UPLINK=250 # seems to be OK most of the time, not when throttled
UPLINK=300 # known slow with lots of high priority traffic (was OK for ages)
UPLINK=600 # maybe OK after upgrade
#UPLINK=350
#UPLINK=400
#UPLINK=500 # seems ok recently, when not throttled
# UPLINK=1000
UDEV=eth1
# Parameters for second network interface
DDEV=eth0
DOWNLINK2=$[$DOWNLINK*8/10]
UPLINK2=$[$UPLINK*9/10]
bulkrate=$[$DOWNLINK/2]
# in case bulk downloads interfere with skype:
# bulkrate=500
maxrate=$DOWNLINK
hour=`date '+%H'`
if [ $hour -ge 10 -a $hour -lt 15 ]; then
# 2400 MB / 5 hours = 480 MB/hour = 8 MB/min = 64 Mb/min ~ 1000 kbps
# 6000 MB / 5 hours = 1200 MB/hour = 20 MB/min = 2666 kbps
# bulkrate=800
# maxrate=1000
bulkrate=2000
# maxrate=2600
elif [ $hour -ge 15 -a $hour -lt 21 ]; then
# 1200 MB / 5 hours = 240 MB/hour = 4 MB/min = 32 Mb/min ~ 500 kbps
# 3000 MB / 5 hours = 600 MB/hour = 10 MB/min = 1333 kbps
# bulkrate=350
# maxrate=450
bulkrate=1000
# maxrate=1300
fi
TC=/sbin/tc
if [ "$1" = "status" ]
then
echo "Uplink ($UDEV):"
$TC -s qdisc ls dev $UDEV
$TC -s class ls dev $UDEV
echo
echo "Downlink ($DDEV):"
$TC -s qdisc ls dev $DDEV
$TC -s class ls dev $DDEV
exit
fi
LOCKFILE=/var/run/wshaper.pid
if [ -r "$LOCKFILE" ]; then
OTHERPID=`cat $LOCKFILE`
if [ -n "$OTHERPID" -a -d "/proc/$OTHERPID" ]; then
echo "Another wshaper is already running with pid $OTHERPID"
exit 2
fi
echo "Removing stale lockfile $LOCKFILE for $OTHERPID"
rm $LOCKFILE
fi
echo $$ > $LOCKFILE
# clean existing down- and uplink qdiscs, hide errors
$TC qdisc del dev $UDEV root 2> /dev/null > /dev/null
$TC qdisc del dev $UDEV ingress 2> /dev/null > /dev/null
$TC qdisc del dev $DDEV root 2> /dev/null > /dev/null
$TC qdisc del dev $DDEV ingress 2> /dev/null > /dev/null
iptables='/sbin/iptables'
old_blocked=`mktemp /tmp/blocked.XXXXXX`
$iptables -t filter -L blocked > $old_blocked
$iptables -t nat -F blocked
$iptables -t filter -F blocked
$iptables -t filter -F throttle
if [ "$1" = "stop" ]
then
rm $LOCKFILE
exit
fi
# blocking
echo '
SELECT ip_src, sum(bytes) as b, "uploaded"
FROM acct_v7
WHERE stamp_inserted > CONCAT(LEFT(NOW(), 10), " 15:00")
AND stamp_inserted < CONCAT(LEFT(NOW(), 10), " 20:00")
AND hour(now()) < 20
AND ip_src <> "0.0.0.0"
AND ip_src <> "192.168.0.1"
AND ip_dst <> "192.168.0.1"
AND bytes < 100000000
GROUP BY ip_src
HAVING b > 1000000000;
SELECT ip_dst, sum(bytes) as b, "downloaded 1000-1500"
FROM acct_v7
WHERE stamp_inserted > CONCAT(LEFT(NOW(), 10), " 10:00")
AND stamp_inserted < CONCAT(LEFT(NOW(), 10), " 15:00")
AND hour(now()) < 15
AND ip_dst <> "0.0.0.0"
AND ip_dst <> "192.168.0.1"
AND ip_src <> "192.168.0.1"
AND bytes < 100000000
GROUP BY ip_dst
HAVING b > 4000000000;
SELECT ip_dst, sum(bytes) as b, "downloaded 1600-2100"
FROM acct_v7
WHERE stamp_inserted > CONCAT(LEFT(NOW(), 10), " 16:00")
AND stamp_inserted < CONCAT(LEFT(NOW(), 10), " 21:00")
AND hour(now()) < 21
AND ip_dst <> "0.0.0.0"
AND ip_dst <> "192.168.0.1"
AND ip_dst <> "192.168.0.113"
AND ip_src <> "192.168.0.1"
AND bytes < 100000000
GROUP BY ip_dst
HAVING b > 1600000000;
' | mysql pmacct -u root -N | while read ip bytes direction; do
blocking="$blocking : blocking $ip for $bytes bytes $direction"
$iptables -A blocked -s $ip -d 192.168.0.1 -p tcp \
-m multiport --dports 53,81 -j ACCEPT
$iptables -A blocked -s $ip -d 192.168.0.1 -p udp \
--dport 53 -j ACCEPT
$iptables -A blocked -s $ip -j REJECT
$iptables -A blocked -d $ip -s 192.168.0.1 -p tcp \
-m multiport --sports 53,81 -j ACCEPT
$iptables -A blocked -d $ip -s 192.168.0.1 -p udp \
--sport 53 -j ACCEPT
$iptables -A blocked -d $ip -j REJECT
$iptables -t nat -A blocked -s $ip -p tcp --dport 80 \
-j DNAT --to-dest 192.168.0.1:81
done
new_blocked=`mktemp /tmp/blocked.XXXXXX`
$iptables -t filter -L blocked > $new_blocked
if ! diff -u $old_blocked $new_blocked; then
echo "Blocking changed: $blocking"
fi
rm $old_blocked $new_blocked
###### uplink
# install root HTB, point default traffic to 1:20:
$TC qdisc add dev $UDEV root handle 1: htb default 20
# shape everything at $UPLINK speed - this prevents huge queues in your
# DSL modem which destroy latency:
$TC class add dev $UDEV parent 1: classid 1:1 htb \
rate ${UPLINK}kbit burst 16k \
quantum 1500
# high prio class 1:10:
$TC class add dev $UDEV parent 1:1 classid 1:10 htb rate \
$[${UPLINK}/2]kbit ceil ${UPLINK}kbit burst 8k \
prio 1 quantum 1500
# bulk & default class 1:20 - gets slightly less traffic,
# and a lower priority:
$TC class add dev $UDEV parent 1:1 classid 1:20 htb \
rate $[${UPLINK}/4]kbit ceil $[${UPLINK}/2]kbit \
burst 6k prio 2 quantum 1500
# backups
$TC class add dev $UDEV parent 1:1 classid 1:30 htb \
rate 50kbit ceil $[(${UPLINK}*2)/4]kbit burst 6k prio 3 quantum 1500
# everything else
$TC class add dev $UDEV parent 1:1 classid 1:40 htb \
rate 50kbit ceil $[${UPLINK}/2]kbit burst 6k prio 3 quantum 1500
# all get Stochastic Fairness:
$TC qdisc add dev $UDEV parent 1:10 handle 10: sfq perturb 10
$TC qdisc add dev $UDEV parent 1:20 handle 20: sfq perturb 10
$TC qdisc add dev $UDEV parent 1:30 handle 30: sfq perturb 10
$TC qdisc add dev $UDEV parent 1:40 handle 40: sfq perturb 10
# TOS Minimum Delay (ssh, NOT scp) in 1:10:
# iptables='/usr/local/sbin/iptables'
$iptables -t mangle -F
mangle() {
$iptables -t mangle -A POSTROUTING $1 -j CLASSIFY --set-class 1:$2
# $iptables -t mangle -A POSTROUTING $1 -j MARK --set-mark 0x$2
}
#$TC filter add dev $UDEV parent 1:0 protocol ip prio 10 u32 \
# match ip tos 0x10 0xff flowid 1:10
# default 1:40
mangle "-o $UDEV" 40
# mangle "-o $UDEV -m tos --tos 0x08" 30
# voip
mangle "-o $UDEV -p udp -m length --length 0:250" 10 # voip
mangle "-o $UDEV -p tcp -m length --length 0:100" 20 # acks
mangle "-o $UDEV -p tcp --dport 80" 20
mangle "-o $UDEV -p tcp --sport 80" 20
mangle "-o $UDEV -p tcp --dport 443" 20
mangle "-o $UDEV -p tcp --sport 3000" 20
mangle "-o $UDEV -p tcp --sport 4949" 20 # munin-node
mangle "-o $UDEV -p tcp --dport 5666" 20 # nrpe
mangle "-o $UDEV -p tcp --dport imaps" 10
mangle "-o $UDEV -p tcp --dport imap" 10
mangle "-o $UDEV -p tcp --dport smtp" 10
mangle "-o $UDEV -m tos --tos 0x10" 10 # interactive
mangle "-o $UDEV -m tos --tos 0x0 -p tcp --dport 48001" 10 # unknown
mangle "-o $UDEV -m tos --tos 0x8 -p tcp --dport 48001" 30 # bulk
mangle "-o $UDEV -m tos --tos 0x0 -p tcp --sport 48001" 10
mangle "-o $UDEV -m tos --tos 0x0 -p tcp --sport 8080" 10
mangle "-o $UDEV -m tos --tos 0x0 -p tcp --dport 22" 10
mangle "-o $UDEV -p tcp --dport 5902" 10 # vnc
mangle "-o $UDEV -p tcp --dport 5903" 10 # vnc
mangle "-o $UDEV -p tcp --dport 3389" 10 # rdp
mangle "-o $UDEV -p icmp" 10
mangle "-o $UDEV -d 72.21.192.0/19" 30 # backups to Amazon S3
filter() {
$iptables -A throttle -i $UDEV "$@"
# $iptables -t mangle -A POSTROUTING $1 -j MARK --set-mark 0x$2
}
filter -p tcp --sport 80 -j throttle_hi
filter -p tcp --sport 443 -j throttle_hi
filter -p tcp --sport 993 -j throttle_hi
filter -p tcp --sport 48001 -m tos --tos 0x10 -j throttle_hi
filter -p tcp --dport 48001 -m tos --tos 0x10 -j throttle_hi
filter -p tcp -j throttle_lo
#$TC filter add dev $UDEV parent 1:0 protocol ip prio 11 u32 \
# match ip tos 0x08 0xff flowid 1:30
# ICMP (ip protocol 1) in the interactive class 1:10 so we
# can do measurements & impress our friends:
#$TC filter add dev $UDEV parent 1:0 protocol ip prio 10 u32 \
# match ip protocol 1 0xff flowid 1:10
#mangle "-o $UDEV -p icmp" 10
# To speed up downloads while an upload is going on, put ACK packets in
# the interactive class:
#$TC filter add dev $UDEV parent 1: protocol ip prio 10 u32 \
# match ip protocol 6 0xff \
# match u8 0x05 0x0f at 0 \
# match u16 0x0000 0xffc0 at 2 \
# match u8 0x10 0xff at 33 \
# flowid 1:10
# mangle "-o $UDEV -p tcp --tcp-flags SYN,PSH,ACK ACK" 10
#mangle "-o $UDEV -m length --length 0:200" 10
#mangle "-o $UDEV -m length --length 200:1600" 30
#mangle "-o $UDEV -p tcp --dport 48001" 20
# mangle "-o $UDEV -p icmp" 10
# rest is 'non-interactive' ie 'bulk' and ends up in 1:20 by default
# some traffic however suffers a worse fate
#for port in $NOPRIOPORTDST
#do
# #$TC filter add dev $UDEV parent 1: protocol ip prio 14 u32 \
# # match ip dport $port 0xffff flowid 1:30
# mangle "-o $UDEV -p tcp --dport $port" 30
# mangle "-o $UDEV -p udp --dport $port" 30
#done
#
#for port in $NOPRIOPORTSRC
#do
# #$TC filter add dev $UDEV parent 1: protocol ip prio 15 u32 \
# # match ip sport $a 0xffff flowid 1:30
# mangle "-o $UDEV -p tcp --sport $port" 30
# mangle "-o $UDEV -p udp --sport $port" 30
#done
#
#for host in $NOPRIOHOSTSRC
#do
# #$TC filter add dev $UDEV parent 1: protocol ip prio 16 u32 \
# # match ip src $a flowid 30
# mangle "-o $UDEV -s $host" 30
#done
#
#for host in $NOPRIOHOSTDST
#do
# #$TC filter add dev $UDEV parent 1: protocol ip prio 17 u32 \
# # match ip dst $a flowid 30
# mangle "-o $UDEV -d $host" 30
#done
#
## rest is 'non-interactive' ie 'bulk' and ends up in 1:20
#
##$TC filter add dev $UDEV parent 1: protocol ip prio 18 u32 \
# match ip dst 0.0.0.0/0 flowid 1:20
#$iptables -t mangle -A POSTROUTING -p tcp -m mark --mark 0x10 \
# -m limit --limit 1/s -j LOG
#$iptables -t mangle -A POSTROUTING -m mark --mark 0x10 \
# -j TOS --set-tos 0x10
#$iptables -t mangle -A POSTROUTING -m mark --mark 0x20 \
# -j TOS --set-tos 0x08
#$iptables -t mangle -A POSTROUTING -m mark --mark 0x30 \
# -j TOS --set-tos 0x08
########## downlink to us #############
# slow downloads down to somewhat less than the real speed to prevent
# queuing at our ISP. Tune to see how high you can set it.
# ISPs tend to have *huge* queues to make sure big downloads are fast
#
# attach ingress policer:
$TC qdisc add dev $UDEV ingress handle ffff:
# filter *everything* to it (0.0.0.0/0), drop everything that's
# coming in too fast:
$TC filter add dev $UDEV parent ffff: protocol ip prio 50 u32 match ip src \
0.0.0.0/0 police rate ${maxrate}kbit burst 10k drop flowid :1
###### downlink to computers behind us
if true; then
# install root HTB, point default traffic to 1:130 (bulk)
$TC qdisc add dev $DDEV root handle 1: htb default 130
# shape everything at $DOWNLINK2 speed - this prevents huge queues in your
# DSL modem which destroy latency:
$TC class add dev $DDEV parent 1: classid 1:1 htb rate 100mbit \
ceil 100mbit burst 6k quantum 1500
$TC class add dev $DDEV parent 1:1 classid 1:10 htb rate ${DOWNLINK2}kbit \
ceil ${DOWNLINK2}kbit burst 6k quantum 1500
$TC class add dev $DDEV parent 1:1 classid 1:11 htb rate 100mbit \
ceil 100mbit burst 6k quantum 1500
# high prio class 1:10:
$TC class add dev $DDEV parent 1:10 classid 1:110 htb rate $[${DOWNLINK2}/4]kbit \
ceil ${DOWNLINK2}kbit burst 6k prio 1 quantum 1500
# bulk & default class 1:20 - gets slightly less traffic,
# and a lower priority:
$TC class add dev $DDEV parent 1:10 classid 1:120 htb \
rate 8bps ceil ${DOWNLINK2}kbit burst 2k prio 2 quantum 1500
$TC class add dev $DDEV parent 1:10 classid 1:130 htb \
rate 8bps ceil ${bulkrate}kbit burst 2k prio 3 quantum 1500
$TC class add dev $DDEV parent 1:10 classid 1:140 htb \
rate 8bps ceil $[${bulkrate}/2]kbit burst 2k prio 3 quantum 1500
# all get Stochastic Fairness:
$TC qdisc add dev $DDEV parent 1:110 handle 10: sfq perturb 10
$TC qdisc add dev $DDEV parent 1:120 handle 20: sfq perturb 10
$TC qdisc add dev $DDEV parent 1:130 handle 30: sfq perturb 10
$TC qdisc add dev $DDEV parent 1:140 handle 40: sfq perturb 10
# default is bulk (1:30)
mangle "-o $DDEV" 130
# TOS Minimum Delay (ssh, NOT scp) in 1:110:
mangle "-o $DDEV -m tos --tos 0x10" 110 # interactive
mangle "-o $DDEV -m tos --tos 0x08" 130 # bulk
mangle "-o $DDEV -p tcp --sport 80" 120
mangle "-o $DDEV -p tcp --sport 443" 120
mangle "-o $DDEV -p tcp --sport 5903" 110 # vnc
mangle "-o $DDEV -p tcp --sport imaps" 120
mangle "-o $DDEV -p tcp --sport imap" 120
mangle "-o $DDEV -p tcp --sport smtp" 120
mangle "-o $DDEV -p udp -m length --length 0:100" 110 # voip
mangle "-o $DDEV -p tcp -m length --length 0:100" 110 # TCP acks
mangle "-o $DDEV -s 192.168.0.1" 11 # local
# eric bulk
mangle "-o $DDEV -d 192.168.0.175" 140 # eric
mangle "-o $DDEV -d 192.168.0.115" 140 # roberto
# $TC filter add dev $DDEV parent 1:0 protocol ip prio 10 u32 \
# match ip tos 0x10 0xff flowid 1:10
# ICMP (ip protocol 1) in the interactive class 1:10 so we
# can do measurements & impress our friends:
# $TC filter add dev $DDEV parent 1:0 protocol ip prio 10 u32 \
# match ip protocol 1 0xff flowid 1:10
# To speed up downloads while an upload is going on, put ACK packets in
# the interactive class:
#$TC filter add dev $DDEV parent 1: protocol ip prio 10 u32 \
# match ip protocol 6 0xff \
# match u8 0x05 0x0f at 0 \
# match u16 0x0000 0xffc0 at 2 \
# match u8 0x10 0xff at 33 \
# flowid 1:10
# rest is 'non-interactive' ie 'bulk' and ends up in 1:20
# some traffic however suffers a worse fate
#for a in $NOPRIOPORTDST
#do
# $TC filter add dev $DDEV parent 1: protocol ip prio 14 u32 \
# match ip dport $a 0xffff flowid 1:30
#done
#
#for a in $NOPRIOPORTSRC
#do
# $TC filter add dev $DDEV parent 1: protocol ip prio 15 u32 \
# match ip sport $a 0xffff flowid 1:30
#done
#
#for a in $NOPRIOHOSTSRC
#do
# $TC filter add dev $DDEV parent 1: protocol ip prio 16 u32 \
# match ip src $a flowid 1:30
#done
#
#for a in $NOPRIOHOSTDST
#do
# $TC filter add dev $DDEV parent 1: protocol ip prio 17 u32 \
# match ip dst $a flowid 1:30
#done
#
## rest is 'non-interactive' ie 'bulk' and ends up in 1:20
#
#$TC filter add dev $DDEV parent 1: protocol ip prio 18 u32 \
# match ip dst 0.0.0.0/0 flowid 1:20
#
fi
rm $LOCKFILE
More information about the Techtalk
mailing list