Python 中的 SFTP 服务器与 Paramiko

问题描述 投票:0回答:1

我正在使用 paramiko 通过 python 托管 SFTP 服务器。 我使用 PostgreSQL 数据库来存储用户的凭据。

这些代码与我最初写的代码有很大不同,因为我尝试使用AI来纠正这些代码,但没有成功。

我创建了一个扩展 paramiko.ServerInterface 的类:

class SftpServer(paramiko.ServerInterface):
    def __init__(self, home_dir=None):
        self.home_dir = home_dir

    def check_auth_password(self, username, password):
        if authenticate_user(username, password=password):
            logging.debug(f"User {username} authenticated by password.")
            return paramiko.AUTH_SUCCESSFUL
        else:
            logging.debug(f"Failed password authentication for user {username}.")
            return paramiko.AUTH_FAILED

    def check_auth_publickey(self, username, key):
        public_key = key.get_base64()
        if authenticate_user(username, public_key=public_key):
            logging.debug(f"User {username} authenticated by public key.")
            return paramiko.AUTH_SUCCESSFUL
        else:
            logging.debug(f"Failed public key authentication for user {username}.")
            return paramiko.AUTH_FAILED

    def check_channel_request(self, kind, chanid):
        logging.debug(f"Channel request type: {kind}")
        if kind == 'session':
            return paramiko.OPEN_SUCCEEDED
        elif kind == "[email protected]":
            logging.debug(f"Non standard request recived: {kind}")
            return paramiko.OPEN_SUCCEEDED
        else:
            logging.debug(f"Channel type not supported: {kind}")
            return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED

    def check_channel_subsystem_request(self, channel, name):
        logging.debug(f"Channel request type (subsystem): {name}")
        if name == 'sftp':
            return paramiko.OPEN_SUCCEEDED
        elif name == "[email protected]":
            logging.debug(f"Non standard request recived by subsystem: {name}")
            return paramiko.OPEN_SUCCEEDED
        return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
    
    def check_channel_pty_request(self, channel, term, width, height, pixelwidth, pixelheight, modes):
        logging.debug("PTY request granted.")
        return True

    def check_channel_shell_request(self, channel):
        logging.debug("Shell request granted.")
        return True

Then i use this function to handle client channels:

    def handle_client(channel: paramiko.Channel, server: SftpServer):
    try:
        # Check if the client requested a pseudo-terminal
        if channel.get_pty():
            # Start interactive shell
            logging.debug("PTY allocated. Starting interactive shell.")
            start_shell(channel)
        else:
            # If no PTY requested, start the SFTP session
            logging.debug("Starting SFTP session.")
            sftp_server = paramiko.SFTPServer(channel=channel, server=server, name='sftp')
            sftp_server.start()

            while not channel.closed:
                time.sleep(1)
    except paramiko.SSHException as e:
        logging.error(f"SSH exception: {e}")
    except Exception as e:
        logging.error(f"Error handling client: {e}")
    finally:
        logging.debug("Closing channel.")
        channel.close()

然后这个函数来启动服务器:


def start_sftp_server():
    logging.info("Starting SFTP server...")
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.settimeout(60)
    server_socket.bind(('localhost', 2222))
    server_socket.listen(100)

    host_key = paramiko.RSAKey.generate(2048)

    while True:
        try:
            client_socket, addr = server_socket.accept()
            logging.info(f"Connection accepted from {addr}")

            transport = paramiko.Transport(client_socket)
            transport.add_server_key(host_key)

            server = SftpServer(home_dir="C:/sftp_users")

            try:
                transport.start_server(server=server)
            except paramiko.SSHException as e:
                logging.error(f"SSH negotiation failed: {e}")
                continue

            channel = transport.accept(20)
            if channel is None:
                logging.error("No channel found")
                continue

            logging.info("Client authenticated, starting SFTP session.")
            threading.Thread(target=handle_client, args=(channel, server)).start()
        
        except Exception as e:
            logging.error(f"An error occurred accepting the connection: {e}")

当我尝试使用 Filezilla 或 WinSCP 服务器等客户端连接到此服务器时,返回错误:

