描述
纯JavaScript编写的SSH2客户端和服务器模块,用于node.js。
开发/测试基于OpenSSH(目前为8.7版本)。
v1.0.0中的变更(包括破坏性变更)可以在此找到。
目录
- 依赖
- 安装
- 客户端示例
- 在服务器上执行'uptime'
- 开始一个交互式shell会话
- 向服务器端口80发送原始HTTP请求
- 将本地连接转发到服务器端口8000
- 通过SFTP获取目录列表
- 连接跳转
- 转发远程X11连接
- 使用SOCKSv5代理动态(1:1)端口转发(使用
socksv5) - 使用自定义http(s).Agent轻松进行HTTP(S)连接
- 调用任意子系统(例如netconf)
- 服务器示例
- 密码和公钥认证以及非交互式(exec)命令执行
- 仅限SFTP服务器
- 其他示例
- 生成一个SSH密钥
- API
- 客户端
- 客户端事件
- 客户端方法
- 服务器
- 服务器事件
- 服务器方法
- 连接事件
- 连接方法
- 会话事件
- 通道
- 伪终端设置
- 终端模式
- HTTPAgent
- HTTPAgent方法
- HTTPSAgent
- HTTPSAgent方法
- 工具
- 客户端
依赖
-
node.js - v10.16.0或更新版本
- node v12.0.0或更新版本支持Ed25519密钥
-
(可选)
cpu-features被设置为一个可选包依赖项(你不需要从ssh2显式/单独安装它)。如果可能,它将自动构建并使用。请参阅项目文档了解其自身的需求。- 此插件目前用于帮助生成一个最优的默认密码列表
安装
npm install ssh2
客户端示例
在服务器上执行'uptime'
const { readFileSync } = require('fs');
const { Client } = require('ssh2');
const conn = new Client();
conn.on('ready', () => {
console.log('Client :: ready');
conn.exec('uptime', (err, stream) => {
if (err) throw err;
stream.on('close', (code, signal) => {
console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
conn.end();
}).on('data', (data) => {
console.log('STDOUT: ' + data);
}).stderr.on('data', (data) => {
console.log('STDERR: ' + data);
});
});
}).connect({
host: '192.168.100.100',
port: 22,
username: 'frylock',
privateKey: readFileSync('/path/to/my/key')
});
// 示例输出:
// Client :: ready
// STDOUT: 17:41:15 up 22 days, 18:09, 1 user, load average: 0.00, 0.01, 0.05
//
// Stream :: exit :: code: 0, signal: undefined
// Stream :: close
开始一个交互式shell会话
const { readFileSync } = require('fs');
const { Client } = require('ssh2');
const conn = new Client();
conn.on('ready', () => {
console.log('Client :: ready');
conn.shell((err, stream) => {
if (err) throw err;
stream.on('close', () => {
console.log('Stream :: close');
conn.end();
}).on('data', (data) => {
console.log('OUTPUT: ' + data);
});
stream.end('ls -l\nexit\n');
});
}).connect({
host: '192.168.100.100',
port: 22,
username: 'frylock',
privateKey: readFileSync('/path/to/my/key')
});
// 示例输出:
// Client :: ready
// STDOUT: Last login: Sun Jun 15 09:37:21 2014 from 192.168.100.100
//
// STDOUT: ls -l
// exit
//
// STDOUT: frylock@athf:~$ ls -l
//
// STDOUT: total 8
//
// STDOUT: drwxr-xr-x 2 frylock frylock 4096 Nov 18 11:05 mydir
//
// STDOUT: -rw-r--r-- 1 frylock frylock 25 Apr 11 2013 test.txt
//
// STDOUT: frylock@athf:~$ exit
//
// STDOUT: logout
//
// Stream :: close
向服务器端口80发送原始HTTP请求
const { Client } = require('ssh2');
const conn = new Client();
conn.on('ready', () => {
console.log('Client :: ready');
conn.forwardOut('192.168.100.102', 8000, '127.0.0.1', 80, (err, stream) => {
if (err) throw err;
stream.on('close', () => {
console.log('TCP :: CLOSED');
conn.end();
}).on('data', (data) => {
console.log('TCP :: DATA: ' + data);
}).end([
'HEAD / HTTP/1.1',
'User-Agent: curl/7.27.0',
'Host: 127.0.0.1',
'Accept: */*',
'Connection: close',
'',
''
].join('\r\n'));
});
}).connect({
host: '192.168.100.100',
port: 22,
username: 'frylock',
password: 'nodejsrules'
});
// 示例输出:
// Client :: ready
// TCP :: DATA: HTTP/1.1 200 OK
// Date: Thu, 15 Nov 2012 13:52:58 GMT
// Server: Apache/2.2.22 (Ubuntu)
// X-Powered-By: PHP/5.4.6-1ubuntu1
// Last-Modified: Thu, 01 Jan 1970 00:00:00 GMT
// Content-Encoding: gzip
// Vary: Accept-Encoding
// Connection: close
// Content-Type: text/html; charset=UTF-8
//
//
// TCP :: CLOSED
将本地连接转发到服务器端口8000
const { Client } = require('ssh2');
const conn = new Client();
conn.on('ready', () => {
console.log('Client :: ready');
conn.forwardIn('127.0.0.1', 8000, (err) => {
if (err) throw err;
console.log('Listening for connections on server on port 8000!');
});
}).on('tcp connection', (info, accept, reject) => {
console.log('TCP :: INCOMING CONNECTION:');
console.dir(info);
accept().on('close', () => {
console.log('TCP :: CLOSED');
}).on('data', (data) => {
console.log('TCP :: DATA: ' + data);
}).end([
'HTTP/1.1 404 Not Found',
'Date: Thu, 15 Nov 2012 02:07:58 GMT',
'Server: ForwardedConnection',
'Content-Length: 0',
'Connection: close',
'',
''
].join('\r\n'));
}).connect({
host: '192.168.100.100',
port: 22,
username: 'frylock',
password: 'nodejsrules'
});
// 示例输出:
// Client :: ready
// Listening for connections on server on port 8000!
// (.... 然后从服务器上的另一个终端:`curl -I http://127.0.0.1:8000`)
// TCP :: INCOMING CONNECTION: { destIP: '127.0.0.1',
// destPort: 8000,
// srcIP: '127.0.0.1',
// srcPort: 41969 }
// TCP DATA: HEAD / HTTP/1.1
// User-Agent: curl/7.27.0
// Host: 127.0.0.1:8000
// Accept: */*
//
//
// TCP :: CLOSED
通过SFTP获取目录列表
const { Client } = require('ssh2');
const conn = new Client();
conn.on('ready', () => {
console.log('Client :: ready');
conn.sftp((err, sftp) => {
if (err) throw err;
sftp.readdir('foo', (err, list) => {
if (err) throw err;
console.dir(list);
conn.end();
});
});
}).connect({
host: '192.168.100.100',
port: 22,
username: 'frylock',
password: 'nodejsrules'
});
// 示例输出:
// Client :: ready
// [ { filename: 'test.txt',
// longname: '-rw-r--r-- 1 frylock frylock 12 Nov 18 11:05 test.txt',
// attrs:
// { size: 12,
// uid: 1000,
// gid: 1000,
// mode: 33188,
// atime: 1353254750,
// mtime: 1353254744 } },
// { filename: 'mydir',
// longname: 'drwxr-xr-x 2 frylock frylock 4096 Nov 18 15:03 mydir',
// attrs:
// { size: 1048576,
// uid: 1000,
// gid: 1000,
// mode: 16877,
// atime: 1353269007,
// mtime: 1353269007 } } ]
连接跳转
const { Client } = require('ssh2');
const conn1 = new Client();
const conn2 = new Client();
// 通过192.168.1.1检查10.1.1.40的uptime
conn1.on('ready', () => {
console.log('FIRST :: connection ready');
// 另外,你可以使用netcat或socat与exec()一起使用,而不是forwardOut(),
// 这取决于服务器允许什么
conn1.forwardOut('127.0.0.1', 12345, '10.1.1.40', 22, (err, stream) => {
if (err) {
console.log('FIRST :: forwardOut error: ' + err);
return conn1.end();
}
conn2.connect({
sock: stream,
username: 'user2',
password: 'password2',
});
});
}).connect({
host: '192.168.1.1',
username: 'user1',
password: 'password1',
});
conn2.on('ready', () => {
// 这个连接是到10.1.1.40的
console.log('SECOND :: connection ready');
conn2.exec('uptime', (err, stream) => {
if (err) {
console.log('SECOND :: exec error: ' + err);
return conn1.end();
}
stream.on('close', () => {
conn1.end(); // 关闭父连接(以及此连接)
}).on('data', (data) => {
console.log(data.toString());
});
});
});
转发远程X11连接
const { Socket } = require('net');
const { Client } = require('ssh2');
const conn = new Client();
conn.on('x11', (info, accept, reject) => {
const xserversock = new net.Socket();
xserversock.on('connect', () => {
const xclientsock = accept();
xclientsock.pipe(xserversock).pipe(xclientsock);
});
// 连接到localhost:0.0
xserversock.connect(6000, 'localhost');
});
conn.on('ready', () => {
conn.exec('xeyes', { x11: true }, (err, stream) => {
if (err) throw err;
let code = 0;
stream.on('close', () => {
if (code !== 0)
console.log('Do you have X11 forwarding enabled on your SSH server?');
conn.end();
}).on('exit', (exitcode) => {
code = exitcode;
});
});
}).connect({
host: '192.168.1.1',
username: 'foo',
password: 'bar'
});
使用SOCKSv5代理动态(1:1)端口转发(使用socksv5)
const socks = require('socksv5');
const { Client } = require('ssh2');
const sshConfig = {
host: '192.168.100.1',
port: 22,
username: 'nodejs',
password: 'rules'
};
socks.createServer((info, accept, deny) => {
// 注意:你可以只使用一个ssh2客户端连接来处理所有转发,但是
// 如果你在任何给定时间打开太多转发,你可能会碰到服务器强制的限制
const conn = new Client();
conn.on('ready', () => {
conn.forwardOut(info.srcAddr,
info.srcPort,
info.dstAddr,
info.dstPort,
(err, stream) => {
if (err) {
conn.end();
return deny();
}
const clientSocket = accept(true);
if (clientSocket) {
stream.pipe(clientSocket).pipe(stream).on('close', () => {
conn.end();
});
} else {
conn.end();
}
});
}).on('error', (err) => {
deny();
}).connect(sshConfig);
}).listen(1080, 'localhost', () => {
console.log('SOCKSv5 proxy server started on port 1080');
}).useAuth(socks.auth.None());
// 测试使用cURL:
// curl -i --socks5 localhost:1080 google.com
使用自定义http(s).Agent轻松进行HTTP(S)连接
const http = require('http');
const { Client, HTTPAgent, HTTPSAgent } = require('ssh2');
const sshConfig = {
host: '192.168.100.1',
port: 22,
username: 'nodejs',
password: 'rules'
};
// 对于HTTPS请求,使用`HTTPSAgent`代替
const agent = new HTTPAgent(sshConfig);
http.get({
host: '192.168.200.1',
agent,
headers: { Connection: 'close' }
}, (res) => {
console.log(res.statusCode);
console.dir(res.headers);
res.resume();
});
调用任意子系统
const { Client } = require('ssh2');
const xmlhello = `
<?xml version="1.0" encoding="UTF-8"?>
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<capabilities>
<capability>urn:ietf:params:netconf:base:1.0</capability>
</capabilities>
</hello>]]>]]>`;
const conn = new Client();
conn.on('ready', () => {
console.log('Client :: ready');
conn.subsys('netconf', (err, stream) => {
if (err) throw err;
stream.on('data', (data) => {
console.log(data);
}).write(xmlhello);
});
}).connect({
host: '1.2.3.4',
port: 22,
username: 'blargh',
password: 'honk'
});
服务器示例
密码和公钥认证以及非交互式(exec)命令执行
const { timingSafeEqual } = require('crypto');
const { readFileSync } = require('fs');
const { inspect } = require('util');
const { utils: { parseKey }, Server } = require('ssh2');
const allowedUser = Buffer.from('foo');
const allowedPassword = Buffer.from('bar');
const allowedPubKey = parseKey(readFileSync('foo.pub'));
function checkValue(input, allowed) {
const autoReject = (input.length !== allowed.length);
if (autoReject) {
// 防止泄露长度信息,当长度与我们期望的不匹配时,总是使用
// 与输入相同的比较...
allowed = input;
}
const isMatch = timingSafeEqual(input, allowed);
return (!autoReject && isMatch);
}
new Server({
hostKeys: [readFileSync('host.key')]
}, (client) => {
console.log('Client connected!');
client.on('authentication', (ctx) => {
let allowed = true;
if (!checkValue(Buffer.from(ctx.username), allowedUser))
allowed = false;
switch (ctx.method) {
case 'password':
if (!checkValue(Buffer.from(ctx.password), allowedPassword))
return ctx.reject();
break;
case 'publickey':
if (ctx.key.algo !== allowedPubKey.type
|| !checkValue(ctx.key.data, allowedPubKey.getPublicSSH())
|| (ctx.signature && allowedPubKey.verify(ctx.blob, ctx.signature, ctx.hashAlgo) !== true)) {
return ctx.reject();
}
break;
default:
return ctx.reject();
}
if (allowed)
ctx.accept();
else
ctx.reject();
}).on('ready', () => {
console.log('Client authenticated!');
client.on('session', (accept, reject) => {
const session = accept();
session.once('exec', (accept, reject, info) => {
console.log('Client wants to execute: ' + inspect(info.command));
const stream = accept();
stream.stderr.write('Oh no, the dreaded errors!\n');
stream.write('Just kidding about the errors!\n');
stream.exit(0);
stream.end();
});
});
}).on('close', () => {
console.log('Client disconnected');
});
}).listen(0, '127.0.0.1', function() {
console.log('Listening on port ' + this.address().port);
});
仅限SFTP服务器
const { timingSafeEqual } = require('crypto');
const { readFileSync } = require('fs');
const { inspect } = require('util');
const {
Server,
sftp: {
OPEN_MODE,
STATUS_CODE,
},
} = require('ssh2');
const allowedUser = Buffer.from('foo');
const allowedPassword = Buffer.from('bar');
function checkValue(input, allowed) {
const autoReject = (input.length !== allowed.length);
if (autoReject) {
// 防止泄露长度信息,当长度与我们期望的不匹配时,总是使用
// 与输入相同的比较...
allowed = input;
}
const isMatch = timingSafeEqual(input, allowed);
return (!autoReject && isMatch);
}
// 这个简单的SFTP服务器实现了文件上传,其中内容被忽略...
new ssh2.Server({
hostKeys: [readFileSync('host.key')]
}, (client) => {
console.log('Client connected!');
client.on('authentication', (ctx) => {
let allowed = true;
if (!checkValue(Buffer.from(ctx.username), allowedUser))
allowed = false;
switch (ctx.method) {
case 'password':
if (!checkValue(Buffer.from(ctx.password), allowedPassword))
return ctx.reject();
break;
default:
return ctx.reject();
}
if (allowed)
ctx.accept();
else
ctx.reject();
}).on('ready', () => {
console.log('Client authenticated!');
client.on('session', (accept, reject) => {
const session = accept();
session.on('sftp', (accept, reject) => {
console.log('Client SFTP session');
const openFiles = new Map();
let handleCount = 0;
const sftp = accept();
sftp.on('OPEN', (reqid, filename, flags, attrs) => {
// 只允许打开/tmp/foo.txt进行写入
if (filename !== '/tmp/foo.txt' || !(flags & OPEN_MODE.WRITE))
return sftp.status(reqid, STATUS_CODE.FAILURE);
// 创建一个假句柄返回给客户端,这可能是一个真实的文件描述符,例如如果实际在磁盘上打开文件
const handle = Buffer.alloc(4);
openFiles.set(handleCount, true);
handle.writeUInt32BE(handleCount++, 0);
console.log('Opening file for write')
sftp.handle(reqid, handle);
}).on('WRITE', (reqid, handle, offset, data) => {
if (handle.length !== 4
|| !openFiles.has(handle.readUInt32BE(0))) {
return sftp.status(reqid, STATUS_CODE.FAILURE);
}
// 伪造写操作
sftp.status(reqid, STATUS_CODE.OK);
console.log('Write to file at offset ${offset}: ${inspect(data)}');
}).on('CLOSE', (reqid, handle) => {
let fnum;
if (handle.length !== 4
|| !openFiles.has(fnum = handle.readUInt32BE(0))) {
return sftp.status(reqid, STATUS_CODE.FAILURE);
}
console.log('Closing file');
openFiles.delete(fnum);
sftp.status(reqid, STATUS_CODE.OK);
});
});
});
}).on('close', () => {
console.log('Client disconnected');
});
}).listen(0, '127.0.0.1', function() {
console.log('Listening on port ' + this.address().port);
});
其他示例
生成一个SSH密钥
const { utils: { generateKeyPair, generateKeyPairSync } } = require('ssh2');
// 同步生成未加密的ED25519 SSH密钥
let keys = generateKeyPairSync('ed25519');
// ... 使用 `keys.public` 和 `keys.private`
// 同步生成带有注释的未加密ECDSA SSH密钥
keys = generateKeyPairSync('ecdsa', { bits: 256, comment: 'node.js rules!' });
// ... 使用 `keys.public` 和 `keys.private`
// 异步生成加密的RSA SSH密钥
generateKeyPair(
'rsa',
{ bits: 2048, passphrase: 'foobarbaz', cipher: 'aes256-cbc' },
(err, keys) => {
if (err) throw err;
// ... 使用 `keys.public` 和 `keys.private`
}
);
你可以在本仓库的examples目录中找到更多示例。
API
require('ssh2').Client 是 Client 构造函数。
require('ssh2').Server 是 Server 构造函数。
require('ssh2').utils 是一个包含一些实用工具的对象。
require('ssh2').HTTPAgent 是一个 http.Agent 构造函数。
require('ssh2').HTTPSAgent 是一个 https.Agent 构造函数。其API与 HTTPAgent 相同,除了它是用于HTTPS连接。
代理相关
require('ssh2').AgentProtocol 是一个Duplex流类,有助于在OpenSSH代理协议上进行通信。
require('ssh2').BaseAgent 是一个基类,用于创建自定义认证代理。
require('ssh2').createAgent 是一个帮助函数,用于创建一个新的代理实例,使用与 Client 的 agent 配置选项相同的逻辑:如果平台是Windows并且值是 "pageant",则创建一个 PageantAgent,否则如果不是Windows管道的路径,则创建一个 CygwinAgent。在所有其他情况下,它创建一个 OpenSSHAgent。
require('ssh2').CygwinAgent 是一个代理类实现,与Cygwin环境中的代理进行通信。
require('ssh2').OpenSSHAgent 是一个代理类实现,通过UNIX套接字与OpenSSH代理进行通信。
require('ssh2').PageantAgent 是一个代理类实现,与Pageant代理进程进行通信。
客户端
客户端事件
-
banner(< string >message, < string >language) - 服务器在连接时发送的通知。
-
change password(< string >prompt, < function >done) - 如果使用基于密码的用户认证,服务器已请求更改用户的密码。调用
done并提供新密码。 -
close() - 套接字已关闭。
-
end() - 套接字已断开连接。
-
error(< Error >err) - 发生了错误。一个 'level' 属性表明 'client-socket' 用于套接字级错误,'client-ssh' 用于SSH断开连接消息。在 'client-ssh' 消息的情况下,可能有一个 'description' 属性提供了更多的细节。
-
handshake(< object >negotiated) - 当握手完成(初始或重连)时发出。
negotiated包含握手的协商细节,形式如下:
// 在这种特殊情况下,`mac` 是空的,因为没有单独的MAC
// 因为集成到AES在GCM模式中
{ kex: 'ecdh-sha2-nistp256',
srvHostKey: 'rsa-sha2-512',
cs: { // 客户端到服务器算法
cipher: 'aes128-gcm',
mac: '',
compress: 'none',
lang: ''
},
sc: { // 服务器到客户端算法
cipher: 'aes128-gcm',
mac: '',
compress: 'none',
lang: ''
}
}
-
hostkeys(< array >keys) - 当服务器宣布其可用的主机密钥时发出。
keys是解析后的(使用parseKey())主机公钥列表。 -
keyboard-interactive(< string >name, < string >instructions, < string >instructionsLang, < array >prompts, < function >finish) - 服务器请求对给定的
prompts进行回复,用于键盘交互式用户认证。name通常是用作窗口标题(对于GUI应用程序)。prompts是一个包含{ prompt: 'Password: ', echo: false }风格对象的数组(这里echo表示用户输入是否应该显示在屏幕上)。所有提示的答案必须作为字符串数组提供给finish,当你准备继续时。注意:服务器可能会回来并询问更多的问题。 -
ready() - 认证成功。
-
rekey() - 当重连操作完成(客户端或服务器发起)时发出。
-
tcp connection(< object >details, < function >accept, < function >reject) - 请求一个传入的转发TCP连接。调用
accept接受连接并返回一个Channel对象。调用reject拒绝连接,不需要进一步操作。details包含:-
destIP - string - 连接在服务器上接收的远程IP(在早期调用
forwardIn()时给出)。 -
destPort - integer - 连接在服务器上接收的远程端口(在早期调用
forwardIn()时给出)。 -
srcIP - string - 连接的原始IP。
-
srcPort - integer - 连接的原始端口。
-
-
unix connection(< object >details, < function >accept, < function >reject) - 请求一个传入的转发UNIX套接字连接。调用
accept接受连接并返回一个Channel对象。调用reject拒绝连接,不需要进一步操作。details包含:- socketPath - string - 连接的原始UNIX套接字路径。
-
x11(< object >details, < function >accept, < function >reject) - 请求一个传入的X11连接。调用
accept接受连接并返回一个Channel对象。调用reject拒绝连接,不需要进一步操作。details包含:-
srcIP - string - 连接的原始IP。
-
srcPort - integer - 连接的原始端口。
-
客户端方法
-
(constructor)() - 创建并返回一个新的客户端实例。
-
connect(< object >config) - 尝试使用
config中给出的信息连接到服务器:-
agent - string - ssh-agent的UNIX套接字路径,用于ssh-agent基础用户认证。Windows用户:设置为 'pageant' 用于与Pageant或(实际)路径到cygwin "UNIX套接字" 进行认证。 默认值:(无)
-
agentForward - boolean - 设置为
true以使用OpenSSH代理转发(auth-agent@openssh.com)连接的生命周期。也必须设置agent以使用此功能。 默认值:false -
algorithms - object - 此选项允许你明确覆盖用于连接的默认传输层算法。每个类别的值必须是有效算法名称的数组,最理想的放在第一位。有关有效和默认算法名称的列表,请参阅所使用的
ssh2版本的文档。有效键:-
cipher - mixed - 密码。
- 默认列表(从最理想到最不理想的顺序):
chacha20-poly1305@openssh.com(优先级取决于CPU和/或可选绑定的可用性)aes128-gcmaes128-gcm@openssh.comaes256-gcmaes256-gcm@openssh.comaes128-ctraes192-ctraes256-ctr
- 其他支持的名称:
3des-cbcaes256-cbcaes192-cbcaes128-cbcarcfour256arcfour128arcfourblowfish-cbccast128-cbc
- 默认列表(从最理想到最不理想的顺序):
-
compress - mixed - 压缩算法。
- 默认列表(从最理想到最不理想的顺序):
nonezlib@openssh.comzlib
- 其他支持的名称:
- 默认列表(从最理想到最不理想的顺序):
-
hmac - mixed - (H)MAC算法。 - 默认列表(从最理想到最不理想的顺序):
hmac-sha2-256-etm@openssh.comhmac-sha2-512-etm@openssh.comhmac-sha1-etm@openssh.comhmac-sha2-256hmac-sha2-512hmac-sha1- 其他支持的名称:
hmac-md5hmac-sha2-256-96hmac-sha2-512-96hmac-ripemd160hmac-sha1-96hmac-md5-96
-
kex - mixed - 密钥交换算法。
- 默认列表(从最理想到最不理想的顺序):
curve25519-sha256(node v14.0.0+)curve25519-sha256@libssh.org(node v14.0.0+)ecdh-sha2-nistp256ecdh-sha2-nistp384ecdh-sha2-nistp521diffie-hellman-group-exchange-sha256diffie-hellman-group14-sha256diffie-hellman-group15-sha512diffie-hellman-group16-sha512diffie-hellman-group17-sha512diffie-hellman-group18-sha512
- 其他支持的名称:
diffie-hellman-group-exchange-sha1diffie-hellman-group14-sha1diffie-hellman-group1-sha1
- 默认列表(从最理想到最不理想的顺序):
-
serverHostKey - mixed - 服务器主机密钥格式。
- 默认列表(从最理想到最不理想的顺序):
ssh-ed25519(node v12.0.0+)ecdsa-sha2-nistp256ecdsa-sha2-nistp384ecdsa-sha2-nistp521rsa-sha2-512rsa-sha2-256ssh-rsa
- 其他支持的名称:
ssh-dss
- 默认列表(从最理想到最不理想的顺序):
-
-
authHandler - mixed - 必须是如下所述的对象数组,包含有效认证方法名称的字符串数组(用户名和凭据从传递给
connect()的对象中获取),或者是一个函数,参数为(methodsLeft, partialSuccess, callback)其中methodsLeft和partialSuccess分别是数组和布尔值。返回或调用callback()与下一个要尝试的认证方法的名称或包含方法名称和特定方法详细信息的对象(返回/传递false表示没有更多的方法要尝试)。有效方法名称为:'none', 'password', 'publickey', 'agent', 'keyboard-interactive', 'hostbased'。 默认值: 函数,按照以下方法顺序:None -> Password -> Private Key -> Agent(-> 如果tryKeyboard是true,则为 keyboard-interactive)-> Hostbased- 当返回或调用
callback()与对象时,它可以采取以下形式之一:
- 当返回或调用
-
{
type: 'none',
username: 'foo',
}
{
type: 'password'
username: 'foo',
password: 'bar',
}
{
type: 'publickey'
username: 'foo',
// 可以是字符串、Buffer或包含私钥的解析密钥
key: ...,
// `passphrase` 仅在加密密钥所需的
passphrase: ...,
}
{
type: 'hostbased'
username: 'foo',
localHostname: 'baz',
localUsername: 'quux',
// 可以是字符串、Buffer或包含私钥的解析密钥
key: ...,
// `passphrase` 仅在加密密钥所需的
passphrase: ...,
}
{
type: 'agent'
username: 'foo',
// 可以是字符串,就像 `agent` 连接配置选项一样,也可以是自定义代理
// 对象/实例,继承并实现 `BaseAgent`
agent: ...,
}
{
type: 'keyboard-interactive'
username: 'foo',
// 这与 'keyboard-interactive' 客户端事件处理程序的工作方式完全相同
prompt: (name, instructions, instructionsLang, prompts, finish) => {
// ...
},
}
-
debug - function - 设置此函数以接收单个字符串参数,获取详细(本地)调试信息。 默认值:(无)
-
forceIPv4 - boolean - 仅通过解析的IPv4地址连接到
host。 默认值:false -
forceIPv6 - boolean - 仅通过解析的IPv6地址连接到
host。 默认值:false -
host - string - 服务器的主机名或IP地址。 默认值:
'localhost' -
hostHash - string - 任何node支持的有效哈希算法。使用此算法对主机的密钥进行哈希处理,并将哈希值作为十六进制字符串传递给 hostVerifier 函数。 默认值:(无)
-
hostVerifier - function - 具有参数
(key[, callback])的函数,用于验证主机密钥,其中key如果设置了hostHash,则是密钥哈希的十六进制字符串,否则是原始主机密钥的 Buffer 形式。使用utils.parseKey()获取主机密钥类型。返回true继续握手或返回false拒绝并断开连接,或者如果需要异步验证,则调用callback()传递true或false。 默认值:(如果未设置hostVerifier,则自动接受) -
keepaliveCountMax - integer - 可以发送多少连续的、未回答的SSH级keepalive数据包到服务器之前断开连接(类似于OpenSSH的ServerAliveCountMax配置选项)。 默认值:
3 -
keepaliveInterval - integer - 向服务器发送SSH级keepalive数据包的频率(以毫秒为单位)(类似于OpenSSH的ServerAliveInterval配置选项)。设置为0以禁用。 默认值:
0 -
localAddress - string - 用于连接到服务器的网络接口的IP地址。 默认值:(无 - 由操作系统确定)
-
localHostname - string - 与 localUsername 和 privateKey 一起设置,用于基于主机的用户认证。 默认值:(无)
-
localPort - string - 用于连接的本地端口号。 默认值:(无 - 由操作系统确定)
-
localUsername - string - 与 localHostname 和 privateKey 一起设置,用于基于主机的用户认证。 默认值:(无)
-
passphrase - string - 对于加密的
privateKey,这是用于解密它的密码短语。 默认值:(无) -
password - string - 基于密码的用户认证的密码。 默认值:(无)
-
port - integer - 服务器的端口号。 默认值:
22 -
privateKey - mixed - 包含私钥的 Buffer 或 string,用于基于密钥或基于主机的用户认证(OpenSSH格式)。 默认值:(无)
-
readyTimeout - integer - 等待SSH握手完成的时间(以毫秒为单位)。 默认值:
20000 -
sock - ReadableStream - 一个 ReadableStream 用于与服务器通信,而不是创建和使用新的TCP连接(适用于连接跳转)。
-
strictVendor - boolean - 在发送特定于供应商的请求等之前执行严格的服务器供应商检查(例如检查OpenSSH服务器时使用
openssh_noMoreSessions())。 默认值:true -
tryKeyboard - boolean - 如果主要用户认证方法失败,则尝试键盘交互式用户认证。如果设置为
true,则需要处理keyboard-interactive事件。 默认值:false -
username - string - 用户认证的用户名。 默认值:(无)
-
end() - 断开套接字连接。
-
exec(< string >command[, < object >options], < function >callback) - 在服务器上执行
command。callback有2个参数:< Error >err, < Channel >stream。有效的options属性是:-
env - object - 用于命令执行的环境。
-
pty - mixed - 设置为
true以分配一个带有默认设置的伪终端,或者是一个包含特定伪终端设置的对象(见 'Pseudo-TTY settings')。设置伪终端对于处理期望从实际终端接收输入的远程进程(例如sudo的密码提示)很有用。 -
x11 - mixed - 设置为
true以使用默认值,设置为数字以指定特定的屏幕号,或一个对象,具有以下有效属性:-
cookie - mixed - 认证cookie。可以是十六进制 string 或包含原始cookie值的 Buffer(将被转换为十六进制字符串)。 默认值:(随机16字节值)
-
protocol - string - 认证协议名称。 默认值:
'MIT-MAGIC-COOKIE-1' -
screen - number - 使用的屏幕号 默认值:
0 -
single - boolean - 只允许一个连接? 默认值:
false
-
-
-
forwardIn(< string >remoteAddr, < integer >remotePort, < function >callback) - 绑定到服务器上的
remoteAddr的remotePort并转发传入的TCP连接。callback有2个参数:< Error >err, < integer >port(如果remotePort为0,则port是分配的端口号)。以下是remoteAddr的一些特殊值及其关联的绑定行为:-
'' - 接受所有支持的协议族的连接。
-
'0.0.0.0' - 监听所有IPv4地址。
-
'::' - 监听所有IPv6地址。
-
'localhost' - 仅在环回地址上监听所有支持的协议族。
-
'127.0.0.1' 和 '::1' - 分别在IPv4和IPv6的环回接口上监听。
-
-
forwardOut(< string >srcIP, < integer >srcPort, < string >dstIP, < integer >dstPort, < function >callback) - 打开一个连接,源地址和端口为
srcIP和srcPort,远程目标地址和端口为dstIP和dstPort。callback有2个参数:< Error >err, < Channel >stream。 -
openssh_forwardInStreamLocal(< string >socketPath, < function >callback) - OpenSSH扩展,绑定到服务器上的
socketPath的UNIX域套接字,并转发传入的连接。callback有1个参数:< Error >err。 -
openssh_forwardOutStreamLocal(< string >socketPath, < function >callback) - OpenSSH扩展,打开到服务器上的
socketPath的UNIX域套接字的连接。callback有2个参数:< Error >err, < Channel >stream。 -
openssh_noMoreSessions(< function >callback) - OpenSSH扩展,发送请求以拒绝此连接的任何新会话(例如exec、shell、sftp、subsys)。
callback有1个参数:< Error >err。 -
openssh_unforwardInStreamLocal(< string >socketPath, < function >callback) - OpenSSH扩展,从服务器上的
socketPath解除绑定UNIX域套接字,并停止转发传入的连接。callback有1个参数:< Error >err。 -
rekey([< function >callback]) - 初始化与服务器的重连。如果提供
callback,则将其添加为rekey事件的一次性处理程序。 -
setNoDelay([< boolean >noDelay]) - 调用底层套接字的
setNoDelay()。禁用Nagle算法可以提高延迟,以换取较低的吞吐量。 -
sftp(< function >callback) - 开始SFTP会话。
callback有2个参数:< Error >err, < SFTP >sftp。有关sftp上可用的方法,请参阅SFTP客户端文档。 -
shell([[< mixed >window,] < object >options]< function >callback) - 在服务器上开始一个交互式shell会话,可选的
window对象包含伪终端设置(见 'Pseudo-TTY settings')。如果window === false,则不分配伪终端。options支持exec()中描述的x11和env选项。callback有2个参数:< Error >err, < Channel >stream。 -
subsys(< string >subsystem, < function >callback) - 在服务器上调用
subsystem。callback有2个参数:< Error >err, < Channel >stream。 -
unforwardIn(< string >remoteAddr, < integer >remotePort, < function >callback) - 从服务器的
remoteAddr的remotePort解除绑定并停止转发传入的TCP连接。在callback被调用之前,可能仍然有更多连接进来。callback有1个参数:< Error >err。
服务器
服务器事件
- connection(< Connection >client, < object >info) - 有一个新的客户端连接。
info包含以下属性:-
family - string - 连接的
remoteFamily。 -
header - object - 关于客户端头部的信息:
-
identRaw - string - 原始客户端识别字符串。
-
versions - object - 各种版本信息:
-
protocol - string - SSH协议版本(始终为
1.99或2.0)。 -
software - string - 客户端的软件名称和版本。
-
-
comments - string - 软件名称/版本后的任何文本。
-
-
示例:识别字符串 SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 将被解析为:
{
identRaw: 'SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2',
versions: {
protocol: '2.0',
software: 'OpenSSH_6.6.1p1'
},
comments: 'Ubuntu-2ubuntu2'
}
-
ip - string - 连接的
remoteAddress。 -
port - integer - 连接的
remotePort。
服务器方法
-
(constructor)(< object >config[, < function >connectionListener]) - 创建并返回一个新的服务器实例。服务器实例还具有与
net.Server相同的方法/属性/事件。如果提供了connectionListener,则将其添加为connection监听器。有效的config属性:-
algorithms - object - 此选项允许你明确覆盖用于传入客户端连接的默认传输层算法。每个类别的值必须是一个有效算法的数组。算法在数组中的顺序很重要,最有利的放在第一位。有关有效和默认算法名称的列表,请参阅所使用的
ssh2版本的文档。有效键:-
cipher - array - 密码。
-
compress - array - 压缩算法。
-
hmac - array - (H)MAC算法。
-
kex - array - 密钥交换算法。
-
serverHostKey - array - 服务器主机密钥格式。
-
-
banner - string - 向客户端发送的消息,一次,在认证开始前。默认值:(无)
-
debug - function - 设置此函数以接收单个字符串参数,获取详细(本地)调试信息。 默认值:(无)
-
greeting - string - 向客户端发送的消息,连接后立即,在握手开始前。注意: 大多数客户端通常忽略此消息。 默认值:(无)
-
highWaterMark - integer - 这是要用于解析流的
highWaterMark。 默认值:32 * 1024 -
hostKeys - array - 包含主机私钥的缓冲区/字符串的数组,或者格式为
{ key: <Buffer/string>, passphrase: <string> }的对象,用于加密私钥。(必需) 默认值:(无) -
ident - string - 自定义服务器软件名称/版本标识符。 默认值:
'ssh2js' + moduleVersion + 'srv'
-
-
injectSocket(< DuplexStream >socket) - 注入双向流,就好像它是TCP套接字连接。此外,
socket应包括net.Socket类似的属性,以确保最佳兼容性(例如socket.remoteAddress,socket.remotePort,socket.remoteFamily)。
连接事件
-
authentication(< AuthContext >ctx) - 客户端请求认证。
ctx.username包含客户端用户名,ctx.method包含请求的认证方法,ctx.accept()和ctx.reject([< Array >authMethodsLeft[, < Boolean >isPartialSuccess]])用于接受或拒绝认证请求。如果客户端中止认证请求,则发出'abort'事件。其他属性/方法可用在ctx上,取决于客户端请求的认证ctx.method:-
hostbased:-
blob - Buffer - 这包含传递给(连同签名)
key.verify()的数据,其中key是使用parseKey()解析的公钥。 -
key - object - 包含客户端发送的公钥信息:
-
algo - string - 密钥算法的名称(例如
ssh-rsa)。 -
data - Buffer - 实际的密钥数据。
-
-
localHostname - string - 客户端提供的本地主机名。
-
localUsername - string - 客户端提供的本地用户名。
-
signature - Buffer - 这包含一个签名,传递给(连同blob)
key.verify(),其中key是使用parseKey()解析的公钥。 -
hashAlgo - mixed - 这是要么
undefined,要么包含用于验证期间(传递给key.verify())的显式哈希算法的 string。
-
-
keyboard-interactive:-
prompt(< array >prompts[, < string >title[, < string >instructions]], < function >callback) - 向客户端发送提示。
prompts是一个包含{ prompt: 'Prompt text', echo: true }对象的数组(prompt是提示文本,echo表示客户端对提示的响应是否应该显示在他们的显示器上)。callback被调用时传入(responses),其中responses是与prompts匹配的字符串响应数组。 -
submethods - array - 客户端发送的首选认证“子方法”列表。这可能用于确定要向客户端发送什么(如果有的话)提示。
-
-
password:-
password - string - 这是客户端发送的密码。
-
requestChange(< string >prompt, < function >callback) - 向客户端发送密码更改请求。
callback被调用时传入(newPassword),其中newPassword是客户端提供的 newPassword。你可以在接受、拒绝或在callback被调用后提示另一个密码更改。
-
-
publickey:-
blob - mixed - 如果值为
undefined,则客户端仅检查key的有效性。如果值为 Buffer,则这包含传递给(连同签名)key.verify()的数据,其中key是使用parseKey()解析的公钥。 -
key - object - 包含客户端发送的公钥信息:
-
algo - string - 密钥算法的名称(例如
ssh-rsa)。 -
data - Buffer - 实际的密钥数据。
-
-
signature - mixed - 如果值为
undefined,则客户端仅检查key的有效性。如果值为 Buffer,则这包含一个签名,传递给(连同blob)key.verify(),其中key是使用parseKey()解析的公钥。 -
hashAlgo - mixed - 这是要么
undefined,要么包含用于验证期间(传递给key.verify())的显式哈希算法的 string。
-
-
-
close() - 客户端套接字已关闭。
-
end() - 客户端套接字已断开连接。
-
error(< Error >err) - 发生了错误。
-
handshake(< object >negotiated) - 当握手完成(初始或重连)时发出。
negotiated包含握手的协商细节,形式如下:
// 在这种特殊情况下,`mac` 是空的,因为没有单独的MAC
// 因为集成到AES在GCM模式中
{ kex: 'ecdh-sha2-nistp256',
srvHostKey: 'rsa-sha2-512',
cs: { // 客户端到服务器算法
cipher: 'aes128-gcm',
mac: '',
compress: 'none',
lang: ''
},
sc: { // 服务器到客户端算法
cipher: 'aes128-gcm',
mac: '',
compress: 'none',
lang: ''
}
}
-
openssh.streamlocal(< function >accept, < function >reject, < object >info) - 当客户端请求连接到UNIX域套接字时发出。
accept()返回一个新的 Channel 实例,表示连接。info包含:- socketPath - string - 传出连接的目的套接字路径。
-
ready() - 当客户端已成功认证时发出。
-
rekey() - 当重连操作完成(客户端或服务器发起)时发出。
-
request(< mixed >accept, < mixed >reject, < string >name, < object >info) - 当客户端发送
name的全局请求时发出(例如tcpip-forward或cancel-tcpip-forward)。如果客户端请求响应,accept和reject是函数。如果bindPort === 0,则你应该将选择的端口传递给accept(),以便客户端将知道绑定了哪个端口。info包含有关请求的额外详细信息:cancel-tcpip-forward和tcpip-forward:-
bindAddr - string - 要开始/停止绑定的IP地址。
-
bindPort - integer - 要开始/停止绑定的端口。
-
cancel-streamlocal-forward@openssh.com和streamlocal-forward@openssh.com:- socketPath - string - 要开始/停止绑定的套接字路径。
-
session(< function >accept, < function >reject) - 当客户端请求新会话时发出。会话用于开始交互式shell、执行命令、请求X11转发等。
accept()返回一个新的 Session 实例。 -
tcpip(< function >accept, < function >reject, < object >info) - 当客户端请求出站(TCP)连接时发出。
accept()返回一个新的 Channel 实例,表示连接。info包含:-
destIP - string - 传出连接的目的IP地址。
-
destPort - string - 传出连接的目的端口。
-
srcIP - string - 传出连接的源IP地址。
-
srcPort - string - 传出连接的源端口。
-
连接方法
-
end() - 关闭客户端连接。
-
forwardOut(< string >boundAddr, < integer >boundPort, < string >remoteAddr, < integer >remotePort, < function >callback) - 向客户端发出传入TCP连接在
boundAddr的boundPort上的通知,来自remoteAddr的remotePort。callback有2个参数:< Error >err, < Channel >stream。 -
openssh_forwardOutStreamLocal(< string >socketPath, < function >callback) - 向客户端发出传入UNIX域套接字连接在
socketPath上的通知。callback有2个参数:< Error >err, < Channel >stream。 -
rekey([< function >callback]) - 初始化与客户端的重连。如果
callback被提供,则将其添加为rekey事件的一次性处理程序。 -
setNoDelay([< boolean >noDelay]) - Connection - 调用底层套接字的
setNoDelay()。禁用Nagle算法可以提高延迟,以换取较低的吞吐量。 -
x11(< string >originAddr, < integer >originPort, < function >callback) - 向客户端发出来自
originAddr的传入X11客户端连接的通知,来自originPort。callback有2个参数:< Error >err, < Channel >stream。
会话事件
-
auth-agent(< mixed >accept, < mixed >reject) - 客户端请求将传入的ssh-agent请求转发给他们。
accept和reject是函数,如果客户端请求响应。 -
close() - 会话已关闭。
-
env(< mixed >accept, < mixed >reject, < object >info) - 客户端请求为此会话设置环境变量。
accept和reject是函数,如果客户端请求响应。info具有以下属性:-
key - string - 环境变量的名称。
-
value - string - 环境变量的值。
-
-
exec(< mixed >accept, < mixed >reject, < object >info) - 客户端请求执行命令字符串。
accept和reject是函数,如果客户端请求响应。accept()返回一个 Channel 用于命令执行。info具有以下属性:- command - string - 要执行的命令行。
-
pty(< mixed >accept, < mixed >reject, < object >info) - 客户端请求为此会话分配伪TTY。
accept和reject是函数,如果客户端请求响应。info具有以下属性:-
term - string - 伪TTY的终端类型。
-
cols - integer - 伪TTY的列数。
-
height - integer - 伪TTY的高度(以像素为单位)。
-
modes - object - 包含伪TTY的请求模式的对象,键为模式名称,值为模式参数。 (请参见表格末尾的有效名称)。
-
rows - integer - 伪TTY的行数。
-
width - integer - 伪TTY的宽度(以像素为单位)。
-
-
sftp(< mixed >accept, < mixed >reject) - 客户端请求SFTP子系统。
accept和reject是函数,如果客户端请求响应。accept()返回一个 SFTP 实例,处于服务器模式(有关SFTP文档的详细信息)。 -
shell(< mixed >accept, < mixed >reject) - 客户端请求交互式shell。
accept和reject是函数,如果客户端请求响应。accept()返回一个 Channel 用于交互式shell。 -
signal(< mixed >accept, < mixed >reject, < object >info) - 客户端发送信号。
accept和reject是函数,如果客户端请求响应。info具有以下属性:- name - string - 信号名称(例如
SIGUSR1)。
- name - string - 信号名称(例如
-
subsystem(< mixed >accept, < mixed >reject, < object >info) - 客户端请求任意子系统。
accept和reject是函数,如果客户端请求响应。accept()返回一个 Channel 用于子系统。info具有以下属性:- name - string - 子系统的名称。
-
window-change(< mixed >accept, < mixed >reject, < object >info) - 客户端报告在此会话期间窗口尺寸发生变化。
accept和reject是函数,如果客户端请求响应。info具有以下属性:-
cols - integer - 客户端窗口的新列数。
-
height - integer - 客户端窗口的新高度(以像素为单位)。
-
rows - integer - 客户端窗口的新行数。
-
width - integer - 客户端窗口的新宽度(以像素为单位)。
-
-
x11(< mixed >accept, < mixed >reject, < object >info) - 客户端请求X11转发。
accept和reject是函数,如果客户端请求响应。info具有以下属性:-
cookie - string - 以十六进制编码的X11认证cookie。
-
protocol - string - 使用的X11认证方法的名称(例如
MIT-MAGIC-COOKIE-1)。 -
screen - integer - 要转发X11连接的屏幕号。
-
single - boolean -
true如果只应转发一个连接。
-
通道
这是一个正常的 streams2 双工流(客户端和服务器均使用),具有以下更改:
-
布尔属性
allowHalfOpen存在,并且行为类似于net.Socket的同名属性。当调用流的end()时,如果allowHalfOpen为true,则仅发送EOF(服务器仍然可以发送数据,如果他们尚未发送EOF)。此属性的默认值为true。 -
当通道在客户端和服务器上完全关闭时,发出
close事件。 -
客户端特定:
- 对于 exec():
-
当进程完成时,可能会发出
exit事件(SSH2规范表示这是可选的)。如果进程正常完成,则将进程的返回值传递给exit回调。如果进程被信号中断,则将以下内容传递给exit回调:null, < string >signalName, < boolean >didCoreDump, < string >description。 -
如果有
exit事件,则close事件将传递相同的参数以方便使用。 -
stderr属性包含表示来自stderr的输出的可读流。
-
- 对于 exec() 和 shell():
-
可读侧表示stdout,写入侧表示stdin。
-
setWindow(< integer >rows, < integer >cols, < integer >height, < integer >width) - (void) - 让服务器知道本地终端窗口已调整大小。这些参数的含义在 'Pseudo-TTY settings' 部分中描述。
-
signal(< string >signalName) - (void) - 向服务器上的当前进程发送POSIX信号。有效的信号名称为:'ABRT', 'ALRM', 'FPE', 'HUP', 'ILL', 'INT', 'KILL', 'PIPE', 'QUIT', 'SEGV', 'TERM', 'USR1', 和 'USR2'。某些服务器实现可能会忽略此请求,如果它们不支持信号。注意:如果你尝试发送SIGINT并发现
signal()无法工作,请尝试向通道流写入'\x03'。
-
- 对于 exec():
-
服务器特定:
- 对于启用了exec的通道实例,在关闭通道之前可以调用一个额外的方法。它有两种不同的签名:
-
exit(< integer >exitCode) - (void) - 向客户端发送退出状态代码。
-
exit(< string >signalName[, < boolean >coreDumped[, < string >errorMsg]]) - (void) - 向客户端发送退出状态代码。
-
- 对于启用了exec的通道实例,在关闭通道之前可以调用一个额外的方法。它有两种不同的签名:
伪终端设置
-
cols - < integer > - 列数。 默认值:
80 -
height - < integer > - 高度(以像素为单位)。 默认值:
480 -
modes - < object > - 一个包含终端模式的对象,键为模式名称,值为每个模式参数。 默认值:
null -
rows - < integer > - 行数。 默认值:
24 -
width - < integer > - 宽度(以像素为单位)。 默认值:
640
rows 和 cols 在 rows 和 cols 非零时覆盖 width 和 height。
像素维度指的是窗口的可绘制区域。
零维度参数被忽略。
终端模式
| 名称 | 描述 |
|---|---|
| CS7 | 7位模式。 |
| CS8 | 8位模式。 |
| ECHOCTL | 将控制字符作为^(Char)回显。 |
| ECHO | 启用回显。 |
| ECHOE | 可视化擦除字符。 |
| ECHOKE | 可视化擦除行。 |
| ECHOK | 杀字符丢弃当前行。 |
| ECHONL | 即使ECHO关闭,也回显NL。 |
| ICANON | 规范化输入行。 |
| ICRNL | 将CR映射到NL上输入。 |
| IEXTEN | 启用扩展。 |
| IGNCR | 在输入上忽略CR。 |
| IGNPAR | 忽略奇偶校验标志。参数应该是0如果这个标志是FALSE,如果是TRUE则是1。 |
| IMAXBEL | 输入队列满时响铃。 |
| INLCR | 将NL映射到CR上输入。 |
| INPCK | 启用奇偶校验错误检查。 |
| ISIG | 启用信号INTR、QUIT、[D]SUSP。 |
| ISTRIP | 去掉字符的第8位。 |
| IUCLC | 将大写字符转换为小写。 |
| IXANY | 任何字符都会在停止后重启。 |
| IXOFF | 启用输入流控制。 |
| IXON | 启用输出流控制。 |
| NOFLSH | 中断后不刷新。 |
| OCRNL | 将回车翻译成换行(输出)。 |
| OLCUC | 将小写转换为大写。 |
| ONLCR | 将NL映射到CR-NL。 |
| ONLRET | 新行执行回车(输出)。 |
| ONOCR | 将换行翻译成回车-换行(输出)。 |
| OPOST | 启用输出处理。 |
| PARENB | 启用奇偶校验。 |
| PARMRK | 标记奇偶校验和帧错误。 |
| PARODD | 奇数奇偶校验,否则为偶数。 |
| PENDIN | 重输入挂起的输入。 |
| TOSTOP | 阻止后台作业从输出。 |
| TTY_OP_ISPEED | 指定输入波特率,单位为每秒比特。 |
| TTY_OP_OSPEED | 指定输出波特率,单位为每秒比特。 |
| VDISCARD | 切换刷新终端输出。 |
| VDSUSP | 另一个挂起字符。 |
| VEOF | 文件结束字符(从终端发送EOF)。 |
| VEOL2 | 另一个行结束字符。 |
| VEOL | 除了回车和/或换行之外的行结束字符。 |
| VERASE | 删除光标左侧的字符。 |
| VFLUSH | 刷新输出的字符。 |
| VINTR | 中断字符;如果没有则为255。类似地,对于其他字符。并非所有这些字符在所有系统上都受支持。 |
| VKILL | 杀死当前输入行。 |
| VLNEXT | 将下一个输入的字符作为字面量输入,即使它是特殊字符 |
| VQUIT | 退出字符(在POSIX系统上发送SIGQUIT信号)。 |
| VREPRINT | 重印当前输入行。 |
| VSTART | 继续暂停的输出(通常为控制-Q)。 |
| VSTATUS | 打印系统状态行(负载、命令、pid等)。 |
| VSTOP | 暂停输出(通常为控制-S)。 |
| VSUSP | 挂起当前程序。 |
| VSWTCH | 切换到不同的shell层。 |
| VWERASE | 删除光标左侧的单词。 |
| XCASE | 启用大写字符的输入和输出,通过在它们的小写等价物前加上""。 |
HTTPAgent
HTTPAgent方法
- (constructor)(< object >sshConfig[, < object >agentConfig]) - 创建并返回一个新的
http.Agent实例,用于通过SSH隧道HTTP连接。sshConfig是传递给client.connect()的内容,agentOptions传递给http.Agent构造函数。
HTTPSAgent
HTTPSAgent方法
- (constructor)(< object >sshConfig[, < object >agentConfig]) - 创建并返回一个新的
https.Agent实例,用于通过SSH隧道HTTP连接。sshConfig是传递给client.connect()的内容,agentOptions传递给https.Agent构造函数。
工具
-
generateKeyPair(< string >keyType[, < object >options], < function >callback) - 生成一个给定类型的SSH密钥对。
keyType可以是'rsa','ecdsa', 或'ed25519'(node.js v12+)。callback的签名为(err, keys)其中keys是包含private和public属性的对象,包含生成的SSH密钥。options可能包含:-
bits - integer - 对于ECDSA和RSA密钥,这是密钥强度。对于ECDSA,这被限制为
256,384, 或521。 默认值:(无) -
cipher - string - 用于加密密钥的(SSH,而不是OpenSSL)密码。 默认值:(无)
-
comment - string - 包含在私钥和公钥中的注释。 默认值:
'' -
format - string - 要使用的SSH密钥格式。目前只支持
'new',代表当前的OpenSSH密钥格式。 默认值:'new' -
passphrase - mixed - 加密密钥所需的密码短语。这可以是字符串或 Buffer。 默认值:(无)
-
rounds - integer - 对于
'new'格式的SSH密钥,这是在生成加密密钥的密码参数时使用的bcrypt轮数。 默认值:16
-
-
generateKeyPairSync(< string >keyType[, < object >options]) - 同步生成给定类型的SSH密钥对。
-
parseKey(< mixed >keyData[, < string >passphrase]) - 解析OpenSSH、RFC4716或PPK格式的私钥/公钥。对于加密的私钥,使用给定的
passphrase解密。keyData可以是包含密钥内容的 Buffer 或 string 值。返回值是一个对象数组(目前是现代OpenSSH密钥的情况)或具有以下属性和方法的对象:-
comment - string - 密钥的注释
-
equals(< mixed >otherKey) - 如果
otherKey(一个解析或可解析的密钥)与此密钥相同,则返回true。此方法不比较密钥的注释。 -
getPrivatePEM() - 返回私钥的PEM版本
-
getPublicPEM() - 返回公钥的PEM版本(无论是公钥还是从私钥派生的)
-
getPublicSSH() - 返回公钥的SSH版本(无论是公钥还是从私钥派生的)
-
isPrivateKey() - 如果密钥是私钥,则返回
true -
sign(< mixed >data) - 使用此密钥对给定的
data进行签名,并返回包含签名的 Buffer。成功时返回 Buffer,失败时返回 Error。data可以是任何被node的sign.update()接受的内容。 -
type - 完整的密钥类型(例如
'ssh-rsa') -
verify(< mixed >data, < Buffer >signature) - 使用此密钥验证给定
data的signature,并返回如果签名可以被验证则返回true。失败时返回false或在更严重的失败时返回 Error。data可以是任何被node的verify.update()接受的内容。
-
-
sftp.OPEN_MODE -
OPEN_MODE -
sftp.STATUS_CODE -
STATUS_CODE -
sftp.flagsToString -
flagsToString() -
sftp.stringToFlags -
stringToFlags()
AgentProtocol
AgentProtocol事件
-
identities(< opaque >request) - (仅服务器模式) 客户端请求存储在代理中的公钥列表。使用
failureReply()或getIdentitiesReply()适当地回复。 -
sign(< opaque >request, < mixed >pubKey, < Buffer >data, < object >options) - (仅服务器模式) 客户端请求使用
pubKey标识的密钥对data进行签名。使用failureReply()或signReply()适当地回复。options可能包含:- hash - string - 明确希望在计算签名时使用的哈希。目前如果设置,这可能是RSA密钥的
'sha256'或'sha512'。
- hash - string - 明确希望在计算签名时使用的哈希。目前如果设置,这可能是RSA密钥的
AgentProtocol方法
-
(constructor)(< boolean >isClient) - 创建并返回一个新的AgentProtocol实例。
isClient确定实例是在客户端还是服务器模式下运行。 -
failureReply(< opaque >request) - (仅服务器模式) 用失败响应回复给定的
request。 -
getIdentities(< function >callback) - (仅客户端模式) 请求代理列出公钥。
callback被传递(err, keys)其中keys是可能的公钥数组,用于认证。 -
getIdentitiesReply(< opaque >request, < array >keys) - (仅服务器模式) 用给定的
keys数组响应身份列表request。 -
sign(< mixed >pubKey, < Buffer >data, < object >options, < function >callback) - (仅客户端模式) 请求代理使用
pubKey标识的密钥对data进行签名。pubKey可以是任何使用utils.parseKey()解析的或可解析的密钥值。callback被传递(err, signature)其中signature是可能的包含data签名的 Buffer。options可能包含:- hash - string - 明确希望在计算签名时使用的哈希。目前如果设置,这可能是RSA密钥的
'sha256'或'sha512'。
- hash - string - 明确希望在计算签名时使用的哈希。目前如果设置,这可能是RSA密钥的
-
signReply(< opaque >request, < Buffer >signature) - (仅服务器模式) 用给定的
signature签名回复签名request。
BaseAgent
为了创建自定义代理,你的类必须:
-
扩展
BaseAgent -
在构造函数中调用
super() -
实现至少以下方法:
-
getIdentities(< function >callback) - 传递
(err, keys)给callback其中keys是可能的公钥数组,用于认证。 -
sign(< mixed >pubKey, < Buffer >data, < object >options, < function >callback) - 使用
pubKey标识的密钥对data进行签名。pubKey可以是任何使用utils.parseKey()解析的或可解析的密钥值。callback应该被传递(err, signature)其中signature是可能的包含data签名的 Buffer。options可能包含:- hash - string - 明确希望在计算签名时使用的哈希。目前如果设置,这可能是RSA密钥的
'sha256'或'sha512'。
- hash - string - 明确希望在计算签名时使用的哈希。目前如果设置,这可能是RSA密钥的
此外,你的类可以实现以下方法以支持客户端上的代理转发:
- getStream(< function >callback) - 传递
(err, stream)给callback其中stream是可能的双向流,用于与你的代理通信。你可能想要使用AgentProtocol因为代理转发是OpenSSH功能,所以stream需要能够传输/接收OpenSSH代理协议数据包。
createAgent
- createAgent(< string >agentValue) - 创建并返回一个新的代理实例,使用与
Client的agent配置选项相同的逻辑:如果平台是Windows并且值是 "pageant",则创建一个PageantAgent,否则如果不是Windows管道的路径,则创建一个CygwinAgent。在所有其他情况下,它创建一个OpenSSHAgent。
CygwinAgent
CygwinAgent方法
- (constructor)(< string >socketPath) - 在Cygwin环境中与
socketPath上的代理进行通信。
OpenSSHAgent
OpenSSHAgent方法
- (constructor)(< string >socketPath) - 与在UNIX套接字
socketPath上的OpenSSH代理进行通信。
PageantAgent
PageantAgent方法
- (constructor)() - 创建一个新的代理实例,用于与正在运行的Pageant代理进程进行通信。