Ошибка доступа к SFTP-узлу

Я реализую серверный скрипт SFTP Nodejs на основе libssh (npm install ssh)

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 или пометить как корневую группу, и это не помогло.

Я надеюсь, что кто-нибудь изучит это и поможет мне выяснить, почему появляется эта ошибка доступа, спасибо!

1 ответ

Последнее replyNames должно включать флаг EOF, а responseStatus должен иметь код SSH_FX_EOF. В противном случае статус считается ошибкой. Может быть, этот код будет делать:

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

Полезно включить отладку в lftp, чтобы увидеть сообщения протокола, а затем сравнить успешные и неудачные сеансы.

Другие вопросы по тегам