העבר ל-ssh2 את ה-socket שנפתח דרך SOCKS
נהלו משא ומתן על חיבור SOCKS תחילה, ואז העבירו את socket היעד שלו ל-ssh2 לפני פתיחת תת-המערכת SFTP.
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 שנגיש מהאינטרנט הציבורי, רשימת ה-proxy של SOCKS5 יכולה לספק מועמדים; כל אחד מהם עדיין צריך להתיר את יעד ה-SSH ואת היציאה. לשיטת שם המשתמש/סיסמה שלו, השתמשו ב-socks.auth.UserPassword(proxyUser, proxyPassword) בתוך auths. אישורים אלה אינם מחליפים את חשבון ה-SSH.
localDNS false מעביר את שם המארח של היעד לשרת ה-SOCKS, תוך שימוש בפתרון היעד בצד ה-proxy. בלי הבחירה המפורשת הזו, ברירת המחדל המתועדת של socksv5 מנסה פתרון מקומי.
ה-callback של SOCKS רץ לאחר המשא ומתן. המתינו לאירוע ready של ssh2 לפני בקשת SFTP. אלה שלבים מוצלחים נפרדים; לא חיבור TCP ל-proxy ולא תשובת SOCKS מוכיחים שאימות ה-SSH או תת-המערכת SFTP הצליחו.