paramiko是基于python实现的ssh2远程安全连接,支持秘钥认证,实现远程命令执行,文件传输,中间ssh代理等功能


安装paramiko

paramiko依赖第三方的crypto,ecdsa,python-devel

yum install -y python-devel

打开https://pypi.org/project/ecdsa/#files 下载

https://files.pythonhosted.org/packages/f9/e5/99ebb176e47f150ac115ffeda5fedb6a3dbb3c00c74a59fd84ddf12f5857/ecdsa-0.13.tar.gz

tar zxf ecdsa-0.13.tar.gz 

cd ecdsa-0.13/

python setup.py install

打开https://pypi.org/project/pycrypto/#files 下载

https://files.pythonhosted.org/packages/60/db/645aa9af249f059cc3a368b118de33889219e0362141e75d4eaf6f80f163/pycrypto-2.6.1.tar.gz

tar zxf  pycrypto-2.6.1.tar.gz

cd pycrypto-2.6.1/

python setup.py install

下载paramiko 

wget https://github.com/paramiko/paramiko/archive/v1.12.2.tar.gz

tar zxf v1.12.2.tar.gz 

cd paramiko-1.12.2/

python setup.py install


paramiko的两个核心组件 SSHClient 和 SFTPClient


远程ssh运行命令示例:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import paramiko
hostname='192.168.1.124'
username='root'
password='123456'
paramiko.util.log_to_file('syslogin.log')

ssh=paramiko.SSHClient()
ssh.load_system_host_keys()

ssh.connect(hostname=hostname,username=username,password=password)
stdin,stdout,stderr=ssh.exec_command('free -m')
print stdout.read()
ssh.close()


sftpclient应用示例:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import paramiko

username="root"
hostname="192.168.1.124"
password="lkj123456"
port=22
try:
	t=paramiko.Transport((hostname,port))
	t.connect(username=username,password=password)
	sftp=paramiko.SFTPClient.from_transport(t)
	sftp.put("/home/test","/tmp/test")
	sftp.get("/tmp/test.txt","/home/test.txt")
	sftp.mkdir("/home/test.py")
	sftp.rmdir("/home/test.info")
	sftp.rename("/home/test.tt","home/testfile.tt")
	print sftp.stat("/home/test.info")
	print sftp.listdir("/home")
	t.close()
except Exception,e:
	print str(e)
	
	


运行ssh秘钥方式登录主机示例:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import paramiko
import os

username="root"
hostname="192.168.1.124"
paramiko.util.log_to_file('syslogin.log')

ssh=paramiko.SSHClient()
ssh.load_system_host_keys()
privatekey=os.path.expanduser('/home/key/id_rsa')
key=paramiko.RSAKey.from_private_key_file(privatekey)

ssh.connect(hostname=hostname,username=username,pkey=key)
stdin,stdout,stderr=ssh.exec_command('free -m')
print stdout.read()
ssh.close()


通过堡垒机远程执行命令示例:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import paramiko
import os,sys,time

blip="192.168.1.2"		#定义堡垒机
bluser="root"
blpasswd="lkj123456"

hostname="192.168.1.124"	#业务机器
username="root"
password="lkj123456"

passinfo='\'s password: '
paramiko.util.log_to_file('syslogin.log')

ssh=paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=blip,username=bluser,password=blpasswd)

channel=ssh.invoke_shell()	#开启命令调用
channel.settimeout(10)

buff=''
resp=''
channel.send('ssh '+username+'@'+hostname+'\n')
while not buff.endswith(passinfo):
	try:
		resp=channel.recv(9999)
	except Exception,e:
		print 'Error info: %s connection time.' % (str(e))
		channel.close()
		ssh.close()
		sys.exit()
	buff += resp
	if not buff.find('yes/no')==-1:
		channel.send('yes\n')
		buff=''
channel.send(password+'\n')
buff=''
while not buff.endswith('# '):
	resp=channel.recv(9999)
	if not resp.find(passinfo)==-1:
		print 'Error info: Authentication failed'
		channel.close()
		ssh.close()
		sys.exit()
	buff += resp

channel.send('free -m\n')
buff=''
try:
	while buff.find('# ')==-1:
		resp=channel.recv(9999)
		buff += resp
except Exception,e:
	print "error info:"+str(e)
print buff
channel.close()
ssh.close()


使用堡垒机模式下上传文件示例:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import paramiko
import os,sys,time

blip="192.168.1.2"		#定义堡垒机
bluser="root"
blpasswd="lkj123456"

hostname="192.168.1.124"	#业务机器
username="root"
password="lkj123456"

passinfo='\'s password: '
paramiko.util.log_to_file('syslogin.log')
tmpdir="/tmp"
remotedir="/data"
localpath="/home/nginx.tar.gz"
tmppath=tmpdir+"/nginx.tar.gz"
remotepath=remotedir+"nginx_access.tar.gz"
port=22

t=paramiko.Transport((blip,port))
t.connect(username=bluser,password=blpasswd)
sftp=paramiko.SFTPClient.from_transport(t)
sftp.put(localpath,tmppath)
sftp.close()

ssh=paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=blip,username=bluser,password=blpasswd)

channel=ssh.invoke_shell()
channel.settimeout(10)

buff=''
resp=''

channel.send('scp '+tmppath+' '+username+'@'+hostname+':'+remotepath+'\n')

while not buff.endswith(passinfo):
	try:
		resp=channel.recv(9999)
	except Exception,e:
		print 'Error info: %s connection time.' % (str(e))
		channel.close()
		ssh.close()
		sys.exit()
	buff += resp
	if not buff.find('yes/no')==-1:
		channel.send('yes\n')
		buff=''

while not buff.endswith('# '):
	resp=channel.recv(9999)
	if not resp.find(passinfo)==-1:
		print 'Error info: Authentication failed'
		channel.close()
		ssh.close()
		sys.exit()
	buff += resp

print buff
channel.close()
ssh.close()


一次连接多次执行命令的示例:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import paramiko
import sys
import os
import socket
import select
import getpass
import tty
import termios
# from paramiko.py3compat import u   py27需要注释
tran = paramiko.Transport(('192.168.1.124',22,))
tran.start_client()
tran.auth_password('root','123456')
#打开一个通道
chan = tran.open_session()
#获取一个通道
chan.get_pty()
#激活器
chan.invoke_shell()
#获取原tty属性,目的是为了在操作完以后恢复终端原型
oldtty = termios.tcgetattr(sys.stdin)
try:
    #为tty设置新属性
    #默认当前tty设备属性
    #输入一行回车,执行
    #ctrl +c 进程退出,遇到特殊字符,特殊处理
    #这是为原始模式,不认识特殊字符号
    #放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到 远程服务器
    tty.setraw(sys.stdin.fileno())
    chan.settimeout(0.0)
    while True:
        #监视用户输入和服务器返回数据
        #阻塞,直到句柄可读
        readable,writeable,error = select.select([chan,sys.stdin,],[],[],1)
        if chan in readable:
            try:
                #x = u(chan.recv(1024))
                x = chan.recv(1024)      #py27写法
                if len(x) == 0:
                    print('\r\n*** EOF\r\n')
                    break
                sys.stdout.write(x)
                sys.stdout.flush()
            except socket.timeout:
                pass
        if sys.stdin in readable:
            inp = sys.stdin.read(1)
            if len(inp) == 0:
                break
            chan.send(inp)
finally:
    #重新设置终端属性
    termios.tcsetattr(sys.stdin,termios.TCSADRAIN,oldtty)
chan.close()
tran.close()


示例仅供参考