20/09/2010

Cisco port-channel

Ora, premesso che il port-channeling NON E' argomento CCNA come ho sentito spesso dire (almeno per quanto riguarda l'esame 640-801), il seguente post ha lo scopo di chiarire a cosa serve effettivamente la feature in questione.

Nella fattispecie, mediante il port-channeling è possibile fare in modo che più interfacce vengano coinvolte da un unico flusso logico di informazioni (in pratica è come se costituissero un'unica interfaccia), semplificando notevolmente la vita agli amministratori, soprattutto in caso di guasti o nel caso in cui si vogliano evitare i loop senza la necessità di utilizzare il protocollo STP.

Ora, le condizioni necessarie per garantire il corretto funzionamento del port-channeling sono le seguenti:

- Stessa velocità e duplex (half/full) delle porte coinvolte (è impensabile creare un port-channel tra una FastEthernet ed una GibabitEthernet);

- Le porte devono appartenere alla medesima VLAN (se il port-channeling non viene utilizzato per un trunk);

- Nel caso in cui il port-channeling riguardi un trunk, è indispensabile che tutte le porte coinvolte siano caratterizzate dallo stesso tipo di trunk, abbiano le stesse VLAN native e permettano il traffico proveniente dalle stesse VLAN (identificate con il termine VLAN-allowed);

- Nel caso in cui venga utilizzato l'STP per la gestione dei loop, le porte coinvolte devono avere il medesimo costo nell'ambito delle VLAN di appartenenza;

- Sulle interfacce coinvolte non deve essere implementato il port-mirroring (SPAN), il cui scopo è quello di mandare una replica dei frame ricevuti su una data porta dello switch verso un'altra porta dello stesso switch a cui è collegato un sistema di monitoring (ad esempio un IDS).

Detto questo, occorre fare alcune precisazioni:

1) quasi tutti gli switch marcati Cisco permettono la creazione di un numero massimo di port-channel pari a 64;

2) Ciascun canale può coinvolgere dalle 2 alle 8 interfacce, in modo tale da favorire le operazioni di bilanciamento del traffico (load-balancing).

Per ciò che concerne proprio il load-balancing, è possibile implementare un metodo di bilanciamento diverso per ogni port-channel. I metodi applicabili possono basarsi su alcuni parametri riguardanti i livelli 2, 3 e 4 della pila ISO/OSI. Nella fattispecie, le discriminanti possono essere:

1) Indirizzo MAC sorgente - src-mac;

2) Indirizzo MAC di destinazione - dst-mac;

3) Entrambi gli indirizzi MAC (sia sorgente che di destinazione) - src-dst-mac;

4) Indirizzo IP sorgente - src-ip;

5) Indirizzo IP di destinazione - dst-ip;

6) Entrambi gli indirizzi IP (sia sorgente che di destinazione) - src-dst-ip;

7) Porta (UDP o TCP) sorgente - src-port;

8) Porta (UDP O TCP) di destinazione - dst-port;

9) Entrambe le porte UDP o TCP (sia sorgenti che di destinazione) - src-dst-port.

Per scegliere il metodo pù adatto alle nostre esigenze ed implementarlo sullo switch basta digitare il comando:

Switch(config)# port-channel load-balance <opzione>

Per quanto riguarda, invece, la possibilità di formare i port-channel in modo dinamico, possono essere utilizzati i seguenti protocolli:

- PAgP (proprietario CISCO);

- LACP 802.1AD

Per mettere in piedi il port-channel vero e proprio è necessario digitare:

Switch(config-if)# channel-group <identificativo numerico> mode <modalità di funzionamento>

nell'ambito del sottomenù delle interfaccie che devono essere coinvolte durante formazione del port-channel stesso.

Le modalità di funzionamento sono le seguenti:

- on (non fa uso nè di PAgP nè di LACP 802.1AD, disabilitando di fatto la formazione dinamica dei port-channel);

