Tc

A Unix/Linux szerverek üzemeltetése wikiből

A hálózatunkba beérkező forgalmat nem tudjuk sajnos igazán jól formázni, mert nincs hatásunk rá. Kb. olyan mit a papíralapú levelezés, a postásnak nem mondhatjuk meg, hogy naponta csak 5 levelet tegyen a levélszekrényünkbe, mert különben gond lesz. Viszont az olyan forgalmat, aminek forrása az általunk felügyelt hálózatban van, azt már könnyen szabályozhatjuk. Erre jó a tc.


Tartalomjegyzék

1 A traffic control architektúrája

1.1 Terminológia

Queueing Discipline (qdisc)

  • Egy eszköz feldolgozási sorának működési algoritmusa

root qdisc

  • A tc az osztályozókat, szűrőket eszközhöz tartozó fa struktórába rendezi. Ez a qdisc kapcsolódik az eszközhöz, éz a fa struktúra kiindulópontja. Ehhez kapcsolódnak az osztályok, qdisc-ek, filterek, ide kerül be minden csomag és jut egyre lejjebb a struktúrán.

Classless qdisc

  • Osztályozásmentes viselkedés, a queue-ba kerülő csomagokat nem szórja szét osztályokba, csak újraütemezi, várakoztatja vagy eldobja. Semmit nem lehet rajta konfigurálni, egyszerűen csak van és lehet használni.

Classful qdisc

  • Osztályokra bontható qdisc. Az osztályokból egy fastruktúra építhető fel. Az ilyen qdisc-eknek már sok (rengeteg) paraméterét lehet beállítani.
    • pfifo_fast
    • Token Bucket Filter (TBF)
    • Stochastic Fairness Queueing (SFQ)
    • PRIO
    • Class Based Queueing (CBQ)
    • Hierarchical Token Bucket (HTB)
    • Intermediate queueing (IMQ) (nem igazi qdisc)

Class (osztály)

  • Egy qdisc-nek több osztálya is lehet, egy osztálynak lehet több gyermek osztálya. Minden osztályhoz tartozik egy qdisc.

Leaf Class (levél osztály)

  • Az a vége az osztályozásnak, innem már csak a kernel elveszi a csomagot, amikor az adott osztályra kerül a sor.

Classifier (osztályozó)

  • Ez dönti el, hogy melyik csomag melyik osztályba kerül tovább.

Filter (szűrő)

  • Az osztályozás a szűrőkkel pontosítható, ha egy csomag paraméterei megfelelnek egy feltételnek, akkor az osztályozó a parancsban meghatározott módon fog eljárni vele.
  • Minden olyan csomag aminek 80-as a forrás portja az a 1:3-as flow-ba kerül besorolásra.
# tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip \
  sport 80 0xffff flowid 1:3

Scheduling (ütemezés)

  • A csomagok ütemezését szolgálja a qdisc-eken keresztül az osztályozó segítségével.

Shaping (formázás)

  • Az határozza meg, hogy egy csomag mikor kerülhet ki a médiumra, hogy az adott paramétereket (sávszélesség, burstösség) teljesítse a csomagfolyam.

Policing (rendelkezés)

  • Meghatárzza, hogy mi történjen a csomaggal. Késleltetést szenvedjen, eldobásra kerüljön (a Linux csak eldobni tudja, mivel nincs bemeneti sor, vagy legalábbis nem túl használható).

Work-Conserving

  • Ez olyan qdisc, ha van kiküldendő csomag, akkor azt kiküldi.

non-Work-Conserving

  • Ez olyan qdisc, hogy ha van kiküldendő csomag, akkor azt csak akkor küldi ki, ha belefér a paraméterek álatal meghatározott forgalmi mintába (pl. nem lesz túl nagy a burst)

1.2 A tc a kernelben

               Userspace programs
                    ^
                    |
    +---------------+-----------------------------------------+
    |               Y                                         |
    |    -------> IP Stack                                    |
    |   |              |                                      |
    |   |              Y                                      |
    |   |              Y                                      |
    |   ^              |                                      |
    |   |  / ----------> Forwarding ->                        |
    |   ^ /                           |                       |
    |   |/                            Y                       |
    |   |                             |                       |
    |   ^                             Y          /-qdisc1-\   |
    |   |                            Egress     /--qdisc2--\  |
 --->->Ingress                       Classifier ---qdisc3---- | ->
    |   Qdisc                                   \__qdisc4__/  |
    |                                            \-qdiscN_/   |
    |                                                         |
    +---------------------------------------------------------+
  • Az egész nagy doboz a kernel
  • Ha a gépnek szól egy csomag akkor az felfelé megy, ha nem, akkor jobbra

1.3 A hierarchia

Minden interface-nek van egy kimeneti root qdisc-je, az alapértelmezésben pfifo_fast. Minden qdisc-hez és class-hez tartozik egy handle (fogantyú), amivel a későbbi parancsoknál lehet hivatkozni az adott qdisc-re. Egy interfésznek a kimeneti qdisc-en kívűl lehet bemeneti qdisc-je is.

A handle-ök nevei 2 számból állnak <major>:<minor>. az osztályoknak a szülőivel azonos major azonosítóval kell rendelkezniük. A minor azonosítónak pedig egyedinek kell lennie az adott qdiscben és és annak osztályaiban.

1.4 A fa szerkezet

                    1:   root qdisc
                     |
                    1:1    child class
                  /  |  \
                 /   |   \
                /    |    \
                /    |    \
             1:10  1:11  1:12   child classes
              |      |     | 
              |     11:    |    leaf class
              |            | 
              10:         12:   qdisc
             /   \       /   \
          10:1  10:2   12:1  12:2   leaf classes


2 CBQ

