Archivi tag: routing

Redirect del traffico in uscita mediante iptables

Iptables, ovvero l’interfaccia a linea di comando del celeberrimo firewall Netfilter, consente di fare dei veri e propri giochi di prestigio.

Ad esempio, potrebbe succedere che, per ragioni di sicurezza, un dato server Web non sia in ascolto sulla classica porta TCP 80, ma su una porta non standard (ad esempio la 9876). Supponiamo, inoltre, che a tale sito debbano accedere gli sviluppatori, che, di volta in volta dovranno forgiare opportune URL con l’estensione :9876.

netfilter.jpg

Per semplicifare loro la vita si può agire direttamente sul firewall/router, facendo un semplice redirect del traffico in uscita diretto alla porta 80 del server Web. Ecco la regola:

iptables -t nat -A OUTPUT -p tcp -d ipserverweb –dport 80 -j DNAT –to-destination ipserverweb:9876
Ovviamente potete lavorare anche di file hosts, aggiungendo dei record A statici che vi possano aiutare a creare le regole più facilmente, senza doversi obbligatoriamente ricordare gli indirizzi IP coinvolti a memoria.
In quest’ultimo caso la suddetta regola diverrebbe:
iptables -t nat -A OUTPUT -p tcp -d miodominio.com --dport 80 -j DNAT --to-destination miodominio.com:9876
Semplice, vero?
A presto.

RIP e RIPv2

L’acronimo RIP sta per Routing Information Protocol e rappresenta uno dei primi protocolli di routing (è stato sviluppato nel 1969 come parte integrante di ARPANET, l’antenata di Internet).

Esso è un protocollo distance-vector e prevede l’invio dell’intera tabella di routing ogni 30 secondi (solo tra i router vicini). La sua distanza amministrativa è 120 e la metrica utilizzata per identificare il costo dei cammini viene calcolata in base al numero di hop, ovvero il numero di salti che un pacchetto compie prima di raggiungere la destinazione.

Il numero massimo di hop supportato dal protocollo in questione è pari a 15. Una rotta avente metrica superiore a 15, di conseguenza, viene marcata come irraggiungibile.

Esistono, inoltre, diversi metodi attraverso i quali è possibile limitare la formazione dei famigerati routing loop. Uno di questi è lo split-horizon, ovvero un router che ha ricevuto l’aupdate di una rotta attraverso una determinata porta (ad esemprio Ethernet0), non potrà rimandare indietro l’update lungo quella stessa porta. Un altro metodo è rappresentato dal route poisoning, letteralmente “avvelenamento di rotta”. Nella fattispecie, per fare in modo che non si formino loop, un router assegna ad una determinata rotta una metrica fittizia pari a 16 (in questo modo la rotta viene “avvelenata”), costringendo i router che hanno ricevuto l’update a scegliere percorsi alternativi. Il RIP fa anche uso dei cosiddetti hold-down timers: quando una rotta è irraggiungibile il router scarterà tutti gli update relativi a quella stessa rotta fino allo scadere del timer (solitamente 180 secondi).

Uno dei maggiori limiti del protocollo in questione è rappresentato dal fatto che ha tempi di convergenza abbastanza elevati, oltre a prevedere l’inoltro degli update mediante broadcast, congestionando pesantemente la linea trasmissiva, soprattutto se la banda dispobile è piuttosto limitata. Inoltre, il RIP è un protocollo classfull, ovvero nell’ambito degli update non invia le subnet mask (impedendo l’uso del VLSM). Tale scelta si è rivelata necessaria in quanto, durante i primi anni di vita del protocollo di routing in questione, le velocità di trasmissione erano piuttosto ridotte e quindi si voleva fare in modo che i RIP-update non appesantissero ulteriormente il collegamento.

Altra pecca relativa al RIP riguarda l’assenza di un meccanismo di autenticazione.

Proprio a causa di queste limitazioni è stata realizzata una versione migliorata del RIP, ovvero RIP version 2 (RIPv2). Tale protocollo, per mantenere la retrocompatibilità con il suo predecessore, usa una matrica basata sugli hop (max 15) ed una distanza amministrativa pari a 120. Nell’ambito degli update, però, invia informazioni relative alle subnet (classless) e prevede un meccanismo di autenticazione basato su password in chiaro (piuttosto vulnerabile) oppure sul digest generato mediante algoritmo MD5. Inoltre, a differenza della versione 1, RIPv2 invia gli update in multicast, più precisamente all’indirizzo 224.0.0.9.

