zoukankan      html  css  js  c++  java
  • python之paramiko模块

    Paramiko

    • 和pexpect模块功能相似,不过更简洁。基于SSH远程登录,默认端口22

    • pip3 install paramiko 第三方模块,提供了SSH远程登录服务器执行命令和下载文件的功能。

    • 基于用户名和密码的SSHClient登录

      • AutoAddPolicy:遇到陌生主机,自动把信任主机添加到host_allow列表

      • RejectPolicy:遇到陌生主机直接拒绝

      • WarningPolicy:遇到陌生主机会提示,还是会添加

      • connect(hostname, port, username, password, pkey, key_filename, timeout, allow_agent, look_for_keys, compress, sock, gss_auth,gss_kex, gss_deleg_creds, gss_host, banner_timeout, auth_timeout, gss_trust_dns, passphrase)

      • exec_command(command, bufsize, timeout, get_pty, environment)

        • bufszie 缓冲区大小,默认为-1

      ssh = paramiko.SSHClient()#实例一个连接对象
      ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy)#设置允许连接陌生主机
      ssh.connect(hostname,username,port,password,pkey)#连接被管理机
      stdio,stdout,stderr = ssh.exec_command(cmd)#发送命令
      print(stdout.read().decode())#获取命令结果
      ssh.close()#关闭连接
    • 基于密钥的SSHClient登录

      • 连接端生成私钥和公钥,把公钥给服务器,连接只需私钥免密登录

        • 公钥.pub后缀 私钥没后缀

      • sudo ssh-keygen -t rsa 创建密钥文件

      • sudo ssh-copy-id -i 文件路径.pub root@xxx.xxx.xxx.xxx 分发公钥到服务器

      • paramiko.RSAKey.from_private_key_file('.ssh/id_rsa',password) 指定本地的RSA私钥文件,默认目录为''.ssh/id_rsa"

        • 如果创建密钥文件时设置有密码,就给参数password

        • 没设置就免密登录

      import paramiko
      ssh = paramiko.SSHClient()
      ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy)
      pkey = paramiko.RSAKey.from_private_key_file('.ssh/id_rsa')
      ssh.connect(hostname,port,username,pkey)
      stdio,stdout,stderr = ssh.exec_command(cmd)
      print(stdout.read(),stderr.read())
    • 基于Transport用户名和密码登录

      • Transport方式不止执行命令还可以执行下载上传命令

      • Transport(sock, default_window_size, default_max_packet_size, gss_kex, gss_deleg_creds)

      import paramiko
      #基于Transport用户名密码方式登录
      tran = paramiko.Transport(('192.168.0.1',22))
      tran.connect(username='root',password='123456')
      #实例一个SSHClient对象
      ssh = paramiko.SSHClient()
      #将SSHClient的对象的transport指定为以上的tran就可以和SSHClient一样执行命令
      ssh._transport = tran
      #执行命令
      stdio,stdout,stderr = ssh.exec_command(cmd)
      print(stdout.read())
    • 基于Transport的密钥登录

      pkey = paramiko.RSAKey.from_prviate_key_file('/.ssh/id_rsa')
      tran = paramiko.Transport(('192.168.0.1',22))
      tran.connect(username,pkey)
      ssh = paramiko.SSHClient()
      ssh._transport = tran
      ssh.exec_command(cmd)
    • Transport对象下载上传文件,SFTPClient方式

      • 一个Transport实例相当于创建一个通道进行文件传输

      • SFTPClient.from_transport(t, window_size, max_packet_size) t为创建的实例

    from paramiko import SFTPClient,Transport
    def connect_(ip,username,pkey):
        try:
            tran = Transport((ip,22))
            tran.connect(username,pkey)
            #把Transport实例通道传进来,指定连接的通道
            sftp = SFTPClient.from_transport(tran) 
        except Exception:
            return None
        return sftp
    def upload_file(sftp,localpath,remotepath):
        #上传文件
        sftp.put(localpath,remotepath)
    def download_file(sftp,localpath,remotepath):
        #下载文件
        sftp.get(localpath,remotepath)
    def main():
        pkey = RSAKey.from_prviate_key_file('/.ssh/id_rsa')
        sftp = connect_(ip, username, pkey)
        if sftp:
            upload_file(sftp, localpath, remotepath)
            #download_file(sftp, localpath, remotepath)
        sftp.close()
    if __name__ == '__main__':
        main()
    • 接受命令的虚拟终端

      • 1.开一个socket连接 tran = Transport((ip,port))

      • 2.开启一个客户端 tran.start_client()

      • 3.登录服务器 tran.auth_password(username, password, event, fallback)

      • 4.创建一个会话终端对象 channel = tran.open_session(window_size=Nonemax_packet_size=Nonetimeout=None )

      • 5.获取终端 channel.get_pty()

      • 6.激活终端 channel.invoke_shell()

      • 7.发送命令 channel.sendall(cmd)

      • 8.获取命令结果 channel.recv(1024)

    #类似xshell的终端模拟软件,保持一个shell状态
    import paramiko
    import os
    import sys
    import select
    def connect_(username,ip,password):
        try:
            tran = paramiko.Transport((ip,22))#建立一个socket通道
            tran.start_client() #启动一个客户端
            tran.auth_password(username=username, password=password)#用户名和密码登录
            channel = tran.open_session()#打开一个会话通道
            channel.get_pty()#获取终端
            channel.invoke_shell()#激活终端 
        except paramiko.ssh_exception.SSHException:
            print('连接错误')
            return None
        return channel
    # 下面就可以执行你所有的操作,用select实现
    # 对输入终端sys.stdin和 通道进行监控,
    # 当用户在终端输入命令后,将命令交给channel通道,这个时候sys.stdin就发生变化,select就可以感知
    # channel的发送命令、获取结果过程其实就是一个socket的发送和接受信息的过程
    def main():
        username = 'root'
        ip = '192.168.0.1'
        password = '123456'
        channel = connect_(username, ip, password)
        if channel:
            while True:
                readlist,writelist,errlist = select.select([channel,sys.stdin],[],[])
                #发送命令
                if sys.stdin in readlist:
                    cmd = sys.stdin.read(1)
                    channel.sendall(cmd)
    ​
                #获取命令结果
                if channel in readlist:
                    res = channel.recv(1024)#接受结果
                    if not res:#判断结果是否为空
                        print('断开连接')
                        break
                    sys.stdout.write(res.decode())#输出到屏幕
                    sys.stdout.flush()#刷新缓冲区
            channel.close()
            tran.close()
    if __name__ == '__main__':
        main()
  • 相关阅读:
    Python进阶08 生成器
    Python进阶07 迭代
    Python进阶06 列表推导
    Python进阶05 函数property
    Python基础14 集合
    支付宝支付和微信消息推送
    Redis
    django之contenttype
    数据分析系列
    IPython
  • 原文地址:https://www.cnblogs.com/kmnskd/p/9994054.html
Copyright © 2011-2022 走看看