A legrégebbi és talán a legkomplexebb qdisc és persze a legelterjedtebb is.

Ha nekiesünk, mint tót az anyjának, akkor érdekes eredményt kaphatunk. Pl ha egy 10 Mbites forgalmat akarunk 1 Mbitre korlátozni, akkor a cbq-val könnyen azt is elérhetjük, hogy az idő 10%-ben teli a sávszélesség és 90%-ban meg üres, pedig nekünk nem ez kellene. Érdemes végig mazsolázni a paramétereket, hogy jól be tudjuk állítani.

A CBQ a link fizikai sávszélessége alapján kiszámolja, hogy mekkora legyen az átlagos idő, amikor nem tesz ki csomagokat a mediumra (avgidle), hogy a sávszélesség a kivánt legyen, erre exponenciálisan súlyozott mozgó átlagot használ. Ebből tudja, hogy meddig kell adnia ami a csövön befér és meddig nem kell adnia. Egy túlterhelt linknek lehet akár negatív avgidle értéke is, akkor egyszerűen nem ad csomagot amig ismét el nem éri a kívánt értéket. Viszont egy alacsony kihasználtságú linken óriási burst-ök is kialakulhatnak.

2.1 CBQ paraméterek

avpkt

  • Átlagos csomag hossz (byte-ban). Ez szükséges a minidle kisámításához, ami a maxburstből van származtatva, de azt csomagban mérik.

bandwidth

  • Az eszköz fizikai sávszélessége. Ez az idle time kiszámításához szükséges.

cell

  • Ennyi idő alatt rakunk ki a vonalra egy csomagot. Ez adja a granularitást. Csomagméret alapján nőhet. Általában 8 az értéke, de 2 egészszámú többszörösének kell lennie.

maxburst

  • A maxidle kiszámításához használják. Ha a maxidle és az avgidle közel azonos, akkor gyakran burst-ösödhet, mielött lekapcsolja az adást. Érdemes magasabbra állítani, így toreránsabb lesz a burst-ökhöz, nagy burst miatt nem kapcsolja le az eszközt. A maxidle csak ezen a paraméteren keresztül állítható.

minburst

  • Mivel a CBQ túlterhelésnél hajlamos az eldugulásra, az lenne a jó, ha kiszámolnánk, hogy mennyi az idle time aztán küldenénk egy csomagot, majd pihennénk egy idle time-nyi időt. De sajnos ez a kernel ütemezője miatt sem olyan egyszerű, hiszen nehéz kevesebb mint 10 ms-nél rövidebbre ütemezni egy eseményt. Így mégis csak jobb, ha először sokat adunk és utána csak minburst-nyi csomagokat rakunk ki egyszerre, aztán megint pihenünk egy kicsit. A nagyobb minburst érték jobb forgalomformázáshoz vezet nagyobb időre vetítve, de ms-os felbontásnál nagyobb burst-öket okoz.

minidle

  • Ha az avgidle kisebb mint 0, akkor addig nem rakunk csomagot a vonalra, amig az avgidle nem lesz elég nagy egy csomag küldésére. Hogy megelőzzük a hirtelen burst-öket a link lekacsolása miatt, az avgidle-t visszaállítjuk a minidle-re, ha túl alacsonyra csökkenne. A megadott értéket negatív számként kell értelmezni, mikroszekundumban.

mpu

  • Minimum Packet Size. Szükséges az idle time pontosabb kiszámításához. Az ethernet, ha üres csomagot küldünk, akkor is kitömi 64byte-osra, mert különben nem lehetne érzékelni az ütközést.

rate

  • milyen időközönként hagyhatja el csomag az adott qdisc-et.

A CBQ prioritásokat is képes figyelembe venni. Az magasabb prioritásúakkal kezdni, és megy körbe. Nénány paraméter a súlyozott round rubin (WRR) processhez, ami a prioritásokat kérdezgeti le.

allot

  • Egyszerre ennyi adatot küldhet egy osztály. (Plusz infó a wight paraméternél.)

prio

  • A CBQ is tud úgy vislekedni, mint a PRIO, előszőr a nagyobb prioritással rendelkező csomagokat küldi ki, majd utána a többit prioritási sorrenben. Addig nem küld ki alacsonyabb prioritású csomagot, amig van magasabb prioritású.

whight

  • A súlyozásban segíti a WRR-t. Minden osztály esélyt kap egy-egy körben. Ha van egy osztály, aminek jóval nagyobb a forgalma, akkor ez segíthet abban, hogy több adatot tudjon kiküldeni egy kör alatt, mint a többiek. A súlytényezőket normalizálja, csak az arány a lényeg. A normalizált súlyt ezután megszorozza az allot paraméterrel ebből megkapja, hogy egy körben mennyi adatot küldhet ki az adott osztály.

Egy CBQ-n belül ugyanazon a major számon kell osztozniuk.

Pár paraméter a sávszélesség megosztáshoz és kölcsönkéréshez.

isolated/sharing

  • Az isolated a hozzá rendelt sávszélt nem osztja meg a testvér osztályaival. A sharing igen.

bounded/borrow

  • A bounded nem kér kölcsön, a borrow igen.

Viszont egy osztályon belüli gyermek osztályok már kérhetnek kölcsön egymástól.

Példa

              1:           root qdisc
              |
             1:1           child class
            /   \
           /     \
         1:3     1:4       leaf classes
          |       |
         30:     40:       qdiscs
        (sfq)   (sfq)

Van egy 100mbit-es NIC-ünk, a webservernek 5mbit sávot adunk, az smtp-nek pedig 3 mbit-et

# tc qdisc add dev eth0 root handle 1:0 cbq bandwidth 100Mbit         \
  avpkt 1000 cell 8
# tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 100Mbit  \
  rate 6Mbit weight 0.6Mbit prio 8 allot 1514 cell 8 maxburst 20      \
  avpkt 1000 bounded

Ezzel a két folyamhoz összesen 6 mbit sávot rendelünk.

# tc class add dev eth0 parent 1:1 classid 1:3 cbq bandwidth 100Mbit  \
  rate 5Mbit weight 0.5Mbit prio 5 allot 1514 cell 8 maxburst 20      \ 
  avpkt 1000                       
# tc class add dev eth0 parent 1:1 classid 1:4 cbq bandwidth 100Mbit  \
  rate 3Mbit weight 0.3Mbit prio 5 allot 1514 cell 8 maxburst 20      \
  avpkt 1000

Itt pedig a fenti külön-külön sávot rendeljük a két folyamhoz.

# tc qdisc add dev eth0 parent 1:3 handle 30: sfq
# tc qdisc add dev eth0 parent 1:4 handle 40: sfq

Ezzel meghatározzuk a qdisc algoritmusát.

# tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip \
  sport 80 0xffff flowid 1:3
# tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip \
  sport 25 0xffff flowid 1:4 

Itt pedig azt határozzuk meg, hogy melyik folyamot melyik kezeljen.

A pfifo_fast a TOS bitek alapján osztályozza a csomagokat. Erre a CBQ-ban is van lehetőség. Erre a split és a defmap paraméterek szolgálnak. A split azt mondja meg, hogy melyik qdisc-ben alkalmazzuk ezt az osztályozást is, a defmap pedig, hogy mely TOS biteknek szükséges beállítva lenni, hogy a szabály érvényeslüljön a csomagra.

Példa a split és defmap-re:

TOS bitek értelmezése:

   0     1     2     3     4     5     6     7
+-----+-----+-----+-----+-----+-----+-----+-----+
|                 |                       |     |
|   PRECEDENCE    |          TOS          | MBZ |
|                 |                       |     |
+-----+-----+-----+-----+-----+-----+-----+-----+
Binary Decimcal  Meaning
-----------------------------------------
1000   8         Minimize delay (md)
0100   4         Maximize throughput (mt)
0010   2         Maximize reliability (mr)
0001   1         Minimize monetary cost (mmc)
0000   0         Normal Service
TC_PRIO..          Num  Corresponds to TOS
-------------------------------------------------
BESTEFFORT         0    Maximize Reliablity        
FILLER             1    Minimize Cost              
BULK               2    Maximize Throughput (0x8)  
INTERACTIVE_BULK   4                               
INTERACTIVE        6    Minimize Delay (0x10)      
CONTROL            7                               

Jobbról vannak számozva a bitek.

A példában 2 részre oszjuk az átmenő adatokat. Az egyik egy interaktív folyam, a másik pedig egy ömlesztett adatfolyam.

# tc class add dev eth1 parent 1:1 classid 1:2 cbq bandwidth 10Mbit     \
  rate 1Mbit allot 1514 cell 8 weight 100Kbit prio 3 maxburst 20        \
  avpkt 1000 split 1:0 defmap c0

# tc class add dev eth1 parent 1:1 classid 1:3 cbq bandwidth 10Mbit     \
  rate 8Mbit allot 1514 cell 8 weight 800Kbit prio 7 maxburst 20        \
  avpkt 1000 split 1:0 defmap 3f

A parancsok hatására következő képpen oszlanak szét a folyamok a TOS bitek alapján

priority	send to
0		1:3
1		1:3
2		1:3
3		1:3
4		1:3
5		1:3
6		1:2
7		1:2

2.2 Jelzés elhelyezése a csomagokon

Ha egy csomag az eth0-án érkezik, de mi csak az eth1-en kimenetkor akarjuk piszkálni a packeteket, akkor a például a következőt kell csinálnunk.

# tc filter add dev eth1 protocol ip parent 1:0 prio 1 handle 6 fw flowid 1:1
# iptables -A PREROUTING -t mangle -i eth0 -j MARK --set-mark 6

Az iptables-szel elhelyezünk egy jelzést, még a route-olás előtt.

3 HTB

A CBQ sok beállítási lehetőséggel rendelkezik, de van benne néhány sotét folt. A sok pararaméter miatt bonyolult is. Ezt Martin Devera is felismerte, ezért elkészítette a HTB qdisc-et.

3.1 rate és ceil

tc qdisc add dev eth0 root handle 1: htb default 12
tc class add dev eth0 parent 1: classid 1:1 htb rate 100kbps ceil 100kbps 
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 30kbps ceil 100kbps
tc class add dev eth0 parent 1:1 classid 1:11 htb rate 10kbps ceil 100kbps
tc class add dev eth0 parent 1:1 classid 1:12 htb rate 60kbps ceil 100kbps
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
  match ip src 1.2.3.4 match ip dport 80 0xffff flowid 1:10
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
  match ip src 1.2.3.4 flowid 1:11

Az első paranccsal az eth0-hoz rendelünk qdisc-et és az olyan csomagok, amelyek nem kerülnek osztályozásra a szűrők által, azok a 12-es osztályba kerülnek. A második parancsban létrehozzuk az 1:1 osztályt, ami egy 100kbps sebességű folyamot fog eredményezni. Ezután létrehozzuk a 1:1 osztályon belül az 1:11 osztályt ez az osztály 30kbps adatfolyamot tud generálni, ha teli van a medium, ha nincs, akkor max 100kbps sávszélességet tud felhasználni. Ugyanezekre van a 4. és 5. parancs is. Ezekután a két szűrő parancs 3 osztályba sorolja az adatfolyam csomagjait. Az első, amelyik a 1.2.3.4 gépről jön és 80-as port a cél, a második minden ami a 1.2.3.4 gépről jön. A harmadik rész pedig a maradék.

