还记得前一节做的socket和socketserver吗?写了很多实现了一个小功能,但是今天的paramiko真让人有种土枪换炮的感觉!

paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接。paramiko支持Linux, Solaris, BSD, MacOS X, Windows等平台通过SSH从一个平台连接到另外一个平台。利用该模块,可以方便的进行ssh连接和sftp协议进行sftp文件传输。


本文只演示paramiko连接linux操作系统。

-----------------------------------------------------

paramiko包里一共有种连接方式(两个类):SSHClient和Transport,每种连接方式都支持口令认证证书认证

paramiko也有一些其它的方法和属性。本文只介绍简单、常用的。

paramiko不是python基本模块,需是基于pycrypto模块,所以需要安装pycrypto,再安装paramiko

pip3 install pycrypto # windows下多半是会报错的,原因是因为需要安装c++,并且设置变量。

pip3 install paramiko    
# 实际上直接安装paramiko,自动安装依赖的包。我使用的pip版本是pip 9.0.3
# 成功的时候会提示安装了下面这些包:pycparser, cffi, pynacl, bcrypt, pyasn1, asn1crypto, cryptography, paramiko

paramiko.png


一、SSHClient:用来远程执行命令。

    

方法/属性名
参数:
说明
connect()

实现SSH的加密连接

hostname
port 
username 
password 
pkey 
timeout 
allow_agent 
look_for_keys 
compress   

参数类型:作用

str :主机ip       # 必须参数

int :端口        # 必须参数

str:用户名     # 用户名和pkey密钥连接方式必须存在一个

str :密码

pkey: 秘钥

float: 超时时间      # 可选

boool :当为flase时,禁用连到ssh代理      # 可选

bool : flase时,禁用在~/.ssh中搜索秘钥文件      # 可选

bool : true时打开压缩。      # 可选


exec_command()

远程执行命令,popen的远程版。。。

"command"

bufsize


参数类型:作用

str:远程执行的命令,如果有多个命令需要操作时,需要通过分号进行分割

int:缓冲区的大小,默认-1,无限制

load_system_host_keys()

加载本地公秘钥校验文件,默认为~/.ssh/known_hosts

filename

参数类型:作用

str : 远程主机公钥记录文件,linux系统下默认路径~/.ssh/known_hosts

set_missing_host_key_policy()

连接主机没有本地主机秘钥或者HostKeys对象时策略,目前支持三种:AutoAddPolicy,RejectPolicy,WarningPolicy


AutoAddPolicy:自动添加主机名以及主机密钥

RejectPolicy(默认):自动拒绝未知的主机名和秘钥

WarningPolicy: 用于记录一个未知主机秘钥的Python警告



示例:

ssh = paramiko.SSHClient()

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

ssh.connect(.................)


stdin.wirte(str)str输入str型的字符确认继续。应该类似bat 中的pause

示例一:使用用户名和密码进行SSHClient连接

import paramiko
paramiko.util.log_to_file('/tmp/ssh_log') # 记录连接信息
# 使用用户名密码连接远程
def Myssh():
    cmd = input("要执行的命令->>:").strip()
    return cmd
    
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())    # 在connect前,设置参数,自动添加主机到linux的 host_knows文件里
ssh.connect(hostname = '192.168.1.100', port = 9999, username = 'david',password = 'wonianqing')
#也可以传形参:ssh.connect('192.168.1.100', 9999, 'david','wonianqing')


cmd = Myssh()
stdin,stdout,stderr = ssh.exec_command(cmd)

if stdout.read():
    print (stdout.read())            # stdout和stderr两者只能有一个有数据,stdout正常返回,stderr返回的错误。
else:
    print (stderr.read())



ssh.close()

示例二:使用证书认证进行SSHClient连接。

import paramiko
ssh = paramiko.SSHClient()
ssh.connect("localhost",9999,pkey="")        # 需要在linux下创建个密钥,pkey就是客户机上的私钥地址,服务端地址默认


二、Transport:用来上传下载远程主机的文件

方法/属性名
作用
参数
示例
Transport((主机名,端口号))
建立远程主机加密码管道对象

主机名:ip或者主机名,str型

端口号:指定端口,int型

sf = paramiko.Transport(("192.168.1.1",22))
connect(username,password)
建立远程连接

username:用户名

password:密码

sf.connect(username = "root",password="areyouok1")
SFTPClient.from_transport(加密管道)
建立一个客户端对象,通过ssh transport操作远程文件
加密管道:之前创建的sf对象
sftp = paramiko.SFTPClient.from_transport(sf)
get(远程文件,本地文件)从远程下载指定文件存到本地

远程文件名

本地文件名


sftp.get(remotepath,localpath)
put(本地文件,远程文件)从本地上传指定文件到远程路径

本地文件名

远程文件名

sftp.put(localpath,remotepath)
listdir(远程路径)列出远程指定路径的文件夹远程路径名sftp.listdir("..")


 


 

import paramiko
"""SFTPClient"""

sftp_transport_obj = paramiko.Transport(("192.168.1.106", 22))
sftp_transport_obj.connect(username="root",password="a2266351z")
sftp = paramiko.SFTPClient.from_transport(sftp_transport_obj)
# sftp.get()
# sftp.put()
ss=sftp.listdir("..")
print(ss)
print(ss.read())

'''paramiko也可以使用socket对象连接'''

import socket,paramiko

addr = "192.168.1.106" 
port = 22
socket_obj = socket.socket()
socket_obj.connect((addr,port))
sftp_transport_obj = paramiko.Transport(socket_obj)
sftp_obj = paramiko.SFTPClient.from_transport(sftp_transport_obj)

cmd_result = sftp_obj.listdir('..')

print(cmd_result)

sftp_transport_obj.close()


错误1:

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# 解决paramiko.ssh_exception.SSHException: Server '192.168.1.119' not found in known_hosts

# 必须在connect方法前设置



参考资料:

http://python.jobbole.com/87088/