Archivi tag: lan

Cisco 877: configurare il QoS per il traffico VOIP (SIP/RTP)

Un po’ di teoria (ToS vs DiffServ)

Il QoS (acronimo che sta ad indicare il cosiddetto Quality of Service) è una tecnica L3 per la prioritizzazione del traffico, in grado cioè di garantire una banda minima e/o bassi livelli di latenza e jitter (a seconda dei casi e delle esigenze). Tutte le politiche di QoS si basano su un campo dell’header IP, denominato DS filed (un tempo ToS – Type of Service – ormai deprecato). In particolare, esso presenta la seguente struttura:

DS5     DS4     DS3     DS2     DS1     DS0     ECN     ECN

dove i 3 bit più significativi (DS5, DS4 e DS3) rappresentano, per il ToS, alla cosiddetta IP Precedence. Ad esempio, il pattern DiffServ 101 000 indica una priorità pari a 5 (ovvero la traduzione del digit 101 in decimale). Da ciò si evince che tutte le politiche QoS basate su DiffServ che tengono conto dei soli 3 bit più significativi, sono perfettamente retrocompatibili con il  ToS (e quindi con tutti i dispositivi più datati che supportano esclusivamente tale tipologia di QoS).

NB: I 6 bit DS prendono il nome di DSCP (Differentiated Services Code Point).

Il motivo per cui il protocollo DiffServ è riuscito a soppiantare quasi completamente il ToS è molto semplice: la sua maggiore granularità nella gestione del traffico interessante (ovvero quello oggetto delle politiche di QoS) rispetto al suo predecessore.

 Ancora teoria (DiffServ PHB)

qosdiagramIl DiffServ prevede 5 tipologie di comportamento (PHB – Per Hop Behaviour) che i router attraversati da uno specifico datagramma possono intraprendere. Essi sono i seguenti:

1) Default PHB, con i bit DS  settati a  000 000 – Best Effort (aka nessuna garanzia di instradamento);

2) Expedited Forwarding (EF PHB), con i bit DS settati a 101110 – il migliore in assoluto (poichè molto affidabile, prevede bassissimi tempi di latenza e valori di jitter minimi, nonchè basse probabilità che il datagramma venga droppato);

3) Assured Forwarding (AF PHB), che fa fede alla seguente tabella:

Low Drop AF11 (DSCP 10) AF21 (DSCP 18) AF31 (DSCP 26) AF41 (DSCP 34)
Med Drop AF12 (DSCP 12) AF22 (DSCP 20) AF32 (DSCP 28) AF42 (DSCP 36)
High Drop AF13 (DSCP 14) AF23 (DSCP 22) AF33 (DSCP 30) AF43 (DSCP 38)

4) Voice Admit PHB, con i bit DS settati a 101100 – identico all’EF PHB per affidabilità e bassa latenza, si basa sul CAC (Call Admission Control);

5) Class Selector (CS PHB):  retrocompatibile con l’IP Precedence del ToS, fa fede alla seguente tabella:

DSCP    Binary     Decimal  Typical Application     Examples
CS0     000 000    0        N/A                  N/A (best effort)    
CS1     001 000    8        Scavenger            YouTube, Gaming, P2P
CS2     010 000    16       OAM                  SNMP,SSH,Syslog
CS3     011 000    24       Signaling            SCCP,SIP,H.323
CS4     100 000    32       Realtime             TelePresence
CS5     101 000    40       Broadcast video      Cisco IPVS
CS6     110 000    48       Network Control      EIGRP,OSPF,HSRP,IKE

In definitiva, è possibile utilizzare la seguente tabella per la mappatura dei pattern DSCP con l’IP Precedence:

Value Decimal Meaning Drop Probability Equivalent IP Precedence Value
 101 110 46   EF               N/A        101 Critical
 000 000  0   Best Effort      N/A        000 - Routine
 001 010 10   AF11             Low        001 - Priority
 001 100 12   AF12             Medium     001 - Priority
 001 110 14   AF13             High       001 - Priority
 010 010 18   AF21             Low        010 - Immediate
 010 100 20   AF22             Medium     010 - Immediate
 010 110 22   AF23             High       010 - Immediate
 011 010 26   AF31             Low        011 - Flash
 011 100 28   AF32             Medium     011 - Flash
 011 110 30   AF33             High       011 - Flash
 100 010 34   AF41             Low        100 - Flash Override
 100 100 36   AF42             Medium     100 - Flash Override
 100 110 38   AF43             High       100 - Flash Override

Definizione delle politiche di QoS sul router Cisco 877

Dopo questa breve carrellata teorica veniamo alla pratica. Per prima cosa occorre distinguere tra le politiche di QoS in ingresso e quelle in uscita.

