###################带着问题来学习往往可以事半功倍###################
问题1:什么是paramiko模块或者说paramiko模块的作用?
问题2:paramiko模块的应用场景
##############################################################
一、基本概念
(1)paramiko模块是基于Python实现的SSH2远程安全连接,支持认证及密钥方式来连接到Linux服务器。
功能:可以实现远程命令的执行(查看日志状态等)、文件传输(上传和下载)、批量配置远程服务器、中间的SSH代理(堡垒机)!
(2)paramiko模块的几种安装方式
方式1) pip安装
方式2)easy_install-3.7
方式3)源码安装
更简单:Pycharm中,import paramiko--->空格键+Enter自动安装----->等价方式
备注:方式1和更简单的安装,在编译python的时候需要正确配置openssl!
二、paramiko模块的应用
(1)单个远程连接
import paramiko
# (1)建立SSH服务的会话对象
client = paramiko.SSHClient()
# (2)由于不知道known_list中是否有此IP的信息,所以选择三种策略中最宽容的AutoAddPolicy策略
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# (3)通过"相应的参数"来实现认证的方式进行远程SSH连接
client.connect(
hostname='172.25.2.104',
username='root',
password='redhat'
)
# (4)连接之后,远程执行命令,将结果分别封装的不同的输入输出对象中!
stdin, stout, stderr = client.exec_command('df')
# (5)打印命令的执行结果--->如果编码和解码一致,则不需要指定指定的字符集!
# 注意:返回的是list列表的形式,可以通过readlines逐行读(内存不够的话)!
print(stout.read().decode('utf-8'))
# (6)关闭ssh连接
client.close()
(2)批处理远程连接
# ssh连接不成功的异常:连接失败(IP不通)和用户名和密码的认证失败
from paramiko.ssh_exception import NoValidConnectionsError, AuthenticationException
# 由于是批处理,都需要远程连接,所以定义一个函数循环来处理!
def connect(cmd, hostname, user, password):
"""
:param cmd: 远程连接成功之后执行的远程命令
:param hostname: 连接的主机名(DNS解析)或者IP
:param user: 以远程主机的什么身份来登陆
:param password: 此身份的认证密码
:return:
"""
import paramiko
# (1)或取SSH会话对象
client = paramiko.SSHClient()
# (2)最宽容的策略-->解决第一次yes的问题
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
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 '未知错误'
# (4)远程执行命令
stdin, stdout, stderr = client.exec_command('hostname')
# (5)获取命令的执行结果
return stdout.read().decode('utf-8')
# (6)关闭连接--->思考:每个都浪费资源
if __name__ == '__main__':
with open('hosts') as f:
# 思考:会话对象可不可以定义在这里?
for line in f:
# 去除末尾的换行,并且由于文件的格式(以":"分割)-->所以用":"来分割!
hostname, username, password = line.strip().split(':')
# 调用函数--->
res = connect('hostname', hostname, username, password)
print(res)
备注:host文件自定义,最好放在当前路径下,并且host文件最好包含上述的三种情况!
python:浅析python 中__name__ = '__main__' 的作用
(3)免密连接
import paramiko
#(1)建立客户端的连接对象
client=paramiko.SSHClient()
#(1)指定本地的RSA私钥文件,如果建立密钥对时设置的有密码,password为设定的密码,如无不用指定password参数
# 说明:必须事先建立免密认证才可以采用这种方式!!!
#(2)读取钥匙文件,建立对象
private_key=paramiko.RSAKey.from_private_key_file('/home/kiosk/.ssh/id_rsa')
#(3)健壮性-->第一次连接
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
#(4)利用连接对象进行连接
client.connect(
hostname='172.25.254.1',
port=22,
username='kiosk',
pkey=private_key
)
# 标准输入 标准输入 标准错误输出
#(5)连接成功执行命令
stdin,stdout,stderr=client.exec_command('pwd')
print(stdout.read().decode('utf-8'))
# 关闭连接
client.close()
备注:必须已经做好免密的配置,详细参见!
(4)文件的传输
import paramiko
from paramiko import AuthenticationException,SSHException
def put(hostname,password,source_name,target_name):
try:
# 类似于ssh+ftp命令
# 建立与远程主机的通道
tarnsport = paramiko.Transport((hostname,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 '未知错误:',e
else:
# 上传文件
sftp.put(source_name,target_name)
# 下载文件
# sftp.get('/mnt/name')
finally:
# 关闭两台主机建立的通道
tarnsport.close()
# 执行函数
put('172.25.2.250','dd','/etc/passwd','/mnt/hello')
注意:get和put的时候需要指定文件名(不是目录),不能省略!
(5)