您可以将类似文件的对象作为参数传递给Python中的pysftp.CnOpts吗

发布于 2025-01-09 14:31:13 字数 740 浏览 0 评论 0原文

我有一个 Python 脚本,它使用 pysftp 创建到远程主机的 SFTP 连接,如下所示:

 cnopts = pysftp.CnOpts(knownhosts='known_hosts') # REFERENCE A STATIC FILE
 sftp = pysftp.Connection(host=parm0, username=parm1, password=parm2, cnopts=cnopts)

文件“known_hosts”位于 Python 脚本所在的同一目录中。我想消除静态 Know_hosts 文件并将类似文件的对象传递给 pysftp.CnOpts() ,如下所示:

 remote_public_key = subprocess.getoutput('ssh-keyscan myRemoteSFTPServer.com')
 key_buffer.write(remote_public_key)
 key_buffer.seek(0)
 cnopts = pysftp.CnOpts(knownhosts=key_buffer.read()) # REFERENCE A FILE LIKE OBJECT
 sftp = pysftp.Connection(host=parm0, username=parm1, password=parm2, cnopts=cnopts)     
 

但是,这失败了。是否可以将类似文件的对象作为参数传递给 pysftp.CnOpts,如果可以,我该怎么做?

I have a Python script that uses pysftp to create an SFTP connection to a remote host as shown:

 cnopts = pysftp.CnOpts(knownhosts='known_hosts') # REFERENCE A STATIC FILE
 sftp = pysftp.Connection(host=parm0, username=parm1, password=parm2, cnopts=cnopts)

The file "known_hosts" lives in the same directory where the Python script lives. I would like to eliminate the static know_hosts file and pass a file like object to pysftp.CnOpts() like this:

 remote_public_key = subprocess.getoutput('ssh-keyscan myRemoteSFTPServer.com')
 key_buffer.write(remote_public_key)
 key_buffer.seek(0)
 cnopts = pysftp.CnOpts(knownhosts=key_buffer.read()) # REFERENCE A FILE LIKE OBJECT
 sftp = pysftp.Connection(host=parm0, username=parm1, password=parm2, cnopts=cnopts)     
 

However, this fails. Is it possible to pass a file like object as a parameter to pysftp.CnOpts, and if so, how do I do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

腹黑女流氓 2025-01-16 14:31:14

您是否尝试

cnopts = pysftp.CnOpts(knownhosts=key_buffer)

只传递类似文件的对象?如果您执行 key_buffer.read() ,这将相当于

cnopts = pysftp.CnOpts(knownhosts="# 127.0.0.1:22 SSH-2.0-OpenSSH_8.1...")

缓冲区中的任何内容,并且 pysftp 可能会尝试将其解释为文件名。

否则,

with tempfile.NamedTemporaryFile("wb") as key_buffer:
    remote_public_key = subprocess.getoutput('ssh-keyscan myRemoteSFTPServer.com')
    key_buffer.write(remote_public_key)
    key_buffer.seek(0)
    cnopts = pysftp.CnOpts(knownhosts=key_buffer.name)
    sftp = pysftp.Connection(host=parm0, username=parm1, password=parm2, cnopts=cnopts)     

NamedTemporaryFile 会在 with 块的末尾自动删除。)

Did you try

cnopts = pysftp.CnOpts(knownhosts=key_buffer)

to just pass in the file-like object? If you do key_buffer.read(), that'd be equivalent to

cnopts = pysftp.CnOpts(knownhosts="# 127.0.0.1:22 SSH-2.0-OpenSSH_8.1...")

or whatever is in the buffer, and pysftp would likely try to interpret that as a filename.

Failing that,

with tempfile.NamedTemporaryFile("wb") as key_buffer:
    remote_public_key = subprocess.getoutput('ssh-keyscan myRemoteSFTPServer.com')
    key_buffer.write(remote_public_key)
    key_buffer.seek(0)
    cnopts = pysftp.CnOpts(knownhosts=key_buffer.name)
    sftp = pysftp.Connection(host=parm0, username=parm1, password=parm2, cnopts=cnopts)     

(NamedTemporaryFiles are automagically deleted at the end of the with block.)

晚雾 2025-01-16 14:31:14

谢谢@AKX。我最终重写了我的 Python 脚本以使用 Paramiko 而不是 pysftp 并得到了一个可行的解决方案。首先,我创建了一个名为 get_remote Server_key 的函数来生成 SSH 密钥。然后我调用了 Paramiko Transport 对象的 add_server_key(pkey) 方法。这样我就不必传递类似文件的对象。

def get_remote_server_key(ip: str, port: int=22) -> paramiko.pkey.PKey:
    # Returns PKey for given server
    # :param ip: IP or Hostname
    # :param port: Port
    # :return: Returns PKey
    my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    my_socket.settimeout(10)
    my_socket.connect((ip, port))
    my_transport = paramiko.Transport(my_socket)
    my_transport.start_client()
    ssh_key = my_transport.get_remote_server_key()
    my_transport.close()
    my_socket.close()
    return ssh_key 

def getSFTPConnection(server, port, uid, pw):
    client = paramiko.SSHClient()
    **pkey = get_remote_server_key(server,port)**
    trans = paramiko.Transport((server, port))
    **trans.add_server_key(pkey)**
    trans.connect(username=uid, password=pw)
    sftp = paramiko.SFTPClient.from_transport(trans)
    return sftp

sftp=getSFTPConnection(server, port, uid, password)

Thanks @AKX. I ended up rewriting my Python script to use Paramiko instead of pysftp and have a working solution. First I created a function called get_remote Server_key to generate an SSH key. Then I called the add_server_key(pkey) method of the Paramiko Transport object. This way I don't have to pass a file like object.

def get_remote_server_key(ip: str, port: int=22) -> paramiko.pkey.PKey:
    # Returns PKey for given server
    # :param ip: IP or Hostname
    # :param port: Port
    # :return: Returns PKey
    my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    my_socket.settimeout(10)
    my_socket.connect((ip, port))
    my_transport = paramiko.Transport(my_socket)
    my_transport.start_client()
    ssh_key = my_transport.get_remote_server_key()
    my_transport.close()
    my_socket.close()
    return ssh_key 

def getSFTPConnection(server, port, uid, pw):
    client = paramiko.SSHClient()
    **pkey = get_remote_server_key(server,port)**
    trans = paramiko.Transport((server, port))
    **trans.add_server_key(pkey)**
    trans.connect(username=uid, password=pw)
    sftp = paramiko.SFTPClient.from_transport(trans)
    return sftp

sftp=getSFTPConnection(server, port, uid, password)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文