美文网首页
Paramiko的SSH和SFTP使用

Paramiko的SSH和SFTP使用

作者: 点滴技术 | 来源:发表于2019-12-01 22:04 被阅读0次

    [TOC]

    1. 概述

    本来是不想写Paramiko的,因为我觉得之前的一篇关于Netmiko模块更适合网工,后来发现paramiko有包含SFTP功能,所以还是有必要来讲讲,毕竟我们在设备上是要经常下载配置、上传版本/升级版本用的,而且SFTP比FTP、TFTP更安全。

    所以, 你也不用借助其他工具来上传、下载了,通通用 'Python' 来帮你搞定了。

    SSH和SFTP都是使用一样的端口号 22。如果对数据安全传输较重视,那么SFTP替代FTP、TFTP是首选。

    实验环境说明:

    • 一台思科路由器,用于SSH登陆;
    • 一台华为交换机,用于SFTP上传/下载;
    • PyCharm Pro

    2. Paramiko的基本使用

    2.1 SSHClient关键参数介绍

    connect()函数:

    用途:用于连接远端主机,其中'hostname'为必选参数。

    常用参数
    hostname    //远端主机,填写IP和域名都可以
    port=SSH_PORT   //缺省为22端口
    username=None   //用于登陆远端主机使用的用户名
    password=None   //用于登陆远端主机使用的密码
    pkey=None   //使用私钥用于身份认证,也叫'免密'登陆
    key_filename=None   //使用私钥文件名
    timeout=None    //tcp连接超时时间
    allow_agent=True    //缺省允许连接到ssh代理
    look_for_keys=True  //缺省在~/.ssh中搜索私钥文件,默认为True 允许
    compress=False  //缺省没有开启压缩
    

    load_system_host_keys()函数:

    用途:用于加载主机密钥,密钥保存"known_hosts"文件中。

    filename=None   //缺省会加载"~/.ssh/known_hosts"文件
    

    set_missing_host_key_policy()函数:

    用途:用于检查远端主机在本地'host keys'是否有记录并使用哪种策略。

    #目前支持的三种策略: 
    1.AutoAddPolicy     //自动添加主机名及主机密钥到本地HostKeys对象,不依赖load_system_host_key的配置。即新建立ssh连接时不需要再输入yes或no进行确认
    2.WarningPolicy     //用于记录一个未知的主机密钥的python警告。并接受,功能上和AutoAddPolicy类似,但是会提示是新连接
    3.RejectPolicy      //自动拒绝未知的主机名和密钥,依赖load_system_host_key的配置。此为默认选项
    

    exec_command()函数:

    用途:用于在远端主机执行的命令,并返回输入、输出、错误信息。

    command //执行的命令
    stdin, stdout, stderr   //分别表示输入、输出、错误
    

    2.2 SSHClient常用示例

    2.2.1 通过用户名和密码方式登陆:

    import paramiko
    
    def ssh_client():
        # 创建一个实例化
        ssh = paramiko.SSHClient()
        # 加载系统HostKeys密钥
        ssh.load_system_host_keys()
        # 自动添加策略,保存远端主机的主机名和密钥信息,如果不添加,那么不在本地knows_hosts文件中记录的主机将无法连接,默认拒接
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        #连接远端主机
        ssh.connect('192.168.0.101',port=22, username='admin', password='Admin@123')
        #执行命令
        stdin, stdout,stderr = ssh.exec_command('show ip int br')
        print(stdout.read().decode('utf-8'))
        #关闭连接
        ssh.close()
    
    if __name__ == '__main__':
        ssh_client()
    

    执行代码返回结果如下:

    2.2.2 通过用户名和密码方式登陆 ( transport方式 )

    def ssh_client():
        # 创建一个实例化
        ssh = paramiko.SSHClient()
        #transport封装
        t = paramiko.Transport('192.168.0.101', 22)
        t.connect(username='admin', password='Admin@123')
        ssh._transport = t
    
        # 加载系统HostKeys密钥
        ssh.load_system_host_keys()
        # 自动添加策略,保存远端主机的主机名和密钥信息,如果不添加,那么不在本地knows_hosts文件中记录的主机将无法连接,默认拒接
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        #执行命令
        stdin, stdout,stderr = ssh.exec_command('show ip int br')
        print(stdout.read().decode('utf-8'))
        #关闭连接
        ssh.close()
    
    if __name__ == '__main__':
        ssh_client()
    

    执行代码返回结果如下:

    ​ 结果同上,输出结果一样。

    2.2.3 通过用户名和密钥方式登陆

    思科路由器公钥配置:

    username admin privilege 15 password Admin@123
    ip domain name cisco.com
    crypto key generate rsa modulus 1024
    ip ssh version 2
    ip ssh pubkey-chain
      username admin
       key-hash ssh-rsa 560DE41351E40FF6C237F9BBFF4238AC singvis@DESKTOP-IQ964AEendend
    line vty 0 4
     exec-timeout 5 0
     logging synchronous
     login local
     transport input ssh
     privilege level 15
    

    python代码:

    import paramiko
    
    def ssh_client():
        #私钥的绝对路径
        private = paramiko.RSAKey.from_private_key_file(r'C:\Users\singvis\Documents\Identity')
    
        # 创建一个实例化
        ssh = paramiko.SSHClient()
        # 加载系统HostKeys密钥
        ssh.load_system_host_keys()
        # 自动添加策略,保存远端主机的主机名和密钥信息,如果不添加,那么不在本地knows_hosts文件中记录的主机将无法连接,默认拒接
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        #连接远端主机,此处不需要密码,为私钥文件
        ssh.connect('192.168.0.101',port=22, username='admin', pkey=private)
        #执行命令
        stdin, stdout,stderr = ssh.exec_command('show ip int br')
        print(stdout.read().decode('utf-8'))
        ssh.close()
    
    if __name__ == '__main__':
        ssh_client()
    

    通过SecurityCRT采用密钥方式登陆192.168.0.101,不用输入密码,直接就登陆:

    说明:密钥的生成路径:tools->creat public key ( 本次通过SecurityCRT )

    2.3 SFTPClient关键参数介绍

    SFTPCLient作为一个sftp的客户端对象,根据ssh传输协议的sftp会话,实现远程文件操作,如上传、下载、权限、状态。

    from_transport(cls,t)   //创建一个已连通的SFTP客户端通道
    put(localpath, remotepath, callback=None, confirm=True) //将本地文件上传到远端主机
    get(remotepath, localpath, callback=None)   //从远端主机下载文件到本地
    mkdir()     //创建目录
    remove()    //删除目录
    rename()    //重命名目录
    stat()      //查看文件状态
    listdir()   //列出目录下的文件
    

    2.4 SFTPClient常用示例

    以华为交换机为例子说明,交换机配置如下:

    rsa local-key-pair create
    #
    stelnet server enable
    sftp server enable
    #
    aaa
     local-user admin password simple Admin@123
     local-user admin privilege level 15
     local-user admin service-type terminal ssh
     #
    ssh authentication-type default password
    ssh user admin authentication-type password
    ssh user admin service-type all
    ssh user admin sftp-directory flash:/
    #
    user-interface vty 0 4
     authentication-mode aaa
     protocol inbound ssh
    

    Python代码如下:

    import paramiko
    
    def sftp_put():
        #文件路径
        local_file =r'D:\test\123.txt'
        remote_file ='flash:/123.txt'
    
        t = paramiko.Transport('192.168.0.200', 22)
        t.connect(username='admin', password='Admin@123')
    
        sftp = paramiko.SFTPClient.from_transport(t)
        sftp.put(local_file,remote_file)
        t.close()
    
    def sftp_get():
        local_path = r'D:\test\vrpcfg.zip'
        remote_path = 'flash:/vrpcfg.zip'
    
        t = paramiko.Transport('192.168.0.200', 22)
        t.connect(username='admin', password='Admin@123')
        #
        sftp = paramiko.SFTPClient.from_transport(t)
        sftp.get(remote_path, local_path)
        t.close()
    
    if __name__ == '__main__':
        sftp_put()
        sftp_get()
    

    执行代码返回结果如下:

    3. 完整代码

    #!/usr/bin/env python
    #coding:utf-8
    #欢迎关注微信公众号:点滴技术
    #这里有靠谱的、有价值的、共成长的,专属于网络攻城狮
    
    import paramiko, time
    from paramiko.ssh_exception import NoValidConnectionsError,AuthenticationException
    
    def ssh_client(host, user, pwd, cmds, verbose=True):
        # 私钥文件的存放路径
        # private = paramiko.RSAKey.from_private_key_file(r'C:\Users\singvis\Documents\Identity')
        # 创建一个实例化
        ssh = paramiko.SSHClient()
        # 加载系统SSH密钥
        ssh.load_system_host_keys()
        # 自动添加策略,保存服务器的主机名和密钥信息,如果不添加,那么不在本地knows_hosts文件中记录的主机将无法连接,默认拒接
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        # 连接设备
        try:
            ssh.connect(hostname=host,
                        username=user,
                        timeout=5,
                        compress=True,
                        password=pwd
                        #pkey=private,  #可以采用密钥连接
                        )
    
            print("正在连接主机{}.....".format(host))
        except NoValidConnectionsError:
            print('连接出现了问题')
        except AuthenticationException:
            print('用户名或密码错误')
        except Exception as e:
            print('其他错误问题{}'.format(e))
        finally:
            #激活交互式shell
            chan = ssh.invoke_shell()
            time.sleep(1)
    
            for cmd in cmds:
                chan.send(cmd.encode())
                #一定要有回车'Enter'这个动作
                chan.send(b'\n')
                time.sleep(2)
                r = chan.recv(40960).decode()
                if verbose:
                    print(r)
            chan.close()
            ssh.close()
    
    def sftp_get(ip, user, pwd, local_file,remote_file, port=22):
        try:
            t = paramiko.Transport(ip, port)
            t.connect(username=user, password=pwd)
            sftp = paramiko.SFTPClient.from_transport(t)
            sftp.get(remote_file, local_file)
            t.close()
    
        except Exception as e:
            print(e)
    
    
    def sftp_put(ip, user, pwd, local_file, remote_file, port=22):
        try:
            t = paramiko.Transport(ip, port)
            t.connect(username=user, password=pwd)
            sftp = paramiko.SFTPClient.from_transport(t)
            sftp.put(local_file, remote_file)
            t.close()
    
        except Exception as e:
            print(e)
    
    
    if __name__ == '__main__':
        '''
        不要运行的,请注释掉,前面加'#'符号
        '''
        ip = '192.168.0.101'
        user= 'admin'
        pwd= 'Admin@123'
        # local_file = r'D:\test\123.txt'
        # remote_file = 'flash:/vrpcfg.zip'
        # sftp_get(ip='192.168.0.200', user=user, pwd=pwd, remote_file=remote_file, local_file=r'D:\test\vrpcfg.zip')
        # sftp_put(ip='192.168.0.200', user=user, pwd=pwd, local_file=local_file, remote_file='flash:/123.txt')
    
        cmds = ['terminal length 0', 'show version', 'show ip int br','show ip route']
        # cmds = ['disp ip int br','disp device','disp clock']
        ssh_client(ip, user, pwd, cmds)
    

    参考信息:

    思科路由器和交换机SSH配置

    相关文章

      网友评论

          本文标题:Paramiko的SSH和SFTP使用

          本文链接:https://www.haomeiwen.com/subject/flmtgctx.html