DEB [20241015-22:42:43.279] thr=2   paramiko.transport: starting thread (server mode): 0xefa33b0
DEB [20241015-22:42:43.279] thr=2   paramiko.transport: Local version/idstring: SSH-2.0-paramiko_3.5.0
DEB [20241015-22:42:43.330] thr=2   paramiko.transport: Remote version/idstring: SSH-2.0-WinSCP_release_6.3.5
INF [20241015-22:42:43.330] thr=2   paramiko.transport: Connected (version 2.0, client WinSCP_release_6.3.5)
DEB [20241015-22:42:43.334] thr=2   paramiko.transport: === Key exchange possibilities ===
DEB [20241015-22:42:43.334] thr=2   paramiko.transport: kex algos: [email protected], curve448-sha512, curve25519-sha256, [email protected], ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, diffie-hellman-group-exchange-sha1, diffie-hellman-group18-sha512, diffie-hellman-group17-sha512, diffie-hellman-group16-sha512, diffie-hellman-group15-sha512, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1, rsa2048-sha256, rsa1024-sha1, diffie-hellman-group1-sha1, ext-info-c, [email protected]
DEB [20241015-22:42:43.335] thr=2   paramiko.transport: server key: rsa-sha2-512, rsa-sha2-256, ssh-rsa, ssh-ed448, ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, ssh-dss
DEB [20241015-22:42:43.335] thr=2   paramiko.transport: client encrypt: aes256-ctr, aes256-cbc, [email protected], aes192-ctr, aes192-cbc, aes128-ctr, aes128-cbc, [email protected], [email protected], [email protected], 3des-ctr, 3des-cbc, blowfish-ctr, blowfish-cbc, arcfour256, arcfour128
DEB [20241015-22:42:43.336] thr=2   paramiko.transport: server encrypt: aes256-ctr, aes256-cbc, [email protected], aes192-ctr, aes192-cbc, aes128-ctr, aes128-cbc, [email protected], [email protected], [email protected], 3des-ctr, 3des-cbc, blowfish-ctr, blowfish-cbc, arcfour256, arcfour128
DEB [20241015-22:42:43.337] thr=2   paramiko.transport: client mac: hmac-sha2-256, hmac-sha2-512, hmac-sha1, hmac-sha1-96, hmac-md5, [email protected], [email protected], [email protected], [email protected], [email protected]
DEB [20241015-22:42:43.337] thr=2   paramiko.transport: server mac: hmac-sha2-256, hmac-sha2-512, hmac-sha1, hmac-sha1-96, hmac-md5, [email protected], [email protected], [email protected], [email protected], [email protected]
DEB [20241015-22:42:43.337] thr=2   paramiko.transport: client compress: none, zlib, [email protected]
DEB [20241015-22:42:43.338] thr=2   paramiko.transport: server compress: none, zlib, [email protected]
DEB [20241015-22:42:43.338] thr=2   paramiko.transport: client lang: <none>
DEB [20241015-22:42:43.338] thr=2   paramiko.transport: server lang: <none>
DEB [20241015-22:42:43.338] thr=2   paramiko.transport: kex follows: False
DEB [20241015-22:42:43.339] thr=2   paramiko.transport: === Key exchange agreements ===
DEB [20241015-22:42:43.339] thr=2   paramiko.transport: Strict kex mode: True
DEB [20241015-22:42:43.339] thr=2   paramiko.transport: Kex: [email protected]
DEB [20241015-22:42:43.339] thr=2   paramiko.transport: HostKey: rsa-sha2-512
DEB [20241015-22:42:43.340] thr=2   paramiko.transport: Cipher: aes256-ctr
DEB [20241015-22:42:43.340] thr=2   paramiko.transport: MAC: hmac-sha2-256
DEB [20241015-22:42:43.341] thr=2   paramiko.transport: Compression: none
DEB [20241015-22:42:43.341] thr=2   paramiko.transport: === End of kex handshake ===
DEB [20241015-22:42:43.347] thr=2   paramiko.transport: Resetting outbound seqno after NEWKEYS due to strict mode
DEB [20241015-22:42:43.347] thr=2   paramiko.transport: kex engine KexCurve25519 specified hash_algo <built-in function openssl_sha256>
DEB [20241015-22:42:43.408] thr=2   paramiko.transport: Switch to new keys ...
DEB [20241015-22:42:43.408] thr=2   paramiko.transport: Resetting inbound seqno after NEWKEYS due to strict mode
DEB [20241015-22:42:43.429] thr=2   paramiko.transport: Auth request (type=none) service=ssh-connection, username=MagoLione
INF [20241015-22:42:43.430] thr=2   paramiko.transport: Auth rejected (none).
DEB [20241015-22:42:43.456] thr=2   paramiko.transport: Auth request (type=password) service=ssh-connection, username=MagoLione
INF [20241015-22:42:43.909] thr=2   paramiko.transport: Auth granted (password).
DEB [20241015-22:42:43.910] thr=2   paramiko.transport: [chan 0] Max packet in: 32768 bytes
DEB [20241015-22:42:43.910] thr=2   paramiko.transport: [chan 0] Max packet out: 16384 bytes
DEB [20241015-22:42:43.911] thr=2   paramiko.transport: Secsh channel 0 (session) opened.
DEB [20241015-22:42:43.911] thr=2   paramiko.transport: [chan 0] Unhandled channel request "[email protected]"
DEB [20241015-22:42:43.913] thr=2   paramiko.transport: [chan 0] EOF sent (0)
ERR [20241015-22:42:43.972] thr=2   paramiko.transport: Socket exception: Connessione in corso interrotta forzatamente dall'host remoto (10054)

