python - 使用 pysftp 和 Python 3 仅使用服务器指纹连接到 SFTP 服务器

标签 python ssh pysftp

我遇到了一种奇怪的情况,我需要第一次连接到 SFTP 服务器,但我似乎找不到一种方法来访问服务器的已知主机条目。我可以连接如果我说:

import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
with pysftp.Connection('host', username='me', password='pass', cnopts=cnopts):

但显然这会让你容易受到中间人的攻击。所以我尝试连接:

cnopts = pysftp.CnOpts(knownhosts='config/known_host')
cnopts.hostkeys = None

with pysftp.Connection(host, username=username, password=password, cnopts=cnopts) as sftp:

我收到了各种各样的错误消息。最近的一个是:

paramiko.hostkeys.InvalidHostKey

问题是我没有主机 key ,因为我是第一次连接。我尝试从其他连接获取 key 。我使用 WinSCP,但它将 key 存储在注册表文件中,并且格式与known_host 不同。我尝试使用 PuTTY 使用 ssh-keyscan 获取它,但服务器甚至不允许我启动终端 session 。我们不拥有这个盒子,托管提供商也不太可能为我们提供我们需要的东西。

我运气不好吗?我应该直接跳过检查 key 吗?

最佳答案

解决方案可以在 Python - pysftp / paramiko - Verify host key using its fingerprint 找到但我必须对其进行一些更改才能使用 Python 3。

import hashlib as hl


def trim_fingerprint(fingerprint):
    #if fingerprint.startswith('ecdsa-sha2-nistp384 384 '):
        #return fingerprint[len('ecdsa-sha2-nistp384 384 '):]
    return fingerprint


def clean_fingerprint(fingerprint):
    #return trim_fingerprint(fingerprint).replace(':', '')
    return trim_fingerprint(fingerprint)

class FingerprintKey:

    def __init__(self, fingerprint):
        self.fingerprint = clean_fingerprint(fingerprint)

    def compare(self, other):
        if callable(getattr(other, "get_fingerprint", None)):
            return other.get_fingerprint() == self.fingerprint
        elif clean_fingerprint(other) == self.get_fingerprint():
            return True
        #elif hl.md5(other).digest().encode('hex') == self.fingerprint:
        #The line below is required for Python 3.  Above is Python 2.
        elif hl.md5(other).hexdigest() == self.fingerprint:
            return True
        else:
            return False

    def __cmp__(self, other):
        return self.compare(other)

    def __contains__(self, other):
        return self.compare(other)

    def __eq__(self, other):
        return self.compare(other)

    def __ne__(self, other):
        return not self.compare(other)

    def get_fingerprint(self):
        return self.fingerprint

    def get_name(self):
        return u'ecdsa-sha2-nistp384'

    def asbytes(self):
         # Note: This returns itself.
         #   That way when comparisons are done to asbytes return value,
         #   this class can handle the comparison.
        return self

我必须手动从指纹中删除任何“:”,因为它从来没有允许脚本执行此操作。

用法:

options = pysftp.CnOpts()
options.hostkeys.clear()
options.hostkeys.add('www.sample.com', u'ecdsa-sha2-nistp384 384 ', AuthOnFingerPrint.FingerprintKey(serverkey))

其中serverkey是指纹。

关于python - 使用 pysftp 和 Python 3 仅使用服务器指纹连接到 SFTP 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47586224/

相关文章:

python - 将 Paramiko AutoAddPolicy 与 pysftp 结合使用

python - 集合中加权元素的组合,其中加权和等于固定整数(在Python中)

python - 如何在 Django 中访问通过表单集上传的图像?

linux - 添加 ssh 到退出 ubuntu 失败

java - Jenkins SSH 步骤无效私钥

c++ - 是否有 Vim 插件可以帮助我像 Visual Studio 一样进行调试?

python - 无法使用 pysftp 将文件夹上传到 Sftp

python - Google App Engine 教程中出现错误

python - 如何消除 matplotlib 中子图之间的间隙

python - 如何使用pysftp检查SFTP中是否存在文件?