一、简介
paramiko是基于实现SSH2远程安全连接,支持认证及密钥方式。可以实现远程命令执行、文件传输、中间SSH代理等功能,相对于Pexpect,封装的层次更高,更贴近SSH协议的功能
二、安装
#pip方式安装 pip install paramiko
三、简单示例
import paramiko hostname='172.17.9.68' username='root' password='xxxx' paramiko.util.log_to_file('login.log') #发送paramiko日志到login.log文件,没有太大可读性 ssh=paramiko.SSHClient() #创建ssh客户端client对象 # ssh.load_system_host_keys() #首次登录无法找到hosts_keys,会报错,默认在~/.ssh/know_hosts,非默认需指定路径, ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #以下标题4.4会讲解 ssh.connect(hostname=hostname,username=username,password=password)#创建ssh连接 stdin,stdout,stderr=ssh.exec_command('ps -ef') #调用远程执行命令方法exec_command() print(stdout.read().decode('utf-8')) #read()得到的内容是Bytes字节,需要解码成utf-8 ssh.close() #关闭ssh连接
四、SSHClient类
1.connect方法
#方法定义: connect(self,hostname,port=22,username=None,password=None,pkey=None,key_filename=None,timeout=None,allow_agent=True,look_for_keys=True,compress=False #参数说明 hostname(str类型):连接的目标主机地址 port(int类型):连接目标主机的端口,默认是22 username(str类型):校验的用户名(默认为当前的本地用户名) password(str类型):密码用于身份校验或解锁私钥 pkey(PKey类型):私钥方式用于身份验证 key_filename(str o list(str)类型):一个文件名或文件名的列表,用于私钥的身份验证 timeout(float类型):一个可选的超时时间(已秒为单位)的TCP连接 allow_agent(bool类型):设置为False时用于禁用连接到SSH代理 look_for_keys(bool类型):设置为False时用来禁用在~/.ssh中搜索秘钥文件 compress(bool类型):设置为True时打开压缩
2.exec_command方法
#方法定义 exec_command(self,command,bufsize=-1) #参数说明 command(str类型):执行的命令 bufsize(int类型):文件缓冲区的大小,默认-1(不限制) #用处 远程命名执行方法,分别返回stdin,stdout,stderr
3.load_system_host_keys方法
#方法定义 load_system_host_keys(self,filename=None) #参数说明 filename(str类型):指定远程主机公钥记录文件 #用处 加载本地公钥校验文件,默认为~/.ssh/known_hosts,非默认路径需要手工指定
4.set_missing_host_key_policy方法
ssh.set_missing_host_key_policy方法 针对连接的远程主机没有本地主机密钥或Host_keys对象时的策略。 目前支持三种参数AutoAddPolicy、RejectPolicy(默认)、WarningPolicy,仅限用于SSHClient类 1.AutoAddPolicy:自动添加主机名及主机密钥到本地Host_Keys对象,不依赖load_system_host_keys()的配置, 即使~/.ssh/known_hosts不存在也不产生影响 2.RejectPolicy:自动拒绝未知的主机名和密钥,依赖load_system_host_keys()的配置 3.WarningPolicy:用于记录一个未知的主机密钥的Python警告,并接受它,功能上与AutoAddPolicy相似, 但未知主机会有告警
ssh=paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
五、SFTPClient类
5.1简介
SFTPClient作为一个SFTP客户端对象,根据SSH传输协议的sftp会话,实现远程操作,比如文件上传,下载,权限,状态等,端口就是SSH端口
5.2 from_transport方法
扫描二维码关注公众号,回复:
1648885 查看本文章
#方法定义 from_transport(cls,t) #参数 t(Transport),一个已通过验证的传输对象 #应用 t=paramiko.Transport(("192.168.1.22",22)) t.connect(username='root',password='xxxxx') sftp=paramiko.SFTPClient.from_transport(t)
5.3 put方法
#方法定义 put(self,localpath,remotepath,callback=None,confirm=True) #参数说明 localpath(str类型):需上传的本地文件(源) remotepath(str类型):远程路径(目标) callback(function(int,int)),获取已接收的字节数及总传输字节数,以便毁掉函数调用,默认为None confirm(bool类型):文件上传完毕后是否调用stat()方法,以便确认文件的大小 #应用 localpath='/home/access.log' remotepath='/data/logs/access.log' sftp.put(localpath,remotepath)
5.4 get方法
#方法定义 get(self,remotepath,localpath,callback=None) #参数说明 remotepath(str类型):需下载的远程文件(源) localpath(str类型):本地路径(目标) callback(function(int,int)),获取已接收的字节数及总传输字节数,以便回调函数调用,默认为None #应用 remotepath='/data/log/access.log' localpath='/home/access.log' sftp.get(remotepath=remotepath,localpath=localpath) #推荐使用关键字参数,因为容易与put上传的位置参数混淆
5.5 其他方法
mkdir:在SFTP服务器端创建目录,如sftp.mkdir('/home/userdir',777) remove:删除SFTP服务端指定目录,如sftp.remove('/home/userdir') rename:重命名SFTP服务器端文件或目录,如sftp.rename('/home/test.sh','/home/newfile.sh') stat:获取远程SFTP服务器指定文件信息,如sftp.stat('/home/newfile.sh') listdir:获取远程SFTP服务器端指定目录列表,以Python的列表(List)形式返回,如sftp.listdir('/home')
5.6 SFTP示例
''' 实现文件上传,下载和 创建目录,删除目录等功能 ''' import paramiko username='root' password='xxxx' hostname='172.17.9.68' port =22 try: t=paramiko.Transport((hostname,port)) t.connect(username=username,password=password) sftp=paramiko.SFTPClient.from_transport(t) sftp.put(remotepath='/home/test05.py',localpath='test05.py') sftp.get(remotepath='/home/test05.py',localpath='test0555.py') # sftp.mkdir('/home/kuku327',mode=775) sftp.rmdir('/home/kuku327') print(sftp.listdir('/home')) print(sftp.stat('/home/kuku326')) t.close() except Exception as e: print(str(e))
六、paramiko通过堡垒机在远程访问服务器示例
import paramiko import sys blip="10.254.24.100" #堡垒机地址 bluser="xxx" #堡垒机用户名 blpasswd='xxx' #堡垒机密码 hostname='10.100.255.220' #业务服务器地址 username='root' #业务服务器用户名 password='xxxx' #业务服务器密码 port=22 #堡垒机连接端口 def receive_data(match,receive_len=9999): buff='' resp='' while not buff.endswith(match): #接受到的数据末尾如果是match,结束循环 try: resp = channel.recv(receive_len) #远端接受数据 except Exception as e: print('Eroor info:%s connection time' % str(e)) channel.close() ssh.close() sys.exit() buff += resp.decode('utf-8') #resp为bytes,需转成str,才可进行字符串拼接成buff return buff def save_file(filename,mode,content): with open(filename,mode,encoding='utf-8') as f: f.write(content) if __name__ == '__main__': sum ='' paramiko.util.log_to_file('login.log') ssh=paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname=blip,port=port,username=bluser,password=blpasswd) channel=ssh.invoke_shell() #创建会话,开启命令调用 channel.settimeout(20) #20秒超时 match_list=['page: ','account: ','Input account: ',"'s password: ",'# ','# '] send_list=['0\n','%s\n'%blip,'1\n','%s\n'%username,'%s\n'%password,'ifconfig\n'] for index,per_match in enumerate(match_list): channel.send(send_list[index]) buff=receive_data(per_match) sum +=buff # print(buff) print(sum) #打印真个过程的交互数据 save_file('6_3_2_operate.log','w',sum) channel.close() ssh.close()