SFTP nodejs服务器访问错误

时间:2016-07-09 04:35:36

标签: node.js ubuntu-14.04 sftp libssh lftp

我正在实现基于libssh(npm install ssh)

的SFTP Nodejs服务器脚本
var config = require('config');
var fs = require('fs');
var path = require('path');
var libssh = require('ssh');

var server;
var options = {
    host: 'localhost',
    port: '3022',
    // Get the common name of ssh_keys
    host_key: config.get('logshipper.sftp.host_key'),
    // Root path of SFTP folder on the machine
    root: path.join(__dirname, config.get('logshipper.sftp.root')),
    test_username: 'correct_username',
    test_password: 'correct_password'
};

server = libssh.createServer({
    hostRsaKeyFile: __dirname + '/ssh_keys/' + 'rsa_' + options.host_key,
    hostDsaKeyFile: __dirname + '/ssh_keys/' + 'dsa_' + options.host_key
});

server.on('connection', function (session) {
    session.on('auth', function (message) {
        // Maybe check username/password
        return message.replyAuthSuccess();
    });

    session.on('channel', function (channel) {
        channel.on('subsystem', function (message) {
            if (message.subsystem == 'sftp') {
                message.replySuccess();
                message.sftpAccept();
            }
        });

        channel.on('sftp:realpath', function (message) {
            console.log('server cmd sftp:realpath');
            if (message.filename == '.' || (/\/$/).test(message.filename)) {
                message.replyName(path.join(options.root, message.filename), {
                    permissions: +libssh.Stat('777').dir()
                })
            } else {
                message.replyName(message.filename, {
                    permissions: +libssh.Stat('777').reg()
                })
            }
        });

        channel.on('sftp:stat', statHandle);

        function statHandle(message) {
            console.log('server cmd sftp:stat');

            var attrs = {
                permissions: +libssh.Stat(777).dir()
                , uid: 101
                , gid: 202
                , size: 100
                , atime: Date.now()
                , mtime: Date.now()
            };

            message.replyAttr(attrs)
        }

        // can be handled the same way as 'stat' if you like
        channel.on('sftp:lstat', statHandle);

        channel.on('sftp:opendir', function (message) {
            console.log('server cmd sftp:opendir');
            message.replyHandle(message.filename + '/');
        });

        var lastmsg;
        channel.on('sftpmessage', function (message) {
            lastmsg = message
        });

        channel.on('sftp:readdir', function (message) {
            console.log('server cmd sftp:readdir', message.handle);

            if (lastmsg.type == 'readdir') {
                return message.replyStatus('ok');
            }

            var readPath = message.handle;
            fs.readdir(readPath, function(err, files) {
                if (err) {
                    console.log(err);
                    throw err;

                } else {
                    files = files.map(function(file) {
                        return {
                            filename: file,
                            longname: file,
                            attrs: { permissions: +libssh.Stat(644).reg() }
                        };
                    });
                    return message.replyNames(files);
                }
            });
        });

        channel.on('sftp:close', function (message) {
            console.log('server cmd sftp:close');
            message.replyStatus('ok');
        })
    })
});

server.listen(options.port, options.host);
console.log('Listening on port ' + options.port);

Ubuntu 14.04,nodejs 0.10.25 在sftp.root目录中,我有测试文件,我应该可以下载到,检查它是否在sftp服务器上等。

当我使用sftp(ubuntu cmd连接到我得到的服务器)时:

sftp -P 3022 localhost
Connected to localhost.
sftp> dir
Couldn't read directory: No error
test-file  
sftp> 

服务器输出:

/usr/bin/node sftpServer.js
Listening on port 3022
server cmd sftp:realpath
server cmd sftp:opendir
server cmd sftp:readdir /home/MyFolder/uploads/
server cmd sftp:readdir /home/MyFolder/uploads/
server cmd sftp:close

无法读取目录:无错误

但它实际上是一个测试,我需要通过lftp

使用这个服务器
lftp sftp://localhost:3022
lftp localhost:~> dir
ls: ls: Access failed:     
lftp localhost:~> 

我正在访问失败的错误。我试图将文件夹chmod 777或标记为root组,但它没有帮助。

我希望有人会调查并帮助我找出出现此访问错误的原因,谢谢!

1 个答案:

答案 0 :(得分:1)

最后的replyNames应该包含EOF标志,而replyStatus必须包含代码SSH_FX_EOF。否则,状态将被视为错误。 也许这段代码会这样做:

        if (lastmsg.type == 'readdir') {
            return message.replyStatus('eof');
        }

在lftp中启用debug以查看协议消息,然后比较成功会话与不成功会话是很有用的。