Le prime si basano sul cosiddetto CAR (Committed Access Rate); per le seconde, invece, bisogna utilizzare l’accoppiata class-map/policy-map. In entrambi i casi occorre definire un’opportuna ACL per l’identificazione del traffico interessante, ad esempio:

access-list 105 remark inbound VOIP (SIP/RTP) traffic gets top priority (5) with CAR
access-list 105 permit udp any any eq 5060
access-list 105 permit udp any any range 10000 20000

Alla luce di quanto detto, per il QoS del traffico in ingresso possiamo utilizzare la seguente configurazione:

rate-limit input access-group 105 128000 65536 65536 conform-action set-prec-transmit 5 exceed-action set-prec-continue 0 
rate-limit input 13414000 13000000 13400000 conform-action transmit exceed-action drop

Per il traffico in uscita, invece, dobbiamo digitare:

class-map voice
match access-group 105

policy-map policy1
class voice
priority 128
class class-default
bandwidth 795
fair-queue

Per prima cosa abbiamo definito la class-map voice che fa uso dell’ACL precedentemente definita. La suddetta class-map andrà a popolare la policy-map policy1 (che può essere vista come una sorta di contenitore di una o più class-map), dentro la quale definiremo il traffico prioritario (grazie alla direttiva priority). Il valore si intende espresso in kbps.

La class-default, invece, consente di riservare la banda minima garantita per tutto il traffico che non rientra nel QoS, dove fair-queue è sinonimo di best effort. Anche in questo caso parliamo di kbps. Ovviamente i valori assegnati sono stati calcolati basandosi sull’uplink rate dell’interfaccia ADSL del router.

NB: per traffico prioritario si intende quello con bassa probabilità di drop e bassi valori di latenza/jitter.

L’ultimo step consiste nell’assegnazione della policy-map policy1 all’interfaccia fa0 (LAN) ed ATM0 (WAN). Per la LAN avremo:

 interface FastEthernet0
 no ip address
 service-policy output policy1

mentre per la WAN:

interface ATM0
 no ip address
 no atm ilmi-keepalive
 pvc 8/35
  vbr-nrt 923 923 1
  tx-ring-limit 3
  service-policy out policy1
  pppoe-client dial-pool-number 1
 !

In particolare, la policy-map va assegnata direttamente al PVC ATM (e non all’interfaccia dialer come ci si potrebbe aspettare), previa definizione delle direttive vbr-nrt e tx-ring-limit.

La prima è indispensabile per la politica di controllo del traffico (detta GTS Generic Traffic Shaping) supportata da questo tipo di interfaccia, dove il termine vbr-nrt sta per variable bit rate not real time (GTS ed ubr, ovvero l’undefined bit rate impostato di default sul PVC, non sono tra loro compatibili). La sintassi da utilizzare è la seguente:

vbr-nrt <Peak Cell Rate> <Sustained Cell Rate> <Maximum Burst Size>

Inoltre, per individuare i valori di PCR ed SCR ho applicato la seguente prassi:

1) ho identificato l’uplink rate della linea ADSL, utilizzando il comando:

sh atm int atm0

il cui output è simile al seguente:

VCIs per VPI: 1024,
Max. Datagram Size: 4528
PLIM Type: ADSL - 972Kbps Upstream, DMT, TX clocking: LINE

2) ho calcolato il 95% dell’ upstream rate, ed il valore risultante è servito a popolare sia PCR che SCR;

3) ho impostato l’MBR a 1.

La seconda direttiva (ovvero tx-ring-limit), serve, invece, per la gestione della coda (a livello HW) dell’interfaccia ATM. Nella fattispecie, limitando il buffer a soli 3 pacchetti, si fa in modo che la politica QoS possa essere applicata ai dati prima del loro ingresso nel buffer (dove il QoS non può più essere attuato).

Per ciò che concerne la visualizzazione delle statistiche relative al QoS (ad esempio il drop rate), è sufficiente utilizzare il comando show policy map, specificando l’interfaccia oggetto di analisi:

#sh policy-map interface atm0

il cui output sarà simile al seguente:

 ATM0: VC 8/35 -

  Service-policy output: policy1

    queue stats for all priority classes:

      queue limit 64 packets
      (queue depth/total drops/no-buffer drops) 0/0/0
      (pkts output/bytes output) 5590/3316821

    Class-map: voice (match-all)
      5590 packets, 3316821 bytes
      5 minute offered rate 0 bps, drop rate 0 bps
      Match: access-group 105
      Priority: 128 kbps, burst bytes 4470, b/w exceed drops: 0

    Class-map: class-default (match-any)
      270413 packets, 94967696 bytes
      5 minute offered rate 7000 bps, drop rate 0 bps
      Match: any
      Queueing
      queue limit 64 packets
      (queue depth/total drops/no-buffer drops/flowdrops) 0/147/0/147
      (pkts output/bytes output) 270266/94753611
      Fair-queue: per-flow queue limit 16
      bandwidth 795 kbps

