# qos solution

## void4ever

Good afternoon,

I'm looking for a good qos solution to setup on a gentoo box that will act as a bridge to a pix 501 to do the firewalling.

I want to setup certain address's and blocks of addresses to be qos'ed while leaving others alone to take whatever they can pull. I was hoping for a few suggestions on scripts, or software you all have tried and liked.

I currently have the gentoo box setup as a bridge and it's passing traffic just fine, just need to qos whats passing through eth1 now.

Void4ever

----------

## alex.blackbit

try net-firewall/shorewall

----------

## eulogious

Hello,

I have just recently been trying to get qos setup also on my linux router at home, and I have come up with a good solution.  First there is a how to that will point you in the right direction for learning about how to do packet shaping. http://gentoo-wiki.com/HOWTO_Packet_Shaping.  Basically you will need iptables, tc and l7protocols.  This will mark the packets that you want, and then setup ques, and then place the packets into the ques.  I have improved on the script that is in the tutorial, and it works great for my network.  My script also will be able to prioritize based off of IP address, or even a whole subnet.  You will have to modify this to fit your needs.  I can tell you this probably won't work with your setup.  I would highly recommend reading up iptables, and htb (for ques), and l7proto before really diving into this.  It can get real difficult real quick.  Here's my script

edit:  This was actually created by Jomen, he deserves all the credit for this awesome script!

