Catturare il traffico di rete

redirectRedirect fai da te

Molte volte vi capitera’ (ed a me e’ capitato piu’ volte) di aver bisogno di gestire il traffico di rete ottimizzandolo, filtrandolo e redirezionandolo.
Si pensi, ad esempio, ai test di sviluppo effettuati sulle molte VM in cui si deve tenere conto della quantita’ di Server interessati e del carico di rete da gestire bilanciando quest’ultimo e gestendo le porte interessate.

In questo articolo illustrero’ alcuni dei migliori tra quelli da me usati in ambito OpenSource sono, Rinetd, LVS e Pound, ma l’elenco potrebbe ancora allungarsi, magari per un seguito.

PARTIAMO

rinetd

E’ il piu’ semplice dei tre, dunque partiremo da questo; esso permette di ridirigere una destinazione TCP, definita attraverso una coppia <indirizzo-ip>:<numero-di-porta>, presso un’altra coppia di questi valori. Lo scopo di questo può essere semplicemente quello di dirigere una porta locale verso un’altra porta locale, oppure si può arrivare a intercettare il traffico IP che attraversa un router in modo da ridirigere alcune coppie di indirizzi e porte presso altre destinazioni.

Tutto è composto semplicemente da un daemon, rinetd, che si avvale di un file di configurazione, /etc/rinetd.conf, nel quale si indicano semplicemente le ridirezioni da applicare.

La presenza in funzione di rinetd è incompatibile con altri daemon che stanno in ascolto delle stesse porte che devono essere ridirette, anche se queste sono intese appartenere a host differenti.

Il programma rinetd è il demone che si occupa di ridirigere il traffico TCP in base a quanto contenuto nel file di configurazione /etc/rinetd.conf
E' sufficiente avviarlo e, se il file di configurazione risultera'corretto, iniziare subito a lavorarci. All'avvio, dopo aver letto la configurazione, rinetd deve poter stare in ascolto dell'indirizzo da ridirigere e della porta relativa; qualunque sia l'indirizzo in questione, è necessario che non ci sia già un programma locale che fa la stessa cosa su quella stessa porta; per esempio, non si può tentare di ridirigere il servizio HTTP di un indirizzo qualunque, se questo è presente localmente.

Un esempio di configurazione del file rinetd.conf dovrebbe essere sufficiente a chiarire le idee su questo file. Supponiamo di voler dirottare il traffico diretto verso l’indirizzo IP 10.11.12.13 alla porta 80, in modo che questo vada verso l’indirizzo IP 192.168.1.7, alla porta 80.

120.121.122.123 80 192.168.1.7 80

L’indirizzo da ridirigere, può appartenere a un’interfaccia del nodo presso cui si trova in funzione il demone rinetd,
oppure no, purché i pacchetti diretti a tale indirizzo transitino attraverso il nodo che attua la ridirezione.
Se si vuole apprendere il funzionamento di rinetd senza disporre di una rete vera e propria, basta una direttiva di configurazione simile a quella seguente:

localhost 8888 localhost html

In questo modo, la porta locale 8888 viene ridiretta sulla porta del servizio HTTP (80). Se il servizio HTTP è attivo, si può verificare la ridirezione con un programma di navigazione qualunque, puntando all’URL

http://localhost:8888

Rispetto ai prossimi due tool rinetd non e’ in grado di fungere anche come LoadBalancer.


ipvsadm

Questo servizio aggiorna la tabella d’instradamento IPVS nel kernel. Il demone lvs imposta e gestisce Load Balancer Add-On richiamando ipvsadm per aggiungere, modificare e cancellare le voci all’interno della tabella d’instradamento IPVS. Inoltre ipvsadm fa parte del paccheto LVS  che è una soluzione di bilanciamento del carico avanzato per sistemi Linux.
Si tratta di un progetto open source avviato da Wensong Zhang nel lontano 1998. La missione del progetto è di costruire un server ad alte prestazioni e ad alta disponibilità per Linux utilizzando tecnologie di clustering, offrendo una buona scalabilità, affidabilità e facilità di manutenzione. L’opera principale del progetto LVS è ora quello di sviluppare un software avanzato di bilanciamento del carico IP (IPVS), ed un software di bilanciamento a livello dell’applicazione (KTCPVS), ed i componenti di gestione dei cluster.

Ipvs in pratica

