python之paramiko模块

Paramiko

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

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

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

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

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

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

    • 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)code

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

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

    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登陆dns

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

      • 公钥.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()
相关文章
相关标签/搜索