tc qdisc add dev eth0 parent 1:10 handle 20: pfifo limit 5
tc qdisc add dev eth0 parent 1:11 handle 30: pfifo limit 5
tc qdisc add dev eth0 parent 1:12 handle 40: sfq perturb 10

Ezek után akár mindegyik levél osztályhoz újra rendelhetünk qdisc-et. Ha nem rendelünk hozzá másikat, akkor alapból pfifo-t fog használni. A limit azt adja meg, hogy hány csomag hosszú a fifoban.

3.2 burst és cburst

burst (byte-ban)

  • a ceil paraméteren meghatározott sebességen adható adatmennyiség. Figyelembe kell venni, hogy a gyermek osztályoknak mekkora burst van beállítva. Minimum a gyermek osztályok burst paramétereinek legmagasabb értékét kell beállítani, ellenkező esetben a szülő osztály eldugulhat.

cburst (byte-ban)

  • A hárdware által meghatározott maximális sebességen egyszerre adható adatmennyiség. Itt is érdemes figyelembe venni a gyermek osztályok beállításait.
tc class change dev eth0 parent 1:2 classid 1:10 htb \
 rate 50kbps ceil 100kbps burst 2k

3.3 prio

A prio paraméterrel az osztályokhoz prioritást lehet rendelni. (0 a magasabb prioritás) Arra is figyelemnel kell venni, hogy ha egyvalakinek javítunk a helyzetén, akkor egy másik (vagy az összes többi) helyzete romlani fog.

tc class add dev eth0 parent 1:1 classid 1:10 htb \
 rate 50kbps ceil 100kbps prio 1

4 IMQ

Az IMQ nem qdisc, de szorosan kapcsolódik hozzájuk. Linuxnál a qdisc-ek a hálózati eszközhöz kapcsolódnak. Minden ami egy eszköz feldolgozási sorába kerül, azt először a qdisc feldolgozási sorába helyez el. Ez a megoldás 2 kötötséget vet fel.

  1. Csak kimeneti forgalom formázás lehetséges. (Bár létezik bementi qdisc, de egy classful qdisc-hez képest meglehetősen korlátozott lehetőségel van felvértezve)
  2. Egy qdisc csak egy interface forgalmát látja, teljes rendszerre kiterjedő korlátozásokat nem lehet benne elhelyezni.

Az IMQ megoldaja ezt a 2 korlátozást. Egy speciális csomagjelzés segítségével, a netfilter a NF_IP_PRE_ROUTING és NF_IP_POST_ROUTING hookok segítségével az IMQ eszköz qdisc-jének adja át a csomagot. Iptables-nek erre van egy külön IMQ targetje.

Ez lehetővé teszi a bemeneti forgalom formázását. Csak meg kell jelölni a a csomagot, attól függően, hogy honnan jöt és/vagy melyik interface dolgozta fel, ezt kezelheted mint egy-egy osztályt amire globális korlátozásokat lehet beállítani. Sok féle lehetőséget nyújt ez, pl. egy qdisc-be rakjuk a http csomagokat vagy az új kapcsolatokhoz tartozó csomagokat.

4.1 Példa script

tc qdisc add dev imq0 root handle 1: htb default 20
tc class add dev imq0 parent 1: classid 1:1 htb rate 2mbit burst 15k
tc class add dev imq0 parent 1:1 classid 1:10 htb rate 1mbit
tc class add dev imq0 parent 1:1 classid 1:20 htb rate 1mbit
tc qdisc add dev imq0 parent 1:10 handle 10: pfifo
tc qdisc add dev imq0 parent 1:20 handle 20: sfq
tc filter add dev imq0 parent 10:0 protocol ip prio 1 u32 match ip dst 10.0.0.230/32 flowid 1:10

4.2 Iptables target használata

  • IMQ [ --todev n ]
    • n azt jelöli, hogy melyik IMQ-ba kívánjuk a csomagot tovább adni.
    • Az IMQ target a mangle tábla PREROUTING és POSTROUTING láncain használható
iptables -t mangle -A PREROUTING -i eth0 -j IMQ --todev 0
ip link set imq0 up

Az viszont meg kell jegyezni, hogy ha a csomag nem fut rá erre a rule-ra akkor nem kerül bele az IMQ-ba. A pontos helye, ahol a forgalom belekerül az IMQ-ba az a forgalom irányától függ (ki/be). Néhány előre definiált hook a netfilterben, amit az iptables is használ:

enum nf_ip_hook_priorities {
        NF_IP_PRI_FIRST = INT_MIN,
        NF_IP_PRI_CONNTRACK = -200,
        NF_IP_PRI_MANGLE = -150,
        NF_IP_PRI_NAT_DST = -100,
        NF_IP_PRI_FILTER = 0,
        NF_IP_PRI_NAT_SRC = 100,
        NF_IP_PRI_LAST = INT_MAX,
};

A bejövő forgalomnál az IMQ NF_IP_PRI_MANGLE + 1 prioritással regisztrálja magát. Ez azt jelenti, hogy a csomag rögtön a mangle PREROUTING lánca után bekerül az IMQ-ba. A kimenő forgalom NF_IP_PRI_LAST priorotást használ, így a filter táblában eldobott csomagok nem fognak erőforrást foglalni a queue-ban.

5 Listázás

5.1 qdisc

