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/');