Visualizzazione dei risultati da 1 a 2 su 2

Discussione: nat-traverse e sockets

  1. #1

    nat-traverse e sockets

    Salve,

    Sto cercando di creare una serie di scripts che mi permetta di trasferire files anche se si è dietro NAT o firewall.

    Tempo fa mi è stato suggerito l'ottimo script "nat-traverse" http://linide.sourceforge.net/nat-traverse/ che risiede da entrambe le parti -host server- e -host client- e lanciato quasi in contemporanea sulle due macchine crea un collegameno UDP tra di loro.

    ad esempio:

    user@left $ nat-traverse 40000:natgw-of-right:40001
    user@right $ nat-traverse 40001:natgw-of-left:40000

    in più aggiungendo "--cmd" come spiegato nel sito:

    "The command will be run with its STDIN and STDOUT bound to the socket, i.e. everything the command writes to STDOUT will be forwarded to the peer."

    sul computer server ho questo script (stdin.pl)
    codice:
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    use IO::Handle;
    STDOUT->autoflush();
    
    while ( defined($_ = <STDIN>) )
    {
    	print STDOUT $_ , "\n";
    }
    Ovvero...tutto quello che riceve lo deve rimandare al mittente

    Sempre sul computer "server" eseguo:

    nat-traverse --cmd="/usr/bin/perl /users/larry/stdin.pl" 40000:user@client:40001

    e quasi in contemporanea sul computer "client" eseguo:

    nat-traverse 40001:user@server:40000

    ...perfetto, la connessione è avvenuta con successo e tutto quello che digito mi viene rispedito indietro...

    Ora ho bisogno nel client di legare nat-traverse ad uno script che si metta in ascolto e che tutto quello che riceve lo spedisca a nat-traverse (che a sua volta lo rispedira a user@server)

    questo è lo script (socket.pl)
    codice:
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    use IO::Socket::INET;
    use IO::Handle;
    
    STDOUT->autoflush();
    
    my $server = IO::Socket::INET->new(LocalPort => '9999', Proto => 'tcp', Reuse => 1) || die $!;
    
    my $client;
    my $buff;
    
    while ( $server->listen() )
    {
    	$client = $server->accept();
    	$client->autoflush(1);
    	while(1)
    	{
    		recv($client, $buff, 1024, 0);
    		
    		print STDOUT $buff;
    		
    		while ( defined($_ = <STDIN>) )
    		{		
    			syswrite $client, $_;
    		}
    	}
    }
    
    close($server);
    ora rilancio sul computer server:

    nat-traverse --cmd="perl /users/larry/stdin.pl" 40000:user@client:40001

    e sul computer client eseguo:

    nat-traverse --cmd="perl /users/larry/socket.pl" 40001:user@server:40000

    ...la connessione avviene con successo e sempre sul computer client eseguo "netstat -an" e vedo che socket.pl è in ascolto su *.9999

    ora mi collego con "nc 127.0.0.1 9999" e digito qualcosa...fantastico!!! mi viene rispedito indietro...vuol dire che tutto il sistema funziona...purtroppo se continuo a digitare non mi torna indietro più niente...ma socket *.9999 è ancora in ascolto!!! cosa avrò sbagliato?!?!?

    in più volevo sapere, quando in socket.pl mi trovo:

    recv($client, $buff, 1024, 0);
    print STDOUT $buff;
    while ( defined($_ = <STDIN>) )
    {
    syswrite $client, $_;
    }


    quella recv è bloccante? e poi...quando sto in "while defined($_ = <STDIN>)" devo per forza aspettare di uscire dal ciclo per poter riscrivere in recv?

    Spero che abbiate capito tutto quello che ho scritto...

    grazie
    Alla batteria dai retta ballA

  2. #2
    Ho fatto alcuni cambiamnti allo script server ed ora ho una connessione
    stabile client/server...tuttavia non posso chiudere le connessione di nc
    (infatti quando imposto nc come server accetta solo una connessione ed
    alla fine di essa nc si chiude)

    Prima vorrei vorrei darvi un idea dello scenario:
    codice:
    HOST1 (user@client) dietro NAT
    {
       Browser per connetersi ad internet
    }
    
    HOST2 (user@server) dietro NAT
    {
       Apache running on port 80
    }
    Con il browser da HOST1 non posso collegarmi a HOST2 per ovvi motivi in
    quanto HOST2 non è visibile ne raggiungibile direttamente dall'esterno.

    Da notare che user@server e user@client sono nomi fitizi, in verità
    questi test vengono fatti in locale usando 127.0.0.1 sia come server che
    come client.

    **

    dal lato client (user@client) chiamo lo script:

    perl nat-traverse.pl --cmd="nc -lvp 65000" 40000:user@server:40001

    in questo caso "nat-traverse" reindirizza il proprio STDIN e STDOUT a nc
    dopo essersi collegato con il "nat-traverse" che risiede sull'host
    server. La funzione di "nc" è di raccogliere richieste e spedirle nel
    tunnel UDP verso il server.

    **

    dal lato server (user@server) chiamo lo script:

    perl nat-travesre.pl --cmd="perl server.pl" 40001:user@client:40000

    appena "nat-traverse" instaura la connessione con il "nat-traverse"
    residente sul computer client il proprio STDIN e STDOUT viene
    reindirizzato allo script "server.pl" di cui posto il codice:
    codice:
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    use lib "libwww-perl/lib";
    use LWP;
    use Data::Dumper;
    use IO::Handle;
    STDOUT->autoflush();
    
    my (%header, $key, $req, $data, $browser, $res, $content);
    
    $browser = LWP::UserAgent->new;
    
    while(1)
    {
       my $req = <STDIN>;
    
       while( defined($_ = <STDIN>) )
       {  
          s/[\r\n]+$//;
          last unless length $_;
          /^ ([\w\-]+) :[\ \t]+ (.+) $/x;
          $key = uc($1);
          $key =~ tr/-/_/;
          $header{$key} = $2
       }
       
       # $data = Dumper(\%header);
       # print STDOUT "HTTP/1.1 200 OK\n\nHello World!!!\n\n$req\n\n$data";
    
       $res = $browser->get("http://127.0.0.1:80/");
       $content = $res->content;
    
       print STDOUT $content;
    
    }
    Questo script riceve la richiesta in uscita dal tunnel UDP e fa una cosa
    minima, richiede ad apache la pagina di default...index.html
    respidendola al mittente.

    **

    Da HOST1 ho "nc" in ascolto sulla porta 65000. (so che "nc" è un varco
    verso apache in ascolto su HOST2)

    Mi collego tramite: nc 127.0.0.1 65000 e digito due volte a capo...con
    molto piacere ottengo come response: "HTTP/1.1 200 OK ...etc.." in poche
    parole mi viene riportata la semplice pagina html che risiede su HOST2.
    Sono riuscito a connettermi anche se entrambi gli HOST sono dietro NAT.

    Tuttavia se da HOST1 apro il browser e digito: 127.0.0.1:65000 non viene
    restituito niente finchè non chiudo "nc" che è in ascolto...il che
    equivalerebbe ad un close($socket)

    Come posso ovviare a questo? dovrei forse inserire un carattere di EOF?

    Un'altra domanda, credete che sia sbagliato sparare tutto il contenuto
    di un file nel tunnel UDP tramite: print STDOUT $content; ?? credete che
    dovrei spedire chunks di 1024 bytes??

    grazie mille
    Alla batteria dai retta ballA

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.