- off (fa in modo che la porta non venga coinvolta nell'ambito del port-channel);

- auto (fa uso del PAgP in modalità passiva);

- desirable (fa uso del PAgP in modalità attiva);

- passive (fa uso del protocollo LACP in modalità passiva);

- active (fa uso del protocollo LACP in modalità attiva).

Ma qual è la differenza esistente tra la modalità attiva e quella passiva? Semplicemente nel primo caso l'interfaccia rimarrà in attesa di ricevere pacchetti appartenenti al protocollo utilizzato (PAgP  o LACP). Nel secondo caso sarà proprio l'interfaccia ad inviare i pacchetti necessari alla formazione dinamica del port-channel.

Ora, per risparmiare tempo e fatica, è stato implementato un utilissimo comando che consente di settare i parametri necessari per la creazione del port-channel su tutte le porte coinvolte (o su alcune di esse). Tale comando è il cosiddetto range:

Switch(config)# interface range fa0/0 - 4

E, successivamente, il prompt dei comandi apparirà nel seguente modo:

Switch(config-range-if)#

Possiamo dunque digitare (ad esempio):

Switch(config-range-if)# channel-group 1 mode on

Infine, alcuni comandi che possono tornare utili per eventuali operazioni di troubleshooting sono i seguenti:

Switch(config)# sh interfaces port-channel <identificativo del group-channel>

oppure:

Switch(config)# sh etherchannel <identificativo del group-channel> summary

e ancora:

Switch(config)# test etherchannel load-balance interface port-channel <identificativo> ip <IP sorgente> <IP di destinazione>

A presto.

14/09/2010

Algoritmo Diffie-Helman per lo scambio delle chiavi

L'algoritmo Diffie-Helman rappresenta il primo esempio di crittografia a chiave pubblica. In particolare, esso consente a 2 utenti che vogliono comunicare in modo "sicuro", di scambiarsi una chiave segreta da usare in fase di cifratura/decifratura.

La robustezza di tale algoritmo si basa sostanzialmente sulla difficoltà di calcolo dei logaritmi discreti. Quindi, per capire bene il funzionamento dell'algoritmo in questione, occorre definire in modo chiaro cos'è un logaritmo discreto.

Sia a la radice primitiva di un numero primo p, dove per radice primitiva si intende il numero le cui potenze generano tutti gli interi compresi tra 1 e p-1. In altre parole, i seguenti valori:

a mod p, a^2 mod p, ..., a^p-1 mod p

saranno tutti compresi nell'intervallo [1, p-1]. Notate che sto utilizzando il modulo in quanto abbiamo a che fare con numeri discreti.

Ora, dato un qualunque numero intero b ed una radice primitiva a di un numero primo p, allora è possibile trovare un unico esponente i tale che:

b = a^i mod p

dove 0 <= i <= (p-1). L'esponente i rappresenta proprio il logaritmo discreto di b rispetto alla base a mod p e può essere rappresentato mediante la seguente notazione:

i = dloga,p(b)

Bene, ora che sappiamo cosa si intende per logaritmo discreto, possiamo illustrare il funzionamento dell'algoritmo Diffie-Helman.

Supponiamo che 2 utenti (A e B) vogliano instaurare una comunicazione bidirezionale cifrata. Essi utilizzeranno due valori pubblici, ovvero q ed a, con q numero primo ed a radice primitiva di q.

A questo punto, l'utente A sceglierà un intero casuale XA, con XA < q, che manterrà segreto. Successivamente, calcolerà YA, ovvero la chiave pubblica, dove:

YA = a^XA mod q

Tale operazione verrà effettuata anche dall'utente B, per il quale avremo:

YB = a^XB mod q

Adesso che entrambe le parti hanno generato le rispettive chiavi pubbliche, esse calcoleranno la chiave condivisa (K) nel modo seguente:

Utente A

K = YB^XA

Utente B

K = YA^XB

Ora, si può dimostrare che le due chiavi K così generate sono identiche:

1) K = YB^XA mod q

Sapendo che

2) YB = a^XB mod q

sostituendo la 2) nella 1) avremo:

K = (a^XB mod q)^XA mod q = (a^XB)^XA mod q = (a^XA)^XB mod q = (a^XA mod q)^XB mod q = YA^XB mod q

Facendo il punto della situazione, abbiamo 2 valori privati, ovvero XA ed XB, e 4 valori pubblici: a, q, YA ed YB. Affinchè l'attaccante possa individuare la chiave privata dell'utente B, egli dovrà calcolare:

XB = dloga,q(YB)

che, come affermato in precedenza, è un'operazione molto complessa dal punto di vista computazionale.

Attacchi bruteforce

Nel caso in cui il numero primo q scelto da una delle due parti che vogliono condividere una chiave K sia troppo piccolo, l'attaccante può provare, mediante un approccio a forza bruta, a calcolare uno dei due valori segreti (XA oppure XB).

Ma facciamo un esempio. Supponiamo che q sia pari a 353. Per definizione di algoritmo discreto abbiamo che:

b = a^i mod p

dove b è la chiave pubblica, i il logaritmo discreto in base a mod p ed a rappresenta la radice primitiva di q.

Come già detto in precedenza, i valori associati a b, a e p sono noti, nella fattispecie:

a = 3;

b = 90;

q = 353.

Quindi l'attaccante dovrà risolvere la seguente equazione:

90 = 3^i mod 353

Per trovare il valore di i (che rappresenta proprio la chiave segreta XA o XB, a seconda di quale dei due utenti sia la vittima dell'attacco) gli basterà calcolare tutte le potenze di 3 mod 353 fino a quando non otterrà 90 come risultato. A questo punto calcolerà K utilizzando la chiave pubblica della controparte. Ovviamente tale operazione diventa improponibile per valori di q elevati.

Attacchi replay

Ma come avviene lo scambio dei valori pubblici a e q tra l'utente A e l'utente B? Una possibile soluzione consiste nel concordarli a priori, oppure nel fare in modo che l'utente A (che inizializza la comunicazione) ne calcoli il valore e lo includa, successivamente, nel primo messaggio inviato alla controparte. Un altro approccio prevede l'uso di una directortory condivisa e fidata (per garantire in qualche modo l'autenticità della fonte), in cui salvare le chiavi pubbliche dei vari utenti. In questo caso possono comunque essere attuati degli attacchi di tipo replay.

Attacchi man-in-the-middle

Analizziamo il seguente scenario: supponiamo che Alice (utente A) e Bob (utente B) vogliano scambiarsi una chiave segreta, e che Darth (l'attaccante, ovvero l'utente D) sia in grado di intercettare le chiavi pubbliche di Alice (YA) e di Bob (YB) (nel momento in cui avviene lo scambio delle stesse).

Prima di intercettare le chiavi, l'utente D genererà una coppia di valori privati, ovvero XD1 ed XD2, che verranno usati per creare rispettivamente le chiavi pubbliche YD1 ed YD2. Nel momento in cui A invierà a B la propria chiave pubblica (ovvero YA), l'utente D la intercetterà e la sostituirà con YD1.

A questo punto, l'utente D è in possesso della chiave pubblica di A e la utilizzerà per calcolare la chiave condivisa K2:

K2 = YA^XD2 mod q

L'utente B, avendo ricevuto YD1 come chiave pubblica dell'utente A, calcolerà anch'egli K2:

K2 = YD1^XB mod q

A questo punto l'utente B invierà all'utente A la propria chiave pubblica YB. Essa verrà intercettata dall'utente D e sostituita dallo stesso con YD2.

L'utente A, convinto che YD2 sia la chiave pubblica dell'utente B, calcolerà la chiave condivisa K1:

K1 = YD2^XA mod q

Anche l'utente D calcolerà la chiave condivisa K1:

K1 = YB^XD1 mod q

Ora, l'utente A e l'utente B crederanno di condividere una chiave segreta K. In realtà, l'utente A condivide con l'utente D la chiave K1, mentre l'utente B condivide, sempre con l'utente D, la chiave K2. Darth può quindi: intercettare le comunicazioni provenienti da Alice o da Bob e/o alterare le informazioni dirette da Alice verso Bob e viceversa (tampering). Da ciò si deduce che l'algoritmo Diffie-Helman non può essere utilizzato nell'ambito della cifratura simmetrica (dato che non garantisce l'autenticazione della fonte), tornando comunque utile per lo scambio di una chiave segreta ad autenticazioni delle parti avvenuta.

Fine del post, a presto.