Prima di concludere il post occorre fare una precisazione: ho adoperato un’ACL per la definizione del traffico interessante poichè, in questo modo, lato PBX non è stato necessario effettuare alcuna modifica di configurazione. Infatti, per utilizzare, ad esempio, una class-map così definita:

class-map match-any VOIP-SIGNAL
 match ip dscp cs5
 match ip precedence 4
 match ip precedence 3
class-map match-any VOIP-RTP
 match ip dscp ef
 match ip precedence 5

sarebbe stato necessario imporre al PBX (Asterisk nel mio caso) di “modificare” il contenuto dell’header dei pacchetti IP (DS Field) applicando un particolare pattern DSCP o un determinato valore di IP Precedence (definendo, nel file sip.conf, delle entry come tos_sip=cs3 per la segnalazione, tos_audio=ef per il traffico RTP audio e tos_video=af41 per il traffico RTP video).

E’ tutto, alla prossima.

PS: La banda che ho definito per il QoS si riferisce ad un’unica chiamata in ingresso/uscita. In particolare, essa dipende strettamente da 2 fattori, ovvero:

1) il numero di chiamate che si vogliono gestire in contemporanea;

2) il tipo di codec da utilizzare per il traffico voce (specificato all’interno del protocollo SDP, insieme alle porte coinvolte nel traffico RTP). Per maggiori dettagli sulla corrispondenza codec/banda è possibile consultare la seguente tabella:

VoIP-Codec-table-from-Cisco-sml

Creare una VPN SSL/TLS con OpenVPN

Lo standard de facto per realizzare i tunnel VPN è sicuramente IPSec. Tale protocollo è compatibile con dispositivi di vendor diversi (interoperabilità) e permette di creare dei tunnel altamente affidabili e robusti in termini di sicurezza. Per contro, però, esso risulta essere piuttosto complesso da configurare e proprio per questo motivo, soprattutto in ambito SOHO, si opta per soluzioni alternative. Una di queste è sicuramente OpenVPN, in grado di realizzare dei tunnel cifrati mediante i protocolli SSL/TLS.

Di seguito un breve howto in cui viene descritta la configurazione di OpenVPN per un bastion host dual-homed Linux.

Nello specifico, la rete locale è così definita:

Internet - Screened router - interfaccia UNTRUST del bastion - FW IPTABLES - interfaccia TRUST del bastion - LAN

Configurazione del server

Per prima cosa occorre installare l’applicativo in questione digitando il comando:

nightfly@nightbox:~$ sudo apt-get install openvpn

ad installazione completata, posizioniamoci nella directory /etc/openvpn e creiamo le subdir certificati e log:

 nightfly@nightbox:/etc/openvpn$ sudo mkdir log
 nightfly@nightbox:/etc/openvpn$ sudo mkdir certificati

Successivamente, creiamo i due file in cui verranno salvati i log:

 nightfly@nightbox:/etc/openvpn$ cd log
 nightfly@nightbox:/etc/openvpn/log$ sudo touch openvpn.log openvpn-status.log

A questo punto possiamo creare il file di configurazione:

nightfly@nightbox:/etc/openvpn$ sudo nano server.conf

il cui contenuto dovrà essere simile al seguente:

tls-server

port 5002

dev tun
ifconfig 192.168.110.1 192.168.110.2

persist-key
persist-tun

push "route 192.168.1.0 255.255.255.0"

#Percorsi dei certificati
ca certificati/ca.crt
cert certificati/server.crt
key certificati/server.key 
dh certificati/dh1024.pem
tls-auth certificati/ta.key 0 # 0 per il server ed 1 per il client, essenziale per la generazione dell'hash HMAC nell'header TLS

cipher BF-CBC
comp-lzo

keepalive 10 120

#log and security
user nobody
group nogroup
status log/openvpn-status.log
log-append log/openvpn.log
verb 3
scrip-security 2

Mediante la direttiva tls-server sto imponendo al mio bastion host di fungere da server per le sessioni TLS.

Con port specifico su quale porta OpenVPN deve rimanere in ascolto, mentre con dev tun sto scegliendo la tipologia di interfaccia da realizzare. A tal proposito, occorre precisare che i tipi di interfaccia che può tirar su OpenVPN sono 2, ovvero:

1) tun, per le VPN routed (livello 3);

