使用ssh2模块在node.js中设置sftp服务器

时间:2015-06-17 19:10:30

标签: node.js sftp

我想使用node.js设置一个sftp服务器。

我查看了ssh2模块,看起来非常适合启动sftp服务器。

我也查看了sftp-stream api,但我无法弄清楚如何向我的服务器验证用户的选项,哪个目录将成为sftp的根目录

1 个答案:

答案 0 :(得分:0)

如果要创建也处理身份验证和所有内容的SFTP服务器(而不仅仅是SFTP服务器作为OpenSSH服务器的子系统),您还需要编写ssh2服务器部分的代码。这是一个只允许密码验证并且只启动sftp会话的简单示例:

var fs = require('fs');
var ssh2 = require('ssh2'),
    Server = ssh2.Server;
var OPEN_MODE = ssh2.SFTP_OPEN_MODE,
    STATUS_CODE = ssh2.SFTP_STATUS_CODE;

new Server({
  privateKey: fs.readFileSync('host.key')
}, function(client) {
  console.log('Client connected!');

  client.on('authentication', function(ctx) {
    if (ctx.method === 'password'
        && ctx.username === 'foo'
        && ctx.password === 'bar')
      ctx.accept();
    else
      ctx.reject();
  }).on('ready', function() {
    console.log('Client authenticated!');

    client.on('session', function(accept, reject) {
      var session = accept();
      session.on('sftp', function(accept, reject) {
        console.log('Client SFTP session');
        var openFiles = {};
        var handleCount = 0;
        // `sftpStream` is an `SFTPStream` instance in server mode
        var sftpStream = accept();
        sftpStream.on('OPEN', function(reqid, filename, flags, attrs) {
          // only allow opening /tmp/foo.txt for writing
          if (filename !== '/tmp/foo.txt' || !(flags & OPEN_MODE.WRITE))
            return sftpStream.status(reqid, STATUS_CODE.FAILURE);
          // create a fake handle to return to the client, this could easily
          // be a real file descriptor number for example if actually opening
          // the file on the disk
          var handle = new Buffer(4);
          openFiles[handleCount] = true;
          handle.writeUInt32BE(handleCount++, 0, true);
          sftpStream.handle(reqid, handle);
          console.log('Opening file for write')
        }).on('WRITE', function(reqid, handle, offset, data) {
          if (handle.length !== 4 || !openFiles[handle.readUInt32BE(0, true)])
            return sftpStream.status(reqid, STATUS_CODE.FAILURE);
          // fake the write
          sftpStream.status(reqid, STATUS_CODE.OK);
          var inspected = require('util').inspect(data);
          console.log('Write to file at offset %d: %s', offset, inspected);
        }).on('CLOSE', function(reqid, handle) {
          var fnum;
          if (handle.length !== 4 || !openFiles[(fnum = handle.readUInt32BE(0, true))])
            return sftpStream.status(reqid, STATUS_CODE.FAILURE);
          delete openFiles[fnum];
          sftpStream.status(reqid, STATUS_CODE.OK);
          console.log('Closing file');
        });
      });
    });
  }).on('end', function() {
    console.log('Client disconnected');
  });
}).listen(0, '127.0.0.1', function() {
  console.log('Listening on port ' + this.address().port);
});