tc -s -d qdisc show dev eth0
 qdisc pfifo 22: limit 5p
 Sent 0 bytes 0 pkts (dropped 0, overlimits 0) 
 qdisc pfifo 21: limit 5p
 Sent 2891500 bytes 5783 pkts (dropped 820, overlimits 0) 
 qdisc pfifo 20: limit 5p
 Sent 1760000 bytes 3520 pkts (dropped 3320, overlimits 0) 
 qdisc htb 1: r2q 10 default 1 direct_packets_stat 0
 Sent 4651500 bytes 9303 pkts (dropped 4140, overlimits 34251)
  • overlimits
    • ennyi csomagot kellett várakoztatni
  • direct_packets_stat
    • ennyi csomag ment át minden feldolgozás nélkül
  • r2q
    • quantum kiszámításához használják, quantum=r2q*mtu

5.2 class

tc -s -d class show dev eth0
 class htb 1:1 root prio 0 rate 800Kbit ceil 800Kbit burst 2Kb/8 mpu 0b 
    cburst 2Kb/8 mpu 0b quantum 10240 level 3 
 Sent 5914000 bytes 11828 pkts (dropped 0, overlimits 0) 
 rate 70196bps 141pps 
 lended: 6872 borrowed: 0 giants: 0
class htb 1:2 parent 1:1 prio 0 rate 320Kbit ceil 4000Kbit burst 2Kb/8 mpu 0b 
    cburst 2Kb/8 mpu 0b quantum 4096 level 2 
 Sent 5914000 bytes 11828 pkts (dropped 0, overlimits 0) 
 rate 70196bps 141pps 
 lended: 1017 borrowed: 6872 giants: 0
class htb 1:10 parent 1:2 leaf 20: prio 1 rate 224Kbit ceil 800Kbit burst 2Kb/8 mpu 0b 
    cburst 2Kb/8 mpu 0b quantum 2867 level 0 
 Sent 2269000 bytes 4538 pkts (dropped 4400, overlimits 36358) 
 rate 14635bps 29pps 
 lended: 2939 borrowed: 1599 giants: 0
  • overlimit
    • Az olyan csomagokat számolja, amelyeket nem tudott kiküldeni a rate/ceil megkötései miatt.
  • giants
    • Az olyan csomagok, amelyik nagyobbak a tc-ben beállított mtu-nál (default 1600 bájt).

6 Mi kell mindehez

A kernelben a következő részeket kell kijelölni ehhez:

-> Networking
 -> Networking support
  -> Networking options
   -> QoS and/or fair queueing

Ezen menüpont alatt a használni kívánt algoritmusokat kell kijelölni fordításra.

7 Egy rövid példascript

#!/bin/sh

INET_IF="ppp0"
INET_IP="1.2.3.4"

INTRA_IF="eth1"
INTRA_IP="10.1.0.1"

INET='! 10.0.0.0/8'

INTRA="10.0.0.0/8"
LOCALNET="10.0.0.0/8"

SERVERS="10.0.0.0/16"
FIREWALLS="10.1.0.0/16"
OFFICE="10.3.0.0/16"
NETCAFE="10.4.0.0/16"
TERMS="10.5.0.0/16"
OFFICE2="10.6.0.0/16"

HOSTED_SERVERS="2.3.4.0/28"

ALLOT="1500"
AVPKT="1000"

WEIGHT="10000"

UP_DEV="ppp0"
UP_IF_BANDWIDTH="100"
UP_IF_BANDWIDTH_UNIT="Mbit"
UP_LINK_BANDWIDTH="150"
UP_LINK_BANDWIDTH_UNIT="kbit"

DOWN_DEV="eth1"
DOWN_IF_BANDWIDTH="100"
DOWN_IF_BANDWIDTH_UNIT="Mbit"
DOWN_LINK_BANDWIDTH="1000"
DOWN_LINK_BANDWIDTH_UNIT="kbit"

# Clean up qdiscs
tc qdisc del dev $UP_DEV root
tc qdisc del dev $DOWN_DEV root

# Clean up ip tables
iptables -t mangle -D INPUT -j classify 2>/dev/null
iptables -t mangle -D OUTPUT -j classify 2>/dev/null
iptables -t mangle -D FORWARD -j classify 2>/dev/null
iptables -t mangle -D PREROUTING -j classify 2>/dev/null
iptables -t mangle -D POSTROUTING -j classify 2>/dev/null
iptables -t mangle -F classify 2>/dev/null
iptables -t mangle -X classify 2>/dev/null

###############################################################################
# "Upload" and "Download" CBQ classes
#

# Create root CBQ qdisc
tc qdisc add dev $UP_DEV root handle 1:         cbq avpkt $AVPKT \
                         bandwidth ${UP_IF_BANDWIDTH}${UP_IF_BANDWIDTH_UNIT}


tc qdisc add dev $DOWN_DEV root handle 1:               cbq avpkt $AVPKT \
                         bandwidth ${DOWN_IF_BANDWIDTH}${DOWN_IF_BANDWIDTH_UNIT}
# Shape everything at UP_LINK_BANDWIDTH speed on the UP_DEV
# This prevents huge queues the ADSL modem, which destroy latency
tc class add dev $UP_DEV parent 1:      classid 1:1     cbq allot $ALLOT                \
                         rate ${UP_LINK_BANDWIDTH}${UP_LINK_BANDWIDTH_UNIT}             prio 5     bounded isolated

tc class add dev $DOWN_DEV parent 1:    classid 1:1     cbq allot $ALLOT                \
                         rate ${DOWN_IF_BANDWIDTH}${DOWN_IF_BANDWIDTH_UNIT}             prio 5   bounded isolated

# SSH Interactive
tc class add dev $UP_DEV parent 1:1     classid 1:101   cbq allot $ALLOT                \
                         rate $[7*$UP_LINK_BANDWIDTH/10]$UP_LINK_BANDWIDTH_UNIT         prio 1   bounded sharing weight