```

#! /sbin/runscript

depend() {

        need net

}

start() {

        ebegin "Starting QoS v1.1"

echo "Starting QoS v1.1 on Watchdog2..."

#

# Created by eulogious with help from jomen

# 1.0 Cleaned up init script 2-23-08

# 1.1 Fixed packet handling issues, and Bittorrent issues 3-6-08

#

# Interface on which the traffic should be shaped

# NETDEVICE=$(nvram get wan_device)

NETDEVICE=eth0

#test -n "$FAILSAFE" && exit

# load neccesary modules

# !!! no output will be generated in case of failure !!!

# make sure the modules are available

# todo (if needed):  write a test if modules are successfully loaded

# the functionality of these 3 is needed - but these are compiled into kernel - no loading neccesary

# but this may change...

# insmod sch_prio

# insmod sch_sfq

# insmod cls_u32

#insmod cls_fw > /dev/null 2>&1

#insmod ipt_CONNMARK > /dev/null 2>&1

#insmod ipt_connmark > /dev/null 2>&1

#insmod ipt_conntrack > /dev/null 2>&1

#insmod ipt_layer7 > /dev/null 2>&1

#insmod ipt_length > /dev/null 2>&1

#insmod ipt_tos > /dev/null 2>&1

#insmod sch_htb > /dev/null 2>&1

#insmod sch_ingress > /dev/null 2>&1

# UPRATE is (with DSL) about 1/10 of the given Bandwith (1 Mbit == 1024 KBit --> 1/10 davon is about 128 KBit)

# this script is tailored for a 2 MBit DSL

# do set the rate at a little less than full bandwith to make sure the modems send-queue does never get filled

# as this would lead to throwing away packets and the need to resend them

# to avoid this under any circumstance is exactly what is needed/wanted here

#

# Downrate is the rated speed of the DSL - or here: the speed the incoming packets is to be throtteled down to...

#

# this is commented out now as it is not useful - you have NO control whatsoever over the speed/rate of incoming packets

# they are just the unknown answer to what was requested

# P2PRATE is the max bandwith _ever_ to be given to filesharing

# it could be any high rate - but the purpose of this script is to limit their impact on the overall performance as good as possile

# P2P is exactly NOT a priority here - to the contrary

#

# with the standard filter settings - less than 12kBit is _not_ possible - for NO queue here

# I did not bother to figure out how to make this even less

# the filters algorithm may not catch all packets belonging to P2P - so the actual rate may be a little higher in reality

# PRIORATE_x is the base bandwith for each and every of the prio-classes,

# they can "borrow" bandwith from others if it is available and not actually used

# PRIORATE1 --> interactive class - small packets, TOS minimize delay (ACK - but only small ACK's...p2p does also use large ACK's for data-transfer...)

# PRIORATE2 --> general data-traffic: large packets, TOS maximize throughput

# PRIORATE3 --> in here goes everything not explicitely marked otherwise

# P2PRATE_LOW + P2PRATE_HIGH --> a try to catch _all_ filesharing

# these are given a low amount of bandwith to start with - and are _never_ allowed to get the full bandwith...

# see: P2PRATE

#

# Exception: P2PRATE_OWNER - the owner (me) should not be limited in any way even with filesharing

#

# UPRATE + BURST is the max. rate that is allowed to get out to the Internet - avoiding filling the modem-queue

#

# DOWNRATE + DOWNBURST is the max. for the incoming queue

# commented out as one just has no control over ingress (rate of inbound traffic)

#

# !! P2PRATE_LOW + P2PRATE_HIGH + PRIORATE1 + PRIORATE2 + PRIORATE3 = UPRATE (close enough...) !!

# defining variables

# the rates for the different priority-classes

UPRATE="90kbps"

WEBUPRATE="60kbps"

# DOWNRATE="2mbit"

P2PRATE_LOW="10kbps"

P2PRATE_HIGH="30kbps"

PRIORATE1="10kbps"

PRIORATE2="60kbps"

PRIORATE3="10kbps"

P2PRATE_OWNER=$PRIORATE2

# Burst - for a short time the above set rates can be exceeded by this amount

BURST="2k"

# DOWNBURST="50k"

# MARKPRIO_x - the MARKs iptables will set when identifying a matching packet

# these MARKs are the basis to shape all the traffic

# 11 is used here for the highest priority

# 19 is used for the lowest priority

# the 3 groups below are MY partitioning-scheme of all traffic into priority-classes

# 11 - 13 = high  14 - 16 = normal  17 - 19 = low

MARKPRIO_1="11"

MARKPRIO_2="12"

MARKPRIO_3="13"

MARKPRIO_4="14"

MARKPRIO_5="15"

MARKPRIO_6="16"

MARKPRIO_7="17"

MARKPRIO_8="18"

MARKPRIO_9="19"

# create the chains and empty them

      iptables -t mangle -N p2pmatch

      iptables -t mangle -F p2pmatch

      iptables -t mangle -N packetsize

      iptables -t mangle -F packetsize

      iptables -t mangle -N typeofservice

      iptables -t mangle -F typeofservice

      iptables -t mangle -N split

      iptables -t mangle -F split

      iptables -t mangle -N higher_prio

      iptables -t mangle -F higher_prio

      iptables -t mangle -N lower_prio

      iptables -t mangle -F lower_prio

      iptables -t mangle -N ssh

      iptables -t mangle -F ssh

      iptables -t mangle -N vpn

      iptables -t mangle -F vpn

## the chains and what they do

# test if traffic belongs to filesharing

      iptables -t mangle -A POSTROUTING -j p2pmatch

# here is a place for clients entirely disabled to do any filesharing at all

# after the traffic has been MARKed ($MARKPRIO_6) it can be filtered based on host/source/destination address

#      iptables -t mangle -A POSTROUTING -s 104.61.112.15 -m mark --mark $MARKPRIO_6 -j DROP

# a RETURN (go up one level) if packets arealready MARKed P2P

      iptables -t mangle -A POSTROUTING -m mark --mark $MARKPRIO_3 -j RETURN

# go through chains packetsize, typeofservice, ssh, vpn - if not yet MARKed...

      iptables -t mangle -A POSTROUTING -j packetsize

      iptables -t mangle -A POSTROUTING -j typeofservice

      iptables -t mangle -A POSTROUTING -j ssh

      iptables -t mangle -A POSTROUTING -j vpn

# mark packets belonging to filesharing - edonkey was the most common here

# to save computing-time I tried to arrange these matches based on how often they occured here

# reason: this script is to be run on a 200 MHz Home-Router with OpenWRT and a lot of NAT - I wanted to keep the load as low as possible

# after each check there is a RETURN target to save the (possibly) computing-intensive and useless check for the remaining P2P-protocols

#

#Torrents

      iptables -t mangle -A p2pmatch -j CONNMARK --restore-mark

      iptables -t mangle -A p2pmatch -m mark --mark $MARKPRIO_3 -j RETURN

      iptables -t mangle -A p2pmatch -m layer7 --l7proto bittorrent -j MARK --set-mark $MARKPRIO_3

      iptables -t mangle -A p2pmatch -p tcp --sport 8888 -j MARK --set-mark $MARKPRIO_3

      iptables -t mangle -A p2pmatch -p udp --sport 8888 -j MARK --set-mark $MARKPRIO_3

      iptables -t mangle -A p2pmatch -p tcp --dport 8888 -j MARK --set-mark $MARKPRIO_3

      iptables -t mangle -A p2pmatch -p udp --dport 8888 -j MARK --set-mark $MARKPRIO_3

#SSH

      iptables -t mangle -A ssh -m layer7 --l7proto ssh -j MARK --set-mark $MARKPRIO_2

      iptables -t mangle -A ssh -p tcp --sport 22 -j MARK --set-mark $MARKPRIO_2

      iptables -t mangle -A ssh -p tcp --dport 22 -j MARK --set-mark $MARKPRIO_2

      iptables -t mangle -A ssh -p tcp --sport 2222 -j MARK --set-mark $MARKPRIO_2

      iptables -t mangle -A ssh -p tcp --dport 2222 -j MARK --set-mark $MARKPRIO_2   

#VPN      

      iptables -t mangle -A vpn -p tcp --sport 1723 -j MARK --set-mark $MARKPRIO_2

      iptables -t mangle -A vpn -p udp --sport 1723 -j MARK --set-mark $MARKPRIO_2

      iptables -t mangle -A vpn -p tcp --dport 1723 -j MARK --set-mark $MARKPRIO_2

      iptables -t mangle -A vpn -p udp --dport 1723 -j MARK --set-mark $MARKPRIO_2

      iptables -t mangle -A vpn -p 47 -j MARK --set-mark $MARKPRIO_2

      iptables -t mangle -A vpn -m mark --mark $MARKPRIO_2 -j RETURN

      iptables -t mangle -A vpn -j CONNMARK --save-mark

# set MARK based on packet-size, if TOS "Normal-Service"

      iptables -t mangle -A packetsize -m tos --tos ! Normal-Service -j RETURN

      iptables -t mangle -A packetsize -m length --length 0:128 -j MARK --set-mark $MARKPRIO_1

# I put these packets into P2P because Bittorrent seems to use bigger packets for torrents.  With out this, torrents will peak to normal web rate for no apparent cause.  This seems to work really well for Bittorents.      

      iptables -t mangle -A packetsize -m length --length 129: -j MARK --set-mark $MARKPRIO_3

# match and set MARK based on already present TOS field

      iptables -t mangle -A typeofservice -m tos --tos Maximize-Throughput -j MARK --set-mark $MARKPRIO_1

      iptables -t mangle -A typeofservice -m tos --tos Minimize-Delay -j MARK --set-mark $MARKPRIO_1

# chain "split" to be able to assign different priorities to different clients - such as i.e.: the owner of the line...

      iptables -t mangle -A POSTROUTING -j split

# actual split for clients, which are to get higher or lower priority than the rest

# i.e. split for "higher prio" - everything on the local LAN or a whole subnet for example

#      iptables -t mangle -A split -s 192.168.2.9 -j higher_prio

#      iptables -t mangle -A split -s 192.168.2.8 -j higher_prio

#     iptables -t mangle -A split -s 104.61.114.17 -j higher_prio

# i.e. split for "lower prio" - just one client or a whole subnet

#      iptables -t mangle -A split -s 104.61.111.0/24 -j lower_prio

#      iptables -t mangle -A split -s 104.61.111.10 -j lower_prio

# chain "higher_prio" - what has been put into "higher_prio" above gets its MARK value rewritten

# MARKPRIO_4 gets MARKPRIO_1

# MARKPRIO_5 gets MARKPRIO_2

# MARKPRIO_6 gets MARKPRIO_3

      iptables -t mangle -A higher_prio -m mark --mark $MARKPRIO_4 -j MARK --set-mark $MARKPRIO_1

      iptables -t mangle -A higher_prio -m mark --mark $MARKPRIO_5 -j MARK --set-mark $MARKPRIO_2

      iptables -t mangle -A higher_prio -m mark --mark $MARKPRIO_6 -j MARK --set-mark $MARKPRIO_3

# similar thing for "lower_prio"

      iptables -t mangle -A lower_prio -m mark --mark $MARKPRIO_4 -j MARK --set-mark $MARKPRIO_7

      iptables -t mangle -A lower_prio -m mark --mark $MARKPRIO_5 -j MARK --set-mark $MARKPRIO_8

      iptables -t mangle -A lower_prio -m mark --mark $MARKPRIO_6 -j MARK --set-mark $MARKPRIO_9

# htb as traffic-handler - default for unclassified traffic (should'nt be any) is flowid 1:100 (normal priority)

# everything else is going into the assigned queues

      tc qdisc add dev $NETDEVICE root handle 1: htb default 100 r2q 1

# set root class

      tc class add dev $NETDEVICE parent 1: classid 1:1 htb rate $UPRATE burst $BURST

# the sub-classes

# into the first 3 (which are served first) go all packets with highest priority (Me)

      tc class add dev $NETDEVICE parent 1:1 classid 1:10 htb rate $PRIORATE1 ceil $WEBUPRATE burst $BURST prio 1

      tc class add dev $NETDEVICE parent 1:1 classid 1:20 htb rate $PRIORATE2 ceil $UPRATE burst $BURST prio 2

      tc class add dev $NETDEVICE parent 1:1 classid 1:30 htb rate $P2PRATE_LOW ceil $P2PRATE_HIGH prio 3

# the next 3 are "Everyone Else" priority connection

      tc class add dev $NETDEVICE parent 1:1 classid 1:40 htb rate $PRIORATE1 ceil $WEBUPRATE burst $BURST prio 4

      tc class add dev $NETDEVICE parent 1:1 classid 1:50 htb rate $PRIORATE2 ceil $WEBUPRATE burst $BURST prio 5

      tc class add dev $NETDEVICE parent 1:1 classid 1:60 htb rate $P2PRATE_LOW ceil $P2PRATE_HIGH prio 6

# the last 3 are for packets explicitely set to "low" priority

      tc class add dev $NETDEVICE parent 1:1 classid 1:70 htb rate $PRIORATE1 ceil $WEBUPRATE burst $BURST prio 7

      tc class add dev $NETDEVICE parent 1:1 classid 1:80 htb rate $PRIORATE2 ceil $WEBUPRATE burst $BURST prio 8

      tc class add dev $NETDEVICE parent 1:1 classid 1:90 htb rate $P2PRATE_LOW ceil $P2PRATE_LOW prio 9

# default-class (should anything have slipped by) - it goes in here

      tc class add dev $NETDEVICE parent 1:1 classid 1:100 htb rate $PRIORATE3 ceil $WEBUPRATE burst $BURST prio 10

# define sqf as qdisc for the sub-classes

# high

      tc qdisc add dev $NETDEVICE parent 1:10 sfq perturb 10

      tc qdisc add dev $NETDEVICE parent 1:20 sfq perturb 10

      tc qdisc add dev $NETDEVICE parent 1:30 sfq perturb 10

# normal

      tc qdisc add dev $NETDEVICE parent 1:40 sfq perturb 10

      tc qdisc add dev $NETDEVICE parent 1:50 sfq perturb 10

      tc qdisc add dev $NETDEVICE parent 1:60 sfq perturb 10

# low

      tc qdisc add dev $NETDEVICE parent 1:70 sfq perturb 10

      tc qdisc add dev $NETDEVICE parent 1:80 sfq perturb 10

      tc qdisc add dev $NETDEVICE parent 1:90 sfq perturb 10

# default

      tc qdisc add dev $NETDEVICE parent 1:100 sfq perturb 10

# put MARKed packets into the sub-classes

# everything from chain "split" --> "higher_prio" goes into 1:10 / 1:20 / 1:30

# normal traffic goes into 1:40 / 1:50 / 1:60

# everything from chain "split" --> "lower_prio" goes into 1:70 / 1:80 / 1:90

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 1 handle $MARKPRIO_1 fw flowid 1:10

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 2 handle $MARKPRIO_2 fw flowid 1:20

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 3 handle $MARKPRIO_3 fw flowid 1:30

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 4 handle $MARKPRIO_4 fw flowid 1:40

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 5 handle $MARKPRIO_5 fw flowid 1:50

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 7 handle $MARKPRIO_6 fw flowid 1:60

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 8 handle $MARKPRIO_7 fw flowid 1:70

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 9 handle $MARKPRIO_8 fw flowid 1:80

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 10 handle $MARKPRIO_9 fw flowid 1:90

# slowdown downlink

# commented out - it was just an experiment

#      tc qdisc add dev $NETDEVICE handle ffff: ingress

#      tc filter add dev $NETDEVICE parent ffff: protocol ip prio 50 u32 match ip src 0.0.0.0/0 police rate $DOWNRATE burst $DOWNBURST drop flowid :1

#

echo "Uprate = $UPRATE"

echo "Web Uprate = $WEBUPRATE"

echo "Low P2P Rate = $P2PRATE_LOW"

echo "High P2P Rate = $P2PRATE_HIGH"

echo "Web Rate = $PRIORATE1"

echo "SSH/VPN Rate = $PRIORATE2"

echo "Everything Else Rate = $PRIORATE3"

echo "Burst Rate = $BURST"

echo "Successfully Started QoS v1.1 on watchdog2"

eend $?

}

stop() {

        ebegin "Stopping QoS"

echo "Stopping QoS v1.1 on watchdog2..."

# the "stop" part of the script

# remove the whole setup in reverse order of creation

      tc qdisc del dev eth0 root handle 1: htb default 100

#      tc qdisc del dev $NETDEVICE handle ffff: ingress

      iptables -t mangle -D POSTROUTING -j p2pmatch

      iptables -t mangle -F p2pmatch

      iptables -t mangle -X p2pmatch

      iptables -t mangle -D POSTROUTING -j ssh

      iptables -t mangle -F ssh

      iptables -t mangle -X ssh

      iptables -t mangle -D POSTROUTING -j vpn

      iptables -t mangle -F vpn

      iptables -t mangle -X vpn

      

      iptables -t mangle -D POSTROUTING -j packetsize

      iptables -t mangle -F packetsize

      iptables -t mangle -X packetsize

      iptables -t mangle -D POSTROUTING -j typeofservice

      iptables -t mangle -F typeofservice

      iptables -t mangle -X typeofservice

      iptables -t mangle -D POSTROUTING -j split

      iptables -t mangle -F split

      iptables -t mangle -X split

      iptables -t mangle -F higher_prio

      iptables -t mangle -X higher_prio

      iptables -t mangle -F lower_prio

      iptables -t mangle -X lower_prio

      

      iptables -t mangle -F POSTROUTING

        eend $?

}

```

Feel free to ask questions, I will help as much as I can, but I won't do all the work for you  :Smile:   Also these forums are great.  Search for qos if you have queestions and need quick answers.  I found everything I needed in the forums.Last edited by eulogious on Fri Mar 07, 2008 8:45 pm; edited 1 time in total

----------

## eulogious

I am just posting again, because the version of the script that I posted doesn't work the way I intended it too.  I have then fixed it, so if anyone is interested in the newer version, ask and I will post it.  Thanks.

----------

## jomen

@eulogious

This is actually a *very slightly* modified version of the script I made and posted here:

https://forums.gentoo.org/viewtopic.php?p=4892519#4892519

in response to one of your questions.

The comments are still the original ones - only they now do not reflect what is actually being done here.

You could at least have updated those...

You should not have appointed yourself as the creator and me as one that helped.

I'm not jealous but am a liiittle disappointed about that.

I made the script.

But I don't really care.

You could have used it and everybody still can and may - but even if you are not giving credits...

do not sell it as your own please.

That being said - I would of course be interested in the fixes you made to the script to make it work for you.

What did not work as ... I intended it to  :Wink:  ?

----------

## eulogious