这是控制台:

DEBUG:root:User MagoLione authenticated by password.
INFO:paramiko.transport:Auth granted (password).
DEBUG:root:Channel request type: session
DEBUG:paramiko.transport:[chan 0] Max packet in: 32768 bytes
DEBUG:paramiko.transport:[chan 0] Max packet out: 16384 bytes
DEBUG:paramiko.transport:Secsh channel 0 (session) opened.
INFO:root:Client authenticated, starting SFTP session.
DEBUG:paramiko.transport:[chan 0] Unhandled channel request "[email protected]"
DEBUG:root:Channel request type (subsystem): sftp
DEBUG:paramiko.transport:[chan 0] EOF sent (0)
ERROR:root:SSH exception: Channel closed.
DEBUG:root:Closing channel.
DEBUG:root:Shell request granted.
ERROR:paramiko.transport:Socket exception: Connessione in corso interrotta forzatamente dall'host remoto (10054)

在客户端:

> Server refused to start a shell/command

所以我尝试通过以下方式实现 shell/命令功能:

def start_shell(channel):
    import subprocess
    
    shell_process = subprocess.Popen(
        ['powershell.exe'],
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE
    )

    while True:
        data = channel.recv(1024)
        if not data:
            break
        shell_process.stdin.write(data)
        shell_process.stdin.flush()
        
        output = shell_process.stdout.read(1024)
        if output:
            channel.send(output)

    shell_process.terminate()

在执行 SHELL 之前,程序返回错误:

