####python——paramiko模块####

1.什么是paramiko?
paramiko是一个基于ssh用于连接远程服务器做操作的模块,该模块可以进行远程执行命令或文件操作

###paramiko远程密码连接###
1.import paramiko #导入模块
2.client = paramiko.SSHClient( ) #创建一个ssh对象
3.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #首次连接时需要输入yea完成认证,这步是自动选择yes
4.连接主机。参数分别是主机ip,要连接的用户和用户密码
5.client.exec_command(‘要执行的命令’) # 连接成功后,在被连接的主机中执行命令,这个操作返回一个元组,元组中存在三个元素,分别为标准输入 标准输出 错误输出
6.stdin,stdout,stderr = client.exec_command(’’) #使用变量接受返回的内容
7.stdout.read( ).decode(‘utf-8’) #获取标准输出结果 decode(‘utf-8’) 返回结果中有中文时正常显示

import paramiko 
#ssh username@ip
client = paramiko.SSHClient()  #创建一个ssh对象
#解决的问题:如果之前没有连接过的ip(主机),会出现
"""
The authenticity of host '172.25.0.101 (172.25.0.101)' can't be established.
ECDSA key fingerprint is 9d:37:08:8e:a4:ad:45:b5:eb:69:6f:d2:88:d3:da:8c.
Are you sure you want to continue connecting (yes/no)? yes
"""
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())   # 自动选择yes
#连接服务器
client.connect(
    hostname='172.25.254.40',
    username='root',
    password='redhat'
)
#执行操作
#标准输入 标准输出 错误输出
stdin,stdout,stderr = client.exec_command('cat /ect/passwd')
#获取命令的执行结果
print(stdout.read().decode('utf-8')) 
client.close() # 关闭连接
 运行结果
 root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin

###paramiko批量远程密码连接###
当需要处理的主机比较多时,可以使用批量连接的方式。 将需要连接的主机ip 、用户名以及密码等信息按照固定的格式保存到一个文件中,通过读取文件中的内容实现自动批量连接
1.将上述的远程密码连接主机操作定义成一个函数
2.将存有需要批量连接的主机的信息文件用循环遍历的方式对所有主机进行连接(文件对象也是一个可以迭代的对象)

from paramiko.ssh_exception import\
    NoValidConnectionsError,AuthenticationException


def connect(cmd,hostname,user,password):  ##创建的函数需要四个参数:要执行的命令、主机ip、用户名、用户密码
    import paramiko
  client = paramiko.SSHClient()   # 创建一个ssh对象
  client.set_missing_host_key_policy(paramiko.AutoAddPolicy())    # 解决的问题:如果之前没有连接过的ip(主机),会出现
    try:
       
           client.connect(   
            hostname=hostname, # 连接的服务器
            username=user,
            password=password
        )
    except NoValidConnectionsError as e:
        return '主机%s连接失败' %(hostname)
    except AuthenticationException as e:
        return '主机%s密码错误' %(hostname)
    except Exception as e:
        return '未知错误:',e
   stdin,stdout,stderr = client.exec_command('hostname')      #执行操作并使用变量进行接受
    # 获取命令的执行结果
    print(stdout.read().decode('utf-8'))

    # 关闭连接
    client.close()

if __name__ == '__main__':
    with open('hostname') as f:   #打开存有要连接主机信息的文件
        for line in f:  #使用循环遍历文件的每一行
           #172.25.254.40:root:westos   #文件的格式
            hostname,username,password = line.strip().split(':')  #将文件的每行的内容以:为标志分割
            res = connect('pwd',hostname,username,password) 
            print(hostname.center(50,'*'))
            print('主机名:',res)

###paramiko基于公钥和私钥的连接###
由于 paramiko是基于ssh进行的连接,所以可以使用公钥和私钥使指定的用户对指定主机的指定用户进行免密连接;

连接需要提前将公钥放置被连接主机的指定用户/.ssh 目录中,将私钥放置在客户端主机的指定用户~/.ssh 中 设置ssh服务公钥以及私钥

连接操作步骤与第一个所以密码连接基本一致,在连接主机的时候不在使用密码,而是使用生成的私钥对象。