IPVS (IP Virtual Server) implementa un bilanciatore di carico a livello Layer 4 della rete. IPVS in esecuzione su un host si comporta come un sistema di bilanciamento del carico di fronte ad un insieme di server reali in cluster, può indirizzare le richieste per servizi basati si TCP/UDP ai veri server, e fa apparire i servizi dei server reali come un unico servizio virtuale su un unico indirizzo IP.

La componente IPVS è presente in tutti i recenti Kernel, per installare la componente in user-space utilizzate il vostro gestore di pacchetti, ad esempio in Ubuntu:

aptitude install ipvsadm

a questo punto si può creare uno script da far avviare al boot. Io di solito inserisco i comandi all’interno del file
/etc/rc.local.

Prima di tutto dobbiamo resettare l’attuale configurazione con il comando:
ipvsadm -C
Dopodiché iniziamo a dare le regole con i comandi come nell’esempio qui sotto in cui diciamo che le chiamate TCP (parametro -t) all’indirizzo 192.168.10.100 sulla porta 5060 (quella per il protocollo SIP) debbano essere inoltrate alla stessa porta dell’indirizzo 192.168.10.250.  Per reindirizzare una chiamata UDP sostituire il -t con -u.
ipvsadm -A -t 192.168.10.100:5060 -s rr

ipvsadm -a -t 192.168.10.100:5060 -r 192.168.10.250:5060 -m

Naturalmente è possibile catturare il traffico su una porta e inoltrarla ad un’altra con un comando tipo questo:
ipvsadm -A -t 192.168.10.100:88 -s rr
ipvsadm -a -t 192.168.10.100:88 -r 192.168.10.250:80 -m
In questo caso non abbiamo fatto altro che prendere le chiamate alla porta 88 dell’indirizzo 192.168.10.100 e rinviarle al server web dell’IP 192.168.10.250 sulla normale porta 80

Metodi di bilanciamento utilizzati da LVS

In caso si desideri testare il funzionamento di LVS senza la necessita’ di monitorare i servizi e possibile aggiungere e rimuovere nodi con il comando ipvsadm:

ipvsadm -C
ipvsadm -A -t 10.2.1.164:8080 -s lc
ipvsadm -a -t 10.2.1.164:8080 -r 10.2.1.166 -g
ipvsadm -a -t 10.2.1.164:8080 -r 10.2.1.165 -g

Le opzioni utilizzate nelle linee di comando di ipvsadm per l’esempio riportato sono le seguenti:

-C, –clear: cancella la tabella del virtual server.
-A, –add-service: crea un servizio virtuale.
-a, –add-server: aggiunge un nodo ad un servizio virtuale.
-t, –tcp-service: specifica indirizzo ip e numero di porta tcp del servizio virtuale.
-s, –scheduler: specifica l’algoritmo di bilanciamento
-r, –real-server: specifica l’indirizzo ip del nodo reale
-g, –gatewaying: indica il metodo di forwarding direct routing (LVS-DR)

** algoritmi per il bilanciamento che possiamo usare con LVS.

Statici:

– Round Robin

– Weighted Round Robin

– Destination Hashing

– Source Hashing

Dinamici:

– Least-Connection

– Weighted least-connection

– Never queue

– Locality-based least-connection

– Locality-based least-connection with replication scheduling

– Shortest expected delay


pound

Pound è un proxy server di bilanciamento del carico inverso. Accetta richieste da HTTP / HTTPS clienti e li distribuisce a uno o più server web. Le richieste HTTPS vengono decifrati e passati al back-end come semplice protocollo HTTP.

Se più di un server back-end è definita, Pound sceglie uno di loro a caso, sulla base delle priorità definite. Per impostazione predefinita, Pound tiene traccia di associazioni tra client e server back-end (sessioni).

General Principles

In generale, Pound ha bisogno di tre tipi di oggetti definiti, al fine di funzione: ascoltatori , i servizi e back-end .

Ascoltatori
Un ascoltatore è una definizione di come Pound riceve le richieste dai client (browser). Due tipi di ascoltatori può essere definito: normale connessione HTTP ascoltatori e HTTPS (HTTP su SSL / TLS) ascoltatori . Per lo meno un ascoltatore deve definire l’indirizzo e la porta per l’ascolto su, con ulteriori requisiti per HTTPS ascoltatori .