DEB [20241009-10:27:39.371] thr=1   paramiko.transport: starting thread (server mode): 
0xffe8a750
DEB [20241009-10:27:39.372] thr=1   paramiko.transport: Local version/idstring: SSH-2.0-paramiko_3.5.0
DEB [20241009-10:27:39.411] thr=1   paramiko.transport: Remote version/idstring: SSH-2.0-WinSCP_release_6.3.5
INF [20241009-10:27:39.411] thr=1   paramiko.transport: Connected (version 2.0, client WinSCP_release_6.3.5)
DEB [20241009-10:27:39.417] thr=1   paramiko.transport: === Key exchange possibilities ===
DEB [20241009-10:27:39.417] thr=1   paramiko.transport: kex algos: [email protected], curve448-sha512, curve25519-sha256, [email protected], ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, diffie-hellman-group-exchange-sha1, diffie-hellman-group18-sha512, diffie-hellman-group17-sha512, diffie-hellman-group16-sha512, diffie-hellman-group15-sha512, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1, rsa2048-sha256, rsa1024-sha1, diffie-hellman-group1-sha1, ext-info-c, [email protected]
DEB [20241009-10:27:39.417] thr=1   paramiko.transport: server key: rsa-sha2-512, rsa-sha2-256, ssh-rsa, ssh-ed448, ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, ssh-dss
DEB [20241009-10:27:39.418] thr=1   paramiko.transport: client encrypt: aes256-ctr, aes256-cbc, [email protected], aes192-ctr, aes192-cbc, aes128-ctr, aes128-cbc, [email protected], [email protected], [email protected], 3des-ctr, 3des-cbc, blowfish-ctr, blowfish-cbc, arcfour256, arcfour128
DEB [20241009-10:27:39.418] thr=1   paramiko.transport: server encrypt: aes256-ctr, aes256-cbc, [email protected], aes192-ctr, aes192-cbc, aes128-ctr, aes128-cbc, [email protected], [email protected], [email protected], 3des-ctr, 3des-cbc, blowfish-ctr, blowfish-cbc, arcfour256, arcfour128
DEB [20241009-10:27:39.421] thr=1   paramiko.transport: client mac: hmac-sha2-256, hmac-sha2-512, hmac-sha1, hmac-sha1-96, hmac-md5, [email protected], [email protected], [email protected], [email protected], [email protected]
DEB [20241009-10:27:39.422] thr=1   paramiko.transport: server mac: hmac-sha2-256, hmac-sha2-512, hmac-sha1, hmac-sha1-96, hmac-md5, [email protected], [email protected], [email protected], [email protected], [email protected]
DEB [20241009-10:27:39.422] thr=1   paramiko.transport: client compress: none, zlib, [email protected]
DEB [20241009-10:27:39.422] thr=1   paramiko.transport: server compress: none, zlib, [email protected]
DEB [20241009-10:27:39.423] thr=1   paramiko.transport: client lang: <none>
DEB [20241009-10:27:39.423] thr=1   paramiko.transport: server lang: <none>
DEB [20241009-10:27:39.423] thr=1   paramiko.transport: kex follows: False
DEB [20241009-10:27:39.423] thr=1   paramiko.transport: === Key exchange agreements ===
DEB [20241009-10:27:39.423] thr=1   paramiko.transport: Strict kex mode: True
DEB [20241009-10:27:39.423] thr=1   paramiko.transport: Kex: [email protected]
DEB [20241009-10:27:39.424] thr=1   paramiko.transport: HostKey: rsa-sha2-512
DEB [20241009-10:27:39.424] thr=1   paramiko.transport: Cipher: aes256-ctr
DEB [20241009-10:27:39.424] thr=1   paramiko.transport: MAC: hmac-sha2-256
DEB [20241009-10:27:39.425] thr=1   paramiko.transport: Compression: none
DEB [20241009-10:27:39.425] thr=1   paramiko.transport: === End of kex handshake ===
DEB [20241009-10:27:39.441] thr=1   paramiko.transport: Resetting outbound seqno after NEWKEYS due to strict mode
DEB [20241009-10:27:39.442] thr=1   paramiko.transport: kex engine KexCurve25519 specified hash_algo <built-in function openssl_sha256>
DEB [20241009-10:27:40.907] thr=1   paramiko.transport: Switch to new keys ...
DEB [20241009-10:27:40.914] thr=1   paramiko.transport: Resetting inbound seqno after NEWKEYS due to strict mode
DEB [20241009-10:27:40.940] thr=1   paramiko.transport: Auth request (type=none) service=ssh-connection, username=MagoLione
INF [20241009-10:27:40.940] thr=1   paramiko.transport: Auth rejected (none).
DEB [20241009-10:27:46.134] thr=1   paramiko.transport: Auth request (type=password) service=ssh-connection, username=MagoLione
INF [20241009-10:27:46.541] thr=1   paramiko.transport: Auth granted (password).
DEB [20241009-10:27:46.542] thr=1   paramiko.transport: [chan 0] Max packet in: 32768 bytes
DEB [20241009-10:27:46.542] thr=1   paramiko.transport: [chan 0] Max packet out: 16384 bytes
DEB [20241009-10:27:46.543] thr=1   paramiko.transport: Secsh channel 0 (session) opened.
DEB [20241009-10:27:46.543] thr=1   paramiko.transport: [chan 0] Unhandled channel request "[email protected]"
DEB [20241009-10:27:46.544] thr=1   paramiko.transport: EOF in transport thread
DEB [20241009-10:28:19.936] thr=2   paramiko.transport: starting thread (server mode): 0x8291b020
DEB [20241009-10:28:19.936] thr=2   paramiko.transport: Local version/idstring: SSH-2.0-paramiko_3.5.0
DEB [20241009-10:28:20.002] thr=2   paramiko.transport: Remote version/idstring: SSH-2.0-WinSCP_release_6.3.5
INF [20241009-10:28:20.002] thr=2   paramiko.transport: Connected (version 2.0, client WinSCP_release_6.3.5)
DEB [20241009-10:28:20.004] thr=2   paramiko.transport: === Key exchange possibilities ===
DEB [20241009-10:28:20.004] thr=2   paramiko.transport: kex algos: [email protected], curve448-sha512, curve25519-sha256, [email protected], ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, diffie-hellman-group-exchange-sha1, diffie-hellman-group18-sha512, diffie-hellman-group17-sha512, diffie-hellman-group16-sha512, diffie-hellman-group15-sha512, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1, rsa2048-sha256, rsa1024-sha1, diffie-hellman-group1-sha1, ext-info-c, [email protected]
DEB [20241009-10:28:20.005] thr=2   paramiko.transport: server key: rsa-sha2-512, rsa-sha2-256, ssh-rsa, ssh-ed448, ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, ssh-dss
DEB [20241009-10:28:20.005] thr=2   paramiko.transport: client encrypt: aes256-ctr, aes256-cbc, [email protected], aes192-ctr, aes192-cbc, aes128-ctr, aes128-cbc, [email protected], [email protected], [email protected], 3des-ctr, 3des-cbc, blowfish-ctr, blowfish-cbc, arcfour256, arcfour128
DEB [20241009-10:28:20.006] thr=2   paramiko.transport: server encrypt: aes256-ctr, aes256-cbc, [email protected], aes192-ctr, aes192-cbc, aes128-ctr, aes128-cbc, [email protected], [email protected], [email protected], 3des-ctr, 3des-cbc, blowfish-ctr, blowfish-cbc, arcfour256, arcfour128
DEB [20241009-10:28:20.006] thr=2   paramiko.transport: client mac: hmac-sha2-256, hmac-sha2-512, hmac-sha1, hmac-sha1-96, hmac-md5, [email protected], [email protected], [email protected], [email protected], [email protected]
DEB [20241009-10:28:20.007] thr=2   paramiko.transport: server mac: hmac-sha2-256, hmac-sha2-512, hmac-sha1, hmac-sha1-96, hmac-md5, [email protected], [email protected], [email protected], [email protected], [email protected]
DEB [20241009-10:28:20.007] thr=2   paramiko.transport: client compress: none, zlib, [email protected]
DEB [20241009-10:28:20.008] thr=2   paramiko.transport: server compress: none, zlib, [email protected]
DEB [20241009-10:28:20.008] thr=2   paramiko.transport: client lang: <none>
DEB [20241009-10:28:20.009] thr=2   paramiko.transport: server lang: <none>
DEB [20241009-10:28:20.009] thr=2   paramiko.transport: kex follows: False
DEB [20241009-10:28:20.010] thr=2   paramiko.transport: === Key exchange agreements ===
DEB [20241009-10:28:20.010] thr=2   paramiko.transport: Strict kex mode: True
DEB [20241009-10:28:20.010] thr=2   paramiko.transport: Kex: [email protected]
DEB [20241009-10:28:20.011] thr=2   paramiko.transport: HostKey: rsa-sha2-512
DEB [20241009-10:28:20.011] thr=2   paramiko.transport: Cipher: aes256-ctr
DEB [20241009-10:28:20.012] thr=2   paramiko.transport: MAC: hmac-sha2-256
DEB [20241009-10:28:20.012] thr=2   paramiko.transport: Compression: none
DEB [20241009-10:28:20.012] thr=2   paramiko.transport: === End of kex handshake ===
DEB [20241009-10:28:20.018] thr=2   paramiko.transport: Resetting outbound seqno after NEWKEYS due to strict mode
DEB [20241009-10:28:20.018] thr=2   paramiko.transport: kex engine KexCurve25519 specified hash_algo <built-in function openssl_sha256>
DEB [20241009-10:28:20.062] thr=2   paramiko.transport: Switch to new keys ...
DEB [20241009-10:28:20.062] thr=2   paramiko.transport: Resetting inbound seqno after NEWKEYS due to strict mode
DEB [20241009-10:28:20.077] thr=2   paramiko.transport: Auth request (type=none) service=ssh-connection, username=MagoLione
INF [20241009-10:28:20.077] thr=2   paramiko.transport: Auth rejected (none).
DEB [20241009-10:28:20.093] thr=2   paramiko.transport: Auth request (type=password) service=ssh-connection, username=MagoLione
INF [20241009-10:28:20.551] thr=2   paramiko.transport: Auth granted (password).
DEB [20241009-10:28:20.552] thr=2   paramiko.transport: [chan 0] Max packet in: 32768 bytes
DEB [20241009-10:28:20.553] thr=2   paramiko.transport: [chan 0] Max packet out: 16384 bytes
DEB [20241009-10:28:20.553] thr=2   paramiko.transport: Secsh channel 0 (session) opened.
DEB [20241009-10:28:20.553] thr=2   paramiko.transport: [chan 0] Unhandled channel request "[email protected]"
DEB [20241009-10:28:20.554] thr=2   paramiko.transport: EOF in transport thread

