8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

Paramiko 的带有 SFTP 的 SSHClient

Tran To 2月前

75 0

如何通过远程服务器上的 SSHClient 进行 SFTP 传输?我有一个本地主机和两个远程主机。远程主机是备份服务器和 Web 服务器。我需要在备份服务器上找到必要的...

如何 SSHClient 在远程服务器上进行 SFTP 传输?我有一个本地主机和两个远程主机。远程主机是备份服务器和 Web 服务器。我需要在备份服务器上找到必要的备份文件,并通过 SFTP 将其放在 Web 服务器上。如何使 Paramiko 的 SFTP 传输与 Paramiko 的兼容 SSHClient

帖子版权声明 1、本帖标题:Paramiko 的带有 SFTP 的 SSHClient
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Tran To在本站《linux》版块原创发布, 转载请注明出处!
最新回复 (0)
  • paramiko.SFTP客户端

    示例用法:

    import paramiko
    paramiko.util.log_to_file("paramiko.log")
    
    # Open a transport
    host,port = "example.com",22
    transport = paramiko.Transport((host,port))
    
    # Auth    
    username,password = "bar","foo"
    transport.connect(None,username,password)
    
    # Go!    
    sftp = paramiko.SFTPClient.from_transport(transport)
    
    # Download
    filepath = "/etc/passwd"
    localpath = "/home/remotepasswd"
    sftp.get(filepath,localpath)
    
    # Upload
    filepath = "/home/foo.jpg"
    localpath = "/home/pony.jpg"
    sftp.put(localpath,filepath)
    
    # Close
    if sftp: sftp.close()
    if transport: transport.close()
    
  • 很好的答案。不过我想补充一点,Transport 和 SFTPClient 都实现了 __enter__/__exit__ 接口,因此可以在上下文管理器中使用,例如使用 Transport((host, port)) 作为传输:

  • 该实现有效,但是它不会清理进程。sftp-server 进程与其分叉,如果多次运行它,您会发现代码完成后存在很多进程。

  • 虽然这种方法可行,但由于使用了低级 Transport 类,因此会绕过主机密钥验证,这是一个安全漏洞,因为它会使代码容易受到中间人攻击。最好使用正确的 Paramiko SSH API,即 SSHClient。请参阅我的回答。

  • 可接受的答案 “有效” 。但由于使用了低级类 Transport ,它会绕过主机密钥验证,这是一个安全漏洞,因为它使代码容易受到 中间人攻击 .

    更好的方法是使用正确的 Paramiko SSH API,即 SSHClient ,它会验证主机密钥:

    import paramiko
    paramiko.util.log_to_file("paramiko.log")
    
    ssh = paramiko.SSHClient()
    ssh.connect(host, username='user', password='password')
    # or 
    # key = paramiko.RSAKey.from_private_key_file('id_rsa')
    # ssh.connect(host, username='user', pkey=key)
    
    sftp = ssh.open_sftp()
    
    sftp.get(remotepath, localpath)
    # or
    sftp.put(localpath, remotepath)
    

    有关验证主机密钥的详细信息,请参阅:
    Paramiko \'未知服务器\'

  • 如果您有 SSHClient,您还可以使用 open_sftp()

    import paramiko
    
    
    # lets say you have SSH client...
    client = paramiko.SSHClient()
    
    sftp = client.open_sftp()
    
    # then you can use upload & download as shown above
    ...
    
  • 首先,这不是一个独立的答案,而只是对@leoluk 答案的评论。其次,如果您有 SSHClient,您可以简单地执行 sftp = client.open_sftp()。

  • 除了第一个很好但取决于用户名/密码的答案之外,以下内容显示了如何使用 ssh 密钥:

    from paramiko import Transport, SFTPClient, RSAKey
    key = RSAKey(filename='path_to_my_rsakey')
    con = Transport('remote_host_name_or_ip', 22)
    con.connect(None,username='my_username', pkey=key)
    sftp = SFTPClient.from_transport(con)
    sftp.listdir(path='.')
    
  • RayT 2月前 0 只看Ta
    引用 10

    对于那些需要与需要私钥的 ssh/sftp 服务器集成并希望使用特定公钥对已知主机执行主机密钥验证的人来说,下面是带有 paramiko 的代码片段:

    import paramiko
    
    sftp_hostname = "target.hostname.com"
    sftp_username = "tartgetHostUsername"
    sftp_private_key = "/path/to/private_key_file.pvt"
    sftp_private_key_password = "private_key_file_passphrase_if_it_encrypted"
    sftp_public_key = "/path/to/public_certified_file.pub"
    sftp_port = 22
    remote_path = "."
    target_local_path = "/path/to/target/folder"
    
    ssh = paramiko.SSHClient()
        
    # Load target host public cert for host key verification
    ssh.load_host_keys(sftp_public_key)
    
    # Load encrypted private key and ssh connect
    key = paramiko.RSAKey.from_private_key_file(sftp_private_key, sftp_private_key_password)
    ssh.connect(host=sftp_hostname, port=sftp_port, username=sftp_username, pkey=key)
    
    # Get the sftp connection
    sftp_connection = ssh.open_sftp()
    
    directory_list = sftp_connection.listdir(remote_path)
    
    # ...
    
    if sftp_connection: sftp_connection.close()
    if ssh: ssh.close()
    

    请注意,仅支持经典 Openssh 格式 ,否则需要使用以下命令进行转换(也适用于最新的 Openssh 格式):

    $chmod 400 /path/to/private_key_file.pvt
    $ssh-keygen -p -f /path/to/private_key_file.pvt -m pem -P <currentPassphrase> -N <newPassphrase>
    

    为了避免中间人攻击,重要的是不要 paramiko.AutoAddPolicy() 像上面那样以编程方式使用和加载公共主机密钥,也不要从 ~/.ssh/known_hosts
    该文件必须采用以下格式 "<host_name> ssh-rsa AAAAB3NzaC1yc2EAAAA..."
    如果您没有公钥并且您信任目标主机(小心 mitm),您可以使用 $ssh-keyscan target.hostname.com 命令下载它。

    上述代码是我发现的唯一可以避免连接时出现以下错误的方法:

    paramiko.ssh_exception.SSHException: Server 'x.y.z' not found in known_hosts
    

    使用以下方式加载公共证书时也会出现此错误:

    key = paramiko.RSAKey(data=decodebytes(sftp_public_key))
    ssh_client.get_host_keys().add(sftp_hostname, 'ssh-rsa', key)
    

    另外,以下代码也无法让我加载证书(也尝试过用 base64 对证书进行编码):

    ssh_client=paramiko.SSHClient()
    
    rsa_key = paramiko.RSAKey.from_private_key_file(sftp_private_key, sftp_private_key_password)
    rsa_key.load_certificate(sftp_public_key)
    

    它总是以以下内容结束:

      File "/usr/local/lib/python3.9/site-packages/paramiko/pkey.py", line 720, in from_string
        key_blob = decodebytes(b(fields[1]))
      File "/usr/lib64/python3.9/base64.py", line 538, in decodebytes
        return binascii.a2b_base64(s)
    binascii.Error: Incorrect padding
    

    上述代码适用于与 GoAnywhere 的 SFTP 集成。

    我希望这会有所帮助,我没有找到任何可行的示例,并且花了很多时间进行搜索和测试。使用 pysftp 包装器的实现现在被认为从 2016 年开始停止。

返回
作者最近主题: