Recentemente ho avuto bisogno di implementare un servizio di QoS (Quality of Service) tra le due sedi principali per permettere a due apparecchi per videoconferenza di comunicare al meglio fra loro: andava garantita una disponibilità minima di banda alle comunicazioni tra le due due macchine per permettere alla videoconferenza di svolgersi in maniera fluida senza scatti e/o altri disturbi.
La situazione della rete era la seguente:
Sede 1 (solo i parametri effettivamente rilevanti):
rete: 192.168.195.0/24
interfaccia esterna firewall: eth0
interfaccia VPN: tun0
porta openvpn su eth0: 5001
macchina videoconferenza: 192.168.195.218
Sede2
rete: 192.168.196.0/24
interfaccia esterna firewall: eth0
interfaccia VPN: tun0
porta openvpn su eth0: 5001
macchina videoconferenza: 192.168.196.25
ambedue le reti collegate ad internet su fibra ottica con banda 10Mbit (cioè 1250 Kb/s nominali).
In sostanza la necessità era quella di isolare e garantire una quantità certa di banda al traffico vpn tra le due sedi, e all'interno del traffico vpn isolare e garantire la banda necessaria al traffico tra le due macchine.
Per documentarmi sono partito dal Linux Advanced Routing & Traffic Control Howto, ottimo compendio che già avevo consultato quando avevo avuto bisogno di creare delle regole di policy routing. Una lettura della parte riguardante appunto il QoS mi ha fatto ritenere che il sistema di classificazione HTB fosse il più indicato per la mia situazione. Mi sono quindi indirizzato verso HTB Linux queuing discipline manual - user guide.
I due firewall su cui ho lavorato sono due Debian Sarge con kernel di default 2.6.8-3-686. E' sufficiente installare il pacchetto "iproute" per avere tutto ciò che serve.
Seguendo prima la guida e cercando poi di adattare gli esempi alle mie esigenze ho cominciato a scrivere le regole necessarie ad isolare il traffico vpn dal resto del traffico in uscita sull'interfaccia eth0 sul firewall della rete1:
#creo una coda con algoritmo htb sull'interfaccia eth0 e la chiamo "1:"
#default 12 significa che ogni traffico non altrimenti classificato
# viene assegnato alla classe 1:12
tc qdisc add dev eth0 root handle 1: htb default 12
#Creo la classe root 1:1 (figlia diretta di 1:)
tc class add dev eth0 parent 1: classid 1:1 htb rate 1200kbps ceil 1200kbps
#creo le altre classi come figlie di 1:1
# le classi figlie di una classe root possono scambiarsi e ripartirsi fra loro la banda
# diverse classi root invece non possono farlo
# per questo creo le classi di cui ho bisogno come figlie di una root
# tutto il traffico non altrimenti classificato cade in classe 12
# e, quando la banda è satura, ha diritto ad un massimo di 128K/s di banda
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 512kbps ceil 1200kbps
tc class add dev eth0 parent 1:1 classid 1:11 htb rate 256kbps ceil 1200kbps
tc class add dev eth0 parent 1:1 classid 1:12 htb rate 128kbps ceil 1200kbps
# assegno il traffico vpn (porta 5001) alla classe 10
# gli garantisco quindi 512 K/s di banda
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 5001 0xffff match ip sport 5001 0xffff flowid 1:10
A questo punto ho creato tre classi di "banda garantita", la 12 (poca banda, dove metto tutto ciò che non classifico), la 11 (un po' più di banda, per adesso non utilizzata, verrà usata per traffico di media importanza) e la 10 (tanta banda garantita, ci metto il traffico tra i due capi della vpn) e ho isolato il traffico vpn dal traffico normale sull'interfaccia eth0 assegnandolo alla classe 10.
Quello che resta da fare è passare sull'interfaccia vpn (tun0) e classificare il traffico anche qua in modo che il traffico tra le due macchine di videoconferenza abbia una certa banda garantita. I primi passaggi sono gli stessi: creo una coda e delle classi di banda:
tc qdisc add dev tun0 root handle 1: htb default 12
tc class add dev tun0 parent 1: classid 1:1 htb rate 1200kbps ceil 1200kbps
tc class add dev tun0 parent 1:1 classid 1:10 htb rate 512kbps ceil 1200kbps
tc class add dev tun0 parent 1:1 classid 1:11 htb rate 256kbps ceil 1200kbps
tc class add dev tun0 parent 1:1 classid 1:12 htb rate 128kbps ceil 1200kbps
Successivamente creo una regola per identificare il traffico che mi interessa, quello tra le due macchine, ed assegnarlo alla classe 10:
tc filter add dev tun2 protocol ip parent 1:0 prio 1 u32 match ip src 192.168.195.218 match ip dst 192.168.196.25 flowid 1:10
Fatto questo le regole di classificazione sul primo firewall sono pronte. La cosa simpatica è che in questa configurazione i comandi da dare sul secondo firewall sono esattamente gli stessi tranne l'ultimo, nel quale vanno invertiti gli indirizzi ip delle due macchine.
I comandi per ottenere qualche statistica sul traffico sono:
tc -s -d qdisc show dev eth0 # usare tun0 per statistiche sull'altra interfaccia
Questo comando fornisce statistiche generali sulla coda abbinata a una interfaccia. Per interpretarle occorre ricordare che overlimits rappresenta il numero di pacchetti che sono stati "ritardati" dalla regola, mentre dropped rappresenta quelli scartati.
Statistiche più dettagliate per le singole classi abbinate ad una coda si visualizzano con:
tc -s -d class show dev eth0
Chi avrà voglia di leggersi HTB Linux queuing discipline manual - user guide (cosa ovviamente consigliatissima) si renderà immediatamente conto che quanto qui sopra descritto rappresenta solo una piccola parte di quanto si può fare con la classificazione dei pacchetti basata su HTB. Tuttavia per le mie attuali esigenze è stato ampiamente sufficiente e sono riuscito a metterlo in piedi in un paio d'ore partendo da una conoscenza abbastanza superficiale dei meccanismi di QoS. Per finire ho fatto alcuni rapidi test "occhimetrici" ed il risultato è davvero notevole: la banda viene gestita e attribuita correttamente a seconda del tipo di traffico ed il risultato è immediatamente visibile quando si tengono sotto controllo diversi tipi di traffico contemporaneamente.
Nessun commento:
Posta un commento