这是客户端的日志文件:

. 2024-10-16 10:55:04.632 Initialised AES-256 SDCTR (AES-NI accelerated) [aes256-ctr] outbound encryption
. 2024-10-16 10:55:04.632 Initialised HMAC-SHA-256 outbound MAC algorithm
. 2024-10-16 10:55:04.632 Initialised AES-256 SDCTR (AES-NI accelerated) [aes256-ctr] inbound encryption
. 2024-10-16 10:55:04.633 Initialised HMAC-SHA-256 inbound MAC algorithm
. 2024-10-16 10:55:04.633 Detected network event
. 2024-10-16 10:55:04.633 Enumerating network events for socket 3336
. 2024-10-16 10:55:04.633 Enumerated 1 network events making 1 cumulative events for socket 3336
. 2024-10-16 10:55:04.633 Handling network read event on socket 3336 with error 0
. 2024-10-16 10:55:04.633 Waiting for the server to continue with the initialization
. 2024-10-16 10:55:04.633 Looking for incoming data
. 2024-10-16 10:55:04.633 Looking for network events
. 2024-10-16 10:55:04.635 Detected network event
. 2024-10-16 10:55:04.635 Enumerating network events for socket 3336
. 2024-10-16 10:55:04.635 Enumerated 1 network events making 1 cumulative events for socket 3336
. 2024-10-16 10:55:04.636 Handling network read event on socket 3336 with error 0
. 2024-10-16 10:55:04.636 Waiting for the server to continue with the initialization
. 2024-10-16 10:55:04.636 Looking for incoming data
. 2024-10-16 10:55:04.636 Looking for network events
! 2024-10-16 10:55:04.638 Using username "MagoLione".
. 2024-10-16 10:55:04.659 Detected network event
. 2024-10-16 10:55:04.659 Enumerating network events for socket 3336
. 2024-10-16 10:55:04.659 Enumerated 1 network events making 1 cumulative events for socket 3336
. 2024-10-16 10:55:04.659 Handling network read event on socket 3336 with error 0
. 2024-10-16 10:55:04.659 Waiting for the server to continue with the initialization
. 2024-10-16 10:55:04.659 Looking for incoming data
. 2024-10-16 10:55:04.659 Looking for network events
. 2024-10-16 10:55:04.659 Server offered these authentication methods: password
. 2024-10-16 10:55:04.660 Prompt (password, "SSH password", <no instructions>, "&Password: ")
. 2024-10-16 10:55:04.660 Using stored password.
. 2024-10-16 10:55:04.689 Sent password
. 2024-10-16 10:55:05.379 Detected network event
. 2024-10-16 10:55:05.379 Enumerating network events for socket 3336
. 2024-10-16 10:55:05.379 Enumerated 1 network events making 1 cumulative events for socket 3336
. 2024-10-16 10:55:05.379 Handling network read event on socket 3336 with error 0
. 2024-10-16 10:55:05.379 Waiting for the server to continue with the initialization
. 2024-10-16 10:55:05.379 Looking for incoming data
. 2024-10-16 10:55:05.379 Looking for network events
. 2024-10-16 10:55:05.379 Access granted
. 2024-10-16 10:55:05.380 Opening main session channel
. 2024-10-16 10:55:05.381 Detected network event
. 2024-10-16 10:55:05.381 Enumerating network events for socket 3336
. 2024-10-16 10:55:05.381 Enumerated 1 network events making 1 cumulative events for socket 3336
. 2024-10-16 10:55:05.381 Handling network read event on socket 3336 with error 0
. 2024-10-16 10:55:05.381 Waiting for the server to continue with the initialization
. 2024-10-16 10:55:05.381 Looking for incoming data
. 2024-10-16 10:55:05.381 Looking for network events
. 2024-10-16 10:55:05.381 Opened main channel
. 2024-10-16 10:55:05.382 Detected network event
. 2024-10-16 10:55:05.382 Enumerating network events for socket 3336
. 2024-10-16 10:55:05.382 Enumerated 1 network events making 1 cumulative events for socket 3336
. 2024-10-16 10:55:05.382 Handling network read event on socket 3336 with error 0
. 2024-10-16 10:55:05.382 Waiting for the server to continue with the initialization
. 2024-10-16 10:55:05.382 Looking for incoming data
. 2024-10-16 10:55:05.382 Looking for network events
. 2024-10-16 10:55:05.382 Unable to decode terminal mode string
. 2024-10-16 10:55:05.382 Detected network event
. 2024-10-16 10:55:05.382 Enumerating network events for socket 3336
. 2024-10-16 10:55:05.382 Enumerated 1 network events making 1 cumulative events for socket 3336
. 2024-10-16 10:55:05.382 Handling network read event on socket 3336 with error 0
. 2024-10-16 10:55:05.382 Waiting for the server to continue with the initialization
. 2024-10-16 10:55:05.382 Looking for incoming data
. 2024-10-16 10:55:05.382 Looking for network events
. 2024-10-16 10:55:05.382 Primary command failed; attempting fallback
. 2024-10-16 10:55:05.383 Detected network event
. 2024-10-16 10:55:05.383 Enumerating network events for socket 3336
. 2024-10-16 10:55:05.383 Enumerated 1 network events making 1 cumulative events for socket 3336
. 2024-10-16 10:55:05.383 Handling network read event on socket 3336 with error 0
. 2024-10-16 10:55:05.383 Waiting for the server to continue with the initialization
. 2024-10-16 10:55:05.383 Looking for incoming data
. 2024-10-16 10:55:05.383 Looking for network events
. 2024-10-16 10:55:05.383 Detected network event
. 2024-10-16 10:55:05.383 Enumerating network events for socket 3336
. 2024-10-16 10:55:05.383 Enumerated 1 network events making 1 cumulative events for socket 3336
. 2024-10-16 10:55:05.383 Handling network read event on socket 3336 with error 0
. 2024-10-16 10:55:05.383 Waiting for the server to continue with the initialization
. 2024-10-16 10:55:05.383 Looking for incoming data
. 2024-10-16 10:55:05.383 Looking for network events
. 2024-10-16 10:55:05.383 Main session channel closed
. 2024-10-16 10:55:05.383 Timeout waiting for network events
. 2024-10-16 10:55:05.442 --------------------------------------------------------------------------
. 2024-10-16 10:55:05.444 Using SFTP protocol.
. 2024-10-16 10:55:05.444 Doing startup conversation with host.
. 2024-10-16 10:55:05.444 Session upkeep
. 2024-10-16 10:55:05.444 Looking for network events
. 2024-10-16 10:55:05.444 Server refused to start a shell/command
. 2024-10-16 10:55:05.444 Attempt to close connection due to fatal exception:
* 2024-10-16 10:55:05.444 Server refused to start a shell/command
. 2024-10-16 10:55:05.445 Closing connection.
. 2024-10-16 10:55:05.445 Selecting events 0 for socket 3336
* 2024-10-16 10:55:05.516 (EFatal) Server refused to start a shell/command

我不明白出了什么问题。另外,因为我没有找到任何教程、示例或详尽的文档。 Peaple 总是使用 paramiko 作为客户端而不是服务器,所以我也不确定这个库是否可行。 如何为 SFTP 服务器设置根文件夹?

python server sftp paramiko
1个回答
0
投票

您需要使用

sftp
:
注册
Transport.set_subsystem_handler

通道处理程序
transport.set_subsystem_handler('sftp', paramiko.SFTPServer, ActualSFTPServer)

其中

ActualSFTPServer
SFTPServerInterface
的实现。

© www.soinside.com 2019 - 2024. All rights reserved.