2014-06-13 2 views
1

J'essaie de créer un tunnel en utilisant Node.js qui me permettra d'accéder au serveur X à partir du serveur Y. Le serveur X est connecté à un routeur qui n'est pas redirigé et j'ai gagné Vous ne connaissez pas l'adresse IP du serveur X avant qu'il ne se connecte, ce qui signifie que le serveur X doit ouvrir une socket sur le serveur Y et non l'inverse. J'ai réussi à créer une version de ceci en utilisant socket.io. Le serveur X ouvre un socket sur le serveur Y, l'utilisateur peut alors accéder au serveur Y dans un navigateur Web et le serveur Y transfère les demandes vers le serveur X par le biais du socket.Tunnel entre les serveurs prenant en charge n'importe quel port

Ce que je voudrais faire est de permettre l'accès à n'importe quel type de port sur le serveur X, et transmettre non seulement les requêtes Web, mais les demandes de toute nature. Par exemple, je voudrais autoriser le transfert de SSH pour que je puisse accéder à SSH sur le serveur X via le serveur Y (ne doit pas nécessairement être le port 22). localtunnel.me est un service existant qui est un exemple exact de ce que je veux réaliser.

Y a-t-il des bibliothèques qui pourraient m'aider à atteindre cet objectif, ou puis-je le construire à partir de zéro? J'ai construit le tunnel de demande Web facilement, peut-être qu'il peut être adapté pour prendre en charge non seulement le trafic Web? J'ai joint le code à mon tunnel Web existant ci-dessous.

serveur X (se connecte au serveur Y sur le port 3001, reçoit des demandes de données et renvoie:

var socket = require('socket.io-client')('http://localhost:3001'); 
     socket.on('connect', function(){ 
      console.log('Connected'); 

      // Register the event for request of data 
      socket.on('request', function(data){ 
       // Get the path 
       var options = { 
        host: 'localhost', 
        port: 3000, 
        path: data.path, 
        method: data.method 
       }; 

       var request = http.get(options, function(resp){ 
        resp.on('data', function(chunk){ 
        socket.emit('response', { html: chunk }); 
        // Probably need to fix this for file transfers. Use resp.on('end' 
        }); 
       }).on("error", function(e){ 
        console.log("Got error: " + e.message); 
       }); 

       //Write our post data to the request 
       request.write(data.data); 
       //End the request. 
       request.end(); 

      }); 
      socket.on('disconnect', function(){}); 
     }); 

serveur Y (écoute sur le port 3001 pour se connecter au serveur X et écoute sur le port 3002 pour les demandes de l'utilisateur dans le navigateur Web pour transmettre au serveur X:

app.listen(3001); 

var rwPortalSocket; 

function handler (req, res) { 
    fs.readFile(__dirname + '/index.html', 
    function (err, data) { 
    if (err) { 
     res.writeHead(500); 
     return res.end('Error loading index.html'); 
    } 

    res.writeHead(200); 
    res.end(data); 
    }); 
} 

io.on('connection', function (socket) { 
    socket.emit('news', { hello: 'world' }); 
    socket.on('my other event', function (data) { 
    console.log(data); 
    }); 
    // Save the socket object 
    rwPortalSocket = socket; 
}); 

console.log('Data channel server running at http://127.0.0.1:3001/'); 

// Create web server 
var http = require('http'); 
var qs = require('querystring'); 

http.createServer(function (req, res) { 
    // Send a request 
    rwPortalSocket.emit('request', { path: req.url, method: req.method }); 

    // When we get a response 
    rwPortalSocket.on('response', function (responseData) { 
     res.writeHead(200); 
     res.end(responseData.html); 
    }); 

}).listen(3002, '127.0.0.1'); 

console.log('Web server running at http://127.0.0.1:3002/'); 

EDIT

J'ai maintenant mis à jour mon code afin qu'il prenne en charge n'importe quel port TCP ou type de paquet. Le code fonctionne bien quand je dis net.connect pour me connecter à un serveur web, mais quand je le dis pour connecter un serveur SSH, mon client SSH se plaint Protocol error: expected packet type 31, got 20

J'ai ajouté un exemple de mon nouveau code se connectant à un SSH serveur ci-dessous.

serveur X (se connecte au serveur Y sur le port 3001, reçoit des demandes de données et renvoie:

var socket = require('socket.io-client')('http://localhost:3001'); 
     socket.on('connect', function(){ 
      console.log('Connected'); 

      // Connect to 22 
      var buff = ""; 
      var connected = false; 
      var net = require('net'); 
      var client = net.connect({host: 'myserver.com', port: 22}, function() { //'connect' listener 
       connected = true; 
       console.log('Connected to 22'); 
      }); 

      // Register the event for request of data 
      socket.on('request', function(data){ 

       if (!connected) 
       { 
        client = net.connect({host: 'myserver.com', port: 22}, function() { //'connect' listener 
         connected = true; 
         console.log('Connected to 22'); 
         client.write(data.data); 
        }); 
       } 
       else 
       { 
        client.write(data.data); 
       } 

       client.setMaxListeners(0); 
       // When data comes back to this service, we send it on to the other server 
       client.on('data', function(data) { 
        //console.log(data.toString()); 
        console.log('Server sent back: ' + data.toString()); 
        if (connected) 
        { 
         socket.emit('response', { data: data }); 
        } else { 
         buff += d.toString(); 
        } 
       }); 
       client.on('end', function() { 
        console.log('Disconnected from 22'); 
        connected = false; 
       }); 

       client.on('error', function(e) { 
        console.log(e); 
       }); 

       console.log('Client sent: ' + data.data); 
      }); 
      socket.on('disconnect', function(){}); 
     }); 

serveur Y (écoute sur le port 3001 pour se connecter au serveur X et écoute sur le port 3002 pour les demandes de l'utilisateur dans le client SSH (terminal) de transmettre au serveur X:

app.listen(3001); 

var rwPortalSocket; 

function handler (req, res) { 
    fs.readFile(__dirname + '/index.html', 
    function (err, data) { 
    if (err) { 
     res.writeHead(500); 
     return res.end('Error loading index.html'); 
    } 

    res.writeHead(200); 
    res.end(data); 
    }); 
} 

io.on('connection', function (socket) { 
    socket.emit('news', { hello: 'world' }); 
    socket.on('my other event', function (data) { 
    console.log(data); 
    }); 
    // Save the socket object 
    rwPortalSocket = socket; 
}); 

console.log('Data channel server running at http://127.0.0.1:3001/'); 

// Listen for tunnel requests 
net = require('net'); 

var server = net.createServer(function(s) { //'connection' listener 
    s.on('end', function() { 
     console.log('server disconnected'); 
    }); 

    s.on('data', function (d) { 
    rwPortalSocket.emit('request', { data: d }); 
    }); 

    s.on('error', function(e) { 
     console.log(e); 
    }); 

    s.setMaxListeners(0); 

    // When we get a response 
    rwPortalSocket.on('response', function (d) { 
     s.write(d.data); 
    }); 

}); 

server.listen(3002, function() { //'listening' listener 
    console.log('server bound'); 
}); 

console.log('Web server running at http://127.0.0.1:3002/'); 

Répondre

Questions connexes