tc class add dev $DOWN_DEV parent 1:1   classid 1:101   cbq allot $ALLOT                \
                         rate $[7*$DOWN_LINK_BANDWIDTH/10]$DOWN_LINK_BANDWIDTH_UNIT     prio 1   bounded sharing weight

# SERVERS<->OFFICE
tc class add dev $UP_DEV parent 1:1     classid 1:102   cbq allot $ALLOT                \
                         rate $[4*$UP_LINK_BANDWIDTH/10]$UP_LINK_BANDWIDTH_UNIT         prio 2   bounded sharing weight
tc class add dev $DOWN_DEV parent 1:1   classid 1:102   cbq allot $ALLOT                \
                         rate $[4*$DOWN_LINK_BANDWIDTH/10]$DOWN_LINK_BANDWIDTH_UNIT     prio 2   bounded sharing weight

# SSH Bulk (SCP)
tc class add dev $UP_DEV parent 1:1     classid 1:103   cbq allot $ALLOT                \
                         rate $[4*$UP_LINK_BANDWIDTH/10]$UP_LINK_BANDWIDTH_UNIT         prio 3  borrow   sharing weight
tc class add dev $DOWN_DEV parent 1:1   classid 1:103   cbq allot $ALLOT                \
                         rate $[4*$DOWN_LINK_BANDWIDTH/10]$DOWN_LINK_BANDWIDTH_UNIT     prio 3  borrow   sharing weight
# INET<->FW2
tc class add dev $UP_DEV parent 1:1     classid 1:104   cbq allot $ALLOT                \
                         rate $[4*$UP_LINK_BANDWIDTH/10]$UP_LINK_BANDWIDTH_UNIT         prio 3  borrow   sharing weight
tc class add dev $DOWN_DEV parent 1:1   classid 1:104   cbq allot $ALLOT                \
                         rate $[4*$DOWN_LINK_BANDWIDTH/10]$DOWN_LINK_BANDWIDTH_UNIT     prio 3  borrow   sharing weight
# INET<->OFFICE
tc class add dev $UP_DEV parent 1:1     classid 1:105   cbq allot $ALLOT                \
                         rate $[$UP_LINK_BANDWIDTH/10]$UP_LINK_BANDWIDTH_UNIT           prio 3  borrow   sharing weight
tc class add dev $DOWN_DEV parent 1:1   classid 1:105   cbq allot $ALLOT                \
                         rate $[$DOWN_LINK_BANDWIDTH/10]$DOWN_LINK_BANDWIDTH_UNIT       prio 3  borrow   sharing weight
# INET<->NETCAFE
tc class add dev $UP_DEV parent 1:1     classid 1:106   cbq allot $ALLOT                \
                         rate $[$UP_LINK_BANDWIDTH/10]$UP_LINK_BANDWIDTH_UNIT           prio 3  borrow   sharing weight
tc class add dev $DOWN_DEV parent 1:1   classid 1:106   cbq allot $ALLOT                \
                         rate $[$DOWN_LINK_BANDWIDTH/10]$DOWN_LINK_BANDWIDTH_UNIT       prio 3  borrow   sharing weight
# INET<->TERMS
tc class add dev $UP_DEV parent 1:1     classid 1:107   cbq allot $ALLOT                \
                         rate $[$UP_LINK_BANDWIDTH/10]$UP_LINK_BANDWIDTH_UNIT           prio 3  borrow   sharing weight
tc class add dev $DOWN_DEV parent 1:1   classid 1:107   cbq allot $ALLOT                \
                         rate $[$DOWN_LINK_BANDWIDTH/10]$DOWN_LINK_BANDWIDTH_UNIT       prio 3  borrow   sharing weight
# INET<->OFFICE2
tc class add dev $UP_DEV parent 1:1     classid 1:108   cbq allot $ALLOT                \
                         rate $[$UP_LINK_BANDWIDTH/10]$UP_LINK_BANDWIDTH_UNIT           prio 3  borrow   sharing weight
tc class add dev $DOWN_DEV parent 1:1   classid 1:108   cbq allot $ALLOT                \
                         rate $[$DOWN_LINK_BANDWIDTH/10]$DOWN_LINK_BANDWIDTH_UNIT       prio 3  borrow   sharing weight
# OTHER
tc class add dev $UP_DEV parent 1:1     classid 1:109   cbq allot $ALLOT                \
                         rate ${UP_IF_BANDWIDTH}${UP_IF_BANDWIDTH_UNIT}                 prio 4   bounded isolated weigh
tc class add dev $DOWN_DEV parent 1:1   classid 1:109   cbq allot $ALLOT                \
                         rate ${DOWN_IF_BANDWIDTH}${DOWN_IF_BANDWIDTH_UNIT}             prio 4   bounded isolated weigh


tc qdisc add dev $UP_DEV        parent 1:101    handle 101: sfq
tc qdisc add dev $DOWN_DEV      parent 1:101    handle 101: sfq

tc qdisc add dev $UP_DEV        parent 1:102    handle 102: sfq
tc qdisc add dev $DOWN_DEV      parent 1:102    handle 102: sfq

tc qdisc add dev $UP_DEV        parent 1:103    handle 103: sfq
tc qdisc add dev $DOWN_DEV      parent 1:103    handle 103: sfq

tc qdisc add dev $UP_DEV        parent 1:104    handle 104: sfq
tc qdisc add dev $DOWN_DEV      parent 1:104    handle 104: sfq

tc qdisc add dev $UP_DEV        parent 1:105    handle 105: sfq
tc qdisc add dev $DOWN_DEV      parent 1:105    handle 105: sfq

tc qdisc add dev $UP_DEV        parent 1:106    handle 106: sfq
tc qdisc add dev $DOWN_DEV      parent 1:106    handle 106: sfq

