PDA

View Full Version : [C] socket :questi sconosciuti


alifangelo
30-11-2008, 11:54
Ciao a tutti,
dovrei realizzare un bilanciatore di carico nel seguente modo:
Ho un Master server (chiamiamolo M) il quale è in comunicazione (tramite socket) ad N server (chiamiamoli S ). Uno o piu client (chiamiamoli C) fanno una richiesta ad M il quale inoltrerà tale richiesta al S che sta servendo meno richieste. La mia domanda è come posso implementare questa cosa ?
Io avevo pensato ad una cosa tipo questa: <----> questo simbolo è un socket

C <----> M <----> S , C fa una richiesta a M, M la inoltra ad S, S elabora la richiesta e risponde ad M il quale la risponde a C.

Esiste un modo per far comunicare direttamente S con C senza ripassare da M ?

Cioè si puo fare una cosa tipo questa :
C<----> M<---->S<----> C C fa una richiesta a M, M la inoltra ad S, S elabora la richiesta e risponde a C.

In pratica S si può agganciare sul socket tra C e M e rispondere a C ?
Non so se la domanda è chiara, spero di si.

alifangelo
02-12-2008, 18:58
Mi rispondo da solo sperando che le mie ore passate a risolvere il dilemma possano aiutare qualcuno:

La risposta è si usando il protocollo UDP. In pratica il Master invia al Server l' IP e la porta del client.
Con TCP non penso si possa fare(per via del 3-way-handshake).

Se qualcuno ci riesce me lo faccia sapere ;)

cionci
02-12-2008, 19:37
Su stream sbilanciati ovvero dove richieste piccole seguono a risposte molto grandi e computazionalmente impegnative si può optare comunque per lasciare M nel mezzo fra le due connessioni ;)
Il load balancing dei server HTTP (anche di questo sito) funziona così.

Oceans11
02-12-2008, 19:49
Ciao.

Questo tuo quesito mi ha affascinato subito e mi ha anche dato dei bei grattacapi.

Siccome ritengo (nel tuo caso) il protocollo tcp essenziale, ti propongo una soluzione per aggirare il problema: fare una sorta di pre-richiesta al master server (M). Intendo dire:

il client (C) si connette a M per sapere a quale server (S) si può rivolgere. Risultato della richiesta è la coppia ip/porta del server libero.
Da qui in poi parte la connessione vera e propria.

Ora però, fantasticando un pò sulla questione che hai posto, mi viene in mente la tecnica del MITM. Dove voglio andare a parare? Con quella tecnica in sostanza si dirottano (illegalmente?!?) connessioni di rete già avvenute verso un terzo end-point. Quindi chissà che non sia possibile "dirottare" la connessione da M ad un S una volta trovato.