Per completezza, riporto qui di seguito alcuni comandi utili per la configurazione e la gestione del RIP (versione 1 e 2) nell’ambito dei router Cisco.

Per abilitare il rip basta digitare:

Router(config)# router rip

Successivamente, se si vuole utilizzare la versione 2, basta scrivere:

Router(config-router)# version 2

Una volta fatto ciò possiamo dichiarare le reti direttamente connesse al router, le quali verranno propagate mediante gli update:

Router(config-router)# network 10.0.0.0

Router(config-router)# network 172.16.0.0

supponendo che al router siano connesse le reti 10.1.2.0/24 (indirizzo di classe A adattato a classe C) e 172.16.2.0/16 (classe B adattato a classe C). Come potete notare ho utilizzato gli indirizzi 10.0.0.0 e 172.16.0.0, ovvero le majornet, in quanto il RIPv1 non riconosce gli indirizzi “adattati” (ad esempio da classe A a classe C), trattandoli come se fossero appartenenti alla classe originaria (classe A).

Se invece utilizziamo RIPv2, possiamo scrivere:

Router(config-router)# network 10.1.2.0

Router(config-router)# network 172.16.2.0

Nel caso in cui avessimo a che fare con molte subnet simili tra loro, per evitare eventuali errori bisogna disabilitare l’auto summarization mediante il comando:

Router(config-router)# no auto-summary

(vale solo per il RIPv2).

Per abilitare l’autenticazione su una determinata interfaccia occorre digitare:

Router(config-if)# ip rip authentication mode text

(per la password in chiaro)

oppure

Router(config-if)# ip rip authentication mode md5

(per utilizzare md5).

Per ottonere informazioni di diagnostica sullo scambio degli update e sull’autenticazione occorre usare il comando:

Router# debug ip rip

mentre per verificare che una determinata rotta sia stata imparata grazie a tale protocollo di routing basta digitare:

Router# sh ip route

(le rotte marcate con R sono quelle identificate mediante RIP)

Codes: C - connected, S - static, I - IGRP, R - RIP, M - mobile, B - BGP
D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
E1 - OSPF external type 1, E2 - OSPF external type 2, E - EGP
i - IS-IS, L1 - IS-IS level-1, L2 - IS-IS level-2, ia - IS-IS inter area
* - candidate default, U - per-user static route, o - ODR
P - periodic downloaded static route

Gateway of last resort is not set

R    10.1.2.0 [120/12] via 192.16.64.2, 00:03:28, Serial0

C    192.16.64.0/24 is directly connected, Serial0

Nei prossimi post ci soffermeremo sull’EIGRP. A presto.

OSPF (Open Shortest Path First)

Abbiamo già visto qual è la logica su cui si basa il funzionamento di alcuni protocolli utilizzati nell’ambito delle WAN, quali Frame Relay e PPP. Oggi, invece, inizieremo a parlare dei protocolli di routing. Sostanzialmente, essi si dividono in 2 categorie, ovvero protocolli distance vector (ad esempio RIP, RIPv2) e protocolli link-state (come OSPF). Esistono comunque dei protocolli ibridi, il cui funzionamento si basa in parte sull’approccio distance vector ed in parte sulla logica link-state (vedi IGRP ed EIGRP, entrambi proprietari Cisco).

Come avrete già intuito, in questo post mi concentrerò esclusivamente sui protocolli IGP (Interior Gateway Protocol), ovvero quelli utilizzati nell’ambito di uno stesso sistema autonomo (AS), tralasciando quindi (almeno per il momento) i protocolli EGP (Exterior Gateway Protocol), come BGP, MPLS e compaglia bella.

Ma qual è la differenza tra i protocolli distance vector e link-state? Beh, in effetti ce ne sono molte. Una tra tutte riguarda l’update delle tabelle di routing: se infatti i protocolli distance vector prevedono lo scambio delle tabelle in questione (per intero) tra i router adiacenti (altrimenti conosciuti come neighbors) ad intervalli di tempro predefiniti, i protocolli link-state fanno in modo che gli aggiornamenti della topologia memorizzata nei router avvenga se e soltato se nella rete si è manifestato un qualche tipo di cambiamento (ad esempio una rotta viene dichiarata irrangiungibile).

