SOCKS 経由で開いたソケットを ssh2 に渡す
まず SOCKS 接続をネゴシエートし、SFTP サブシステムを開く前にその宛先ソケットを ssh2 に渡します。
ssh2 は sock オプションを通じて、すでに接続済みのストリームを受け取ります。socksv5 に SSH サーバーへの経路を確立させ、そのストリームを SSH に渡します。
const socks = require('socksv5');
const { Client } = require('ssh2');
const connection = socks.connect({
host: sshConfig.host,
port: sshConfig.port || 22,
proxyHost: 'proxy.example',
proxyPort: 1080,
localDNS: false,
auths: [socks.auth.None()],
}, socket => {
const ssh = new Client();
ssh.on('error', error => console.error(error.message));
ssh.on('ready', () => {
ssh.sftp((error, sftp) => {
if (error) {
console.error(error.message);
ssh.end();
return;
}
sftp.readdir('.', (error, entries) => {
if (error) console.error(error.message);
else console.log(entries);
ssh.end();
});
});
});
ssh.connect({ ...sshConfig, sock: socket });
});
connection.on('error', error => console.error(error.message));
sshConfig はアプリケーションが既に持つ SSH 設定で、アカウント、鍵、hostVerifier ポリシーを含みます。SOCKS のホストとポートは中継役を指し、sshConfig.host と port は最終的な SSH サービスを指します。
この例では認証なしの SOCKS エンドポイントを使います。公開インターネットから到達できる SSH サーバーには、SOCKS5 プロキシ一覧から候補を選べますが、いずれも SSH の宛先とポートを許可している必要があります。ユーザー名/パスワード方式では auths に socks.auth.UserPassword(proxyUser, proxyPassword) を指定します。これらの資格情報は SSH アカウントの代わりにはなりません。
localDNS false は宛先ホスト名を SOCKS サーバーに渡し、プロキシ側での宛先解決を使います。この明示的な指定がない場合、socksv5 の文書化された既定値はローカル解決を試みます。
SOCKS のコールバックはネゴシエーション後に実行されます。SFTP を要求する前に ssh2 の ready イベントを待ってください。これらは別々の成功段階であり、プロキシへの TCP 接続も SOCKS の応答も、SSH 認証や SFTP サブシステムの成功を証明しません。