web-dev-qa-db-ja.com

pysftpでホストキーを確認する

私はpysftpを使用してプログラムを書いていますが、C:\Users\JohnCalvin\.ssh\known_hostsに対してSSHホストキーを検証したいと考えています。

PuTTYを使用して、ターミナルプログラムはそれをレジストリ[HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys]に保存しています。

PysftpとPuTTYの違いを調整するにはどうすればよいですか?

私のコードは:

import pysftp as sftp

def Push_file_to_server():
    s = sftp.Connection(Host='138.99.99.129', username='root', password='*********')
    local_path = "testme.txt"
    remote_path = "/home/testme.txt"

    s.put(local_path, remote_path)
    s.close()

Push_file_to_server()

私が受け取っているエラー応答は次のとおりです。

E:\ Program Files(x86)\ Anaconda3\lib\site-packages\pysftp__init __。py:61:UserWarning:
C:\ Users\JohnCalvin.ssh\known_hostsからHostKeysをロードできませんでした。
HostKeys(cnopts.hostkeys.load(filename))を明示的にロードするか、HostKeyチェックを無効にする(cnopts.hostkeys = None)必要があります。 warnings.warn(wmsg、UserWarning)トレースバック(最後の最後の呼び出し):ファイル "E:\ OneDrive\Python\GIT\DigitalCloud\pysftp_tutorial.py"、14行目、Push_file_to_server()ファイル "E:\ OneDrive\Python\GIT\DigitalCloud\pysftp_tutorial.py "、7行目、Push_file_to_server s = sftp.Connection(Host = '138.99.99.129'、username = 'root'、password = '********')ファイル" E :\ Program Files(x86)\ Anaconda3\lib\site-packages\pysftp__init __。py "、132行目、init self._tconnect ['hostkey'] = self._cnopts.get_hostkey(Host)ファイル "E:\ Program Files(x86)\ Anaconda3\lib\site-packages\pysftp__init __。py"、行71、get_hostkey raise SSHException( "ホスト%sのホストキーが見つかりません。"%ホスト)paramiko.ssh_exception.SSHException :ホスト138.99.99.129のホストキーが見つかりません。例外は無視されます:>トレースバック(最後の最後の呼び出し):ファイル "E:\ Program Files(x86)\ Anaconda3\lib\site-packages\pysftp__init __。py"、行1013、del self .close()ファイル "E:\ Program Files(x86)\ Anaconda3\lib\site-packages\pysftp__init __。py"、行784、self._sftp_live:AttributeError: 'Connection'オブジェクトに属性 '_sftp_live'がない場合は近い

47

次の解決策は私のために働いた:

import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None   
with pysftp.Connection(Host, username, password, cnopts=cnopts) as sftp:
    sftp.put(local_path, remote_path)

詳細はこちらで確認できます: https://stackoverflow.com/a/38355117/1060738

61
Noam Peled

セキュリティを気にしない限り、cnopts.hostkeys = Noneを設定しないでください(最も賛成の答えが示すように)。そうすることで、 中間者攻撃 に対する保護を失います。


信頼できるホストキーを管理するには、CnOpts.hostkeysHostKeys を返します)を使用します。

cnopts = pysftp.CnOpts()
cnopts.hostkeys.load('known_hosts')

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

known_hostsには、次のような形式のサーバー公開キーが含まれます。

example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB...

外部ファイルを使用したくない場合は、使用することもできます

from base64 import decodebytes
# ...

keydata = b"""AAAAB3NzaC1yc2EAAAADAQAB..."""
key = paramiko.RSAKey(data=decodebytes(keydata))
cnopts = pysftp.CnOpts()
cnopts.hostkeys.add('example.com', 'ssh-rsa', key)

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

この形式でホストキーを取得する簡単な方法は、OpenSSH ssh-keyscan を使用することです。

$ ssh-keyscan example.com
# example.com SSH-2.0-OpenSSH_5.3
example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB...

アプリケーションに同じことを自動的に行わせることもできます。
pysftpでParamiko AutoAddPolicyを使用
(新しいホストのホストキーをknown_hostsに自動的に追加しますが、既知のホストキーの場合、変更されたキーは受け入れません)


絶対的なセキュリティを確保するために、ホストキーをリモートで取得しないでください。まだ攻撃されていない場合は確認できません。

私の記事を参照してください サーバーを認証するためにSSHホストキーフィンガープリントをどこで取得しますか?
WinSCP SFTPクライアント用ですが、そこにある情報のほとんどは一般的に有効です。


指紋のみを使用してホストキーを確認する必要がある場合は、 Python-pysftp/paramiko-指紋を使用してホストキーを確認 を参照してください。

39
Martin Prikryl

0.2.8バージョンのpysftpライブラリを使用してみてください。 $ pip uninstall pysftp && pip install pysftp==0.2.8

そしてこれを試してください:

try:
    ftp = pysftp.Connection(Host, username=user, password=password)
 except:
    print("Couldn't connect to ftp")
    return False

なんでこれ?基本的には、pysftpの0.2.9のすべての詳細に関するバグです https://github.com/Yenthe666/auto_backup/issues/47

3
wilo087

pysftp github forkauto_add_keyを実装しました。

auto_add_keyは、known_hostsの場合、auto_add_key=Trueにキーを追加します
known_hosts内のホストにキーが存在すると、このキーがチェックされます。

セキュリティの問題について Martin Prikryl -> answer を参照してください。

絶対的なセキュリティを確保するために、ホストキーをリモートで取得しないでください。まだ攻撃されていない場合は確認できません。

import pysftp as sftp

def Push_file_to_server():
    s = sftp.Connection(Host='138.99.99.129', username='root', password='pass', auto_add_key=True)
    local_path = "testme.txt"
    remote_path = "/home/testme.txt"

    s.put(local_path, remote_path)
    s.close()

Push_file_to_server()

注: コンテキストマネージャーを使用する理由

import pysftp
with pysftp.Connection(Host, username="whatever", password="whatever", auto_add_key=True) as sftp:
    #do your stuff here
#connection closed
0
Fabian

こんにちはあなたをよく理解していれば、同じ問題を抱えていました。使用しているpysftpのバージョンを確認してください。 0.2.9が0.2.8にダウングレードされている最新の場合。これをチェックしてください。 https://github.com/Yenthe666/auto_backup/issues/47

0
Omagano Uushona