Dopo questa breve introduzione, focalizziamo la nostra attenzione sull’OSPF. Tipico esempio di protocollo link-state, esso presenta numerosi vantaggi, tra cui:

1) supporta le VLSM (Variable Lenght Subnet Mask), ovvero le subnet possono essere suddivise in net più piccole in base alle necessità, garantendo un massiccio risparmio di indirizzi IP;

2) prevede un’approccio di tipo gerarchico, in modo tale da limitare ad una sola zona della rete eventuali instabilità o malfunzionamenti, consentendo anche di ridurre l’overhead associato alle operazioni di routing;

3) garantisce tempi di convergenza relativamente bassi (grazie all’architettura gerarchica), anche se esistono dei protocolli migliori da questo punto di vista, come EIGRP;

4) non è un protocollo proprietario, ergo può essere utilizzato nell’ambito di network che utilizzano dispositivi multivendor;

5) supporta il bilanciamento di carico (load balancing), instradando un maggior quantitativo di informazioni lungo i link con banda maggiore;

6) prevede un meccanismo di autenticazione dei messaggi basato su MD5, aumentando notevolmente il livello di sicurezza della rete.

L’architettura gerarchica viene realizzata attraverso l’uso delle cosiddette aree. Tra tutte, quella di maggior importanza è certamente l’area 0, altrimenti conosciuta come backbone area, alla quale devono essere collegate tutte le altre aree presenti nell’ambito della topologia.

Durante la fase di convergenza della rete, l’OSPF si occupa di eleggere il cosiddetto DR (Designated Router) ed il BDR (Backup Designated Router), oltre, ovviamente, a fare in modo che tra i router vicini si vengano a creare le cosiddette adiacenze. A tal proposito, è bene sottolineare il fatto che affinchè due router possano creare l’adiacenza senza problemi, è necessario che i loro hello-interval e dead-interval coincidano. In particolare, l’hello-interval identifica l’intervallo di tempo che deve trascorrere tra l’invio di 2 pacchetti hello consecutivi, in modo che entrambi i router sappiano che il rispettivo vicino sta funzionando correttamente. Il dead-interval, invece, definisce il limite di tempo (in cui non è stato ricevuto alcun hello) oltre il quale il vicino viene dichiarato irragiungibile.

Come si articola, invece, l’elezione del DR e del BDR? Il primo fattore che viene preso in considerazione è il RouterID (RID). Esso è rappresentanto dall’indirizzo di loopback più alto, oppure, in assenza di interfacce virtuali, dall’indirizzo più elevato associato alle interfacce fisiche. Ma perchè dare maggiore priorità alle interfacce virtuali piuttosto che a quelle fisiche? Semplicemente perchè anche nel caso in cui le interfacce fisiche subiscano un guasto o non siano più utilizzabili, il processo di routing OSPF continuerà a funzionare senza problemi, evitando di procedere quindi con l’elezione di un nuovo DR e di un nuovo BDR. Modificando, inoltre, l’indirizzo di loopback è possibile fare in modo che un determinato router divenga DR o BDR.

Altro fattore che influenza l’elezione del DR e del BDR è la priorità della porta. Essa può assumere valori compresi tra 0 e 255, dove lo 0 viene utilizzato per impedire l’elezione a DR o BDR di uno o più router (detti DROTHER), mentre valori più elevati rappresentano una maggiore probabilità di elezione.

Ma perchè eleggere un DR ed un BDR? Semplicemente perchè in questo modo viene ridotto il numero di link all’interno della topologia, ottimizzando il funzionamento dell’algoritmo Dijkstra su cui si basa il protocollo in questione. L’immagine seguente può certamente essere esplicativa:


Da notare che a differenza dell’algoritmo Bellmann-Ford, anch’esso utilizzato per l’individuazione dei cammini minimi, l’algoritmo di Dijkstra non prevede l’uso di pesi negativi per gli archi (sostanzialmente una rete viene vista come un grafo in cui i router rappresentano i nodi mentre i link rappresentano gli archi). A tal proposito è bene sottolineare che il peso di un arco può essere calcolato mediante la seguente operazione aritmetica:

100000000/banda.

Inoltre, proprio grazie al DR viene semplificata notevolmente la procedura di foolding: tutti i router inviano al DR i propri LSA (link state advertisement, ovvero informazioni sullo stato dei collegamenti e dei router vicini, in modo da tenere sempre aggiornato il database che rappresenta la topologia della rete) mediante l’indirizzo multicast 224.0.0.6. Se un determinato LSA indica un’eventuale variazione della topologia (ovvero differisce dai precedenti record del database), il DR provvederà ad inoltrarla a tutti i router della rete utilizzando l’indirizzo multicast 224.0.0.5.

Da quanto detto fin’ora è facile capire perchè è necessaria l’elezione di un BDR. Infatti, nel caso in cui il DR andasse giù, la rete OSPF, pur essendo nominalmente ancora operativa, smetterebbe di funzionare. Ciò può essere evitato proprio grazie all’elezione del Backup Designated Router.

Da notare, inoltre, che nel caso in cui venisse aggiunto un router con ID maggiore ripetto a quello del DR, non verrebbe eletto router designato fino a quando DR e BDR attuali continueranno a funzionare correttamente.

Ma DR e BDR sono le uniche tipologie di router presenti nell’albito delle reti OSPF? La risposta è no. Ad esempio, vi sono gli ABR (Area Border Router), impiegati per coleggare una o più aree alla backbone; gli IR (Internal Router) che formano adiacenze solo con router appartenenti alla loro stessa area; i BR (Backbone Router), ovvero router con un’interfaccia conessa alla backbone area. Da ciò si evince che un ABR è anche un BR ma non sempre vale il viceversa.

Però, non in tutte le tipologie di reti è necessaria l’individuazione del DR e del BDR. Infatti, DR e BDR sono indispensabili nelle rete BMA (Broadcast Multi-Access) e NBMA (Non-Broadcast Multi-Access) mentre sono del tutto superflui nell’ambito dei collegamenti Point-To-Point.

Occorre precisare il fatto che oltre alla backbone area esistono anche altre tipologie di aree, tra cui ricordiamo:

1) stub area, la quale non prevede la ricezione di rotte esterne, ovvero di rotte appartenenti ad altri AS;

2) totally stubby area, la quale oltre a non accettare rotte esterne, non consente la route summarization, ovvero riunire più reti in un’unica supernet;

3) not-so-stubby area, che consente la ricezione e l’inoltro delle rotte esterne solo tra i router ad essa appartenenti.

Vediamo adesso alcuni comandi indispensabili per l’implementazione del protocollo OSPF nell’ambito dei dispositivi Cisco. Per prima cosa bisogna specificare l’istanza ospf, la quale ha significato per il router solo localmente:

Router(confing)# router ospf 1

Da notare che il valore minimo che può essere associato all’instanza OSPF è 1 e non 0.

Dichiaro la banda dei collegamenti:

Router(config-router)# bandwidth 64

dove 64 indica 64 Kbps.

Digitando inoltre:

Router(confing)# default-information originate

consentirò la dichiarazione delle rotte statiche nell’ambito dell’OSPF.

Ora definiamo le reti appertenenti ad una determinata area (nell’esempio useremo la backbone area):

Router(confing-router)# network <indirizzo della net> <wildcard mask> area 0

Ovviamente per ogni router basta definire esclusivamente le reti ad esso direttamente collegate.

Per definire gli hello-interval ed i dead-interval occorre digitare:

Router(confing-if)# ip ospf hello-interval <intervallo in secondi>

Router(confing-if)# ip ospf dead-interval <intervallo in secondi>

Per implementare l’autenticazione è possibile seguire due strade. Una prevede l’uso di una password in chiaro, la quale risulta molto vulnerabile ad attacchi di tipo passivo (sniffing), l’altra invece fa uso dell’algoritmo di cifratura MD5, il quale rende molto più complessa l’eventuale individuazione della password da parte di utenti malevoli.

Nel primo caso è necessario utilizzare il comando:

Router(config-router)# area area 0 authentication

Router(config-if)# ip ospf authentication-key <key>

Per ciò che concerne l’MD5, avremo:

Router(config-router)# area area 0 authentication message-digest

Router(config-if)# ip ospf message-digest-key <keyid> <key>