kiosk@foundation40 ~]$ cd .ssh   
[kiosk@foundation40 .ssh]$ ssh-keygen ##生成密钥
Generating public/private rsa key pair.
Enter file in which to save the key (/home/kiosk/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/kiosk/.ssh/id_rsa.
Your public key has been saved in /home/kiosk/.ssh/id_rsa.pub.
The key fingerprint is:
d3:49:f5:a0:20:a9:fe:90:37:93:6d:43:d1:b5:28:79 [email protected]
The key's randomart image is:
+--[ RSA 2048]----+
|      .... .+    |
|      ...o.+ +   |
|     .  o.E . .  |
|    .   .= .     |
|   . . +S o      |
|    + = +.       |
|     + + .       |
|      .          |
|                 |
+-----------------+
[kiosk@foundation40 .ssh]$ ls
authorized_keys  id_rsa  id_rsa.pub  known_hosts

[kiosk@foundation40 .ssh]$ ssh-copy-id -i /home/kiosk/.ssh/id_rsa.pub  [email protected]  #将公钥给被连接的主机
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.

import paramiko  #导入模块
client = paramiko.SSHClient()  #生成ssh对象
private_key = paramiko.RSAKey.\
    from_private_key_file('/home/kiosk/.ssh/id_rsa')   #生成一个私钥对象
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())  #自动输入yes
client.connect(
    hostname='172.25.254.140',
    username= 'root',
    pkey=private_key   #连接的时候使用私钥进行验证
)
#执行操作
# #标准输入   标准输出  标准错误输出
stdin,stdout,stderr = client.exec_command('ifconfig')  ##输入命令
print(stdout.read().decode('utf-8'))#获取执行命令的结果,'utf-8'允许中文
client.close() #关闭连接

###文件的上传和下载##

import paramiko
from paramiko import AuthenticationException,SSHException

def put(hostname,password,source_name,target_name):#主机名 密码
    try: #捕获异常
        tarnsport = paramiko.Transport(hostname,22)  ##ftp连接端口22,建立与主机的通道
        tarnsport.connect(username='root',password=password) #验证用户名和密码是否正确
        sftp = paramiko.SFTPClient.from_transport(tarnsport) # 根据创建名验证成功的通道
    except AuthenticationException as e:
        return '主机%s用户名或密码错误' %(hostname)
    except Exception as e :  #捕获未知错误
        return '未知错误'
    else:
        #上传文件
        sftp.put(source_name,target_name)
        #下载文件
        sftp.get('/mnt/passwd')
    finally:
        #关闭两台主机的通道
        tarnsport.close()

put('172.25.254.40','root','/etc/passwd','/mnt/172.25.254.140')

####python设置字体颜色###
书写格式:

开头部分:\033[显示方式;前景色;背景色m + 结尾部分:\033[0m

注意:开头部分的三个参数:显示方式,前景色,背景色是可选参数,可以只写其中的某一个;另外由于表示三个参数不同含义的数值都是唯一的没有重复的,所以三个参数的书写先后顺序没有固定要求,系统都能识别;但是,建议按照默认的格式规范书写。

对于结尾部分,其实也可以省略,但是为了书写规范,建议\033[***开头,\033[0m结尾。
数值表示的参数含义:

显示方式: 0(默认值)、1(高亮)、22(非粗体)、4(下划线)、24(非下划线)、 5(闪烁)、25(非闪烁)、7(反显)、27(非反显)

前景色: 30(黑色)、31(红色)、32(绿色)、 33(黄色)、34(蓝色)、35(洋 红)、36(青色)、37(白色)

背景色: 40(黑色)、41(红色)、42(绿色)、 43(黄色)、44(蓝色)、45(洋 红)、46(青色)、47(白色)
常见开头格式:

\033[0m 默认字体正常显示,不高亮
\033[32;0m 红色字体正常显示
\033[1;32;40m 显示方式: 高亮 字体前景色:绿色 背景色:黑色
\033[0;31;46m 显示方式: 正常 字体前景色:红色 背景色:青色

格式: \033[显示的方式;字体的颜色;背景色m+显示内容
"""
# RED = '\033[4;31;0m' + '你好'
# print(RED)

class FontColor:
    OKBULE = '\033[94m'
    OKGREEN = '\033[92m'
    WARN = '\033[93m'
    FAIL = '\033[91m'

if __name__ == '__main__':
    f = FontColor()
    print(f.OKBULE + '你好')
    print(f.OKGREEN + '你好')
    print(f.WARN + '你好')
    print(f.FAIL + '你好')

猜你喜欢

转载自blog.csdn.net/weixin_44821839/article/details/91869863