2) tap, per le VPN bridged (livello 2).

Con ifconfig specifico l’indirizzo IP del tunnel VPN lato server (192.168.110.1) e lato client (192.168.110.2). Per la natura delle interfacce tun, trattasi di un collegamento point-to-point (/30).

con push “route 192.168.1.0 255.255.255.0” sto iniettando la rotta per raggiungere la mia LAN (interfaccia TRUST del bastion-host) sul client VPN.

Con le direttive:

 cipher BF-CBC
 comp-lzo

sto definendo il tipo di cifratura (BlowFish) ed il tipo di compressione (LZO – Lempel-Ziv-Oberhumer) messe in atto nel tunnel VPN.

Con keeplive faccio in modo che il tunnel rimanga attivo anche in assenza di traffico, mentre nella sezione #log and security definisco (in quest’ordine) i permessi, i file di log, il verbosity (accuratezza dei log) ed il livello di sicurezza di questo file di configurazione.

Salviamo il file in questione e procediamo con la generazione delle chiavi e dei certificati. Lato server i comandi da lanciare sono i seguenti:

nightfly@nightbox:~$ cd /usr/share/doc/openvpn/examples/easy-rsa/2.0/

nightfly@nightbox:~$ sudo nano vars

che andrà editato customizzando i campi indicati

nightfly@nightbox:~$ source ./vars

nightfly@nightbox:~$ ./clean-all

nightfly@nightbox:~$ ./build-ca

per la generazione del certificato relativo alla CA

nightfly@nightbox:~$ ./build-dh 

per lo scambio delle chiavi mediante l’algoritmo Diffie-Helman (leggasi premaster-key)

nightfly@nightbox:~$ ./build-key-server server

per la generazione della chiave privata associata al server, con relativa richiesta *.crt

nightfly@nightbox:~$ openvpn --genkey --secret ta.key

per la generazione della chiave segreta.

Una volta generate le chiavi ed i certificati copiamoli nella directory /etc/openvpn/certificati:

nightfly@nightbox:~$ sudo cp ca.crt server.crt server.key dh1024.pem ta.key /etc/openvpn/certificati

A questo punto possiamo avviare il demone OpenVPN:

nightfly@nightbox:~$ sudo service openvpn start

Verifichiamo che l’interfaccia tun0 sia attiva mediante il comando ifconfig:

nightfly@nightbox:~$ ifconfig

tun0     Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
indirizzo inet:192.168.110.1  P-t-P:192.168.110.2  Maschera:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisioni:0 txqueuelen:100
Byte RX:0 (0.0 B)  Byte TX:0 (0.0 B)

Configurazione di IPTABLES

Il bastion host ha DROP come azione di default per la chain FORWARD. Proprio per questo motivo, occorre consentire il transito del traffico dall’interfaccia tun0 a quella TRUST (eth0) e viceversa. Le regole da definire sono le seguenti:

 iptables -A FORWARD -i tun0 -o eth0 -j ACCEPT
 iptables -A FORWARD -i eth0 -o tun0 -j ACCEPT

Configurazione del client

A questo punto è possibile installare e configurare il client, che però dovrà utilizzare lo stesso file ca.crt del server, la medesima chiave ta.key del server ma una propria chiave privata (client.key) ed un proprio certificato (client.crt).

Per ambienti Windows vi consiglio questo client Openvpn (se utilizzate Windows 7 fate riferimento a questa pagina per la procedura di installazione).

Quest’altro client, invece, evitatelo come la peste (in quanto bacatissimo, d’altronde è una versione alpha).

Ad installazione completata potrete utilizzare il seguente file di configurazione:

remote <indirizzo IP pubblico del server OpenVPN> 5002
client
tls-client
nobind
dev tun
ifconfig 192.168.110.2 192.168.110.1
pull

ca key/ca.crt
cert key/client.crt
key key/client.key
tls-auth key/ta.key 1

persist-key
persist-tun

cipher BF-CBC

comp-lzo

keepalive 10 120

scrip-security 2

verb 3

Da notare che gli algoritmi di compressione e cifratura devono essere i medesimi di quelli utilizzati dal server, pena l’impossibilità di connettersi allo stesso.

Diagnostica

A connessione VPN avvenuta, potete verificare la raggiungibilità attraverso il tunnel degli host della LAN mediante un seplice ping, ad esempio:

ping 192.168.1.2

Se il ping dovesse andare in timeout, provate a mettere in ascolto tcpdump sulle interfacce tun0 ed eth0 e controllate la tabella di routing del vostro bastion host (attraverso il comando route).

Verificate inoltre che la rotta verso la LAN sia stata correttamente iniettata sul client (Windows), digitando:

route print

Fine del post, bye.