dove <keyid> rappresenta un valore numerico compreso tra 0 e 7 e deve essere uguale per tutti i router in cui è implementata l’autenticazione mediante algoritmo MD5 (altrimenti non si potrà creare l’adiacenza).

Il comando per impostare la priorità dell’interfaccia è il seguente:

Router(config-if)# ip ospf priority <priorità>

Per ciò che concerne la diagnostica, alcuni comandi utili sono i seguenti:

Router# sh ip ospf interface <interfaccia>

che produrrà un output simile a questo (fornendo informazioni relative al DR ed al BDR se la topologia ne prevede l’utilizzo):

Serial0 is up, line protocol is up
Internet Address 192.16.64.1/24, Area 0
Process ID 10, Router ID 172.16.10.36, Network Type POINT_TO_POINT, Cost: 64
Transmit Delay is 1 sec, State POINT_TO_POINT,
Timer intervals configured, Hello 10, Dead 40, Wait 40, Retransmit 5
Hello due in 00:00:04
Index 2/2, flood queue length 0
Next 0x0(0)/0x0(0)
Last flood scan length is 1, maximum is 1
Last flood scan time is 0 msec, maximum is 4 msec
Neighbor Count is 0, Adjacent neighbor count is 0
Suppress hello for 0 neighbor(s)
Simple password authentication enabled

 

Router# sh ip ospf neighbor

il quale mostra informazioni associate ai router adiacenti,
ad esempio:

Neighbor ID     Pri   State           Dead Time   Address     Interface
70.70.70.70       1   FULL/  -        00:00:31    192.16.64.2 Serial0
Router# sh ip route

che mostra le rotte conosciute dal router

Codes: C - connected, S - static, I - IGRP, R - RIP, M - mobile, B - BGP
D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
E1 - OSPF external type 1, E2 - OSPF external type 2, E - EGP
i - IS-IS, L1 - IS-IS level-1, L2 - IS-IS level-2, ia - IS-IS inter area
* - candidate default, U - per-user static route, o - ODR
P - periodic downloaded static route

Gateway of last resort is not set

70.0.0.0/32 is subnetted, 1 subnets
O       70.70.70.70 [110/65] via 192.16.64.2, 00:03:28, Serial0

C   172.16.10.32 is directly connected, Loopback0
C    192.16.64.0/24 is directly connected, Serial0

dove la O indica che quella rotta è stata imparata mediante OSPF, 110 indica la distanza amministrativa di tale protocollo e 65 il costo (metrica) del collegamento

Router# debug ip ospf adjacency
00:50:57: %LINK-3-UPDOWN: Interface Serial0, changed state to down
00:50:57: OSPF: Interface Serial0 going Down
state DOWN
00:50:57: OSPF: 70.70.70.70 address 192.16.64.2 on Serial0 is dead,
state DOWN
00:50:57: %OSPF-5-ADJCHG: Process 10, Nbr 70.70.70.70 on Serial0 from FULL to DOWN,
Neighbor Down: Interface down or detached
00:50:58: OSPF: Build router LSA for area 0, router ID 172.16.10.36,
seq 0x80000009
00:50:58: %LINEPROTO-5-UPDOWN: Line protocol on Interface Serial0,
changed state to down
00:51:03: %LINK-3-UPDOWN: Interface Serial0, changed state to up
00:51:03: OSPF: Interface Serial0 going Up
00:51:04: OSPF: Build router LSA for area 0, router ID 172.16.10.36,
seq 0x8000000A
00:51:04: %LINEPROTO-5-UPDOWN: Line protocol on Interface Serial0,
changed state to up
00:51:13: OSPF: 2 Way Communication to 70.70.70.70 on Serial0,
state 2WAY

dove

00:51:13: %OSPF-5-ADJCHG: Process 10, Nbr 70.70.70.70 on Serial0 from LOADING
to FULL, Loading Done
00:51:14: OSPF: Build router LSA for area 0, router ID 172.16.10.36,
seq 0x8000000B

indica che l’adiacenza è stata creata correttamente.

Ovviamente questa guida rappresenta un piccolo sunto delle potenzialità relative al protocollo OSPF, se volete ulteriori informazioni potrete trovarne a migliaia su Internet.

Il post termina qui, bye.