Closed FaberNa closed 3 years ago
@FaberNa ssh2-sftp-client can't support proxy at this time. ssh2 now only support SOCKSv5
It's possible to have an example where we upload a file with SOCKSv5 ?
@FaberNa sorry. ssh2-sftp-client module also can't support SOCKSv5
@FaberNa Did you find an alternate solution to this package that supports proxies?
@FaberNa @sandrooco I am also looking into a proxy solution, did either of you come up with something?
I struggled a bit for having this module work behind a corporate proxy, trying with ssh2, socksv5 and some of its forks.
I finally got it working using the (very simple to use) socks module.
Here is my solution:
import { SocksClient } from 'socks';
import SFTPClient from 'ssh2-sftp-client';
const host = 'my-sftp-server.net';
const port = 22; // default SSH/SFTP port on remote server
// connect to SOCKS 5 proxy
const { socket } = await SocksClient.createConnection({
proxy: {
host: 'my.proxy', // proxy hostname
port: 1080, // proxy port
type: 5, // for SOCKS v5
},
command: 'connect',
destination: { host, port } // the remote SFTP server
});
const client = new SFTPClient();
await client.connect({
host,
sock: socket, // pass the socket to proxy here (see ssh2 doc)
username: '.....',
privateKey: '.....'
});
// client is connected
I struggled a bit for having this module work behind a corporate proxy, trying with ssh2, socksv5 and some of its forks.
I finally got it working using the (very simple to use) socks module.
Here is my solution:
import { SocksClient } from 'socks'; import SFTPClient from 'ssh2-sftp-client'; const host = 'my-sftp-server.net'; const port = 22; // default SSH/SFTP port on remote server // connect to SOCKS 5 proxy const socket = await SocksClient.createConnection({ proxy: { host: 'my.proxy', // proxy hostname port: 1080, // proxy port type: 5, // for SOCKS v5 }, command: 'connect', destination: { host, port } // the remote SFTP server }); const client = new SFTPClient(); await client.connect({ host, sock: socket, // pass the socket to proxy here (see ssh2 doc) username: '.....', privateKey: '.....' }); // client is connected
Hey, thanks for adding some light here. I can connect to the proxy but right after, when passing the sock param to the sftp i get " TypeError: sock.on is not a function". May i ask if you had this issue and how could be solved ?
const socketCon = await SocksClient.createConnection(options);
console.log('SOCKET CONNECTED') //<- i get here fine
const client = new SFTPClient();
await client.connect({
sock: socketCon, // pass the socket to proxy here (see ssh2 doc)
host: '****',
port: ***,
username: '***',
password: '***',
algorithms: {
serverHostKey: ['ssh-rsa', 'ssh-dss', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521'],
},
});```
Hi @amstrad,
Sorry there was a typo in my snippet. The SocksClient.createConnection
returns an object with a socket
property, and not the socket itself directly.
So you should read
const { socket } = await SocksClient.createConnection(...)
instead of
const socket = await SocksClient.createConnection(...)
I also edited my previous answer.
thanks @jmorino !, still not having luck but i might be missing something else.. i´ll get around this a bit more (i did tried object.socket and others props before, it seems the socket is an object? but docs state "sock - ReadableStream - A ReadableStream to use for communicating with the server instead of creating and using a new TCP connection (useful for connection hopping)." it´s a bit after me, as i´m relatively new to node.. i´ll report back i get it working.
My bad, got this working using @jmorino solution, just dunno why but i need to pass the socket property in the object... my code is as follow:
const {socket} = await SocksClient.createConnection(options)
console.log('SCOCKET CONNECTED. Connecting to SFTP...')
const sftp_client = new SFTPClient();
await sftp_client.connect({
host: '****',
sock: socket.socket,
port: 22, // Normal is 22 port
username: '***',
password: '***',
algorithms: {
serverHostKey: ['ssh-rsa', 'ssh-dss'],
},
}).then(async () => {
console.log('SFTP CONNECTED!')
}).catch((err) => {
console.log('error ' + err)
});
Just to be clear. Here is a full exemple.
The situation : Server B is the only server allowed to connect to server C. I need to use server A to connect to C. Then i create a socks proxy on server B. which means A => B => C
First i need to create a socks proxy
root@A# ssh -D 1818 -q -C -N root@B
then i used this code
require('dotenv').config();
let SocksClient = require('socks').SocksClient;
let Client = require('ssh2-sftp-client');
let fs = require('fs');
(async () => {
try {
const host = 'C';
const port = 22;
// connect to SOCKS 5 proxy
const { socket } = await SocksClient.createConnection({
proxy: {
host: 'B', // proxy hostname
port: 1818, // proxy port
type: 5, // for SOCKS v5
},
command: 'connect',
destination: { host, port } // the remote SFTP server
});
const sftp = new Client();
await sftp.connect({
sock: socket,
host: host,
port: port,
username: process.env.SSH_USERNAME,
agent: process.env.SSH_AGENT,
privateKey: fs.readFileSync(process.env.SSH_PRIVATE_KEY),
})
console.log('SFTP CONNECTED!')
await sftp.end();
} catch(err){
console.error(err);
}
})()
it works.
Can someone help me determine this :
Do i really need to create a socks proxy with ssh myself before executing the script ?
Would an ssh tunnel also work ? do i need to use require('socks') in that case ?
I have never done this myself, but believe it is possible (there is an example in the FAQ section of the README).
You can probably find more information in the ssh2 repository - especially the issues section. The ssh2-sftp-client module is just a wrapper module around ssh2 and ssh2-streams which provides a promise based interface. You should be able to adjust any examples based on ssh2/ssh2-streams to work with ssh2-sftp-client without too many problems.
You could probably achieve the same thing using ssh tunnels, but you would need to setup the tunnel on server B, then connect to that tunnel from server A. Essentially, a 'poor mans' proxy. I would try getting the socks proxy working first as it is likely to be a more robust solution that would provide better security.
As using a SOCKS proxy appears to be possible just using available ssh2 functionality, I don't see any need to add anything to this module. Therefore, I am closing this issue.
let Client = require('ssh2-sftp-client'); let sftp = new Client(); sftp.connect({ host: '127.0.0.1', port: '8080', username: 'username', password: '******' }).then(() => { return sftp.list('/pathname'); }).then((data) => { console.log(data, 'the data info'); }).catch((err) => { console.log(err, 'catch error'); });
I use this type of code but is there an option for setting proxy ?