paramiko是什么?
paramiko是一个基于ssh用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作
01.paramiko远程密码连接
import paramiko #导入模块
client = paramiko.SSHClient() #创建一个ssh对象,类似于 ssh username@ip
client.set_missing_host_key_policy(paramiko.AutoAddPolicy() #自动选择yes
# 解决的问题:如果之前没有连接过的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.connect(
hostname='172.25.0.101',
username='root',
password='redhat'
)
# 执行操作
stdin,stdout,stderr = client.exec_command('pwd')
# 通过ssh连接成功之后,在被连接的主机中执行命令。这个操作返回一个元组,元组存在三个元素,分别为标准输入,标准输出,错误输出。
print(stdout.read().decode('utf-8')) #对标准输出结果进行获取,decode('utf-8') 主要是解决返回结果中存在中文能够正常显示
client.close() #关闭连接对象
02.paramiko批量远程密码连接
当需要处理的主机比较多的时候,可以使用批量连接的方式。将需要连接的主机ip,用户名称以及密码等信息,按照固定的格式保存在文件中,通过读取文件中的内容实现批量自动连接进行操作。
from paramiko.ssh_exception import NoValidConnectionsError,AuthenticationException
def connect(cmd,hname,user,pword):
import paramiko
client = paramiko.SSHClient() # 创建一个ssh连接对象
client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #解决初次连接的确认问题
try:
# 连接的服务器
client.connect(
hostname=hname,
username=user,
password=pword
)
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('cmd')
# 获取命令的执行结果
print(stdout.read().decode('utf-8'))
# 关闭连接
client.close()
if __name__ == '__main__':
with open('hosts') as f:
for line in f:
# 172.25.0.250:root:dd
hostname,username,password = line.strip().split(':')
res = connect('pwd',hostname,username,password)
print(hostname.center(50,'*'))
print('主机名:',res)
03.paramiko基于公钥和私钥的连接
由于 paramiko是基于ssh进行的连接,所以可以使用公钥和私钥使指定的用户对指定主机的指定用户进行免密连接。
连接的前提是,需要提前将公钥放置被连接主机的指定用户~/.ssh 目录中。将私钥放置在客户端主机的指定用户~/.ssh 中 设置ssh服务公钥以及私钥
连接操作步骤与第一个所以密码连接基本一致,值守在连接主机的时候,不在使用密码,而是使用生成的私钥对象。
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())
client.connect(
hostname='172.25.47.104',
username='root',
pkey=private_key # 连接的时候使用私钥对象进行验证
)
stdin,stdout,stderr = client.exec_command('ifconfig eth0')
print(stdout.read().decode('utf-8'))
输出结果:
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.70 netmask 255.255.255.0 broadcast 172.25.47.255
inet6 fe80::5054:ff:fe09:86e1 prefixlen 64 scopeid 0x20<link>
ether 52:54:00:09:86:e1 txqueuelen 1000 (Ethernet)
RX packets 423 bytes 85234 (83.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 493 bytes 95248 (93.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
04.paramiko基于用户和密码的上传和下载文件
import paramiko
from paramiko import AuthenticationException,SSHException
def put(hostname,password,source_name,target_name):
try:
# 类似于ssh+ftp命令
# 建立与远程主机的通道
tarnsport = paramiko.Transport((hostname,22))
# 验证用户名和密码是否正确,连接SSH服务端
tarnsport.connect(username='root',password=password)
# 根据创建并验证成功的通道,获取SFTP对象
sftp = paramiko.SFTPClient.from_transport(tarnsport)
except AuthenticationException as e:
return '主机%s密码错误' %(hostname)
except Exception as e:
return '未知错误:',e
else:
# 上传文件
sftp.put(source_name,target_name)
# 下载文件
# sftp.get('/mnt/name')
finally:
# 关闭两台主机建立的通道
tarnsport.close()
put('172.25.254.70','fairy','/etc/passwd','/mnt/file1')