Bandwidth Limiting HOWTO
Transcript
Bandwidth Limiting HOWTO
Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] Bandwidth Limiting HOWTO Introduzione Mi è stato chiesto di fornire un firewall, con GNU/Linux, che permettesse anche di limitare e gestire in modo intelligente, il traffico generato da alcuni host e/o destinato ad alcuni servizi in particolare. Il risultato delle mie prove è in questo HOWTO, che affronta la problematica, peraltro molto complessa, dal punto di vista pratico. Il mio obiettivo era quello di realizzare un sistema che permettesse di fare shaping della banda in uscita e di smistare il traffico originato da alcuni host della rete interna, o diretto verso particolari servizi esterni. Il metodo utilizzato è vario, ho infatti preso in considerazione diversi sistemi, partendo dal confronto delle soluzioni con CBQ e HTB, ma anche SQUID con i suoi “delay pool”, destinato però solo al controllo del traffico http, per finire con IPROUTE per lo smistamento del traffico La mia base di sperimentazione è stata un sistema centrale, un firewall/router con una struttura che prevedeva due linee di collegamento ad internet, una xDSL (eth1) e l’altra DIALUP (ippp0) con un interfaccia verso la LAN interna (eth0). Una situazione abbastanza classica, dove però il firewall in questione, oltre a effettuare NAT e Filtering doveva effettuare shaping e redistribuzione del traffico sulle due linee. Per la sperimentazione mi sono avvalso di tre sistemi: 1. neo lo shaper ovvero il firewall connesso ad internet essenzialmente su connessione dialup ISDN a 64 kilobits 2. cam client della mini lan creata per i test 3. oberon altro client della mini lan usato per effettuare shaping differenti tra client della stessa rete. Per il firewall è stata utilizzata come distribuzione una Debian/Sarge con Kernel 2.6.8-2-686 standard e con i software tc e ip installati. Dal punto di vista software non è stato aggiunto nulla, se non il frontend per iptables shorewall e alcuni tool di analisi della banda. Lo Shaping: QoS e TC Introduzione Con il termine di shaping e di shaper, lo strumento che permette di effettuarlo, intendiamo la possibilità di limitare e regimentare il traffico che passa per una determinata interfaccia. Questa funzione è permessa sui sistemi GNU/Linux dal kernel, che opportunamente configurato, consente tutta una serie di configurazioni per limitare il traffico in ingesso ed in uscita per una specifica interfaccia. Quality of Service e Traffic Control Prima di passare alla parte pratica ovvero all’implementazione diretta dello shaping è bene vedere qualche concetto teorico sul TC (Traffic Control) e sul QoS (Quality of Service) Innanzitutto occorre ricordare che le nuove funzionalità del kernel permettono un maggior controllo e nuove funzionalità rispetto a quello che era consentito con il vecchio modulo shaper.o. Tra le caratteristiche principali ricordiamo la possibilità di impostare a priori la velocità di trasmissione dei dati in uscita da una determinata interfaccia, inoltre è possibile stabilire delle Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] priorità tra i pacchetti, smistarli in base alla destinazione, al tipo, ai bit TOS (Type Of Service) e su diverse linee. Esistono una serie di elementi che permettono di implementare queste caratteristiche: • • • La Disciplina di accodamento: permette di effettuare lo scheduling dei pacchetti, e va associata alla scheda di rete Le Classi: servono per definire le differenti tipologie di traffico I Filtri: permettono di suddividere il traffico nelle varie classi definite La Disciplina di accodamento Detta anche qdisc rappresenta l'elemento fondante di questo metodo. Infatti tutti i pacchetti provenienti da una specifica interfaccia venogno accodati. E’ proprio sulla base della qdisc voluta che verrà prelevato e inviato attraverso l'interfaccia di output. La gestione della disciplina delle code è un argomento complesso, visto che ne esistono di diverso tipo, quella più nota e di default è la FIFO (First-IN/First-OUT). Secondo questa disciplina il primo pacchetto in ingresso e anche il primo in uscita. Possiamo definire questa disciplina la più semplice, visto che ne esistono altre molto più complesse ed elaborate (RED, CBQ, HTB, TBF e Prio). A seconda delle peculiari caratteristiche si possono scegliere quelle volute. Ad esempio la Class Based Queueing (CBQ) è qdisc principale e più utilizzata. E’ suddivisibile in classi a cui assegnare caratteristiche differenti e attraverso cui segmentare il traffico associandolo a classi ad esempio con banda differente. Una caratteristica di queste classi e di poter essere separate tra loro ma anche di prestarsi banda in caso di inutilizzo. Un limite di cui soffre questa qdisc e di non essere molto precisa nella suddivisone delle banda, a causa della difficoltà di allocazione delle risorse fisiche di banda. Ecco perché si utilizza spesso un’altra qdisc la Hierarchical Token Bucket (HTB), semplice da configurare e molto più precisa nella suddivisone della banda, specie nel caso in cui si vogliano creare classi a cui assegnare una banda garantita. Anche questa soluzione permette di recuperare banda dalla classe parent nel caso in cui ne resti di inutilizzata. Comunque se non viene specificata una disciplina particolare verrà sempre usata quella di default (FIFO). Le Classi Con le classi si possono determinare delle sotto-sezioni a cui assegnare uno specifico bandwidth, la priorità voluta e molti altri parametri. In modo gerarchico ogni classe può avere ulteriori suddivisioni (sottoclassi) a cui associare una coda, che avrà il compito di gestire i pacchetti che in essa venogno accodati e decidere quali pacchetti inviare per primi ed il loro ordine. Ovviamente sarà compito della coda scartare eventuali pacchetti che non soddisfano le regole (limit) o le violano. I Filtri E’ attraverso i filtri che vengono effettivamente suddivisi i pacchetti e inviati verso le classi a cui sono stati associati. E’ proprio qui che sta la parte più interessante in cui si decide in base a quali caratteristiche un pacchetto debba essere associato ad una determina classe e per questo ad una determinata banda impostata. Le caratteristiche possono essere molte dall’ indirizzo sorgente o da quello di destinazione, oppure in base alla. porta destinazione o a quella sorgente. E’ anche possibile filtrare in base al marking da parte di iptables (mangle table). Il nostro Scenario Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] Utilizziamo una macchina gw/firewall con tre interface una eth0 sulla LAN interna l’altra ippp0 verso internet Dial-Up e una eth1 verso una connessione internet xDSL. Per semplificare la descrizione e gli esempi ipotizziamo di effettuare lo shaping sull’interfaccia eth0 per il traffico proveniente dalla LAN, verso l’interfaccia dial-up ippp0. Infatti limitando il rate sull’interfaccia interna verrà di conseguenza limitato anche sull’ippp0 in uscita verso internet ----------eth0 (default GW per la LAN) . | . | . | eth1 ippp0 la distribuzione è una Debian/Sarge con Kernel 2.6.8-2-686 e con i software tc e ip installati. # ip Usage: ip [ OPTIONS ] OBJECT { COMMAND | help } where OBJECT := { link | addr | route | rule | neigh | tunnel | maddr | mroute | monitor | xfrm } OPTIONS := { -V[ersion] | -s[tatistics] | -r[esolve] | -f[amily] { inet | inet6 | ipx | dnet | link } | -o[neline] } # tc Usage: tc [ OPTIONS ] OBJECT { COMMAND | help } where OBJECT := { qdisc | class | filter | action } OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -b[atch] file } Il comando tc E’ attraverso questo comando ed alcuni dei suoi sotto comandi che passa la programmazione delle nostre regole di shaping. Prenderci un po’ di confidenza prima di cercare una configurazione funzionante è una cosa da fare assolutamente. è il sottocomando per creare lo scheduler qdisc root cbq # tc qdisc help Usage: tc qdisc [ add | del | replace | change | get ] dev STRING [ handle QHANDLE ] [ root | ingress | parent CLASSID ] [ estimator INTERVAL TIME_CONSTANT ] [ [ QDISC_KIND ] [ help | OPTIONS ] ] tc qdisc show [ dev STRING ] [ingress] Where: QDISC_KIND := { [p|b]fifo | tbf | prio | cbq | red | etc. } OPTIONS := ... try tc qdisc add <desired QDISC_KIND> help è il sottocomando per creare le classi e le sottoclassi (parent) # tc class help Usage: tc class [ add | del | change | get ] dev STRING [ classid CLASSID ] [ root | parent CLASSID ] [ [ QDISC_KIND ] [ help | OPTIONS ] ] tc class show [ dev STRING ] [ root | parent CLASSID ] Where: QDISC_KIND := { prio | cbq | etc. } OPTIONS := ... try tc class add <desired QDISC_KIND> help è il sottocomando che permette di associare le classi alle regole impostate Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] # tc filter help Usage: tc filter [ add | del | change | get ] dev STRING [ pref PRIO ] [ protocol PROTO ] [ estimator INTERVAL TIME_CONSTANT ] [ root | classid CLASSID ] [ handle FILTERID ] [ [ FILTER_TYPE ] [ help | OPTIONS ] ] tc filter show [ dev STRING ] [ root | parent CLASSID ] Where: FILTER_TYPE := { rsvp | u32 | fw | route | etc. } FILTERID := ... format depends on classifier, see there OPTIONS := ... try tc filter add <desired FILTER_KIND> help Predisposizione Kernel compilato con il supporto iptables e tc e masquerading configurato: Code maturity level options ---> [*] Prompt for development and/or incomplete code/drivers [CONFIG_EXPERIMENTAL] Networking Options ---> ... [*] QoS and/or fair queueing ---> [*] QoS and/or fair queueing (EXPERIMENTAL) [CONFIG_NET_SCHED] <M> CBQ packet scheduler [CONFIG_NET_SCH_CBQ] <M> CSZ packet scheduler [CONFIG_NET_SCH_CSZ] <M> The simplest PRIO pseudoscheduler [CONFIG_NET_SCH_PRIO] <M> RED queue [CONFIG_NET_SCH_RED] <M> SFQ queue [CONFIG_NET_SCH_SFQ] <M> TEQL queue [CONFIG_NET_SCH_TEQL] <M> TBF queue [CONFIG_NET_SCH_TBF] <M> GRED queue <M> Diffserv field marker <M> Ingress Qdisc [*] QoS support [CONFIG_NET_QOS] [*] Rate estimator [CONFIG_NET_ESTIMATOR] [*] Packet classifier API [CONFIG_NET_CLS] <M> TC index classifier <M> Routing table based classifier [CONFIG_NET_CLS_ROUTE4] <M> Firewall based classifier [CONFIG_NET_CLS_FW] <M> U32 classifier [CONFIG_NET_CLS_U32] <M> Special RSVP classifier [CONFIG_NET_CLS_RSVP] <M> Special RSVP classifier for IPv6 [CONFIG_NET_CLS_RSVP6] [*] Traffic policing (needed for in/egress) Impostazione del Masquerading per la LAN alle spalle del firewall: # echo 1 > /proc/sys/net/ipv4/ip_forward #iptables -t nat -A POSTROUTING –s $INTERNAL_LAN -j MASQUERADE Configurazione manuale delle regole Proviamo a configurare manualmente le nostre regole di shaping sulla base di quello che abbiamo appreso fino ad ora. Le configurazioni mostrate utilizzano la qdisc maggiormente implementata ovvero la CBQ (Class Based Queueing). Vedremo alla fine della sezione anche degli esempi che prevedono l’utilizzo dalla soluzione con il metodo della coda HTB (Hierarchical Token Bucket). Creiamo uno script di questo tipo, partendo dal presupposto che il nostro scopo è limitare il traffico verso le porte 80 e 21 di uno specifico host della nostra rete. Tale regola verrà applicata solo per tale host mentre tutti gli altri saranno liberi di sfruttare la connessione a piena banda. Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] Il traffico viene limitato agli host destinatari il cui traffico passa per l’interfaccia della LAN interna eth0 a cui inviano il traffico e che successivamente sarà dirottate (già limitato) all’interfaccia connessione ad internet (ippp0). #tc.rules CBQ qdisc # Questo comando crea e associa all'interfaccia eth0 lo scheduler qdisc root cbq tc qdisc add dev eth0 root handle 1 cbq bandwidth 100Mbit avpkt 1000 cell 8 # Questo comando crea la prima classe root, che ha come genitore il root handle 1:, ed è la classe in cui verranno poi #divideranno il bandwidth dei protocolli/IP scelti. tc class add dev eth0 parent 1: classid 1:10 cbq bandwidth 100Mbit rate 16Kbit weight 3 prio 5 allot 1514 cell 8 maxburst 20 avpkt 1000 bounded # Questo comando crea e associa una classe all'interfaccia eth0, la classe parent è root 1:10 già creata tc qdisc add dev eth0 parent 1:10 handle 10 tbf rate 16Kbit buffer 10Kb/8 limit 15Kb mtu 1500 # Questi comandi permettono effettivamente di associare alla classe root. le regole (ip e porte) voluti per la #limitazione del traffico tc filter add dev eth0 parent 1:0 protocol ip prio 100 u32 match ip sport 80 0xffff match ip dst 192.168.0.169/32 classid 1:10 tc filter add dev eth0 parent 1:0 protocol ip prio 100 u32 match ip sport 21 0xffff match ip dst 192.168.0.169/32 classid 1:10 Il significato dei vari attributi viene ripreso in seguito, quando si vedrà la programmazione semplificata delle regole tramite script. Vediamo in uno schema semplificato le regole di programmazione che abbiamo inserito: In realtà la cosa migliore è utilizzare uno script dal nome cbq.init giunto alla versione 0.7.3, che ci offre un sistema “mediato”, più semplice ed intuibile per la configurazione del nostro shaper. In effetti basta configurare dei file dalla sintassi semplificata e decisamente intuibile, in cui inserire i parametri voluti e poi compilare lo script. A questo punto una volta avviato lo script le regole venogno impostate automaticamente. Con questo sistema si riesce a passare direttamente alla programmazione dello shaker anche se non si ha una grande confidenza con la materia. Vale ovviamente sempre la regola per cui sistemi di questo tipo vanno accuratamente testati per non incorrere in marchiano errori di programmazione, in grado a volte di minare la sicurezza del sistema o addirittura della rete alle sue spalle. Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] Per chi volesse invece approfondire gli aspetti di programmazione ed entrare nel dettagli delle regole consiglio l’ottimo documento “Controllo del traffico, shaping” di Masetti Marco, reperibile all’indirizzo: • http://digilander.libero.it/amilinux/Linux_QoS/tc.html#toc11 Installazione Vediamo adesso come ottenere ed utilizzare rapidamente lo script cbq.init-v0.7.3, per la programmazione semplificata del nostro shaker. Cominciamo con lo scaricare lo script e renderlo eseguibile: # # # # cd /usr/src mv /usr/src/cbq.init-v0.7.3 /sbin/cbq chmod 0700 /sbin/cbq wget http://switch.dl.sourceforge.net/sourceforge/cbqinit/cbq.init-v0.7.3 Configurazione Basta editare lo script per comprenderne la sintassi e notare come la configurazione venga davvero semplificata e resa possibile anche a chi esperto della materia non è. Sintassi ### Device parameters # # DEVICE=<ifname>,<bandwidth>[,<weight>] mandatory # DEVICE=eth0,10Mbit,1Mbit # # <ifname> is the name of the interface you want to control # traffic on, e.g. eth0 # <bandwidth> is the physical bandwidth of the device, e.g. for # ethernet 10Mbit or 100Mbit, for arcnet 2Mbit # <weight> is tuning parameter that should be proportional to # <bandwidth>. As a rule of thumb: <weight> = <bandwidth> / 10 # # When you have more classes on one interface, it is enough to specify # <bandwidth> [and <weight>] only once, therefore in other files you only # need to set DEVICE=<ifname>. ### Filter parameters # # RULE=[[saddr[/prefix]][:port[/mask]],][daddr[/prefix]][:port[/mask]] Creare una directory /etc/sysconfig/cbq in cui depositare i propri script # mkdir /etc/sysconfig/cbq Esempi # cd /etc/sysconfig/cbq # vi cbq-10.ftp_http-network DEVICE=eth0,100Mbit,10Mbit Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] RATE=10Kbit WEIGHT=1Kbit PRIO=5 RULE=:80,192.168.0.0/24 RULE=:20,192.168.0.0/24 RULE=:21,192.168.0.0/24 Limita il rate in download a 10 Kbit ~ 1,5 KB/s # vi cbq-15.posta-network DEVICE=eth0,100Mbit,10Mbit RATE=30Kbit WEIGHT=1Kbit PRIO=5 RULE=:110,192.168.0.0/24 RULE=:25,192.168.0.0/24 RULE=:143,192.168.0.0/24 Limita il rate in download per la posta a 30 Kbit ~ 3,8 KB/s # vi cbq-20.audio-network DEVICE=eth0,100Mbit,10Mbit RATE=35Kbit WEIGHT=3Kbit PRIO=5 # Windows Media Player. RULE=:1755,192.168.0.0/24 # Real Player RULE=:554,192.168.0.0/24 RULE=:7070,192.169.0.0/24 Limita il rate in download a 35 Kbit ~ 4,2 KB/s per alcuni servizi audio Sono stati scelti valori di rate molto bassi perché la linea su cui sono stati fatti i test è una linea ISDN a 64 kbits (8KBytes) e anche perché è più semplice vedere direttamente l’efficacia dello shaper. Attivazione e disattivazione dello shaping # cbq Usage: cbq {start|compile|stop|restart|timecheck|list|stats} # cbq start # cbq stop Stampa delle regole Questo comando è molto utile perché ci mostra come lo shaper programma le table utilizzando il comando tc. # cbq compile 1- /sbin/tc qdisc del dev eth0 root 2- /sbin/tc qdisc add dev eth0 root handle 1 cbq bandwidth 100Mbit avpkt 1000 cell 8 3- /sbin/tc class change dev eth0 root cbq weight 10Mbit allot 1514 Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] 4- /sbin/tc class add dev eth0 parent 1: classid 1:10 cbq bandwidth 100Mbit rate 15Kbit weight 1Kbit prio 5 allot 1514 cell 8 maxburst 20 avpkt 1000 bounded 5- /sbin/tc qdisc add dev eth0 parent 1:10 handle 10 tbf rate 15Kbit buffer 10Kb/8 limit 15Kb mtu 1500 6- /sbin/tc filter add dev eth0 parent 1:0 protocol ip prio 100 u32 match ip dst 192.168.0.169/32 classid 1:10 Vediamo il significato dei comandi nel dettaglio: 1- tc qdisc del dev eth0 root Questo comando elimina una qdisc root eventualmente preesistente già associata all’interfaccia eth0, una sorta di flush delle regole per gli scheduler. 2- tc qdisc add dev eth0 root handle 1 cbq bandwidth 100Mbit avpkt 1000 cell 8 Questo comando crea e associa all'interfaccia eth0 lo scheduler qdisc root cbq e la identifica con handle 1, il bandwidth totale associato è 100Mbit, avpkt è la grandezza del pacchetto medio e serve per determinare il tempo di trasmissione. Il tempo di trasmissione è = a avpkt/bandwidth. Conviene farlo 400 unità più piccolo rispetto alla normale grandezza di un pacchetto. Nel nostro caso il suo valore è 1000 byte. 3- tc class change dev eth0 root cbq weight 10Mbit allot 1514 Questo comando modifica il peso (weight), un parametro per il tuning delle connessioni in genere è WEIGHT ~= RATE / 10. 4- tc class add dev eth0 parent 1: classid 1:10 cbq bandwidth 100Mbit rate 15Kbit weight 1Kbit prio 5 allot 1514 cell 8 maxburst 20 avpkt 1000 bounded Questo comando crea la prima classe ROOT, che ha come genitore il root handle 1:, ed è la classe in cui verranno poi divideranno il bandwidth dei protocolli/IP scelti. In questo caso il bandwidth assegnata 100Mbit, priorità della classe 8. e allot nel caso ethernet è da impostare a 1514 (allot=MTU+MAC), il weight è da scegliere proporzionale a rate, in genere 1/10 di rate. Il significato delle opzioni è: • allot è un parametro formato dall'MTU + MAC header. è sempre più grande di avpkt*3/2. • maxburst è il numero massimo di pacchetti che verranno trasmessi nel flusso più lungo dedicato alla classe • prio è la priorità con cui vengono trattate le classi. Le classi con priorità uguale vengono trattate contemporaneamente. • Esiste anche il parametro weight che dovrebbe servire per determinare il numero di byte che una classe può spedire ad ogni giro di schedulazione.. 5- tc qdisc add dev eth0 parent 1:10 handle 10 tbf rate 15Kbit buffer 10Kb/8 limit 15Kb mtu 1500 Crea e associa una classe all'interfaccia eth0, la classe parent è root 1:10 già creata. La classe è di tipo cbq, il rate 15Kbit buffer 10Kb/8 6- tc filter add dev eth0 parent 1:0 protocol ip prio 100 u32 match ip dst 192.168.0.169/32 classid 1:10 I flussi in uscita si possono assegnare alle classi usando il comando: tc filter. Possiamo associare la nostra regola alla classe root, 1: . L’IP di destinazione è 192.168.0.169/32 Il parametro u32 permette di filtrare i pacchetti in base al contenuto delle intestazioni evitando l'utilizzo del filtro dei pacchetti com il loro marcamento dei pacchetti, permettendo una maggior efficienza. Questo script usato con questo comando (cbq compile) è davvero molto utile perché è una sorta di generatore di regole, utile per poter creare le regole in una forma mediata e poi Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] programmarle con tc sul nostro sistema di shaping. In questo modo le regole diventano comprensibili. Limitazione delle risposta ICMP: un esempio semplice Proviamo a vedere questa semplice ed immediata applicazione di una regola di shaping sulla nostra interfaccia di rete e osserviamo il suo comportamento prima e dopo. Solo per poter verificare in modo semplice ed immediato se il nostro shaper funziona oppure no. In questo caso viene utilizzata, solo a titolo di esempio, una nuova tipologia di coda ovvero TBF. Per condurre il test inviamo dei pacchetti ICMP di una certa dimensione: # ping 151.25.168.165 -c 3 -s 512 PING 151.25.168.165 (151.25.168.165) 512(540) bytes of data. 520 bytes from 151.25.168.165: icmp_seq=1 ttl=55 time=204 ms 520 bytes from 151.25.168.165: icmp_seq=2 ttl=55 time=200 ms 520 bytes from 151.25.168.165: icmp_seq=3 ttl=55 time=208 ms --- 151.25.168.165 ping statistics --3 packets transmitted, 3 received, 0% packet loss, time 2023ms rtt min/avg/max/mdev = 200.140/204.452/208.963/3.642 ms Proviamo adesso a ridurre notevolmente il rate della nostra interfaccia: # tc qdisc add dev ippp0 root tbf rate 1kbit burst 1024 latency 100ms Ora riproviamo a effettuare il ping: # ping 151.25.168.165 -c 3 -s 512 PING 151.25.168.165 (151.25.168.165) 512(540) bytes of data. 520 bytes from 151.25.168.165: icmp_seq=1 ttl=55 time=219 ms 520 bytes from 151.25.168.165: icmp_seq=2 ttl=55 time=201 ms --- 151.25.168.165 ping statistics --3 packets transmitted, 2 received, 33% packet loss, time 2010ms rtt min/avg/max/mdev = 201.801/210.707/219.613/8.906 m Alcuni pacchetti vanno persi, lo shaper è entrato in funzione, verifichiamo anche se ha effettivamente droppato dei pacchetti: # tc -s qdisc show dev ippp0 qdisc tbf 8006: rate 1000bit burst 1023b lat 93.8ms Sent 2152 bytes 10 pkts (dropped 0, overlimits 1) Limitazione Download e Upload: un esempio più elaborato Vediamo un esempio un po’ più complesso in cui è possibile usare la qdisc cbq e la mangle table per poter marcare i pacchetti e limitarli sia nel DOWNLOAD che nell’UPLOAD. In questo caso oltre alle regole di shaping impartire tramite tc, è necessario marcare i pacchetti tramite la mangle table (set-mark) e associarli alla coda specifica creata. Il sistema è un po’ più complesso ma molto versatile in quanto iptables permette una definizione molto specifica, per i pacchetti intercettati, basata su molte caratteristiche del pacchetto stesso (source o destination port, source o destination address, etc). Per fare questo immaginiamo il seguente scenario con 64 Kbits di banda massima a disposizione, e due ----------eth0 (default GW per la LAN) Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] | | | ippp0 (NET) • • eth0 interfaccia connessa alla LAN che vogliamo limitare in UPLOAD e DOWNLOAD ippp0 interfaccia connessa ad INTERNET Questo esempio mostra come utilizzare rapidamente uno script, reperito su web, e opportunamente modificato per limitare il traffico in upload e download, attraverso una normale connessione ad internet. L’operazione richiede due passaggi il primo la configurazione dello script con definizione di alcuni parametri tra cui le interfacce ed i limiti voluti. Della nostra connessione ISDN a 64 kbits di banda disponibile assegniamo 32 kbit al download e 8 appena all’upload. Imposteremo i parametri per la qdisc del download sull’interfaccia interna (eth0) e quelli per l’upload sull’interfaccia esterna (ippp0). #!/bin/bash # rc.tc script TC=/sbin/tc DNLD=32Kbit # Limite per il DOWNLOAD DWEIGHT=4Kbit # DOWNLOAD Weight Factor in genere 1/10 del DOWNLOAD Limit UPLD=8KBit # Limite per l’UPLOAD UWEIGHT=1Kbit # UPLOAD Weight Factor in genere 1/10 del UPLOAD Limit TOTBDWD=100kbit # TOT BAND interfaccia interna TOTBDWU=64kbit # TOT BAND interfaccia esterna LAN=”eth0” # interfaccia interna NET=”ippp0” # interfaccia esterna --------------------------------------------------------------------------------------------------------------------------------tc_start() { $TC qdisc add dev $LAN root handle 11: cbq bandwidth $TOTBDWD avpkt 1000 mpu 64 $TC class add dev $LAN parent 11:0 classid 11:1 cbq rate $DNLD weight $DWEIGHT allot 1514 prio 1 avpkt 1000 bounded $TC filter add dev $LAN parent 11:0 protocol ip handle 2 fw flowid 11:1 $TC qdisc add dev $NET root handle 10: cbq bandwidth $TOTBDWU avpkt 1000 mpu 64 $TC class add dev $NET parent 10:0 classid 10:1 cbq rate $UPLD weight $UWEIGHT allot 1514 prio 1 avpkt 1000 bounded $TC filter add dev $NET parent 10:0 protocol ip handle 1 fw flowid 10:1 } tc_stop() { $TC qdisc del dev $LAN root $TC qdisc del dev $NET root } tc_restart() { tc_stop sleep 1 tc_start } tc_show() { echo "" echo "$LAN:" $TC qdisc show dev $LAN $TC class show dev $LAN $TC filter show dev $LAN echo "" Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] } echo "$NET:" $TC qdisc show dev $NET $TC class show dev $NET $TC filter show dev $NET echo "" tc_count() { echo "" echo "$LAN:" $TC -s qdisc show dev eth0 $TC -s class show dev eth0 $TC -s filter show dev eth0 echo "" echo "$NET:" $TC -s qdisc show dev ippp0 $TC -s class show dev ippp0 $TC -s filter show dev ippp0 echo "" } case "$1" in start) echo -n "Starting bandwidth shaping: " tc_start echo "done" ;; stop) echo -n "Stopping bandwidth shaping: " tc_stop echo "done" ;; restart) echo -n "Restarting bandwidth shaping: " tc_restart echo "done" ;; show) tc_show ;; count) tc_count ;; *) echo "Usage: /etc/init.d/tc.sh {start|stop|restart|show|count}" ;; esac exit 0 Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] La parte relativa alla coda è posto ora occorre impostare la mangle table, in questo caso per un’intera sottorete: # less rc.mangle #!/bin/bash # rc.mangle script # Mark packets to route IPTABLES="/sbin/iptables" LAN=”192.168.0.0/24” #puliamo regole precedenti $IPTABLES -F -t mangle # Upload marking $IPTABLES -t mangle -A FORWARD -s $LAN -j MARK --set-mark 1 # Download marking $IPTABLES -t mangle -A FORWARD -d $LAN -j MARK --set-mark 2 Con questo secondo comando associamo le regole impostate alla mangle table. Ovviamente con iptables è possibile impostare le regole desiderate e applicare lo shaping per il download e per l’upload, anche solo per host specifici o per porte particolari. La mangle table e la parte più critica, quella che permette attraverso la marcatura di alcuni pacchetti, di applicare effettivamente lo shaping e va ovviamente predisposta secondo le proprie esigenze. Per attivare il tutto: # /etc/init.d/rc.tc start # /etc/init.d/rc.mangle Verifichiamo lo shaping provando a fare del traffico sia in upload che in download: # tc -s class show dev eth0 class cbq 11:1 parent 11: rate 32000bit (bounded) prio 1 Sent 278947 bytes 275 pkts (dropped 0, overlimits 581) borrowed 0 overactions 183 avgidle 81 undertime 0 # tc -s class show dev ippp0 class cbq 10:1 parent 10: rate 8000bit (bounded) prio 1 Sent 121121 bytes 284 pkts (dropped 0, overlimits 147) borrowed 0 overactions 73 avgidle 8571 undertime 0 # iptables -L -t mangle Chain FORWARD (policy ACCEPT) target prot opt source destination MARK all -- 192.168.0.0/24 anywhere MARK all -- anywhere 192.168.0.0/24 MARK set 0x1 MARK set 0x2 In effetti in entrambi i sensi lo shaper ha agito marcando dei pacchetti in overlimit. In download otteniamo valori medi intorno a 3,8 kBytes e in upload, effettuato tramite un semplice put in ftp, valori intorno a 1 KBytes, esattamente come ci saremmo aspettati. Ho trovato questo sistema molto adatto e preciso per effettuare shaping sia in UPLOAD che in DOWNLOAD. Wondershaper: una soluzione alternativa Come si può notare molte sono le soluzioni possibili per configurare facilmente lo shaping. Anche questa è una comoda interfaccia, facile da configurare, forse limitata, che permette anche di interfacciarsi a Shorewall, come frontend per il firewall iptables. Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] Informazioni su questo progetto sono disponibili presso: • http://www.my-opensource.org/howto/qostrafficshaping-shorewall-wondershaper-howto.html Una volta scaricati gli script per lo shaping # wget http://lartc.org/wondershaper/wondershaper-1.1a.tar.gz Esistono due script, wshaper, basato su cbq e wshaper.htb basato su htb. Una volta rimossa l’istruzione di exit che ne impedisce l’utilizzo basta configurare le voci: DOWNLINK=16 velocità di UPLOAD in kilobits UPLINK=8 velocità di DOWNLOAD in kilobits DEV=ippp0 interfaccia su cui effettuare lo shaping Attenzione se DEV=Interfaccia esterna (NET) allora DOWNLINK è il valore di download e UPLINK quello di upload, per la rete locale alle spalle dello shaper. Se invece DEV=Interfaccia interna (LAN) allora DOWNLINK è il valore di upload e UPLINK quello di download, per la rete locale alle spalle dello shaper. Questo perché si utilizza l’interfaccia esterna e ciò che è destination diventa source e viceversa. Opzionali sono le voci per la priorizzazione del traffico: # low priority OUTGOING traffic - you can leave this blank if you want # low priority source netmasks NOPRIOHOSTSRC= # low priority destination netmasks NOPRIOHOSTDST= # low priority source ports NOPRIOPORTSRC= # low priority destination ports NOPRIOPORTDST= Una volta eseguito lo script wshaper.htb: # ./wshaper.htb + + + + + + + + + + + + + + + + + + + + + DOWNLINK=16 UPLINK=8 DEV=ippp0 NOPRIOHOSTSRC= NOPRIOHOSTDST= NOPRIOPORTSRC= NOPRIOPORTDST= '[' '' = status ']' tc qdisc del dev ippp0 root tc qdisc del dev ippp0 ingress '[' '' = stop ']' tc qdisc add dev ippp0 root handle 1: htb default 20 tc class add dev ippp0 parent 1: classid 1:1 htb rate 8kbit burst 6k tc class add dev ippp0 parent 1:1 classid 1:10 htb rate 8kbit burst 6k prio 1 tc class add dev ippp0 parent 1:1 classid 1:20 htb rate 7kbit burst 6k prio 2 tc class add dev ippp0 parent 1:1 classid 1:30 htb rate 6kbit burst 6k prio 2 tc qdisc add dev ippp0 parent 1:10 handle 10: sfq perturb 10 tc qdisc add dev ippp0 parent 1:20 handle 20: sfq perturb 10 tc qdisc add dev ippp0 parent 1:30 handle 30: sfq perturb 10 tc filter add dev ippp0 parent 1:0 protocol ip prio 10 u32 match ip tos 0x10 0xff flowid 1:10 tc filter add dev ippp0 parent 1:0 protocol ip prio 10 u32 match ip protocol 1 0xff flowid 1:10 Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] + tc filter add dev ippp0 parent 1: protocol ip prio 10 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 flowid 1:10 + tc filter add dev ippp0 parent 1: protocol ip prio 18 u32 match ip dst 0.0.0.0/0 flowid 1:20 + tc qdisc add dev ippp0 handle ffff: ingress + tc filter add dev ippp0 parent ffff: protocol ip prio 50 u32 match ip src 0.0.0.0/0 police rate 16kbit burst 10k drop flowid :1 Sempre sul solito link ISDN a 64 kilobits ho assegnato un massimo per il download di 16 kilobits. Un semplice test con wget mi conferma il funzionamento della limitazione: # wget http://www.netlink.it/download/file.exe --19:49:11-- http://www.netlink.it/download/file.exe => `file.exe' Resolving www.netlink.it... 212.110.41.203 Connecting to www.netlink.it[212.110.41.203]:80... connected. HTTP request sent, awaiting response... 200 OK Length: 14,841,140 [application/x-msdos-program] 8% [======> ] 1,193,112 1.78K/s ETA 1:35:43 1.78K/s ~ 14-15 kilobits effettivi Ovviamente per poter utilizzare questo script occorre che kernel e programmi (tc) siano presenti sul sistema, ma per il resto è davvero semplice e veloce, e permette in pochi secondi di effettuare una riduzione della banda sia in ingresso che in uscita. Per poter interfacciare questo comodo script con shorewall basta copiarlo sotto la directory delle configurazioni di shorewall con il nome di tcscript, dopo averlo ovviamente configurato: # cp wshaper.htb /etc/shorewall/tcstart # chmod u+x tcstart A questo punto nel file shorewall.conf abilitare il supporto per lo shaping esterno tramite file modificando le opzioni presenti in questo modo: #shorewall.conf TC_ENABLED=Yes CLEAR_TC=Yes Prima di riavviare shorewall è possibile impostare delle porte che abbiano priorità diversa, definendo un file dal nome tcrules, con una sintassi simile: #MARK 1 fw 1 fw 2 fw 2 fw • • SOURCE 0.0.0.0/0 0.0.0.0/0 0.0.0.0/0 0.0.0.0/0 DEST tcp tcp tcp tcp PROTO PORT(S) 6881:6891 6881:6891 80,443 80,443 CLIENT PORT(S) Il mark 1 è per il traffico a bassa priorità Il mark 2 è per il traffico ad alta priorità (ad esempio il traffico http e https) A questo punto riavviare shorewall e lo shaping viene abilitato: # shorewall restart Setting up Traffic Control Rules... TC Rule "1 fw 0.0.0.0/0 tcp 6881:6891 - " added Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] TC Rule "1 fw 0.0.0.0/0 tcp - 6881:6891 " added TC Rule "2 fw 0.0.0.0/0 tcp 80,443 - " added TC Rule "2 fw 0.0.0.0/0 tcp - 80,443 " added Processing /etc/shorewall/tcstart ... L’avvenuta configurazione la si può verificare con i comandi appositamente predisposti: # shorewall show classifiers # shorewall show tc Quest’ultimo comando mostra anche l’effettivo dropping dei testimonianza dell’effettiva applicazione dello shaping: pacchetti in eccesso, a # shorewall show tc Shorewall-3.0.3 Traffic Control at neo - mar gen 10 19:06:11 CET 2006 Device eth0: qdisc pfifo_fast 0: bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 Sent 256507 bytes 767 pkts (dropped 0, overlimits 0) Device ippp0: qdisc htb 1: r2q 10 default 20 direct_packets_stat 0 ver 3.17 Sent 84500 bytes 178 pkts (dropped 0, overlimits 152) Comandi per la verifica Vediamo alcuni comandi generici che permettono di ottenere informazioni circa la configurazione e lo stato di funzionamento dello shaping. Utilizzano tc show e possono quindi essere utilizzati con una qualsiasi delle soluzioni proposte. Ad esempio con questo comando (-s[tatistics]) possiamo verificare il dropping, informazioni che ci mostra inequivocabilmente il funzionamento dello shaping. # tc -s class show dev eth0 class cbq 1: root rate 100000Kbit (bounded,isolated) prio no-transmit Sent 161946 bytes 461 pkts (dropped 0, overlimits 0) borrowed 0 overactions 0 avgidle 81 undertime 0 class cbq 1:10 parent 1: leaf 10: rate 10000bit (bounded) prio 5 Sent 117903 bytes 88 pkts (dropped 19, overlimits 0) borrowed 0 overactions 0 avgidle 859630 undertime 0 class tbf 10:1 parent 10: Con questo -d[etails] ottenere informazioni maggiormente dettagliato sulla configurazione del nostro shaper: # tc -s -d qdisc qdisc cbq 1: dev eth0 rate 100000Kbit cell 8b (bounded,isolated) prio no-transmit/8 weight 10486Kbit allot 1514b level 1 ewma 5 avpkt 1000b maxidle 1us Sent 70138 bytes 72 pkts (dropped 12, overlimits 80) sta effettivamente tagliando backlog 7p borrowed 0 overactions 0 avgidle 81 undertime 0 qdisc tbf 10: dev eth0 rate 32000bit burst 10Kb/8 mpu 0b lat 1.2s Sent 67160 bytes 47 pkts (dropped 12, overlimits 129) backlog 7p Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] qdisc pfifo_fast 0: dev ippp0 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 Sent 194297 bytes 2523 pkts (dropped 0, overlimits 0) Con wget proviamo effettivamente se viene tagliata la banda: # wget http://www.netlink.it/download/file.exe --22:24:46-- http://www.netlink.it/download/file.exe => `file.exe' Resolving www.netlink.it... 212.110.41.203 Connecting to www.netlink.it[212.110.41.203]:80... connected. HTTP richiesta inviata, aspetto la risposta... 200 OK Lunghezza: 14,841,140 [application/x-msdos-program] 0% [ ] 74,264 1.63K/s ETA 2:59:35 Altri comandi # cbq list ### eth0: queueing disciplines qdisc cbq 1: rate 100000Kbit (bounded,isolated) prio no-transmit qdisc tbf 10: rate 10000bit burst 10Kb lat 4.0s ### eth0: traffic classes class cbq 1: root rate 100000Kbit (bounded,isolated) prio no-transmit class cbq 1:10 parent 1: leaf 10: rate 10000bit (bounded) prio 5 class tbf 10:1 parent 10: ### eth0: filtering rules filter parent 1: protocol ip pref 100 filter parent 1: protocol ip pref 100 filter parent 1: protocol ip pref 100 match 00500000/ffff0000 at 20 match c0a81100/ffffff00 at 16 filter parent 1: protocol ip pref 100 match 00140000/ffff0000 at 20 match c0a81100/ffffff00 at 16 filter parent 1: protocol ip pref 100 match 00150000/ffff0000 at 20 match c0a81100/ffffff00 at 16 u32 u32 fh 800: ht divisor 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:10 u32 fh 800::801 order 2049 key ht 800 bkt 0 flowid 1:10 u32 fh 800::802 order 2050 key ht 800 bkt 0 flowid 1:10 ### ippp0: queueing disciplines qdisc pfifo_fast 0: bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 # cbq stats ### eth0: queueing disciplines qdisc cbq 1: rate 100000Kbit (bounded,isolated) prio no-transmit Sent 178352 bytes 236 pkts (dropped 25, overlimits 337) backlog 10p borrowed 0 overactions 0 avgidle 79 undertime 0 qdisc tbf 10: rate 10000bit burst 10Kb lat 4.0s Sent 161998 bytes 107 pkts (dropped 25, overlimits 674) backlog 10p ### eth0: traffic classes class cbq 1: root rate 100000Kbit (bounded,isolated) prio no-transmit Sent 164536 bytes 236 pkts (dropped 0, overlimits 0) borrowed 0 overactions 0 avgidle 81 undertime 0 class cbq 1:10 parent 1: leaf 10: rate 10000bit (bounded) prio 5 Sent 146858 bytes 97 pkts (dropped 25, overlimits 0) Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] backlog 10p borrowed 0 overactions 0 avgidle 722584 undertime 0 class tbf 10:1 parent 10: ### eth0: filtering rules filter parent 1: protocol ip pref 100 filter parent 1: protocol ip pref 100 filter parent 1: protocol ip pref 100 match 00500000/ffff0000 at 20 match c0a81100/ffffff00 at 16 filter parent 1: protocol ip pref 100 match 00140000/ffff0000 at 20 match c0a81100/ffffff00 at 16 filter parent 1: protocol ip pref 100 match 00150000/ffff0000 at 20 match c0a81100/ffffff00 at 16 u32 u32 fh 800: ht divisor 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:10 u32 fh 800::801 order 2049 key ht 800 bkt 0 flowid 1:10 u32 fh 800::802 order 2050 key ht 800 bkt 0 flowid 1:10 ### ippp0: queueing disciplines qdisc pfifo_fast 0: bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 Sent 39823 bytes 433 pkts (dropped 0, overlimits 0) Approfondimenti sulla configurazione di cbq E’ possibile limitare il traffico sia in ingresso che in uscita con una semplice Configurazione. Poniamo il seguente esempio: # # # # # # # # # # # # # # # # # # # # # # # # # # +---------+ 192.168.0.150 INTERNET---eth0 - | linux |-eth1------*-[client] +---------+ Immaginiamo di voler limitare il traffico da internet verso il nostro client a 28Kbit e il traffico nella direzione opposta a 128Kbit. Occorre Configurare due filtri su eth0 (client to internet) e eth1 (internet to client): cbq-028.internet client -------------------------------------------------------------------------DEVICE=eth1,10Mbit,1Mbit RATE=28Kbit WEIGHT=2Kbit PRIO=5 RULE=192.168.0.150 # destination address DOWNLOAD -------------------------------------------------------------------------cbq-128.clientinternet -------------------------------------------------------------------------DEVICE=eth0,10Mbit,1Mbit RATE=128Kbit WEIGHT=10Kbit PRIO=5 RULE=192.168.0.150, # source address UPLOAD -------------------------------------------------------------------------- Sintassi # RULE=[[saddr[/prefix]][:port[/mask]],][daddr[/prefix]][:port[/mask]] Comandi utili Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] Vediamo alcuni comandi sempre di tc, utili un po’ in tutte le situazioni di configurazione: Eliminare una regola: # tc qdisc del dev ippp0 root Visualizzare le regole: # tc -s class show dev eth0 Visualizzare le statistiche in tempo reale: # tc -s class show dev eth0 # watch -n1 tc -s class ls dev eth0 Controllo via web Esiste un modulo per Webmin, che consente di programmare facilmente lo shaping dal proprio browser. Il modulo è stato sviluppato apposta per lo script cbq.init. Basta installare il modulo direttamente da webmin • http://switch.dl.sourceforge.net/sourceforge/webmin-cbq/webmin-cbq-0.1.1.wbm Una volta configurato, basta indicare il path dello script e la directory contenente le configurazioni: Permette di gestire cbq, riavviando o fermandolo, di creare nuove classi oppure di modificare quelle già create: Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] La Qdisc HTB Come anticipato esiste un’altra qdisc supportata da Linux che permette di configurare lo shaping in alternativa a quella CBQ. E’ la qdisc HTB. Vediamo una sua implementazione, del tutto analoga alla precedente attraverso uno script, htb.init, del tutto simile a quello cbq.init, che permette attraverso la configurazione di alcuni file di impostare le regole di shaping in modo altrettanto agevole. La differenza tra questa soluzione e quella precedente consiste essenzialmente che con htb si può specificare eventualmente un surplus di banda da assegnare ad una classe, nel caso in cui questa sia disponibile. Questa operazione viene effettuata tramite il parametro CEIL, particolarmente utile nelle configurazioni standard dove si vuole tagliare la banda alla base, ma la si vuole comunque distribuire se disponibile. Per prima cosa scarichiamo o script ed alcuni file di esempio che semplificano il lavoro di configurazione: # wget http://switch.dl.sourceforge.net/sourceforge/htbinit/htb.init-v0.8.5 # wget http://switch.dl.sourceforge.net/sourceforge/htbinit/htb-lartc.tar.gz # mv tb.init-v0.8.5 /sbin # chmod 0700 /sbin/htb #mkdir /etc/sysconfig/htb # cd /etc/sysconfig/htb # tar tvfz htb-lartc.tar.gz # htb Usage: htb {start|compile|stop|restart|timecheck|list|stats} Vediamo come sfruttare gli esempi per effettuare una configurazione simile a quella fatta con CBQ. All’interno dei file di configurazione occorre utilizzare una serie di parametri tra cui il parametro RATE per indicare la banda assegnata, con CEIL si indica la banda massima che può essere utilizzata prendendone in prestito dalla classe parent, se quest’ultima risulta inutilizzata. Occorre poi specificare il valore di BURST per ogni classe, mentre la priorità nei confronti delle altre classi, indicata con il valore PRIO e opzionale. Con il parametro DEFAULT si specifica la classe in cui includere i pacchetti non classificati attraverso un altro metodo. Ipotizziamo sempre la situazione della connessione attraverso un’interfaccia isdn del tipo ippp0, con al massimo 64 kbit di banda a disposizione ovvero 8 KBs. Lo shaping lo effettueremo sull’interfaccia entrante connessa alla LAN, ovvero eth0. Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] ----------eth0 (default GW per la LAN) | | | ippp0 Procediamo in questo modo, creando una serie di script in /etc/sysconfig/htb: eth0: definisce l’interfaccia su cui fare shaping ed alcuni parametri di default opzionali eth0-2.root: imposta la banda totale disponibile eth0-2:10.www: imposta la banda assegnata la servizio http eth0-2:20.smtp: imposta la banda assegnata al servizio http N.B. Attenzione ai nomi dei file usati apposta per suddividere le sottoclassi. La sintassi utilizzata è questa: # $HTB_PATH/<ifname>-<clsid>(:<clsid>)*<description> Vediamo gli script: # cd /etc/sysconfig/htb # less eth0 # default ID per il traffico non classificato DEFAULT=30 R2Q=100 # less eth0-2.root # root class contenente il bandwidth totale RATE=64kbit # less eth0-2:10.www # classe per il traffico HTTP in uscita RATE=16kbit # 2 K/Bs CEIL=16kbit LEAF=sfq RULE=*:80, # less eth0-2:20.smtp # classe per il traffico SMTP in uscita RATE=16kbit # 2 K/Bs CEIL=16kbit BURST=16k LEAF=sfq RULE=*:25 # less eth0-2:30.ftp # classe per il traffico FTP in uscita RATE=8kbit # 1 K/Bs CEIL=8kbit BURST=8k LEAF=sfq RULE=*:20 RULE=*:21 Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] # less eth0-2:40.dfl # default class per il traffico non classificato RATE=1Kbit CEIL=1Kbit BURST=15k LEAF=sfq Attenzione specificando il valore CEIL si può assegnare una banda inutilizzata della root class, questo permette di ottenete valori di banda superiori a quelli indicate con il parametro RATE. Un altro tipo di configurazione permette invece di suddividere la banda assegnandone maggiormente ad alcuni host rispetto ad altri. Nel caso dell’accesso ai sito web (porta 80): # less eth0-2.root # root class contenente il bandwidth totale RATE=64kbit # less eth0-2:10.www # classe per il traffico uscita dell’host 192.168.0.10 RATE=8kbit # 1 K/Bs CEIL=8kbit LEAF=sfq RULE=*:80,192.168.0.10 # less eth0-2:20.www # classe per il traffico uscita dell’host 192.168.0.11 RATE=16kbit # 2 K/Bs CEIL=16kbit LEAF=sfq RULE=*:80,192.168.0.11 # less eth0-2:30.www # classe per il traffico uscita dell’host 192.168.0.12 RATE=32kbit # 4 K/Bs CEIL=32kbit LEAF=sfq RULE=*:80,192.168.0.12 Se volessimo invece differenziare la banda sulla base dell’host di destinazione potremmo configurare la coda htb in questo modo: # less eth0-2.root # root class contenente il bandwidth totale RATE=64kbit # less eth0-2:10.www # classe per il traffico in ingesso da 212.110.41.203 RATE=8kbit # 1 K/Bs CEIL=8kbit RULE=212.110.41.203:80, Da questo sito si scarica a ~ 1KB/s # less eth0-2:20.www Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] # classe per il traffico in ingresso da 213.254.10.95 RATE=32kbit # 4 K/Bs CEIL=32kbit RULE=213.254.10.95:80, Da questo sito si scarica a ~ 4KB/s. Notare la virgola finale indica il source address Questa configurazione permette di limitare la banda verso i server web di questi specifici host, verso tutti gli altri si viaggerà a banda piena. Anche per il metodo con htb esiste un modulo di webmin analogo che permette la configurazione via web delle regole di filtro. # wget http://sehier.fr/webmin-htb/webmin-htb.tar.gz Installazione e configurazione sono del tutto simili a quelli visti per il modulo CBQ. Controllo della banda in ingresso Proviamo adesso a effettuare shaping solo sulla banda in ingresso, ad esempio se volessimo evitare che tutta la nostra banda venga esaurita da un webserver a cui gli utenti internet accedono possiamo effettuare lo shaping, allo stesso modo visto prima ma in questo caso agiremo sull’interfaccia esterna, nel nostro caso ippp0, che è quella effettivamente esposta su internet. Vediamo gli script: # cd /etc/sysconfig/htb # less ippp0 # default ID per il traffico non classificato DEFAULT=30 R2Q=100 # less ippp0-2.root # root class contenente il bandwidth totale RATE=64kbit # less ippp0-2:10.www # classe per il traffico HTTP in ingresso RATE=16kbit # 2 K/Bs CEIL=16kbit LEAF=sfq RULE=*:80, # indica il SOURCE IP Con questa semplice regola tutto il traffico proveniente da internet verso il mio server web, posto per il nostro test su IP dinamico su linea ISDN, viene limitato a 16 kbit, al massimo 2KB. Come possiamo effettivamente verificare se provassimo a scaricare da un accesso esterno la nostra velocità di download non supererebbe i 2 KBs. # wget http://151.25.163.23/file.exe --16:07:15-- http://151.25.163.23/file.exe => `file.exe' Connecting to 151.25.163.23:80... connected. HTTP request sent, awaiting response... 200 OK Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] Length: 122,342 [application/x-msdos-program] 96% [========================================================================= ============> ] 118,402 1.88K/s ETA 00 Verifichiamo anche che lo shaper stia effettivamente tagliando la banda: # htb stats ### ippp0: queueing disciplines qdisc htb 1: r2q 10 default 0 direct_packets_stat 0 Sent 114892 bytes 78 pkts (dropped 3, overlimits 129) backlog 13p Estendiamo i concetti appena visti ad una configurazione completa per il controllo e la limitazione della banda in ingresso verso i servizi web, come potrebbero essere quelli di una server farm, con priorizzazione del traffico web al di sopra di tutti gli altri. Potrebbe avere una configurazione di questo tipo: 512 Kbit di banda entrante suddivisa in questo modo: # cd /etc/sysconfig/htb L’interfaccia connessa ad internet è la eth1 che passa per un normale router ADSL con banda 2Mbit/512Kbit. # less eth1 # default ID per il traffico non classificato DEFAULT=30 R2Q=100 # less eth1-2.root # root class contenente il bandwidth totale in ingresso RATE=512KBit Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] # less eth1-2:10.www # classe per il traffico HTTP in ingresso RATE=256kbit CEIL=100kbit LEAF=sfq RULE=*:80, # less eth1-2:20.ftp # classe per il traffico FTP in ingresso RATE=128kbit CEIL=64kbit LEAF=sfq RULE=*:80, # less eth1-2:30.smtp # classe per il traffico SMTP in ingresso RATE=64kbit CEIL=16kbit LEAF=sfq RULE=*:25, # less eth1-2:40.pop3+imap # classe per il traffico POP3+IMAP in ingresso RATE=64kbit CEIL=16kbit LEAF=sfq RULE=*:110, RULE=*:143, In questo caso di cui sono state mostrate le configurazioni per esteso, è stato scelto di assegnare la banda eventualmente disponibile (parametro CEIL), in maggioranza sempre al server web, quelle che si presume debba essere il servizio reso maggiormente disponibile. Va da sé che ognuno può utilizzare queste configurazioni per gestire come meglio crede lo shaping in ingresso verso i propri servizi. Configurazione di HTB con il marking (mangle table) Vediamo anche un esempi di configurazione che preveda l’uso della mangle table, che consente una maggior flessibilità per il controllo di source e destination port/address. Vediamo sempre per il controllo della banda in ingresso: # less ippp0 # default ID per il traffico non classificato DEFAULT=30 R2Q=100 # less ippp0-2.root # root class contenente il bandwidth totale RATE=64kbit # less ippp0-2:10.www # classe per il traffico HTTP in uscita Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] RATE=16kbit # 2 K/Bs CEIL=16kbit LEAF=sfq RULE=*:80, MARK=1 Impostiamo la mangle table per tutto il traffico http (source destination): # iptables -A PREROUTING -t mangle -p tcp --sport 80 --j MARK --set-mark 1 # iptables -A PREROUTING -t mangle -p tcp --dport 80 --j MARK --set-mark 1 # iptables -L -n -t mangle MARK tcp -- 0.0.0.0/0 MARK tcp -- 0.0.0.0/0 0.0.0.0/0 0.0.0.0/0 tcp spt:80 MARK set 0x1 tcp dpt:80 MARK set 0x1 Test dello shaping con Iperf Per poter verificare bene la banda a disposizione e verificare che questa venga limitata effettivamente, andiamo oltre il dato fornitoci come download rate da wget, ed utilizziamo iperf, il noto tool client/server pe effettuare misurazioni di banda. E’ necessario installare ed avviare su di un punto remoto, al di fuori della nostra rete, iperf come server in modo da poter effettuare i test. server:~# iperf -s Facciamo il test dal client, ricordandoci che la nostra banda è quella di una connessione ISDN a canale singolo, quindi ci aspettiamo 64k kbits, bit più bit meno. client:~# iperf -c 85.34.156.130 -----------------------------------------------------------Client connecting to 85.34.156.130, TCP port 5001 TCP window size: 16.0 KByte (default) -----------------------------------------------------------[ 5] local 192.168.0.169 port 4618 connected with 85.34.156.130 port 5001 [ 5] 0.0-13.2 sec 104 KBytes 64.8 Kbits/sec Risorse • http://pcquest.ciol.com/content/search/showarticle.asp?artid=56053 Shorewall traffic shaping Introduzione Vediamo anche utilizzando Shorewall come è possbile effettuare il traffic shaping. La nuova versione 3.0 ben lo supporta, inserendo alcuni file ad hoc: tcdevices, tcclasses e tcrules. Nel caso in cui si volesse interfacciare le proprie regole di tc in modo passivo basta abilitare in shorewall.conf le direttive: TC_ENABLED=Yes CLEAR_TC=Yes Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] Ed inserire i propri comandi in un script dal nome /etc/shorewall/tcrules. Questo argomento è stato trattato in precedenza nella sezione relativa all’uso del Wondershaper. Nel caso in cui si volesse invece configurare tc usando i file e le regole di shorewall si può usare una configurazione come quella di seguito presentata. Configurazione tcdevices #INTERFACE IN-BANDWITH# download OUT-BANDWIDTH#upload ippp0 64kbit 64kbit #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE tcclasses ########################################################## ##################### #INTERFACE MARK RATE CEIL PRIORITY OPTIONS ippp0 1 20kbit 5kbit 1 tcp-ack ippp0 2 15kbit 5kbit 3 ippp0 3 10kbit full 3 #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE tcrules ########################################################## ##################### #MARK SOURCE DEST PROTO PORT(S) CLIENT USER TEST # PORT(S) 1:P 0.0.0.0/0 0.0.0.0/0 icmp echo-request 1:P 0.0.0.0/0 0.0.0.0/0 icmp echo-reply 2:P 192.168.0.169 0.0.0.0/0 all 2:P $FW 0.0.0.0/0 all 3:P 192.168.0.190 0.0.0.0/0 all #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE Verifica regole con shorewall # shorewall show tc Shorewall-3.0.3 Traffic Control at neo - lun gen 2 14:50:14 CET 2006 Device eth0: qdisc pfifo_fast 0: bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 Sent 16975917 bytes 68563 pkts (dropped 0, overlimits 0) Device ippp0: qdisc pfifo_fast 0: bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 Sent 438201 bytes 6383 pkts (dropped 0, overlimits 0) # shorewall show mangle Chain tcpre (1 references) pkts bytes target prot opt in 0 0 MARK icmp -- * set 0x1 0 0 MARK icmp -- * set 0x1 out * source 0.0.0.0/0 destination 0.0.0.0/0 icmp type 8 MARK * 0.0.0.0/0 0.0.0.0/0 icmp type 0 MARK Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] 148 9054 MARK all -- * * 192.168.0.169 0.0.0.0/0 MARK set 0x3 Questa Soluzione permette la configurazione direttamente con Shorewall evitando di utilizzare Wondershaper e quindi script esterni. Risulta abbastanza chiara ed intuitiva e permette configurazioni particolareggiate integrandosi con l’uso della mangle table di shorewall. Risorse Documentazione principale http://www.shorewall.net/traffic_shaping.htm Valutazione della velocità http://www.speedcheck.arcor.de/cgi-bin/speedcheck.cgi Iproute e Mangle table: Smistamento del traffico in uscita Introduzione Un’altra esigenza era quella di poter smistare il traffico di un particolare tipo su di un'altra linea, in modo da poter bilanciare il carico. In questo caso non si tratta di shaping ma di smistamento vero e proprio su linee diverse del traffico generato o destinato verso particolari host piuttosto che verso particolari servizi. Ho già affrontato l’argomento in un vecchio HOWTO, in cui si spiegava come distribuire il traffico in basse all’host della rete locale che lo generava. In questo caso ho avuto bisogno di distinguere il tipo traffico, in base al servizio utilizzato e dirottarlo su di una linea piuttosto che su quella di default. Nel mio caso ho dovuto dirottare il traffico SMTP verso l’interfaccia ippp0 per motivi di relay, ovviamente si può scegliere di configurare il sistema in base alle proprie esigenze. Gli strumenti utilizzati sono iproute2 e iptables, di cui entra in gioco la tabella di MANGLE, che permette di manipolare in modo particolare i pacchetti che attraversano il sistema. Come da teoria è costituita da due catene predefinite, quella di PREROUTING e OUTPUT; la prima serve a modificare i pacchetti in entrata prima della decisione di routing, la seconda interviene sui pacchetti locali in uscita prima della decisione di routing. Impostazione Vediamo come marcare e dirottare sull’interfaccia secondaria (ippp0), invece che sul gateway di default eth1, tutto il traffico in uscita destinato alla porta 25. 1 - Marchiamo i pacchetti in uscita con iproute (tabella di prerouting) # iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 25 -j MARK --set-mark 1 Impostiamo il masquerading # iptables -t nat -A POSTROUTING -s $INTERNAL_NET -d 0/0 -j MASQUERADE 2 - Creiamo la entry (mail.out) e la regola per l’uscita della posta verso una specifica interfaccia # echo 201 mail.out >> /etc/iproute2/rt_tables 3 - Impostiamo la rule per il mark 1 # ip rule add fwmark 1 table mail.out Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] # ip rule ls 0: from all lookup local 32765: from all fwmark 0x1 lookup mail.out 32766: from all lookup main 32767: from all lookup default 4 - Impostiamo il default per questa table ($IPPP0=IP interfaccia ippp0) #ip route add default via $IPPP0 dev ippp0 table mail.out # rc.ippp0 EXTERNAL="ippp0" IPPP0=`ifconfig $EXTERNAL | grep inet | cut -d : -f 3 | cut -d \ -f 1` Controlli # iptables -L -t nat Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- 192.168.0.0/24 anywhere # iptables -L -t mangle Chain PREROUTING (policy ACCEPT) target prot opt source destination MARK tcp -- anywhere anywhere tcp dpt:smtp MARK set 0x1 Note Come è facilmente intuibile si può intercettare il traffico di altra Tipologia, o con source o destination particolari usando iptables ed utilizzando successivamente iproute per fargli seguire strade alternative. Ad esempio se volessimo associare protocolli diversi ad una nuova table, e fargli seguire la strada del link xDSL, potremmo utilizzare i seguenti comandi: # iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 80 -j MARK --set-mark 1 # iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 21 -j MARK --set-mark 2 # iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 443 -j MARK --set-mark 3 # echo 202 web.out >> /etc/iproute2/rt_tables # ip rule add fwmark 1 table web.out # ip rule add fwmark 2 table web.out # ip rule add fwmark 3 table web.out # ip route add default via $ETH1 dev eth1 table www.out Shaping con Squid Introduzione Se la nostra necessità fosse quella di limitare il solo traffico http e ftp, lo si potrebbe fare tranquillamente usando un proxy. Ad esempio con Squid e la funzionalità di delay pools questo è possibile. Squid ha bisogno comunque che alcune opzioni in fase di compilazione siano attive in particolare quella di --enable-delay-pools. Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] Vediamo come installare e poi alcuni esempi specifici di configurazione (squid.conf) per differenziare e limitare il traffico verso internet di specifici host. Compilazione # ./configure --prefix=/opt/squid --exec-prefix=/opt/squid --enable-delay-pools --enablecache-digests --enable-poll --disable-ident-lookups --enable-truncate --enable-removalpolicies Limitazione con Squid per IP singoli # Impostiamo le ACL acl allowed_ip1 src 192.168.0.1/32 acl allowed_ip2 src 192.168.0.100/32 # Impostiamo i delay pools delay_pools 2 delay_class 1 2 delay_access 1 allow allowed_ip1 delay_parameters 1 128000/128000 128000/128000 delay_class 2 2 delay_access 2 allow allowed_ip2 delay_parameters 2 32000/32000 32000/32000 • 192.168.0.1/32 scarica a 128 KB/s • 192.168.0.100/32 scarica a 32 KB/s Limitazione con Squid per classi di IP # Impostiamo le ACL acl allowed_ip1 src 192.168.0.0/24 acl allowed_ip2 src 192.168.1.0/24 # Impostiamo i delay pools delay_pools 2 delay_class 1 1 delay_access 1 allow allowed_net1 delay_parameters 1 256000/256000 256000/256000 delay_class 2 1 delay_access 2 allow allowed_net2 delay_parameters 2 64000/64000 64000/64000 • 192.168.0.1/32 scarica a 128 KB/s • 192.168.0.100/32 scarica a 32 KB/s Programmi alternativi per nuove esigenze Se la vostra necessità fosse quella di limitare la banda a disposizione di un determinato programma residente su di un server Linux, esiste una soluzione alternativa molte semplice da utilizzare. Questa alternativa prevede l’utilizzo di un software chiamato Trickle, il quale permette di limitare la banda in upload/download di particolari programmi. Vediamo come funziona: # apt-get install trickle # trickled eseguire tricled Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] # trickle -d 10 wget www.netlink.it/download/file.zip limita il download a 10 KB/s # trickle -u 10 -d 20 ftp limita l’upload a 10 Kb/s e il download a 20 Kb/s Per poter limitare la banda dal sistema in modo semplice ed intuitivo questa soluzione richiede davvero poco sforzo e si dimostra efficace. Provare per credere! Note Finali Molte sono le soluzioni proposte per la configurazione di uno shaper, alcune più dirette con un maggior controllo, ma anche una maggior complessità, come quelle fatte manualmente altre più semplici e mediate ma spesso più difficili da personalizzare. L’uso di script semplifica di molto la configurazione dello shaper, questa è la soluzione da me scelta. Per le mie esigenze ho trovato il sistema dello script htb.init davvero versatile e adatto alle mie esigenze ed è con quello che ho costruito il mio shaper. L’argomento è complesso, e ho volutamente tralasciato parti teoriche, che esulavano dallo scopo del documento e su cui non sarei comunque stato in grado di fare chiarezza. La parte pratica, la più utile, è però stata sviluppata abbastanza, spero con esempi utili, tutti testati e funzionanti, nulla è stato citato a livello teorico, se prima non effettivamente provato. Non ho dati sul lungo termine per verificare l’efficacia dello shaper, realizzato con un semplice PC con Debian Sarge installata, che si è comunque dimostrato davvero efficiente in fase di test. Chi ne avesse la necessità può utilizzare soluzioni analoghe che hanno sempre il pregio del costo nullo in termini di software, specie se paragonate a soluzioni commerciali concorrenti. Se avessi commesso qualche errore o voleste integrare l’articolo fatemelo spere scrivendo a [email protected]. Risorse Un grosso aiuto l’ho avuto da questo documento (Traduzione di Emanuele Tajariol - Maggio 2002.): http://it.tldp.org/HOWTO/Bandwidth-Limiting-HOWTO/index.html Linux 2.4 Advanced Routing HOWTO http://www.linuxguruz.com/iptables/howto/2.4routing-12.html Controllo del traffico, shaping di Masetti Marco http://digilander.libero.it/amilinux/Linux_QoS/tc.html#toc13 Bandwidth Limiting Howto (in Italiano) http://it.tldp.org/HOWTO/Bandwidth-Limiting-HOWTO/install.html http://it.tldp.org/HOWTO/ADSL-Bandwidth-Management-HOWTO/background.html Limitare la banda con Gentoo http://wiki.gentoo-italia.net/index.php/Limitare_la_banda The Wonder Shaper http://lartc.org/wondershaper/ http://www.my-opensource.org/howto/qostrafficshaping-shorewall-wondershaper-howto.html Sistemisti Indipendenti.ORG Sistemisti Indipendenti.ORG http://www.sistemistiindipendenti.org e-mail: [email protected] HOWTO Packet Shaping http://gentoo-wiki.com/HOWTO_Packet_Shaping TC Traffic Control http://digilander.libero.it/amilinux/doc/tc/tc-8.html Altre Risorse http://www.securityfocus.com/infocus/1285 http://www.linuxvalley.com/columns/columns.php?IdCol=123 http://ftp-ildp.httpdnet.com/ADSL-Bandwidth-Management-HOWTO http://www.szabilinux.hu/bandwidth/ http://www.tic.fdns.net/tic/html/uml-QoS.html#conf http://labtel.ing.uniroma1.it/tesi/fdl/tesiHTML3.html http://www.roback.cc/howtos/bandwidth.php#Setting_Bandwidth Doc: shaping.pdf Dott. Paolo PAVAN [Netlink Sas]– [email protected] Data: Dicembre 2005 Note finali Il presente documento è a semplice scopo divulgativo L’autore non si assume la responsabilità di eventuali danni diretti o indiretti derivanti dall'uso dei programmi, o dall’applicazione delle configurazioni menzionate nel seguente articolo I marchi citati sono di proprietà dei rispettivi proprietari e sono stati utilizzati solo a scopo didattico o divulgativo. I contenuti di questo documento vengono rilasciati sotto Licenza Creative Commons. http://creativecommons.org/licenses/by-nc-sa/2.0/ Sono possibili errori o imprecisioni, segnalatemele a [email protected] Chi volesse integrare il presente documento, può scrivere a [email protected]. Sistemisti Indipendenti.ORG