我遇到了一种奇怪的情况,我需要第一次连接到 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是指纹。


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!