tc qdisc add dev $UP_DEV        parent 1:107    handle 107: sfq
tc qdisc add dev $DOWN_DEV      parent 1:107    handle 107: sfq

tc qdisc add dev $UP_DEV        parent 1:108    handle 108: sfq
tc qdisc add dev $DOWN_DEV      parent 1:108    handle 108: sfq
tc qdisc add dev $UP_DEV        parent 1:109    handle 109: sfq
tc qdisc add dev $DOWN_DEV      parent 1:109    handle 109: sfq

###############################################################################
# Create flow filters
#
tc filter add dev $UP_DEV protocol ip parent 1:0 prio 1 handle 1 fw classid 1:101
tc filter add dev $UP_DEV protocol ip parent 1:0 prio 1 handle 2 fw classid 1:102
tc filter add dev $UP_DEV protocol ip parent 1:0 prio 1 handle 3 fw classid 1:103
tc filter add dev $UP_DEV protocol ip parent 1:0 prio 1 handle 4 fw classid 1:104
tc filter add dev $UP_DEV protocol ip parent 1:0 prio 1 handle 5 fw classid 1:105
tc filter add dev $UP_DEV protocol ip parent 1:0 prio 1 handle 6 fw classid 1:106
tc filter add dev $UP_DEV protocol ip parent 1:0 prio 1 handle 7 fw classid 1:107
tc filter add dev $UP_DEV protocol ip parent 1:0 prio 1 handle 8 fw classid 1:108
tc filter add dev $UP_DEV protocol ip parent 1:0 prio 1 handle 9 fw classid 1:109


tc filter add dev $DOWN_DEV protocol ip parent 1:0 prio 1 handle 1 fw classid 1:101
tc filter add dev $DOWN_DEV protocol ip parent 1:0 prio 1 handle 2 fw classid 1:102
tc filter add dev $DOWN_DEV protocol ip parent 1:0 prio 1 handle 3 fw classid 1:103
tc filter add dev $DOWN_DEV protocol ip parent 1:0 prio 1 handle 4 fw classid 1:104
tc filter add dev $DOWN_DEV protocol ip parent 1:0 prio 1 handle 5 fw classid 1:105
tc filter add dev $DOWN_DEV protocol ip parent 1:0 prio 1 handle 6 fw classid 1:106
tc filter add dev $DOWN_DEV protocol ip parent 1:0 prio 1 handle 7 fw classid 1:107
tc filter add dev $DOWN_DEV protocol ip parent 1:0 prio 1 handle 8 fw classid 1:108
tc filter add dev $DOWN_DEV protocol ip parent 1:0 prio 1 handle 9 fw classid 1:109

###############################################################################
# Classify packets into flows
#

# Create classifier table
iptables -t mangle -N classify
iptables -t mangle -I POSTROUTING -j classify
iptables -t mangle -I PREROUTING -j classify
iptables -t mangle -I FORWARD -j classify
iptables -t mangle -I OUTPUT -j classify
iptables -t mangle -I INPUT -j classify

# Do not classify traffic generated by ourselves to the local networks
iptables -t mangle -A classify -s fw.firewalls -d $OFFICE -j RETURN
iptables -t mangle -A classify -s fw.firewalls -d $NETCAFE -j RETURN
iptables -t mangle -A classify -s fw.firewalls -d $TERMS -j RETURN
iptables -t mangle -A classify -s fw.firewalls -d $OFFICE2 -j RETURN

iptables -t mangle -A classify -s fw.foo.bar -d $OFFICE -j RETURN
iptables -t mangle -A classify -s fw.foo.bar -d $NETCAFE -j RETURN
iptables -t mangle -A classify -s fw.foo.bar -d $TERMS -j RETURN
iptables -t mangle -A classify -s fw.foo.bar -d $OFFICE2 -j RETURN

# SSH Interactive and ORACLE
iptables -t mangle -A classify -p tcp --dport 22 --match tos --tos 0x10 -j MARK                          --set-mark 1
iptables -t mangle -A classify -p tcp --dport 22 --match tos --tos 0x10 -j RETURN
iptables -t mangle -A classify -p tcp --sport 22 --match tos --tos 0x10 -j MARK                          --set-mark 1
iptables -t mangle -A classify -p tcp --sport 22 --match tos --tos 0x10 -j RETURN

iptables -t mangle -A classify -p tcp --dport 1521 --match tos --tos 0x10 -j MARK                        --set-mark 1
iptables -t mangle -A classify -p tcp --dport 1521 --match tos --tos 0x10 -j RETURN
iptables -t mangle -A classify -p tcp --sport 1521 --match tos --tos 0x10 -j MARK                         --set-mark 1
iptables -t mangle -A classify -p tcp --sport 1521 --match tos --tos 0x10 -j RETURN
iptables -t mangle -A classify -p tcp --dport 1522 --match tos --tos 0x10 -j MARK                        --set-mark 1
iptables -t mangle -A classify -p tcp --dport 1522 --match tos --tos 0x10 -j RETURN
iptables -t mangle -A classify -p tcp --sport 1522 --match tos --tos 0x10 -j MARK                       --set-mark 1
iptables -t mangle -A classify -p tcp --sport 1522 --match tos --tos 0x10 -j RETURN
iptables -t mangle -A classify -p tcp --dport 1523 --match tos --tos 0x10 -j MARK                        --set-mark 1
iptables -t mangle -A classify -p tcp --dport 1523 --match tos --tos 0x10 -j RETURN
iptables -t mangle -A classify -p tcp --sport 1523 --match tos --tos 0x10 -j MARK                        --set-mark 1
iptables -t mangle -A classify -p tcp --sport 1523 --match tos --tos 0x10 -j RETURN