cionci
02-12-2008, 23:39
MITM = Man In The Middle ???
Il Man In The Middle ha principalmente tre possibilità di lavorare sul traffico:
- impersonificando il server
- intercettando il traffico (i pacchetti gli passano davanti)
- soppressione del traffico (i pacchetti gli passano davanti)
- duplicazione del traffico
- come nel caso sopra (caso più generale dell'impersonificazione): C <-> M <-> S

Non mi risulta che col TCP si possano fare altri magheggi, anche perché il problema principale è che ogni connessione ha un sequence number diverso.

Oceans11: il discorso che hai fatto nella prima parte è corretto, ma implica una modifica del protocollo e quindi non è trasparente all'utente.

Oceans11
03-12-2008, 09:26
MITM = Man In The Middle ???
Il Man In The Middle ha principalmente tre possibilità di lavorare sul traffico:
- impersonificando il server
- intercettando il traffico (i pacchetti gli passano davanti)
- soppressione del traffico (i pacchetti gli passano davanti)
- duplicazione del traffico
- come nel caso sopra (caso più generale dell'impersonificazione): C <-> M <-> S

Non mi risulta che col TCP si possano fare altri magheggi, anche perché il problema principale è che ogni connessione ha un sequence number diverso.

per i casi che contemplano il passaggio dei pacchetti davanti all'attaccante, sono d'accordo, dovevo specificare meglio nel post precendente. Ho scritto "connessioni di rete" senza mettere in luce per bene questo fatto che è chiave. Però non ho capito perchè non è corretto un discorso del genere.
Cerco di spiegarmi un pò meglio: n
essuno deve fare un attacco man in the middle, ma dico che se un attacco man in the middle può "sganciare un endpoint e attaccarlo ad un altro computer" rimanendo trasparente al secondo endpoint, ci sarà un modo per cui il master server riesce a "trasferire" la socket che tiene aperta con un client verso un server???

ps: magari già mi hai risposto e smentito, ma giuro che non ho capito! :(

cionci
03-12-2008, 09:51
Sei sicuro che un Man In the Middle possa "sganciare" un endpoint ed attaccarlo da un'altra parte a connessione già iniziata ?
Ad alto livello è praticamente impossibile farlo perché ci sono aspetti relativi al sequence number che sono impredicibili.
A basso livello sarebbe anche possibile (il NAT lo fa ad esempio), ma la decisione su dove instradare i pacchetti andrebbe presa subito al primo pacchetto di SYN, prendendola dopo anche qui bisognerebbe "indovinare" il sequence number che il server assegnerebbe alla connessione e M dovrà continuare ad instradare i pacchetti che gli arrivano da C verso S (dopo tutto si tratta di un routing). Quindi di fatto M è sempre in mezzo fra C e S, almeno per i pacchetti che da C vanno a S, per quelli nel verso opposto no perché S può rispondere direttamente a C.
Di fatto M non si potrà mai "staccare" completamente dalla connessione fino a quando essa non sarà terminata.

Oceans11
03-12-2008, 11:56
Sei sicuro che un Man In the Middle possa "sganciare" un endpoint ed attaccarlo da un'altra parte a connessione già iniziata ?
Ad alto livello è praticamente impossibile farlo perché ci sono aspetti relativi al sequence number che sono impredicibili.
A basso livello sarebbe anche possibile (il NAT lo fa ad esempio), ma la decisione su dove instradare i pacchetti andrebbe presa subito al primo pacchetto di SYN, prendendola dopo anche qui bisognerebbe "indovinare" il sequence number che il server assegnerebbe alla connessione e M dovrà continuare ad instradare i pacchetti che gli arrivano da C verso S (dopo tutto si tratta di un routing). Quindi di fatto M è sempre in mezzo fra C e S, almeno per i pacchetti che da C vanno a S, per quelli nel verso opposto no perché S può rispondere direttamente a C.
Di fatto M non si potrà mai "staccare" completamente dalla connessione fino a quando essa non sarà terminata.

Evidentemente mi sfugge più di una cosa per quanto riguarda il MITM allora....:D grazie per la risposta...appena posso approfondisco e nel caso vengo a chiedere.

alifangelo
05-12-2008, 16:42
Ciao.

Questo tuo quesito mi ha affascinato subito e mi ha anche dato dei bei grattacapi.

Siccome ritengo (nel tuo caso) il protocollo tcp essenziale, ti propongo una soluzione per aggirare il problema: fare una sorta di pre-richiesta al master server (M). Intendo dire:

il client (C) si connette a M per sapere a quale server (S) si può rivolgere. Risultato della richiesta è la coppia ip/porta del server libero.
Da qui in poi parte la connessione vera e propria.

Ci avevo pensato ma come ha già detto cionci questo significa cambiare il codice del client (l'operazione non è più trasparente).
per quanto riguarda la sicurezza si potrebbe cifrare il tutto con la chiave pubblica/privata e risolvere i problemi del man in the middle.

Su stream sbilanciati ovvero dove richieste piccole seguono a risposte molto grandi e computazionalmente impegnative si può optare comunque per lasciare M nel mezzo fra le due connessioni
Sono daccordo sul fatto che in caso di risposte computazionalmente impegnative si possa lasciare M nel mezzo, ma se la risposta è grande in termini di byte non sarebbe meglio non ripassare da M ?

Il problema che risollevo è :Si puo fare quello che ho fatto in UDP con TCP ?

cionci
05-12-2008, 18:05
Sono daccordo sul fatto che in caso di risposte computazionalmente impegnative si possa lasciare M nel mezzo, ma se la risposta è grande in termini di byte non sarebbe meglio non ripassare da M ?
Si lascia comunque M nel mezzo. Tra l'altro lasciare M nel mezzo è anche una cosa molto furba perché si può fare caching e questo migliora notevolmente vari aspetti:
- in caso di client lento il server non deve aspettare il client, ma scarica su M tutto lo stream e sarà pronto a servire un'altra richiesta, senza contare che la rete fra M e S può essere incredibilmente più veloce (Gigabit Ethernet) di quella tra S e C (ad esempio il collo di bottiglia potrebbe essere un'adsl)
- le richieste già fatte posso essere esaudite direttamente da M senza dover essere rielaborate
- sicurezza: i client vedono solo M e non possono attaccare S
Il problema che risollevo è :Si puo fare quello che ho fatto in UDP con TCP ?
In teoria sì, in pratica no. Proprio per i motivi che ho scritto sopra, inoltre per far passare in un certo momento la connessione direttamente da S e C, M dovrebbe andare a cambiare la tabella di routing, insomma, una cosa colossale.
Quello che limita questa possibilità sono appunto le decine di variabili di stato relative ad un connessione TCP: sequence number, pacchetti ricevuti, ack cumulativi, finestre, insomma sarebbe un bel casotto replicare tutto dall'altra parte ed anche se ci riesco il client gli ACK li invia comunque a M ;)

banryu79
06-12-2008, 12:02
Si lascia comunque M nel mezzo. Tra l'altro lasciare M nel mezzo è anche una cosa molto furba perché si può fare caching e questo migliora notevolmente vari aspetti:
- in caso di client lento il server non deve aspettare il client, ma scarica su M tutto lo stream e sarà pronto a servire un'altra richiesta, senza contare che la rete fra M e S può essere incredibilmente più veloce (Gigabit Ethernet) di quella tra S e C (ad esempio il collo di bottiglia potrebbe essere un'adsl)
- le richieste già fatte posso essere esaudite direttamente da M senza dover essere rielaborate
- sicurezza: i client vedono solo M e non possono attaccare S

In pratica M agisce come un "Caching proxy server"...