目录
一、SSHClient类
ssh远程连接服务器 connet()
远程主机没有本地主机密钥或HostKeys对象时的连接方法,需要配置set_missing_host_key_policy(policy)
远程执行命令
在远程服务器上生成新的交互式shell
关闭ssh连接
open_sftp()
load_system_host_keys方法
SFTPClient类
SFTPClient类常用方法
from_transport方法
get方法
其它方法
示例
paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接。paramiko支持Linux, Solaris, BSD, MacOS X, Windows等平台通过SSH从一个平台连接到另外一个平台。利用该模块,可以方便的进行ssh连接和sftp协议进行sftp文件传输。
# Paramiko中的几个基础名词:
1、Channel:是一种类Socket,一种安全的SSH传输通道;
2、Transport:是一种加密的会话,使用时会同步创建了一个加密的Tunnels(通道),这个Tunnels叫做Channel;
3、Session:是client与Server保持连接的对象,用connect()/
start_client()
/
start_server()开始会话。
与 SSH 服务器的会话的高级表示。此类包装Transport
、Channel
和SFTPClient
以处理身份验证和打开通道的大多数方面。一个典型的用例是:
client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('ssh.example.com')
stdin, stdout, stderr = client.exec_command('ls -l')
connect(hostname, port=22, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None, gss_auth=False, gss_kex=False, gss_deleg_creds=True, gss_host=None, banner_timeout=None, auth_timeout=None, gss_trust_dns=True, passphrase=None)
参数说明:
hostname(str类型),连接的目标主机地址;
port(int类型),连接目标主机的端口,默认为22;
username(str类型),校验的用户名(默认为当前的本地用户名);
password(str类型),密码用于身份校验或解锁私钥;
pkey(Pkey类型),私钥方式用于身份验证;
key_filename(str or list(str)类型),一个文件名或文件名列表,用于私钥的身份验证;
timeout(float类型),一个可选的超时时间(以秒为单位)的TCP连接;
allow_agent(bool类型),设置为False时用于禁用连接到SSH代理;
look_for_keys(bool类型),设置为False时用于来禁用在~/.ssh中搜索私钥文件;
compress(bool类型),设置为True时打开压缩。
import paramiko
ssh = paramiko.SSHClient()
ssh.connect(ip,22,username,passwd,timeout=5)
此处ip、username、passwd都作为变量;
参数常见取值有3种,分别如下:
AutoAddPolicy:自动添加主机名及主机密钥到本地的known_hosts,不依赖load_system_host_key的配置。即新建立ssh连接时不需要再输入yes或no进行确认。最为常用。
WarningPolicy 用于记录一个未知的主机密钥的python警告。并接受,功能上和AutoAddPolicy类似,但是会提示是新连接。
RejectPolicy 自动拒绝未知的主机名和密钥,依赖load_system_host_key的配置。此为默认选项
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
该命令的输入与输出流为标准输入(stdin)、输出(stdout)、错误(stderr)的Python文件对像
命令执行完毕后,通道将关闭,不能再使用。如果您想执行另一个命令,您必须打开一个新频道。
exec_command(command, bufsize=-1, timeout=None, get_pty=False, environment=None)
参数说明:
get_pty
( term='vt100' , width=80 , height=24 , width_pixels=0 , height_pixels=0 )
invoke_shell(term='vt100', width=80, height=24, width_pixels=0, height_pixels=0, environment=None)
在此频道上请求交互式 shell 会话。如果服务器允许,则通道将直接连接到 shell 的 stdin、stdout 和 stderr。
通常您会在此之前调用get_pyt,在这种情况下,shell 将通过 pty 进行操作,并且通道将连接到 pty 的 stdin 和 stdout。
当shell退出时,通道将被关闭并且不能被重用。如果您想打开另一个 shell,您必须打开一个新频道。
例如:
在SSH server端创建一个交互式的shell,且可以按自己的需求配置伪终端,可以在invoke_shell()函数中添加参数配置
chan = ssh.invoke_shell()
chan.send(cmd) #利用send函数发送cmd到SSH server,添加做回车来执行shell命令(cmd中需要有\n命令才能执行)。注意不同的情况,如果执行完telnet命令后,telnet的换行符是\r\n
通过recv函数获取回显 chan.recv(bufsize)
一般回显数据较多,需要通过while循环读取回显数据
ssh.close()
在当前ssh会话的基础上创建一个sftp会话。该方法会返回一个SFTPClient对象。
# 利用SSHClient对象的open_sftp()方法,可以直接返回一个基于当前连接的sftp对象,可以进行文件的上传等操作.
sftp = client.open_sftp()
sftp.put('test.txt','text.txt')
加载本地公钥校验文件,默认为~/.ssh/known_host,非默认路径需要手工指定。(~/.ssh/known_hosts的作用:当ssh会把你每个你访问过计算机的公钥(public key)都记录在~/.ssh/known_hosts。当下次访问相同计算机时,OpenSSH会核对公钥。如果公钥不同,OpenSSH会发出警告)
load_system_host_keys(self,filename=None)
filename(str类型),指定远程主机公钥记录文件。
SFTPClient作为一个SFTP客户端对象,根据SSH传输协议的sftp会话,实现远程文件操作,比如文件上传、下载、权限、状态等操作。
创建一个已连通的SFTP客户端通道。
方法定义:
from_transport(cls,t)
参数说明:
t(transport),一个已通过验证的传输对象。
示例1
import paramiko
t = paramiko.Transport(('192.168.56.132',22))
t.connect(username='root',password='1234567')
sftp = paramiko.SFTPClient.from_transport(t)
这里from_transport()的入参还有其它方法获得
示例2
sshClient = paramiko.SSHClient()
sshClient.set_missing_host_key_policy(paramiko.AutoAddPolicy())
sshClient.connect(ip, port, user, pwd)
sftp = paramiko.SFTPClient.from_transport(sshClient.get_transport())
从远程SFTP服务端下载文件到本地。
方法定义:
get(remotepath, localpath, callback=None)
参数说明:
remotepath(str类型),需要下载的远程文件(源);
callback(funcation(int,int)),获取已接收的字节数及总和传输字节数,以便回调函数调用,默认为None.
示例说明:
remotepath = '/data/logs/access.log'
localpath = '/home/access.log'
sftp.get(remotepath,localpath)
SFTPClient类其它常用方法说明:
class Connection:
def connect(self, ip, port, user, pwd):
self.ip = ip
self.port = port
self.user = user
self.pwd = pwd
self.sshClient = paramiko.SSHClient()
self.sshClient.set_missing_host_key_policy(paramiko.AutoAddPolicy())
if pwd != '':
self.sshClient.connect(ip, port, user, pwd)
else:
try:
self.sshClient.connect(ip, port, user,pwd,look_for_keys=False,timeout=5.0)
except paramiko.ssh_exception.AuthenticationException:
self.sshClient.get_transport().auth_none(user)
self.sftp = paramiko.SFTPClient.from_transport(self.sshClient.get_transport())
def push(self, local_file, remote_file):
self.sftp.put(local_file, remote_file)
def pull(self, remote_file, local_file):
self.sftp.get(remote_file, local_file)
def exe(self, cmd):
try:
a = self.sshClient.exec_command(cmd, timeout=60000)
f_in, f_out, f_err = a
return f_out.read()
except Exception as e:
log(e)
return 'Exception no return'
def exe_invoke(self,cmd,end_str=None):
"""
交互式执行命令,和exe实现功能相同。执行出错的时候可以尝试
:param cmd:
:param end_str: 通过该字段判断命令是否结束
:param delaytime:
:return:
"""
try:
ssh = self.sshClient.get_transport().open_session()
ssh.get_pty()
ssh.invoke_shell()
ssh.send(cmd + '\n')
ret = ""
while True:
out = ssh.recv(1024)
# print(out.decode('utf-8'))
ret = ret + out.decode('utf-8').replace('\r','')
if end_str in out.decode('utf-8'):
break
return ret
except Exception as e:
log(e)
return 'Exception no return'
def exists(self, path):
path_d = '/'.join(path.split('/')[:-1])
path_b = path.split('/')[-1]
print('---------')
print(path_d)
print(path_b)
ls = self.exe('ls %s' % path_d).decode().split('\n')
print(ls)
if path_b in ls:
return True
else:
return False
def reconect(self):
print('reconneting')
try:
self.close()
except:
pass
finally:
self.connect(self.ip, self.port, self.user, self.pwd)
def close(self):
self.sshClient.close()
self.sftp.close()