3

我正在从paramiko github的 demo 文件夹中运行 demo_sftp.py 文件。我在 PyDev 中单步执行它并预计会出现错误,因为我没有尝试连接的服务器的密钥,但我收到打印语句说脚本无法打开主机密钥文件然后它继续进行并进行了获取和放置。

这是一个代码片段。

try:
    host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
except IOError:
    try:
        # try ~/ssh/ too, because windows can't have a folder named ~/.ssh/
        host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/ssh/known_hosts'))
    except IOError:
        print '*** Unable to open host keys file'
        host_keys = {}

if host_keys.has_key(hostname):
    hostkeytype = host_keys[hostname].keys()[0]
    hostkey = host_keys[hostname][hostkeytype]
    print 'Using host key of type %s' % hostkeytype


# now, connect and use paramiko Transport to negotiate SSH2 across the connection
try:
    t = paramiko.Transport((hostname, port))
    t.connect(username=username, password=password, hostkey=hostkey)
    sftp = paramiko.SFTPClient.from_transport(t)

    # dirlist on remote host
    dirlist = sftp.listdir('.')
    print "Dirlist:", dirlist

我真的希望它会转到 t.connect 行上的 except,因为 hostkey 是 NoneType。

当我打开一个 ssh 连接时

    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    try:
        ssh.connect('.'.join([self.name, self.domain]),
                    username=self.username, password=self.password)
        stdin, stdout, stderr = ssh.exec_command("ps aux | grep Xvnc | wc -l")

我必须有 AutoAddPolicy() 行,否则它会失败。那么有什么区别呢?显然我只是在学习这个,但我认为 sftp 会像 ssh 一样严格。

4

2 回答 2

2

看起来这是一种可以接受的做法。

来自 Transport.connect 的评论

'''
Negotiate an SSH2 session, and optionally verify the server's host key
and authenticate using a password or private key.  This is a shortcut
for L{start_client}, L{get_remote_server_key}, and
L{Transport.auth_password} or L{Transport.auth_publickey}.  Use those
methods if you want more control.

You can use this method immediately after creating a Transport to
negotiate encryption with a server.  If it fails, an exception will be
thrown.  On success, the method will return cleanly, and an encrypted
session exists.  You may immediately call L{open_channel} or
L{open_session} to get a L{Channel} object, which is used for data
transfer.

@note: If you fail to supply a password or private key, this method may
succeed, but a subsequent L{open_channel} or L{open_session} call may
fail because you haven't authenticated yet.
'''

来自 SSHClient.connect 的评论

'''
Connect to an SSH server and authenticate to it.  The server's host key
is checked against the system host keys (see L{load_system_host_keys})
and any local host keys (L{load_host_keys}).  If the server's hostname
is not found in either set of host keys, the missing host key policy
is used (see L{set_missing_host_key_policy}).  The default policy is
to reject the key and raise an L{SSHException}.
'''

可能是因为 sftp 只能传输数据,而 ssh 可以运行终端命令。我确实觉得有趣的是,中间人攻击似乎并不令人担忧。

于 2013-07-18T14:30:55.263 回答
0

您可以使用以下语法

    import pysftp
    cnopts = pysftp.CnOpts()
    cnopts.hostkeys = None
    with pysftp.Connection(hostname, port=port, username=user_id, password=password,
                           cnopts=cnopts) as sftp:
        with sftp.cd(self.directory):  # temporarily chdir to public
            sftp.put(filepath)
于 2020-07-24T12:39:20.097 回答