# VNC Interactive
iptables -t mangle -A classify -p tcp --sport 5901 --match tos --tos 0x10 -j MARK                        --set-mark 1
iptables -t mangle -A classify -p tcp --sport 5901 --match tos --tos 0x10 -j RETURN
iptables -t mangle -A classify -p tcp --dport 5901 --match tos --tos 0x10 -j MARK                        --set-mark 1
iptables -t mangle -A classify -p tcp --dport 5901 --match tos --tos 0x10 -j RETURN

iptables -t mangle -A classify -p tcp --sport 5902 --match tos --tos 0x10 -j MARK                        --set-mark 1
iptables -t mangle -A classify -p tcp --sport 5902 --match tos --tos 0x10 -j RETURN
iptables -t mangle -A classify -p tcp --dport 5902 --match tos --tos 0x10 -j MARK                        --set-mark 1
iptables -t mangle -A classify -p tcp --dport 5902 --match tos --tos 0x10 -j RETURN

iptables -t mangle -A classify -d $HOSTED_SERVERS -p tcp --dport 2222:2227  -j MARK                      --set-mark 1
iptables -t mangle -A classify -d $HOSTED_SERVERS -p tcp --dport 2222:2227  -j RETURN
iptables -t mangle -A classify -s $HOSTED_SERVERS -p tcp --sport 2222:2227  -j MARK                      --set-mark 1
iptables -t mangle -A classify -s $HOSTED_SERVERS -p tcp --sport 2222:2227  -j RETURN

#SERVERS<->OFFICE
iptables -t mangle -A classify -d server.foo.bar -p udp --dport 500 -j MARK                       --set-mark 2
iptables -t mangle -A classify -d server.foo.bar -p udp --dport 500 -j RETURN
iptables -t mangle -A classify -s server.foo.bar -p udp --dport 500 -j MARK                      --set-mark 2
iptables -t mangle -A classify -s server.foo.bar -p udp --dport 500 -j RETURN

iptables -t mangle -A classify -d server.foo.bar -p ah -j MARK                                   --set-mark 2
iptables -t mangle -A classify -d server.foo.bar -p ah -j RETURN
iptables -t mangle -A classify -s server.foo.bar -p ah -j MARK                                   --set-mark 2
iptables -t mangle -A classify -s server.foo.bar -p ah -j RETURN

iptables -t mangle -A classify -d $HOSTED_SERVERS -p tcp --sport 873 -j MARK                     --set-mark 6
iptables -t mangle -A classify -d $HOSTED_SERVERS -p tcp --sport 873 -j RETURN
iptables -t mangle -A classify -s $HOSTED_SERVERS -p tcp --dport 873 -j MARK                     --set-mark 6
iptables -t mangle -A classify -s $HOSTED_SERVERS -p tcp --dport 873 -j RETURN

iptables -t mangle -A classify -s $SERVERS -d $OFFICE -j MARK                                    --set-mark 2
iptables -t mangle -A classify -s $SERVERS -d $OFFICE -j RETURN
iptables -t mangle -A classify -d $SERVERS -s $OFFICE -j MARK                                    --set-mark 2
iptables -t mangle -A classify -d $SERVERS -s $OFFICE -j RETURN

# SSH Bulk (SCP)
iptables -t mangle -A classify -p tcp --dport 22 -j MARK                                         --set-mark 3
iptables -t mangle -A classify -p tcp --dport 22 -j RETURN
iptables -t mangle -A classify -p tcp --sport 22 -j MARK                                         --set-mark 3
iptables -t mangle -A classify -p tcp --sport 22 -j RETURN

# INET<->FW2
iptables -t mangle -A classify -s $INET -d fw2.firewalls -j MARK                                 --set-mark 4
iptables -t mangle -A classify -s $INET -d fw2.firewalls -j RETURN
iptables -t mangle -A classify -d $INET -s fw2.firewalls -j MARK                                 --set-mark 4
iptables -t mangle -A classify -d $INET -s fw2.firewalls -j RETURN

# INET<->OFFICE
iptables -t mangle -A classify -s $INET -d $OFFICE -j MARK                                       --set-mark 5
iptables -t mangle -A classify -s $INET -d $OFFICE -j RETURN
iptables -t mangle -A classify -d $INET -s $OFFICE -j MARK                                       --set-mark 5
iptables -t mangle -A classify -d $INET -s $OFFICE -j RETURN

# INET<->NETCAFE
iptables -t mangle -A classify -s $INET -d $NETCAFE -j MARK                                      --set-mark 6
iptables -t mangle -A classify -s $INET -d $NETCAFE -j RETURN
iptables -t mangle -A classify -d $INET -s $NETCAFE -j MARK                                      --set-mark 6
iptables -t mangle -A classify -d $INET -s $NETCAFE -j RETURN

# INET<->TERMS
iptables -t mangle -A classify -s $INET -d $TERMS -j MARK                                        --set-mark 7
iptables -t mangle -A classify -s $INET -d $TERMS -j RETURN
iptables -t mangle -A classify -d $INET -s $TERMS -j MARK                                        --set-mark 7
iptables -t mangle -A classify -d $INET -s $TERMS -j RETURN
 
# INET<->OFFICE2
iptables -t mangle -A classify -s $INET -d $OFFICE2 -j MARK                                      --set-mark 8
iptables -t mangle -A classify -s $INET -d $OFFICE2 -j RETURN
iptables -t mangle -A classify -d $INET -s $OFFICE2 -j MARK                                      --set-mark 8
iptables -t mangle -A classify -d $INET -s $OFFICE2 -j RETURN

# OTHER
iptables -t mangle -A classify -j MARK                                                           --set-mark 9
# Log unclassified packets here?!
iptables -t mangle -A classify -j RETURN

8 Felhasznált/ajánlott irodalom

Személyes eszközök