我处于一种奇怪的情况下,我需要第一次连接到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
问题是我没有主机密钥,因为我是第一次连接。我试图从其他连接中获取密钥。我使用WinSCP,但是它将密钥存储在注册表文件中,并且格式与known_host不同。我试图使用ssh- keyscan用PuTTY来获取它,但是服务器甚至不允许我启动终端会话。我们不是盒子的主人,托管服务提供商不太可能提供我们所需的东西。
我不走运吗?我应该继续绕过按键检查吗?
可以在Python中找到解决方案-pysftp / paramiko- 使用其指纹验证主机密钥,但是我必须对其进行一些改动才能使用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是指纹。