Jomen:  Sorry man, this was for my personal use, and I really didn't even think about it.  Yes you did create the original for sure.  You do deserve the credit for that.  My bad.  I honestly didn't even think about the top line, and forgot that I put that there.  I changed that.  The only thing that I really changed was more of prioritizing SSH and VPN.  I also just commented some more and deleted some stuff.  P2P is such a pain to try to get ALL the traffic.  Here's my "new" script

```

#! /sbin/runscript

depend() {

        need net

}

start() {

        ebegin "Starting QoS v1.3"

#

# Created by Jomen, adapted by eulogious

# 1.0 Cleaned up init script 2-23-08

# 1.1 Fixed packet handling issues, and Bittorrent issues 3-6-08

# 1.2 Fixed downloading being affected, mostly.  Some reason the upload limit is affecting the download rate.  

#   Down rate at 7mbit'ish. Large packets are sent by torrents, therefore sometimes they all can't be 

#   caught.  Use the limiter with the torrent client to throttle them completely.  Everything prioritizes

#   fine, after extensive testing, meaning that all traffic is getting the set rate, it's just the 

#   extra they fight over 3-7-08

# 1.3 Fixed shutting down issues.  Added variable for netowrk device to stopping section.  Stops independantly

#   from the firewall 3-7-08

#

# Interface on which the traffic should be shaped

# NETDEVICE=$(nvram get wan_device)

NETDEVICE=eth0

#test -n "$FAILSAFE" && exit

# load neccesary modules

# !!! no output will be generated in case of failure !!!

# make sure the modules are available

# todo (if needed):  write a test if modules are successfully loaded

# the functionality of these 3 is needed - but these are compiled into kernel - no loading neccesary

# but this may change...

# insmod sch_prio

# insmod sch_sfq

# insmod cls_u32

#insmod cls_fw > /dev/null 2>&1

#insmod ipt_CONNMARK > /dev/null 2>&1

#insmod ipt_connmark > /dev/null 2>&1

#insmod ipt_conntrack > /dev/null 2>&1

#insmod ipt_layer7 > /dev/null 2>&1

#insmod ipt_length > /dev/null 2>&1

#insmod ipt_tos > /dev/null 2>&1

#insmod sch_htb > /dev/null 2>&1

#insmod sch_ingress > /dev/null 2>&1

# UPRATE is (with DSL) about 1/10 of the given Bandwith (1 Mbit == 1024 KBit --> 1/10 davon is about 128 KBit)

# do set the rate at a little less than full bandwith to make sure the modems send-queue does never get filled

# as this would lead to throwing away packets and the need to resend them

# to avoid this under any circumstance is exactly what is needed/wanted here

#

# Downrate is the rated speed of the DSL - or here: the speed the incoming packets is to be throtteled down to...

#

# this is commented out now as it is not useful - you have NO control whatsoever over the speed/rate of incoming packets

# they are just the unknown answer to what was requested

#

# P2PRATE_HIGH is the max bandwith _ever_ to be given to filesharing

# it could be any high rate - but the purpose of this script is to limit their impact on the overall performance as good as possile

# P2P is exactly NOT a priority here - to the contrary

# P2PRATE_LOW is the bandwidth that P2P will always have

#

# with the standard filter settings - less than 12kBit is _not_ possible - for NO queue here

# I did not bother to figure out how to make this even less

# the filters algorithm may not catch all packets belonging to P2P - so the actual rate may be a little higher in reality

#

# PRIORATE_x is the base bandwith for each and every of the prio-classes,

# they can "borrow" bandwith from others if it is available and not actually used

#

# PRIORATE1 --> interactive class - small packets, TOS minimize delay 

#   (ACK - but only small ACK's...p2p does also use large ACK's for data-transfer...)

# PRIORATE2 --> SSH and VPN Traffic only

# PRIORATE3 --> in here goes everything not explicitely marked otherwise

# P2PRATE_LOW + P2PRATE_HIGH --> a try to catch _all_ filesharing

# these are given a low amount of bandwith to start with - and are _never_ allowed to get the full bandwith...

# see: P2PRATE

#

# Exception: P2PRATE_OWNER - the owner (me) should not be limited in any way even with filesharing

#

# UPRATE + BURST is the max. rate that is allowed to get out to the Internet - avoiding filling the modem-queue

#

# !! P2PRATE_LOW + PRIORATE1 + PRIORATE2 + PRIORATE3 = UPRATE (close enough...) !!

#

# defining variables

# the rates for the different priority-classes

UPRATE="90kbps"

WEBUPRATE="60kbps"

P2PRATE_LOW="10kbps"

P2PRATE_HIGH="30kbps"

PRIORATE1="10kbps"

PRIORATE2="60kbps"

PRIORATE3="10kbps"

P2PRATE_OWNER=$PRIORATE2

# Burst - for a short time the above set rates can be exceeded by this amount

BURST="2k"

# Display the Rates

echo "Total Uprate = $UPRATE"

echo "Max Web Uprate = $WEBUPRATE"

echo "Normal Torrent Rate = $P2PRATE_LOW"

echo "Max Torrent Rate = $P2PRATE_HIGH"

echo "Normal Web Rate = $PRIORATE1"

echo "Normal SSH/VPN Rate = $PRIORATE2"

echo "Large Packet Rate = $PRIORATE1"

echo "Everything Else Rate = $PRIORATE3"

echo "Burst Rate = $BURST"

# MARKPRIO_x - the MARKs iptables will set when identifying a matching packet

# these MARKs are the basis to shape all the traffic

# 11 is used here for the highest priority

# 19 is used for the lowest priority

# the 3 groups below are MY partitioning-scheme of all traffic into priority-classes

# 11 - 16 = high/normal 17 - 19 = low

MARKPRIO_1="11"

MARKPRIO_2="12"

MARKPRIO_3="13"

MARKPRIO_4="14"

MARKPRIO_5="15"

MARKPRIO_6="16"

MARKPRIO_7="17"

MARKPRIO_8="18"

MARKPRIO_9="19"

# create the chains and empty them

      iptables -t mangle -N ssh

      iptables -t mangle -F ssh

      iptables -t mangle -N vpn

      iptables -t mangle -F vpn

      iptables -t mangle -N p2pmatch

      iptables -t mangle -F p2pmatch

      iptables -t mangle -N packetsize

      iptables -t mangle -F packetsize

      iptables -t mangle -N typeofservice

      iptables -t mangle -F typeofservice

# Uncomment these to activate giving certain users high/low priority, and also uncomment the lines futher down.

# Note:  I have not set up the proper ques for these.  This will not work as is.  Left in incase I need it someday...

#      iptables -t mangle -N higher_prio

#      iptables -t mangle -F higher_prio

#      iptables -t mangle -N lower_prio

#      iptables -t mangle -F lower_prio

#      iptables -t mangle -N split

#      iptables -t mangle -F split

## the chains and what they do

# test if traffic belongs to SSH, VPN, or P2P

      iptables -t mangle -A POSTROUTING -j ssh

      iptables -t mangle -A POSTROUTING -m mark --mark $MARKPRIO_1 -j RETURN

      iptables -t mangle -A POSTROUTING -j vpn

      iptables -t mangle -A POSTROUTING -m mark --mark $MARKPRIO_2 -j RETURN

      iptables -t mangle -A POSTROUTING -j p2pmatch

      iptables -t mangle -A POSTROUTING -m mark --mark $MARKPRIO_3 -j RETURN

# here is a place for clients entirely disabled to do any filesharing at all

# after the traffic has been MARKed ($MARKPRIO_3) it can be filtered based on host/source/destination address

#      iptables -t mangle -A POSTROUTING -s 104.61.112.15 -m mark --mark $MARKPRIO_3 -j DROP

# go through chains packetsize, typeofservice - if not yet MARKed...

      iptables -t mangle -A POSTROUTING -j packetsize

      iptables -t mangle -A POSTROUTING -j typeofservice

# mark packets belonging to filesharing to save computing-time I tried to arrange these matches based on how often they occured

#   after each check there is a RETURN target to save the (possibly) computing-intensive and useless check 

#   for the remaining P2P-protocols

#SSH

      iptables -t mangle -A ssh -j CONNMARK --restore-mark

      iptables -t mangle -A ssh -m layer7 --l7proto ssh -j MARK --set-mark $MARKPRIO_1

      iptables -t mangle -A ssh -p tcp --sport 22 -j MARK --set-mark $MARKPRIO_1

      iptables -t mangle -A ssh -p tcp --sport 2222 -j MARK --set-mark $MARKPRIO_1

      iptables -t mangle -A ssh -m mark --mark $MARKPRIO_1 -j RETURN

      iptables -t mangle -A ssh -j CONNMARK --save-mark

#VPN  

      iptables -t mangle -A vpn -j CONNMARK --restore-mark

      iptables -t mangle -A vpn -p tcp --sport 1723 -j MARK --set-mark $MARKPRIO_2

      iptables -t mangle -A vpn -p udp --sport 1723 -j MARK --set-mark $MARKPRIO_2

      iptables -t mangle -A vpn -p 47 -j MARK --set-mark $MARKPRIO_2

      iptables -t mangle -A vpn -m mark --mark $MARKPRIO_2 -j RETURN

      iptables -t mangle -A vpn -j CONNMARK --save-mark

#Torrents

      iptables -t mangle -A p2pmatch -j CONNMARK --restore-mark

      iptables -t mangle -A p2pmatch -m layer7 --l7proto bittorrent -j MARK --set-mark $MARKPRIO_3

      iptables -t mangle -A p2pmatch -p tcp --sport 8888 -j MARK --set-mark $MARKPRIO_3

      iptables -t mangle -A p2pmatch -p udp --sport 8888 -j MARK --set-mark $MARKPRIO_3

      iptables -t mangle -A p2pmatch -m mark --mark $MARKPRIO_3 -j RETURN

      iptables -t mangle -A p2pmatch -j CONNMARK --save-mark

# set MARK based on packet-size, if TOS "Normal-Service"

      iptables -t mangle -A packetsize -m tos --tos ! Normal-Service -j RETURN

      iptables -t mangle -A packetsize -m length --length 0:128 -j MARK --set-mark $MARKPRIO_4

      iptables -t mangle -A packetsize -m length --length 129: -j MARK --set-mark $MARKPRIO_5

# match and set MARK based on already present TOS field

      iptables -t mangle -A typeofservice -m tos --tos Maximize-Throughput -j MARK --set-mark $MARKPRIO_6

      iptables -t mangle -A typeofservice -m tos --tos Minimize-Delay -j MARK --set-mark $MARKPRIO_6

# Uncomment the following lines to activate high/low priority

# chain "split" to be able to assign different priorities to different clients - such as i.e.: the owner of the line...

#      iptables -t mangle -A POSTROUTING -j split

# actual split for clients, which are to get higher or lower priority than the rest

# i.e. split for "higher prio" - everything on the local LAN or a whole subnet for example

#      iptables -t mangle -A split -s 192.168.2.9 -j higher_prio

#      iptables -t mangle -A split -s 192.168.2.8 -j higher_prio

#      iptables -t mangle -A split -s 104.61.114.17 -j higher_prio

# i.e. split for "lower prio" - just one client or a whole subnet

#      iptables -t mangle -A split -s 104.61.111.0/24 -j lower_prio

#      iptables -t mangle -A split -s 104.61.111.10 -j lower_prio

# chain "higher_prio" - what has been put into "higher_prio" above gets its MARK value rewritten

# MARKPRIO_4 gets MARKPRIO_1

# MARKPRIO_5 gets MARKPRIO_2

# MARKPRIO_6 gets MARKPRIO_3

#      iptables -t mangle -A higher_prio -m mark --mark $MARKPRIO_4 -j MARK --set-mark $MARKPRIO_1

#      iptables -t mangle -A higher_prio -m mark --mark $MARKPRIO_5 -j MARK --set-mark $MARKPRIO_2

#      iptables -t mangle -A higher_prio -m mark --mark $MARKPRIO_6 -j MARK --set-mark $MARKPRIO_3

# similar thing for "lower_prio"

#      iptables -t mangle -A lower_prio -m mark --mark $MARKPRIO_4 -j MARK --set-mark $MARKPRIO_7

#      iptables -t mangle -A lower_prio -m mark --mark $MARKPRIO_5 -j MARK --set-mark $MARKPRIO_8

#      iptables -t mangle -A lower_prio -m mark --mark $MARKPRIO_6 -j MARK --set-mark $MARKPRIO_9

# htb as traffic-handler - default for unclassified traffic (should'nt be any) is flowid 1:100 (normal priority)

# everything else is going into the assigned queues

      tc qdisc add dev $NETDEVICE root handle 1: htb default 100 r2q 1

# set root class

      tc class add dev $NETDEVICE parent 1: classid 1:1 htb rate $UPRATE burst $BURST

# the sub-classes

# into the first 6 (which are served first) go all packets with highest priority (Me)

      tc class add dev $NETDEVICE parent 1:1 classid 1:10 htb rate $PRIORATE2 ceil $UPRATE burst $BURST prio 1

      tc class add dev $NETDEVICE parent 1:1 classid 1:20 htb rate $PRIORATE2 ceil $UPRATE burst $BURST prio 2

      tc class add dev $NETDEVICE parent 1:1 classid 1:30 htb rate $P2PRATE_LOW ceil $P2PRATE_HIGH prio 3

      tc class add dev $NETDEVICE parent 1:1 classid 1:40 htb rate $PRIORATE1 ceil $WEBUPRATE burst $BURST prio 4

      tc class add dev $NETDEVICE parent 1:1 classid 1:50 htb rate $PRIORATE1 ceil $UPRATE burst $BURST prio 5

      tc class add dev $NETDEVICE parent 1:1 classid 1:60 htb rate $PRIORATE1 ceil $WEBUPRATE prio 6

# these 3 are for packets explicitely set to "low" priority

      tc class add dev $NETDEVICE parent 1:1 classid 1:70 htb rate $PRIORATE1 ceil $WEBUPRATE burst $BURST prio 7

      tc class add dev $NETDEVICE parent 1:1 classid 1:80 htb rate $PRIORATE2 ceil $UPRATE burst $BURST prio 8

      tc class add dev $NETDEVICE parent 1:1 classid 1:90 htb rate $P2PRATE_LOW ceil $P2PRATE_LOW prio 9

# default-class (should anything have slipped by) - it goes in here

      tc class add dev $NETDEVICE parent 1:1 classid 1:100 htb rate $PRIORATE3 ceil $WEBUPRATE burst $BURST prio 10

# define sqf as qdisc for the sub-classes

# high

      tc qdisc add dev $NETDEVICE parent 1:10 sfq perturb 10

      tc qdisc add dev $NETDEVICE parent 1:20 sfq perturb 10

      tc qdisc add dev $NETDEVICE parent 1:30 sfq perturb 10

      tc qdisc add dev $NETDEVICE parent 1:40 sfq perturb 10

      tc qdisc add dev $NETDEVICE parent 1:50 sfq perturb 10

      tc qdisc add dev $NETDEVICE parent 1:60 sfq perturb 10

# low

      tc qdisc add dev $NETDEVICE parent 1:70 sfq perturb 10

      tc qdisc add dev $NETDEVICE parent 1:80 sfq perturb 10

      tc qdisc add dev $NETDEVICE parent 1:90 sfq perturb 10

# default

      tc qdisc add dev $NETDEVICE parent 1:100 sfq perturb 10

# put MARKed packets into the sub-classes

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 1 handle $MARKPRIO_1 fw flowid 1:10

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 2 handle $MARKPRIO_2 fw flowid 1:20

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 3 handle $MARKPRIO_3 fw flowid 1:30

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 4 handle $MARKPRIO_4 fw flowid 1:40

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 5 handle $MARKPRIO_5 fw flowid 1:50

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 7 handle $MARKPRIO_6 fw flowid 1:60

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 8 handle $MARKPRIO_7 fw flowid 1:70

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 9 handle $MARKPRIO_8 fw flowid 1:80

      tc filter add dev $NETDEVICE parent 1:0 protocol ip prio 10 handle $MARKPRIO_9 fw flowid 1:90

echo "Successfully Started QoS v1.3 on watchdog2"

eend $?

}

stop() {

        ebegin "Stopping QoS v1.2"

# the "stop" part of the script

# remove the whole setup in reverse order of creation

NETDEVICE=eth0

      

      tc qdisc del dev $NETDEVICE root handle 1: htb default 100

      

      iptables -t mangle -D POSTROUTING -j p2pmatch

      iptables -t mangle -F p2pmatch

      iptables -t mangle -X p2pmatch

      iptables -t mangle -D POSTROUTING -j ssh

      iptables -t mangle -F ssh

      iptables -t mangle -X ssh

      iptables -t mangle -D POSTROUTING -j vpn

      iptables -t mangle -F vpn

      iptables -t mangle -X vpn

      

      iptables -t mangle -D POSTROUTING -j packetsize

      iptables -t mangle -F packetsize

      iptables -t mangle -X packetsize

      iptables -t mangle -D POSTROUTING -j typeofservice

      iptables -t mangle -F typeofservice

      iptables -t mangle -X typeofservice

# Uncomment if you have activated high/low priority

#

#      iptables -t mangle -D POSTROUTING -j split

#      iptables -t mangle -F split

#      iptables -t mangle -X split

#

#      iptables -t mangle -F higher_prio

#      iptables -t mangle -X higher_prio

#

#      iptables -t mangle -F lower_prio

#      iptables -t mangle -X lower_prio

      

      iptables -t mangle -F POSTROUTING

        eend $?

}

```

Tell me what you think.  You rock man.  I have done alot of research trying to figure this all out, and without this script as a base, I wouldn't have gotten anything quite as nice as I have now.  Do you know of any way to tell the difference between P2P large packets, and other large packets?  I mostly use bittorrent, and unfortunately bittorrent sends large ACK packets which make it hard to tell the difference between bittorent large ACK packet, and normal large ACK packets.  This will cause bittorents uploads to spike to 60k in this case  :Sad:   So I just use Azuerus to limit the upload.  This way SSH and VPN always have bandwidth, and same with the web.  Makes surfing better!  Thanks, you kick ass man!

----------

## jomen

You overread (? correct english ?) this comment:

```
# with the standard filter settings - less than 12kBit is _not_ possible - for NO queue here
```

(I was referring to "per queue")

This is actually VERY important for everything else!

(You used 10kbit ... 3 times...

- but you can't get it smaller than 12kbit chunks)

and you got cought by a bug in my script:

actually - by a bug in a comment  which was not really reflecting the truth of the matter

it is this:

```
# !! P2PRATE_LOW + P2PRATE_HIGH + PRIORATE1 + PRIORATE2 + PRIORATE3 = UPRATE (close enough...) !!
```

I try to explain:

when assigning the traffic to the different classes

```
      tc class add dev $NETDEVICE parent 1:1 classid 1:10 htb rate 1 ceil $UPRATE burst $BURST prio 1

      tc class add dev $NETDEVICE parent 1:1 classid 1:20 htb rate $PRIORATE2 ceil $UPRATE burst $BURST prio 2

      tc class add dev $NETDEVICE parent 1:1 classid 1:30 htb rate   ceil $UPRATE prio 3
```

...and so on...

you are using the variables $PRIORATE1  $PRIORATE2 $P2PRATE_OWNER ...

more than once.

$UPRATE is the sum:

of the rates used ($PRIORATE1 $PRIORATE2 $P2PRATE_HIGH ... and so on)

each multipied with the number of times you use them

That is why my numbers look so small

I use 10 queues and in these queues I use:

$PRIORATE1 - 3 times

$PRIORATE2 - 3 times

$PRIORATE3 - 1 time

$P2PRATE_OWNER - 1 time

$P2PRATE_LOW - 2 times

That is the closest match I could get to without going above the bandwith available to me while actually using these 10 queues.

Actually this is below...

I'm trusting the "ceil" option to use any unused bandwith here.

---------

You are using an $UPRATE of 90

That is: your upstream-bandwitdth is 90kbit - is it?

for the queues you use:

$PRIORATE1 = 10kbit - 4 times

$PRIORATE2 = 60kbit - 3 times

$PRIORATE3 = 10kbit - 1 time

$P2PRATE_LOW = 10kbit - 2 times

this adds up to 40 + 180 + 10 + 20 = 150kbit

This means - if there really is a lot of traffic - each queue gets assigned the amount you specified...

which is of course almost twice the bandwith you really have...

which is why it very probably will not work reliably...

When you are using "layer7" to detect and shape p2p traffic there is always a more or less large uncertanty you should be aware of:

it is if:

-you really catch all p2p you want

-you have no false positives

layer7 will have to fail when it comes to encrypted p2p-traffic - no way to recognize it...

 *Quote:*   

> I mostly use bittorrent, and unfortunately bittorrent sends large ACK packets which make it hard to tell the difference between bittorent large ACK packet, and normal large ACK packets.

 

that is why I use layer 7 - and why I put large packets into a lower priority than small packets -   no "normal ACK" is large  :Wink: 

...unfortunately it is not all that easy...

and more than likely this solution is nowhere near than optimal

I had to use tools available for the OpenWRT-platform 

(because this is running on a standard wireless-home-router like the Linksys WRT54GL or a Buffalo WHR-G54S)

- while a standard recent linux distro as Gentoo could maybe offer more easy to use or more modern concepts of doing this.

HTH

----------

## jomen

My initial problem with p2p in general had to do with the environment I'm using this script in:

in a mesh-network where I do not have control over the setup of the p2p-software which is used on the participating clients - and how (badly usually) it is configured...

I simply do not know who is using the network - and for what purpose.

And because of that I have no control over how the individuals using my uplink have (mis)configured their p2p software.

(...establshing hundreds of connections... not or wrongly specifying the available bandwith... allowing an incredible amount of outgoing traffic...)

I needed to make as sure as possible that p2p-traffic such as bittorrent or edonkey ... would not take over the majority of my bandwith.

The script reflects this hopefully - I'm trying to catch as much p2p as possible and give it a low priority + restricting the bandwith given to it to an acceptable low number in order to assure bandwith for "normal" surfing users (ssh ftp http nntp mail).

I also took the opportunity to prioritize certain clients - most importantly myself  :Wink:  - but also my neighbour and some other mesh-nodes which belong to me and are located at where my brother and other family-members live. These are all given higher priority than the rest of the net I'm sharing my uplink with.

The result is very satisfying - I barely even notice that I'm not the only one using my uplink.

I can share my uplink - others can enjoy a free internet access - without me suffering because of them doing so.

Almost ideal...  :Smile: 

----------

## eulogious

Thanks for the reply!  I do have a couple of things that I would like to point out that I have discovered.  I found a script that will actually tell you that amount of traffic that is leaving each one of the ques.  It's called tcviewer and can be found here http://snaj.ath.cx/tc-viewer/tc-viewer.html.  This way I can see what data is actually moving through the que.  In my reading, I read that that these lines basically give the "minimum" that was promised to each que, no matter what, and then let's it use any other available bandwidth up to the ceiling.

```

      tc class add dev $NETDEVICE parent 1:1 classid 1:10 htb rate $PRIORATE2 ceil $UPRATE burst $BURST prio 1

      tc class add dev $NETDEVICE parent 1:1 classid 1:20 htb rate $PRIORATE2 ceil $UPRATE burst $BURST prio 2

      tc class add dev $NETDEVICE parent 1:1 classid 1:30 htb rate $P2PRATE_LOW ceil $P2PRATE_HIGH prio 3

      tc class add dev $NETDEVICE parent 1:1 classid 1:40 htb rate $PRIORATE1 ceil $WEBUPRATE burst $BURST prio 4

      tc class add dev $NETDEVICE parent 1:1 classid 1:50 htb rate $PRIORATE1 ceil $UPRATE burst $BURST prio 5

      tc class add dev $NETDEVICE parent 1:1 classid 1:60 htb rate $PRIORATE1 ceil $WEBUPRATE prio 6 

```

You are correct about the "amount" of bandwidth I am using is too much.  This is only for my home network, that only I use.  I am the only one who VPNs in, or SSHes in.  I don't do both at the same time.  So that is why those are the same.  And, yes, they will fight over the traffic if I VPN, and SSH in at the same time, which I never do.  I don't plan on having anyone else use my connection.  

The reason that I even have so many ques, was so that I could actually see what traffic was following, and the marking part of my script was working correctly for debugging purpose.  I just decided to leave it that way.  Keep in mind that this is at my house with just me and my girlfriend, so it's not like there's a ton of bandwidth usage.  If I was really going to use this in a more bandwidth intensive environment I would change this, since it's doesn't "add" up to 90k.  The 12k thing, I totally misunderstood that comment.  I will change that tonight.  Why is that?  Is it a limitation with HTB or what?  That's kinda wierd.  In my experiments this setup works good for my personal use.  It's not "perfect" for someone who wants to implement this in a different environment, but if you are trying to implement this, you should be able to read this and see that.  Before I used this in my network, I made sure I understood about 95% of the script, and then modified it to my needs.  Anybody else should also do that.  If someone is going to be SSHing and VPNing at the same time, things will get a little slow the way it's written now, but doesn't effect me.

P2P is a total pain, again.  And you are right that it won't grab encrypted traffic.  I guess that's the point of encryption, right?  I have to use encryption since I have a comcast account, and they are throttling bittorrent traffic, which means that inorder to get around that, use encryption and they can't analyze it.  So it would be hard for me to be able to grab that same traffic, if comcast can't either.  But either way, again since this is just for my own personal use, it's not that big of a deal to me.  It actually works pretty well, and catches about 75% of the bittorent traffic.  If I wasn't using Azuerus to throttle uploads, I would be happy with the upload not maxing out my connection, which was happening before.

I really do like the idea of being able to prioritize certain IPs.  That's why I left that there.  It doesn't effect me now, because I am the only one using the connection.  But good job breaking that down and making that happening.  I wouldn't have been able to figure that out.  

All in all this script again, kicks ass.  It's simple, and "easy" to read.  Anyone can setup QoS with a little bit of time and experimenting using this script.  My situatuion is unique, but I was able to adapt it to my needs.  TCViewer is a really good script if you want to see real time bandwidth usage.  Really helped me out in figuring out what worked and what didn't when separating the traffic.  Does that all makes sense?  Let me know.  Thanks again Jomen!

----------

## jomen

The tc-viewer-script seems nice - unfortunately I can't use it - at least not directly.

The router this is running on only has 4 MB Flash + 16 MB RAM -

which is quite tight and leaves no room for perl.

```
iptables -nvL -t mangle
```

does it close enoug for me.

 *Quote:*   

> 
> 
> ```
> #SSH
> 
> ...

 

Why are you doing

```
-m mark --mark $MARKPRIO_X -j RETURN 
```

only after all the checks already have been done?

My purpose for using this *before* the checks was:

if there is a mark already - no additional check is done - the traffic is already identified then - 

this is supposed to make it faster by saving useless checks that only will come up with an id (for the packet) which was already there

And with bittorrent and the like it will in fact defeat your effort - each packet has to be positively identified as p2p as it is now.

Which layer 7 cannot reliably do when it comes to filesharing...

Doing it "my" way - only a few packets need to be identified - and every packet belonging to the entire connection the identified packet was in will be marked as p2p.

That is the purpose of 

-j CONNMARK --restore-mark

followed directly by

-m mark --mark $MARKPRIO_1 -j RETURN

at the beginning.

As it is now

-j CONNMARK --save-mark after each check is not really useful.

Why? Because you do not use the saved mark but do the check all over again for the next packet

- you only need it once - at the end of all the checks.

And for a positively matched packet - you never get to 

-j CONNMARK --save-mark

because of:

-m mark --mark $MARKPRIO_X -j RETURN

you have right before that

Keep in mind: this is the way ONE packet goes - the next has to pass the checks again

I found a lot of my info here:

http://www.lartc.org

the site was apparently down when I checked - so I can't provide more accurate pointers - for the question about the 12kbit minimum for instance.

As I understood it (as I remember):

it *can* be made smaller when setting up the root qdisc - but calculations for each packet are much more expensive then - a thing I could not do with the above mentioned

200 MHz MIPS processor in the home-router

and here:

http://www.docum.org/docum.org/faq/cache/

for instance

HTH

----------

## eulogious

Thank you so much for explaining the CONNMARK, it wasn't making that much sense (man pages can be confusing as all hell), and now it makes a lot more, and again, I stand corrected.  I was in school for networking about 6 months ago, and I dropped out because I got a job working on mainframe computers.  I know, different fields, but a good job, is a good job.  My point is that I have learned alot about this in school, but dropped out before I got into firewalls and such, and that am I still new and learning.  Thanks for explaining all this to me.  

This script is running on a p4 1.6 with 512MB of ram, and running only a firewall and apache, so I think that I have plenty of processing power, if that is why you said to only use 12k.  My CPU maxes out on a normal basis at about 2%, so I think it can handle that part of it  :Smile:   Anything else that you can think of?  

Different subject, do you understand firewalls at all?  I think that I have a good script for my firewall, but again, I am only assuming because I honestly don't know.  From what I have read, it seems ok, and it does what I want it too.  

Thanks again for taking the time to help me, its nice to talk to someone who really seems to know alot about this, and is willing to answer my questions.

DJH

----------

## jomen

just found this post because I wanted to refresh my memory about why there is the 12kbit thing...

frankO here explains it quite well:

http://forums.vortech.net/read.php?8,53135,53851

some more links inside too...

 *Quote:*   

> do you understand firewalls at all?

 

If I look at the rules for an existing firewall long enough I probably get what they are trying to do  :Wink: 

This does not mean that I would have been able to come up with a complex set of rules.

I learn while and when I have to...like with the shaping-script here which took me *days* to create it.

I only have a very simple setup at my laptop - it does everything I need:

...took an example I found somewhere and adapted it...

```
# allow local-only connections

iptables -A INPUT  -i lo -j ACCEPT

# free output on any interface to any ip for any service (equal to -P ACCEPT)

iptables -A OUTPUT -j ACCEPT

# permit answers on already established connections

# and permit new connections related to established ones (eg active-ftp)

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# incoming from my home-LAN

iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT

iptables -A INPUT -s 10.0.0.0/24 -m state --state NEW -j ACCEPT

# Log everything else:  What's Windows' latest exploitable vulnerability?

iptables -A INPUT -j LOG --log-prefix "FIREWALL:INPUT "

# set a sane policy:    everything not accepted > /dev/null

iptables -P INPUT    DROP

iptables -P FORWARD  DROP

iptables -P OUTPUT   DROP

# be verbose on dynamic ip-addresses     (not needed in case of static IP)

echo 2 > /proc/sys/net/ipv4/ip_dynaddr

# disable ExplicitCongestionNotification - too many routers are still ignorant

echo 0 > /proc/sys/net/ipv4/tcp_ecn
```

Try me - or all the others who are reading this  :Wink: 

If I have the time...

----------

## eulogious

Ok, so if I am reading the link correctly, it should be good below 12K?  I am not getting this error message so I would think that I am ok.  I really don't know.  If you use his example of default 10, and then you make it ten times smaller (1), then you should be ok, as long as you don't set your ques to anything below 1.2KBps which is ten times smaller than 12.  That is assuming I am reading this correctly.  I am like you, I usually don't learn stuff till there is a need.  If it took you days to make this, then it would have taken me weeks  :Smile:   Without this script I seriously would have been lost.  

Here's my firewall script.  This has been taken in chunks from serveral different places, mostly these forums, but I really can't recall what piece goes to who, so sorry about not giving anyone any credit.  I made this script about 7 months ago when I was in a hurry, and I didn't document my sources.  If this looks familiar to anyone, just say so, and I will give credit where credit is due.

```

#! /sbin/runscript

depend() {

        need net

}

start() {

        ebegin "Starting Firewall v1.7"

#

# 1.0 Created on 6-7-07 by eulogious with help from many in the gentoo forums!

# 1.1 Hardened Policies 1-30-08

# 1.2 Fixed Server Web Browsing Issue, Hardened Policies 1-31-08

# 1.3 Fixed Port Forwarding Issues 2-8-08

# 1.4 Updated for Watchdog2, made into an init script, corrected SSH forwarding issues 2-21-08

# 1.5 Added Squid Transparent Proxy 2-29-08

# 1.6 Took out stopping and clearing the mangle tables when stopping firewall.  Messes with QoS 3-6-08

# 1.7 Fixed shutting down issues.  Stops indepedantly without messing with QoS at all 3-7-08

#

# The location of the iptables and kernel module programs 

#

#   If your Linux distribution came with a copy of iptables,

#   most likely all the programs will be located in /sbin.  If

#   you manually compiled iptables, the default location will

#   be in /usr/local/sbin 

#

# ** Please use the "whereis iptables" command to figure out

# ** where your copy is and change the path below to reflect

# ** your setup

#

IPTABLES=/sbin/iptables

DEPMOD=/sbin/depmod

MODPROBE=/sbin/modprobe

#Setting the EXTERNAL and INTERNAL interfaces for the network

#

#  Each IP Masquerade network needs to have at least one

#  external and one internal network.  The external network 

#  is where the natting will occur and the internal network

#  should preferably be addressed with a RFC1918 private address

#  scheme.

#

#  For this example, "eth0" is external and "eth1" is internal" 

#

#

#  NOTE:  If this doesnt EXACTLY fit your configuration, you must

#         change the EXTIF or INTIF variables above. For example:

#

#            If you are a PPPoE or analog modem user:

#

#               EXTIF="ppp0" 

#

#

SQUID_SERVER="192.168.2.12"

SQUID_PORT="3128"

EXTIF="eth0"

INTIF="eth1"

LOCALNETWORK="192.168.2.0/24"

PUBLICPORTS="1024:65535"

echo "External Interface:  $EXTIF"

echo "Internal Interface:  $INTIF"

EXTIP="`/sbin/ifconfig eth0 | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`"

echo "External IP:  $EXTIP"

#======================================================================

#== No editing beyond this line is required for initial MASQ testing == 

#echo "loading modules: "

# Need to verify that all modules have all required dependencies

#

#echo "  - Verifying that all kernel modules are ok"

#$DEPMOD -a

# With the new IPTABLES code, the core MASQ functionality is now either 

# modular or compiled into the kernel.  This HOWTO shows ALL IPTABLES

# options as MODULES.  If your kernel is compiled correctly, there is

# NO need to load the kernel modules manually.

#

#  NOTE: The following items are listed ONLY for informational reasons. 

#        There is no reason to manual load these modules unless your

#        kernel is either mis-configured or you intentionally disabled

#        the kernel module autoloader.

#

# Upon the commands of starting up IP Masq on the server, the 

# following kernel modules will be automatically loaded:

#

# NOTE:  Only load the IP MASQ modules you need.  All current IP MASQ

#        modules are shown below but are commented out from loading.

# =============================================================== 

#echo "----------------------------------------------------------------------"

#Load the main body of the IPTABLES module - "iptable"

#  - Loaded automatically when the "iptables" command is invoked 

#

#  - Loaded manually to clean up kernel auto-loading timing issues

#

#echo "ip_tables, "

#$MODPROBE ip_tables

#Load the IPTABLES filtering module - "iptable_filter"

#  - Loaded automatically when filter policies are activated 

#Load the stateful connection tracking framework - "ip_conntrack"

#

# The conntrack  module in itself does nothing without other specific

# conntrack modules being loaded afterwards such as the "ip_conntrack_ftp" 

# module

#

#  - This module is loaded automatically when MASQ functionality is

#    enabled

#

#  - Loaded manually to clean up kernel auto-loading timing issues

#

#echo "ip_conntrack, " 

#$MODPROBE ip_conntrack

#Load the FTP tracking mechanism for full FTP tracking

#

# Enabled by default -- insert a "#" on the next line to deactivate

#

#echo "ip_conntrack_ftp, " 

#$MODPROBE ip_conntrack_ftp

#Load the IRC tracking mechanism for full IRC tracking

#

# Enabled by default -- insert a "#" on the next line to deactivate

#

#echo "ip_conntrack_irc, " 

#$MODPROBE ip_conntrack_irc

#Load the general IPTABLES NAT code - "iptable_nat"

#  - Loaded automatically when MASQ functionality is turned on

#

#  - Loaded manually to clean up kernel auto-loading timing issues 

#

#echo "iptable_nat, "

#$MODPROBE iptable_nat

#Loads the FTP NAT functionality into the core IPTABLES code

# Required to support non-PASV FTP.

#

# Enabled by default -- insert a "#" on the next line to deactivate 

#

#echo "ip_nat_ftp, "

#$MODPROBE ip_nat_ftp

#Loads the IRC NAT functionality into the core IPTABLES code

# Required to support NAT of IRC DCC requests

#

# Disabled by default -- remove the "#" on the next line to activate 

#

#echo -e "ip_nat_irc"

#$MODPROBE ip_nat_irc

#echo "----------------------------------------------------------------------"

# Just to be complete, here is a partial list of some of the other 

# IPTABLES kernel modules and their function.  Please note that most

# of these modules (the ipt ones) are automatically loaded by the

# master kernel module for proper operation and don't need to be

# manually loaded. 

# --------------------------------------------------------------------

#

#    ip_nat_snmp_basic - this module allows for proper NATing of some

#                        SNMP traffic

#

#    iptable_mangle    - this target allows for packets to be

#                        manipulated for things like the TCPMSS

#                        option, etc.

#

# --

#

#    ipt_mark       - this target marks a given packet for future action.

#                     This automatically loads the ipt_MARK module

#

#    ipt_tcpmss     - this target allows to manipulate the TCP MSS

#                     option for braindead remote firewalls.

#                     This automatically loads the ipt_TCPMSS module

#

#    ipt_limit      - this target allows for packets to be limited to

#                     to many hits per sec/min/hr

#

#    ipt_multiport  - this match allows for targets within a range

#                     of port numbers vs. listing each port individually

#

#    ipt_state      - this match allows to catch packets with various

#                     IP and TCP flags set/unset

#

#    ipt_unclean    - this match allows to catch packets that have invalid

#                     IP/TCP flags set

#

#    iptable_filter - this module allows for packets to be DROPped,

#                     REJECTed, or LOGged.  This module automatically

#                     loads the following modules:

#

#                     ipt_LOG - this target allows for packets to be

#                               logged

#

#                     ipt_REJECT - this target DROPs the packet and returns

#                                  a configurable ICMP packet back to the

#                                  sender.

#

#echo "Done loading modules.\n"

#CRITICAL:  Enable IP forwarding since it is disabled by default since 

#

#           Redhat Users:  you may try changing the options in

#                          /etc/sysconfig/network from:

#

#                       FORWARD_IPV4=false

#                             to

#                       FORWARD_IPV4=true

#

# Dynamic IP users:

#

#   If you get your IP address dynamically from SLIP, PPP, or DHCP, 

#   enable this following option.  This enables dynamic-address hacking

#   which makes the life with Diald and similar programs much easier.

#

echo "Enabling DynamicAddr..."

echo "1" > /proc/sys/net/ipv4/ip_dynaddr 

# Enable simple IP forwarding and Masquerading

#

#  NOTE:  In IPTABLES speak, IP Masquerading is a form of SourceNAT or SNAT.

#

#  NOTE #2:  The following is an example for an internal LAN address in the 

#            192.168.0.x network with a 255.255.255.0 or a "24" bit subnet mask

#            connecting to the Internet on external interface "eth0".  This

#            example will MASQ internal traffic out to the Internet but not

#            allow non-initiated traffic into your internal network.

#

#

#         ** Please change the above network numbers, subnet mask, and your

#         *** Internet connection interface name to match your setup 

#

#Clearing any previous configuration

#

#  Unless specified, the defaults for OUTPUT is DROP

#    The default for INPUT, and FORWARD is DROP (REJECT is not a valid policy)

echo "Clearing any existing rules and setting default policy..."

$IPTABLES -P INPUT DROP

$IPTABLES -P OUTPUT ACCEPT

$IPTABLES -P FORWARD DROP

$IPTABLES -F

$IPTABLES -F INPUT

$IPTABLES -F OUTPUT

$IPTABLES -F FORWARD

$IPTABLES -F -t nat

$IPTABLES -X

# Uncomment to allow ssh to Watchdog from the Internet

#echo "Enabling SSH on port 2022 for Watchdog2..."

#$IPTABLES -A INPUT -i $EXTIF -m state --state NEW -m tcp -p tcp --dport 2022 -j ACCEPT

#Transparent Squid Proxy/Web Accelerator

echo "Enabling Transparent Proxy..."

iptables -t nat -A PREROUTING -i $INTIF -p tcp --dport 80 -j DNAT --to $SQUID_SERVER:$SQUID_PORT

echo "Enabling SSH on port 2222 for Watchdog2..."

$IPTABLES -A INPUT -i $EXTIF -m state --state NEW -m tcp -p tcp --dport 2222 -j ACCEPT

echo "Forwading SSH To Buckfutter..."

$IPTABLES -t nat -A PREROUTING -i $EXTIF -p tcp --dport 22 -j DNAT --to 192.168.2.2

$IPTABLES -A FORWARD -i $EXTIF -o $INTIF -p tcp -d 192.168.2.2 --dport 22 -j ACCEPT

#Bittorent

echo "Forwarding Bittorent Port 8888 to 192.168.2.4..."

$IPTABLES -t nat -A PREROUTING -i $EXTIF -p tcp --dport 8888 -j DNAT --to 192.168.2.4

$IPTABLES -A FORWARD -i $EXTIF -o $INTIF -p tcp -d 192.168.2.4 --dport 8888 -j ACCEPT

$IPTABLES -t nat -A PREROUTING -i $EXTIF -p udp --dport 8888 -j DNAT --to 192.168.2.4

$IPTABLES -A FORWARD -i $EXTIF -o $INTIF -p udp -d 192.168.2.4 --dport 8888 -j ACCEPT

echo "Allowing all connections out and only existing and related ones in..."

$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

$IPTABLES -A INPUT -m state --state NEW -i ! $EXTIF -j ACCEPT

$IPTABLES -A FORWARD -m state --state NEW -i ! $EXTIF -j ACCEPT

$IPTABLES -A FORWARD -i $EXTIF -o $INTIF -m state --state ESTABLISHED,RELATED -j ACCEPT

$IPTABLES -A FORWARD -i $EXTIF -o $INTIF -m state --state NEW,INVALID -j DROP

$IPTABLES -A FORWARD -i $INTIF -o $EXTIF -j ACCEPT

$IPTABLES -A FORWARD -j LOG

$IPTABLES -t nat -A POSTROUTING -o $EXTIF -j SNAT --to $EXTIP

#Allow Connections From Local Network

echo "Allowing Local Connections..."

$IPTABLES -A INPUT -i lo -j ACCEPT

$IPTABLES -A OUTPUT -o lo -j ACCEPT

#Allow pptpd connections (port 1723)

echo "Allowing PPTP(VPN) Connections..."

$IPTABLES -A OUTPUT -p 47 -j ACCEPT

$IPTABLES -A INPUT -p 47 -j ACCEPT

$IPTABLES -A FORWARD -s 192.168.2.0/24 -d 192.168.2.0/24 -j ACCEPT

$IPTABLES -A INPUT -p tcp --dport 1723 -j ACCEPT

$IPTABLES -A INPUT -s 192.168.2.0/24 -d 192.168.2.0/24 -j ACCEPT

#DNS

echo "Allowing DNS..."

$IPTABLES -A INPUT -p udp -s 0/0 --sport 1024:65535 -d $EXTIP --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT

$IPTABLES -A OUTPUT -p udp -s $EXTIP --sport 53 -d 0/0 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT

$IPTABLES -A INPUT -p udp -s 0/0 --sport 53 -d $EXTIP --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT

$IPTABLES -A OUTPUT -p udp -s $EXTIP --sport 53 -d 0/0 --dport 53 -m state --state ESTABLISHED -j ACCEPT

# Here we define a new chain which is going to handle

# packets we don't want to respond to

# limit the amount of logs to 10/min

$IPTABLES -N Firewall

$IPTABLES -A Firewall -m limit --limit 10/minute -j LOG --log-prefix "Firewall: "

$IPTABLES -A Firewall -j DROP

# log those packets and inform the sender that the packet was rejected

$IPTABLES -N Rejectwall

$IPTABLES -A Rejectwall -m limit --limit 10/minute -j LOG --log-prefix "Rejectwall: "

$IPTABLES -A Rejectwall -j REJECT

# here we create a chain to deal with unlegitimate packets

# and limit the number of alerts to 10/min

# packets will be drop without informing the sender

$IPTABLES -N Badflags

$IPTABLES -A Badflags -m limit --limit 10/minute -j LOG --log-prefix "Badflags: "

$IPTABLES -A Badflags -j DROP

# A list of well known combination of Bad TCP flags

# we redirect those to the Badflags chain

# which is going to handle them (log and drop)

$IPTABLES -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j Badflags

$IPTABLES -A INPUT -p tcp --tcp-flags ACK,PSH PSH -j Badflags

$IPTABLES -A INPUT -p tcp --tcp-flags ACK,URG URG -j Badflags

$IPTABLES -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j Badflags

$IPTABLES -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j Badflags

$IPTABLES -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j Badflags

$IPTABLES -A INPUT -p tcp --tcp-flags ALL ALL -j Badflags

$IPTABLES -A INPUT -p tcp --tcp-flags ALL NONE -j Badflags

$IPTABLES -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j Badflags

$IPTABLES -A INPUT -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j Badflags

$IPTABLES -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j Badflags

# Accept certain icmp message, drop the others

# and log them through the Firewall chain

echo "Allowing some ICMP requests, but not all..."

# 0 => echo reply

$IPTABLES -A INPUT -p icmp --icmp-type 0 -j ACCEPT

# 3 => Destination Unreachable

$IPTABLES -A INPUT -p icmp --icmp-type 3 -j ACCEPT

# 11 => Time Exceeded

$IPTABLES -A INPUT -p icmp --icmp-type 11 -j ACCEPT

#8 => Echo

# avoid ping flood

$IPTABLES -A INPUT -p icmp --icmp-type 8 -m limit --limit 1/second -j ACCEPT

$IPTABLES -A INPUT -p icmp -j Firewall

# Drop netbios from the outside, no log, just drop

echo "Dropping netbios from the outside..."

$IPTABLES -A INPUT -p udp --sport 137 --dport 137 -j DROP

echo "Enabling SNAT (MASQUERADE) functionality on $EXTIF..."

$IPTABLES -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE

$IPTABLES -A FORWARD -i $EXTIF -j ACCEPT

# Dropping Everything Else

echo "Blocking Everything Else And Logging It..." 

$IPTABLES -A INPUT -j Rejectwall

echo "Enabling forwarding..."

echo "1" > /proc/sys/net/ipv4/ip_forward

echo "Successfully Started Firewall v1.7 On Watchdog2"

eend $?

}

stop() {

        ebegin "Stopping Firewall v1.7"

IPTABLES=/sbin/iptables

        $IPTABLES -P INPUT ACCEPT

        $IPTABLES -P OUTPUT ACCEPT

        $IPTABLES -P FORWARD ACCEPT

        $IPTABLES -F

        $IPTABLES -F INPUT

        $IPTABLES -F OUTPUT

        $IPTABLES -F FORWARD

        $IPTABLES -F -t nat

        $IPTABLES -X

        eend $?

}

```

This basically goes through and tries its best to get rid of a lot of bad things that come to my computer.  The only way that I have of really testing this is by running Shields Up at http://grc.com.  This site test your firewall for open ports, etc.  Only the ones that I have specified in here are open, and the rest are "stealth".  Think it works.  I don't believe I have been hacked yet  :Smile:  (knock on wood).  It's pretty simple, and I tried to comment on what I was doing.  Let me know what you think!

DJH

----------

## jomen

Quote from frankO

 *Quote:*   

> For smaller minimal rates specify r2q 1 when creating qdisc - it is good from 12 kbit which should be enough.

 

Using 10kbit instead of 12kbit minimum might not be wrong - it just does not make any sense because

with r2q 1 the minimum rate is 12kbit

You will just not get 10kbit precision...

(that is how I read it...)

Your firewall looks o.k. to me...but again - I'm no expert.

I don't understand the #DNS part

are you running a DNS-server?

are these rules needed?

OUTPUT is already allowed by the default policy, is it not?

----------

## eulogious

Yes, I am running a DNS server.  I am also running squid, and apache (for MRTG, and intranet) on the box.  I think that I am going to setup webdav for ical sharing also.  I honestly don't know if those rules are necessary for the output.  I do need dns open coming in I believe for queries, and what not but I could be wrong.  Any suggestions from anyone are welcome on this.  When I made the script again, I was in a hurry, and it worked.  If it ain't broke don't fix it.  I figure it wasn't hurting anything, since I trust my own network, so why bother?  

Thanks for clarifying on the queuing issue.  I will have to monitor it for a while to see what the results are.  So far it seems to be getting really close to 10KBps when my upload is maxed out.  But either way, I think that it's pretty darn close to what works for me  :Wink:   This is all really over kill for me.  Who really needs to have all of this on their home network?  But hey, I figured I got the box, I like networking, I also like gentoo, so I might as well make it a project  :Smile:   Thanks for all of your help man.  Seriously, you have helped me out alot.  Peace,

DJH

----------

## alex.blackbit

wow, a lot of scripts are floating around here.

please don't get me wrong, but do they really provide more functionality than e.g. shorewall?

if that's the case, maybe it would be a good idea to pack these things together as a addon to shorewall (or anything similar) so that

   * the logic and the configuration are clearly separated

   * it can be configured and used in a easy way

   * it is accessible to a lot of people

traffic control is often needed but quite difficult to configure, so such good scripts are like pure gold. why not share that with the rest of the world.

two thumbs up for all the work!

----------

## eulogious

Hello,

I have honestly never used shorewall.  I personally try to stay away from things that "automagically" create scripts for you, especially when dealing with security.  But that's just me.  The machine that these scripts are running on is a headless machine with no x windows, so I find it just as easy to write a script, as it is to run one that will write it for you.   I am sure that shorewall works great, but I like to be able to go in and tinker with the script/app and make it the way that I want.  Again, I have not used shorewall, so I don't know what it's like to configure.  I also wanted to learn about all of this stuff.  I love networking and don't mind taking my network down and breaking it if I can learn something new and improve on it.  That's why I choose to make scripts.  This also makes it easy to start and stop each of these if the need ever comes up.  Some say that you iptables-save and iptables-restore works just as well.  I choose this way for personal reasons, either way looks like it works (I have not personally tried iptable-save or iptables-restore).  

Bundling these up with shorewall, I wouldn't even know where to start.  Anyone is welcome to use my scripts for whatever they need.  The whole reason why I posted them was to get one of them out there because it was really good, and worked well for me.  The forums have given me so much, it's the least that I could do was contribute in what ways that I can back to the community.  Using both of these scripts together works great for my network.  You can stop them seperately without clearing any of the rules of the script that is still running (took me a while to figure that out  :Neutral: ).  Like I said in my first post though, make sure that you do a little reading before you dive in.  There is enough info in this thread to basically figure out almost anything that you need to having to do with traffic shaping.  Both of the scripts are also pretty well commented so you should be able to figure out the flow of things just by doing a little research  :Smile:   Glad someone else liked 'em!

DJH

----------

## jomen

pure gold... - wow - thanks  :Smile: 

 *Quote:*   

> do they really provide more functionality than e.g. shorewall?

 

I don't know shorewall and others - but I bet similar things can be done.

This tc-script was made for a wireless-home-router running OpenWRT - see somewhere above...

Making a script was the only option to me as shorewall ... is not available/would not run on this small embedded device.

If the work done can be beneficial for others - even better!

But as it is made for a special case it is difficult to adapt by others to their needs.

In fact - it is not - but that is me - I know what I made and how it works.

Maybe I'm just not able to write useful comments so others would be able to see through.

Feel free to do that  :Smile: 

It actually is already documented on the wiki of the project I made this for:

http://leipzig.freifunk.net/

http://wiki.leipzig.freifunk.net/Traffic-Shaping

This is in german but I translated the comments as you can see.

I could put both versions there too.

Separating logic and configuration is a todo already

I could post it when it is done sometime...

----------

## alex.blackbit

 *Quote:*   

> shorewall ... is not available/would not run on this small embedded device.

 it should run everywhere, since it is just a way to ease the syntax of both iptables and tc (and others). there are no running daemons or anything. *Quote:*   

> That's why I choose to make scripts.

 shorewall itself is just a set of scripts, maybe you thought that it is something very bloated, but it isn't. again, there are no running daemons. you say just "shorewall start", then the scripts adjust the needed settings and that's it.

maybe it's worth taking a look at it, but you decide yourself, since i am not steve ballmer.   :Laughing: 

----------

## jomen

From what I just read about shorewall I have the impression that it is not much of a difference whether to use it

or to use tc and iptables directly.

It has its own peculiarities and one needs to know how to operate it.

Just as simple or difficult as iptables + tc IMO.

I actually was a little scared when I was browsing through...  :Wink: 

And: you still need to have the knowledge about the internals of what you are about to set up.

However - I found out that shorewall is available for the current release of OpenWRT ("Kamikaze") now.

But not for the previous release.

We here are still using (and will be for some time) this previous release "Whiterussian".

It is based on a 2.4 kernel and has stable support for broadcom wireless devices - these are built into almost all the routers we are using here.

The support for this in "Kamikaze" is not yet stable - and "Kamikaze" is organized very differently than "Whiterussian"

Since the Web-Interface our community-project uses is also built around Whiterussian it is an ongoing work to port it to Kamikaze.

Until all this is done - the possibility to use shorewall for the purpose of easing the setup of iptables-rules is not existant.

Can/does it produce a set of standard iptables rules such as those in the script?

Or does shorewall need to be available on the device to put the rules created with it into effect?

Besides all this - memory is really tight on these devices - one has to concider if a program really *is* neccesary or if one can well do without.

From what I saw: I'll stay away from shorewall for now.

It would be a thing to learn for which I have no use currently.

----------

## void4ever

Thank you so much for the reply's, i'm sorry i haven't said anything sooner but a few other things came up over the course of a few weeks.

I've actually found a QOS script that works very well for me in my tests so far.

http://freshmeat.net/projects/prometheus-qos/

The author has been very helpful via email as most if not all of the support for the program is in Czech.  :Smile: 

I've run into 1 other problem i'm hoping you maybe able to help with, if i need to create a new post i will, but we'll start here.

Currnetly we have a PIX 501 doing all of our firewalling, as well as routing a block of public IP's to different servers behind it. For example the pix routes 111.111.111.111 to our web server on the lan, 111.111.111.112 to our as400on the lan, and 111.111.111.113 is used for all normal lan traffic out to the net (users and such).

I need to put the qos box in between the pix and the rest of the network, but when i do that the pix's routing goes to hell. From that point on all traffic from the web server, as400, and general users are all coming from 1 IP.

I thought i had the gentoo box passing traffic as if it wasn't there, but still qos'ing, but it would appear i do not, or what i'm trying to do may not be possible?

Let me list the current setup:

Eth0 = LAN SIDE 

172.16.1.200    255.255.0.0

Eth1 = WAN SIDE

172.16.1.201    255.255.0.0    gateway(pix501) 172.16.1.1

Running this script at startup to get nat rolling:

LOCALNET="172.16.0.0/255.255.0.0"

iptables -P INPUT ACCEPT

iptables -P OUTPUT ACCEPT

iptables -P FORWARD ACCEPT

iptables -t nat -P POSTROUTING ACCEPT

iptables -t nat -P PREROUTING ACCEPT

iptables -t filter -F

iptables -t mangle -F

iptables -t nat    -F

iptables -t nat -A POSTROUTING -s $LOCALNET -o eth1 -j MASQUERADE

iptables -A FORWARD -m state --state ESTABLISHED,RELATED -d $LOCALNET -j ACCEPT

echo 1 > /proc/sys/net/ipv4/ip_forward

I'm sure i have something wrong in my iptables but i'm not sure what yet (still trying to learn  :Smile:  )

So over all my question would be, is what i'm trying to do possible. I'd like the pix's IP routing to be unaffected by the qos machine. Almost making the qos machine completely transparent i guess, while still having the ability to qos the traffic flowing through it.

----------

## alex.blackbit

there is the possibility to set up a "bridgewall". that should leave all the ip's on the endpoints as they are but you can affect the traffic.

but i am unsure if there is a good way to do that with linux, i heard from one of my friends that openbsd provides quite cool features for that.

----------

## Hu

 *void4ever wrote:*   

> 
> 
> I need to put the qos box in between the pix and the rest of the network, but when i do that the pix's routing goes to hell. From that point on all traffic from the web server, as400, and general users are all coming from 1 IP.
> 
> iptables -t nat -A POSTROUTING -s $LOCALNET -o eth1 -j MASQUERADE
> ...

 

The MASQUERADE target rewrites the source address of the packet to make it look like the packet came from the system running the MASQUERADE target.  This is very useful for NAT, but it is not what you want here.  Omit that rule so that the Linux machine applies a target of ACCEPT to the traffic.  This will pass the packet unchanged to the PIX.  Depending on your network topology, you may have problems with the PIX bypassing the Linux machine for traffic from the Internet.

----------

## void4ever

Ahh i see what your saying Hu, that makes sense. However if i pull that line out all routing stops completely. I assume it's because i no longer have a line in there telling it the source and output nics?

LOCALNET="172.16.0.0/255.255.0.0"

iptables -P INPUT ACCEPT

iptables -P OUTPUT ACCEPT

iptables -P FORWARD ACCEPT

iptables -t nat -P POSTROUTING ACCEPT

iptables -t nat -P PREROUTING ACCEPT

iptables -t filter -F

iptables -t mangle -F

iptables -t nat    -F

iptables -A FORWARD -m state --state ESTABLISHED,RELATED -d $LOCALNET -j ACCEPT

echo 1 > /proc/sys/net/ipv4/ip_forward

Now with that line gone none of my rules mention eth1 as a output. Would i need to add a line similar to the FORWARD line, but specifying eth1? Like 

iptables -A FORWARD -m state --state ESTABLISHED,RELATED -d eth1 -j ACCEPT

I apologize i'm still very new to iptables.

Void4ever

----------

## void4ever

Or maybe a line like this perhaps?

iptables -A FORWARD --in-interface eth0 --out-interface eth1 \ -j ACCEPT

Void4ever

----------

## void4ever

So alex.blackbit i gave your idea a try this afternoon. Using bridging i was indeed able to get the linux box to pass traffic as if it wasn't there, and IP resolution was working perfectly for my servers. The problem with that though is it broke my qos, the script i'm using relys on 2 interfaces and since bridging joins eth0 and 1 together the script was acting very odd.

I tried to setup proxy arp which i think would be the better bridging solution in my case (because it still uses eth0 and 1), but i can't seem to get it to route traffic at all. Tried using these two guides, though i may have done something incorrectly.

http://www.spenneberg.com/talks/linux-kongress2002/ralf-spenneberg.bridgewall.pdf

http://www.sjdjweis.com/linux/proxyarp/

Hu's suggestion might pan out as well once i figure out what i'm missing there.

Void4ever

----------

## Hu

The policy on FORWARD is ACCEPT, so the packet will be accepted whether you match it with a rule in the chain or it falls off the bottom and is accepted by the policy.  The system should be using the standard routing table, so there is no problem with having a ruleset that does not mention eth1.  I suspect your problem is exactly what I mentioned previously: routing problems related to asymmetric routes since the PIX now sees where to send return traffic.

Please provide the output from ip addr ; ip route on the Gentoo machine.  This will serve as a starting point to showing your network topology and the addresses of each network.  Also, post the output of iptables-save -c.  I believe I know how your rules look based on the script, but it is safer to analyze the rules that are loaded, rather than the rules which should be loaded.  Finally, emerge net-analyzer/tcpdump.  Run it as tcpdump -i any -e -v -n and make a connection from the internal LAN to an Internet site.  When the connection completes or you are satisfied that it will not complete, stop the capture and post its output as well.  Beware that this invocation will capture all traffic entering or leaving the Gentoo machine.  This could produce excessive output if you run it while other users are accessing the system.

----------