Servizi
Un servizio è la definizione di come le domande trovano risposta. Il servizio può essere definito all’interno di un ascoltatore o al livello superiore (globale). Quando viene ricevuta una richiesta Pound tenta di far corrispondere a ciascun servizio , a sua volta, a partire dai servizi definiti nel ascoltatore stesso e, se necessario, di proseguire con l’ servizi definiti a livello globale. I servizi possono definire le proprie condizioni al quale le domande si può rispondere: in genere si tratta certo URL (solo foto, o un certo percorso) o intestazioni specifiche (come ad esempio l’intestazione Host). Un servizio può anche definire una sessione meccanismo: se definito le richieste future da un determinato cliente sarà sempre la stessa risposta da parte di back-end .

Back-end
Il back-end sono i server reale per il contenuto richiesto. Di per sé, Pound fornisce nessuna risposta – tutti i contenuti devono essere ricevuti da un vero e proprio “web server”. Il back-end definisce come il server dovrebbe essere contattato.

Tre tipi di back-end può essere definito: un “regolare” back-end che riceve le richieste e le risposte restituisce, un “redirect” back-end in questo caso, Pound risponde con una risposta redirect, senza l’accesso a qualsiasi back-end a tutti , o una “emergenza” back-end che sarà usato solo se tutti gli altri backend sono “morti”.

Multiple back-end può essere definito all’interno di un servizio , nel qual caso Pound sarà bilanciamento del carico tra i disponibili back-end .

Se un back-end non riesce a rispondere, sarà considerato “morto”, nel qual caso Pound si ferma l’invio di richieste ad esso. Dead indietro _ e NDS sono periodicamente controllate per la disponibilità, e una volta che rispondono ancora sono “resurected” e le richieste sono inviati di nuovo la loro strada. Se non back-end sono disponibili (nessuno è stato definito, o sono tutti “morti”), allora Pound risponderà con “503 Servizio non disponibile”, senza verificare ulteriori servizi .

Il collegamento tra Pound e il back end- è sempre via HTTP, a prescindere dal protocollo utilizzato tra Pound e il cliente.

Installazione

sudo apt-get install pound

La gestione completa del servizio avviene tramite la configurazione del file /etc/pound/pound.cfg
Esempio 1:

Semplice configurazione HTTP Proxy
Supponiamo di forwardare le richieste http che arrivano dall”IP pubblico 202.54.10.5 all’IP sulla LAN 192.168.1.5 su cui è configurato un web server Apache sulla porta 8080.
Editiamo il file di configurazione di pound di una distro Debian/Ubuntu:

vim /etc/pound/pound.cfg

Questo è l’aspetto del file:

ListenHTTP
Address  202.54.10.5
Port          80
Service
BackEnd
Address  192.168.1.5
Port           8080
End
End
End

Salvare e chiudere il file e restartare Pound:

/etc/init.d/pound restart

Esempio 2
Semplice configurazione HTTP & HTTPS Proxy
In questo esempio vediamo come “proxare” una richiesta http e https dallo stesso IP pubblico 202.54.10.5 a due web server 192.168.1.5 e 192.168.1.6, entrambi sulla porta 80:

ListenHTTP
Address  202.54.10.5
Port          80
End

ListenHTTPs
Address   202.54.10.5
Port           443
Cert           “/etc/ssl/local.server.pem” -–>percorso certificato ssl
End

Service
BackEnd
Address     192.168.1.5
Port              80
Priority       1
Backend
Address     192.168.1.6
Port              80
Priority       3
End
End

Salviamo il file di configurazione e restartiamo pound.

In questo esempio le richieste alla porta 80 all’ ip 202.54.10.5  vengono inoltrate alla porta 80 del webserver 192.168.1.5, mentre le richieste alla porta 443 dall’ ip 202.54.10.5 vengono inoltrate alla porta 80 del web server 192.168.1.6  e in questo caso pound gestisce il certificato ssl, che è possibile generarsi senza alcuna modifica nel backend del web server, che continua a gestire chiamate in http.

PS: e’ possibile inoltre impostare una priorità di inoltro del traffico differente, nel caso si disponga di più server web, cosi’ come indicato dalla voce “Priority” presente nella configurazione del secondo esempio; minore è la cifra, maggiore sarà la priorità assegnata al server.

Buon divertimento !