I'm trying to understand how x11 port forwarding inside SSH connections works programmatically.
In particular, I'm trying to understand this part of the README that is part of the code recipes inside Node's SSH2 client library. Once the client is instantiated, what do the variables xserversock
and xclientsock
do? Why does xclientsock
pipe data back to itself through xserversock
? Finally, does xserversock
actually connect to 127.0.0.1:6000
, or to 10.13.23.10:6000
?
var net = require('net');
var Client = require('ssh2').Client;
var conn = new Client();
conn.on('x11', function(info, accept, reject) {
var xserversock = new net.Socket();
xserversock.on('connect', function() {
var xclientsock = accept();
xclientsock.pipe(xserversock).pipe(xclientsock);
});
// connects to localhost:0.0
xserversock.connect(6000, 'localhost');
});
conn.on('ready', function() {
conn.exec('xeyes', { x11: true }, function(err, stream) {
if (err) throw err;
var code = 0;
stream.on('end', function() {
if (code !== 0)
console.log('Do you have X11 forwarding enabled on your SSH server?');
conn.end();
}).on('exit', function(exitcode) {
code = exitcode;
});
});
}).connect({
host: '10.13.23.10',
username: 'foo',
password: 'bar'
});
xserversock
is the connection to the X server running locally on your machine.xclientsock
is the stream representing the incoming X client request (e.g. xeyes in the example) to your local X server.xclientsock.pipe(xserversock).pipe(xclientsock);
is notxclientsock
piping to itself, it is merely allowing data to flow in both directions between the local X server and the remote X client.pipe()
always returns the stream passed to it, to allow for easy chaining of streams. So this one line of code is equivalent to:Finally, remember
xserversock
is a socket that is connecting to your local X server. This is evident with the.connect()
arguments passed to the socket, so it will be connecting to 127.0.0.1:6000.