paramiko模块

  paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,值得一说的是,fabric和ansible内部的远程管理就是使用的paramiko来现实。其实它的底层是对ssh的上层代码的一个封装

一、下载安装

#pycrypto,由于 paramiko 模块内部依赖pycrypto,所以先下载安装pycrypto
tomcat@node:~$ pip install pycrypto
tomcat@node:~$ pip install paramiko

二、模块使用

1、SSHClient 用于连接远程服务器并执行基本命令

(1)基于用户名密码连接两种方式:

-->第一种

import paramiko

# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='192.168.1.21', port=22, username='root', password='123456') # 执行命令
stdin, stdout, stderr = ssh.exec_command('ls')
# 获取命令结果
result = stdout.read() # 关闭连接
ssh.close()

-->二种:SSHClient 封装 Transport  

import paramiko

transport = paramiko.Transport(('192.168.1.21', 22))
transport.connect(username='root', password='123456') ssh = paramiko.SSHClient()
ssh._transport = transport stdin, stdout, stderr = ssh.exec_command('df')
print stdout.read() transport.close()

(2)基于公钥密钥连接的两种方式:

-->第一种  

import paramiko

private_key = paramiko.RSAKey.from_private_key_file('/root/.ssh/id_rsa')

# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='192.168.1.21', port=22, username='root', pkey=private_key) # 执行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 获取命令结果
result = stdout.read() # 关闭连接
ssh.close()

-->第二种:SSHClient 封装 Transport  

import paramiko

private_key = paramiko.RSAKey.from_private_key_file('/root/.ssh/id_rsa')

transport = paramiko.Transport(('192.168.1.21', 22))
transport.connect(username='root', pkey=private_key) ssh = paramiko.SSHClient()
ssh._transport = transport stdin, stdout, stderr = ssh.exec_command('df') transport.close()

2、SFTPClient用于连接远程服务器并执行上传下载

(1)基于用户名密码上传下载:

import paramiko

transport = paramiko.Transport(('192.168.1.21',22))
transport.connect(username='root',password='123456') sftp = paramiko.SFTPClient.from_transport(transport) # 将location.py 上传至服务器 /tmp/test.py
sftp.put('/tmp/location.py', '/tmp/test.py') # 将remove_path 下载到本地 local_path
sftp.get('remove_path', 'local_path') transport.close()

(2)基于公钥密钥上传下载:  

import paramiko

private_key = paramiko.RSAKey.from_private_key_file('/root/.ssh/id_rsa')

transport = paramiko.Transport(('192.168.1.21', 22))
transport.connect(username='root', pkey=private_key ) sftp = paramiko.SFTPClient.from_transport(transport) # 将location.py 上传至服务器 /tmp/test.py
sftp.put('/tmp/location.py', '/tmp/test.py') # 将remote_path 下载到本地 local_path
sftp.get('remote_path', 'local_path') transport.close()

3、实例:通过transport实现远程执行命令和上传文件  

#!/usr/bin/env python
# -*- coding:utf-8 -*- import paramiko class SSHConnection(object): def __init__(self, host='192.168.1.21', port=22, username='root',pwd='123456'):
self.host = host
self.port = port
self.username = username
self.pwd = pwd
self.__k = None def run(self):
self.connect()
pass
self.close() def connect(self):
transport = paramiko.Transport((self.host,self.port))
transport.connect(username=self.username,password=self.pwd)
self.__transport = transport def close(self):
self.__transport.close() def cmd(self, command):
ssh = paramiko.SSHClient()
ssh._transport = self.__transport
# 执行命令
stdin, stdout, stderr = ssh.exec_command(command)
# 获取命令结果
result = stdout.read()
return result def upload(self,local_path, target_path):
# 连接,上传
sftp = paramiko.SFTPClient.from_transport(self.__transport)
# 将location.py 上传至服务器 /tmp/test.py
sftp.put(local_path, target_path) ssh = SSHConnection()
ssh.connect()
r1 = ssh.cmd('df')
print(r1.decode())
#ssh.upload('test.py', "/root/test.py")
ssh.upload('s13_par.py', "/root/s7.py")
ssh.close()
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import paramiko
import uuid class SSHConnection(object): def __init__(self, host='172.16.103.191', port=22, username='wupeiqi',pwd=''):
self.host = host
self.port = port
self.username = username
self.pwd = pwd
self.__k = None def create_file(self):
file_name = str(uuid.uuid4())
with open(file_name,'w') as f:
f.write('sb')
return file_name def run(self):
self.connect()
self.upload('/home/wupeiqi/tttttttttttt.py')
self.rename('/home/wupeiqi/tttttttttttt.py', '/home/wupeiqi/ooooooooo.py)
self.close() def connect(self):
transport = paramiko.Transport((self.host,self.port))
transport.connect(username=self.username,password=self.pwd)
self.__transport = transport def close(self): self.__transport.close() def upload(self,target_path):
# 连接,上传
file_name = self.create_file() sftp = paramiko.SFTPClient.from_transport(self.__transport)
# 将location.py 上传至服务器 /tmp/test.py
sftp.put(file_name, target_path) def rename(self, old_path, new_path): ssh = paramiko.SSHClient()
ssh._transport = self.__transport
# 执行命令
cmd = "mv %s %s" % (old_path, new_path,)
stdin, stdout, stderr = ssh.exec_command(cmd)
# 获取命令结果
result = stdout.read() def cmd(self, command):
ssh = paramiko.SSHClient()
ssh._transport = self.__transport
# 执行命令
stdin, stdout, stderr = ssh.exec_command(command)
# 获取命令结果
result = stdout.read()
return result ha = SSHConnection()
ha.run()
# 对于更多限制命令,需要在系统中设置
/etc/sudoers Defaults requiretty
Defaults:cmdb !requiretty
Demo

基于私钥字符串进行连接

import paramiko
from io import StringIO key_str = """-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAq7gLsqYArAFco02/55IgNg0r7NXOtEM3qXpb/dabJ5Uyky/8
NEHhFiQ7deHIRIuTW5Zb0kD6h6EBbVlUMBmwJrC2oSzySLU1w+ZNfH0PE6W6fans
H80whhuc/YgP+fjiO+VR/gFcqib8Rll5UfYzf5H8uuOnDeIXGCVgyHQSmt8if1+e
7hn1MVO1Lrm9Fco8ABI7dyv8/ZEwoSfh2C9rGYgA58LT1FkBRkOePbHD43xNfAYC
tfLvz6LErMnwdOW4sNMEWWAWv1fsTB35PAm5CazfKzmam9n5IQXhmUNcNvmaZtvP
c4f4g59mdsaWNtNaY96UjOfx83Om86gmdkKcnwIDAQABAoIBAQCnDBGFJuv8aA7A
ZkBLe+GN815JtOyye7lIS1n2I7En3oImoUWNaJEYwwJ8+LmjxMwDCtAkR0XwbvY+
c+nsKPEtkjb3sAu6I148RmwWsGncSRqUaJrljOypaW9dS+GO4Ujjz3/lw1lrxSUh
IqVc0E7kyRW8kP3QCaNBwArYteHreZFFp6XmtKMtXaEA3saJYILxaaXlYkoRi4k8
S2/K8aw3ZMR4tDCOfB4o47JaeiA/e185RK3A+mLn9xTDhTdZqTQpv17/YRPcgmwz
zu30fhVXQT/SuI0sO+bzCO4YGoEwoBX718AWhdLJFoFq1B7k2ZEzXTAtjEXQEWm6
01ndU/jhAasdfasdasdfasdfa3eraszxqwefasdfadasdffsFIfAsjQb4HdkmHuC
OeJrJOd+CYvdEeqJJNnF6AbHyYHIECkj0Qq1kEfLOEsqzd5nDbtkKBte6M1trbjl
HtJ2Yb8w6o/q/6Sbj7wf/cW3LIYEdeVCjScozVcQ9R83ea05J+QOAr4nAoGBAMaq
UzLJfLNWZ5Qosmir2oHStFlZpxspax/ln7DlWLW4wPB4YJalSVovF2Buo8hr8X65
lnPiE41M+G0Z7icEXiFyDBFDCtzx0x/RmaBokLathrFtI81UCx4gQPLaSVNMlvQA
539GsubSrO4LpHRNGg/weZ6EqQOXvHvkUkm2bDDJAoGATytFNxen6GtC0ZT3SRQM
WYfasdf3xbtuykmnluiofasd2sfmjnljkt7khghmghdasSDFGQfgaFoKfaawoYeH
C2XasVUsVviBn8kPSLSVBPX4JUfQmA6h8HsajeVahxN1U9e0nYJ0sYDQFUMTS2t8
RT57+WK/0ONwTWHdu+KnaJECgYEAid/ta8LQC3p82iNAZkpWlGDSD2yb/8rH8NQg
9tjEryFwrbMtfX9qn+8srx06B796U3OjifstjJQNmVI0qNlsJpQK8fPwVxRxbJS/
pMbNICrf3sUa4sZgDOFfkeuSlgACh4cVIozDXlR59Z8Y3CoiW0uObEgvMDIfenAj
98pl3ZkCgYEAj/UCSni0dwX4pnKNPm6LUgiS7QvIgM3H9piyt8aipQuzBi5LUKWw
DlQC4Zb73nHgdREtQYYXTu7p27Bl0Gizz1sW2eSgxFU8eTh+ucfVwOXKAXKU5SeI
+MbuBfUYQ4if2N/BXn47+/ecf3A4KgB37Le5SbLDddwCNxGlBzbpBa0=
-----END RSA PRIVATE KEY-----""" private_key = paramiko.RSAKey(file_obj=StringIO(key_str))
transport = paramiko.Transport(('10.0.1.40', 22))
transport.connect(username='root', pkey=private_key) ssh = paramiko.SSHClient()
ssh._transport = transport stdin, stdout, stderr = ssh.exec_command('df')
result = stdout.read() transport.close() print(result)

  

堡垒机

堡垒机执行流程:

  1. 管理员为用户在服务器上创建账号(将公钥放置服务器,或者使用用户名密码)
  2. 用户登陆堡垒机,输入堡垒机用户名密码,现实当前用户管理的服务器列表
  3. 用户选择服务器,并自动登陆
  4. 执行操作并同时将用户操作记录

注:配置.brashrc实现ssh登陆后自动执行脚本,如:/usr/bin/python /home/wupeiqi/menu.py

实现过程(前戏)

# 利用sys.stdin,肆意妄为执行操作
# 用户在终端输入内容,并将内容发送至远程服务器
# 远程服务器执行命令,并将结果返回
# 用户终端显示内容

版本一:能连上远程服务器在终端任意输入命令,但无法做到tab键补全命令

import paramiko
import sys
import os
import socket
import select
import getpass
from paramiko.py3compat import u tran = paramiko.Transport(('192.168.1.21', 22,))
tran.start_client()
tran.auth_password('root', '123456') # 打开一个通道
chan = tran.open_session()
# 获取一个终端
chan.get_pty()
# 激活器
chan.invoke_shell() while True:
# 监视用户输入和服务器返回数据
# sys.stdin 处理用户输入
# chan 是之前创建的通道,用于接收服务器返回信息
readable, writeable, error = select.select([chan, sys.stdin, ],[],[],1)
if chan in readable:
try:
x = u(chan.recv(1024))
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.readline()
chan.sendall(inp) chan.close()
tran.close()

版本二:在版本一上增加了命令补全功能和命令记录 

import paramiko
import sys
import os
import socket
import select
import getpass
import termios
import tty
from paramiko.py3compat import u tran = paramiko.Transport(('192.168.1.21', 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:
# 监视 用户输入 和 远程服务器返回数据(socket)
# 阻塞,直到句柄可读
r, w, e = select.select([chan, sys.stdin], [], [], 1)
if chan in r:
try:
x = u(chan.recv(1024))
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 r:
x = sys.stdin.read(1)
if len(x) == 0:
break
chan.send(x) finally:
# 重新设置终端属性
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) chan.close()
tran.close()

版本三:windows、linux通用版本

import paramiko
import sys
import os
import socket
import getpass from paramiko.py3compat import u # windows does not have termios...
try:
import termios
import tty
has_termios = True
except ImportError:
has_termios = False def interactive_shell(chan):
if has_termios:
posix_shell(chan)
else:
windows_shell(chan) def posix_shell(chan):
import select oldtty = termios.tcgetattr(sys.stdin)
try:
tty.setraw(sys.stdin.fileno())
tty.setcbreak(sys.stdin.fileno())
chan.settimeout(0.0)
log = open('handle.log', 'a+', encoding='utf-8')
flag = False
temp_list = []
while True:
r, w, e = select.select([chan, sys.stdin], [], [])
if chan in r:
try:
x = u(chan.recv(1024))
if len(x) == 0:
sys.stdout.write('\r\n*** EOF\r\n')
break
if flag:
if x.startswith('\r\n'):
pass
else:
temp_list.append(x)
flag = False
sys.stdout.write(x)
sys.stdout.flush()
except socket.timeout:
pass
if sys.stdin in r:
x = sys.stdin.read(1)
import json if len(x) == 0:
break if x == '\t':
flag = True
else:
temp_list.append(x)
if x == '\r':
log.write(''.join(temp_list))
log.flush()
temp_list.clear()
chan.send(x) finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) def windows_shell(chan):
import threading sys.stdout.write("Line-buffered terminal emulation. Press F6 or ^Z to send EOF.\r\n\r\n") def writeall(sock):
while True:
data = sock.recv(256)
if not data:
sys.stdout.write('\r\n*** EOF ***\r\n\r\n')
sys.stdout.flush()
break
sys.stdout.write(data)
sys.stdout.flush() writer = threading.Thread(target=writeall, args=(chan,))
writer.start() try:
while True:
d = sys.stdin.read(1)
if not d:
break
chan.send(d)
except EOFError:
# user hit ^Z or F6
pass def run():
default_username = getpass.getuser()
username = input('Username [%s]: ' % default_username)
if len(username) == 0:
username = default_username hostname = input('Hostname: ')
if len(hostname) == 0:
print('*** Hostname required.')
sys.exit(1) tran = paramiko.Transport((hostname, 22,))
tran.start_client() default_auth = "p"
auth = input('Auth by (p)assword or (r)sa key[%s] ' % default_auth)
if len(auth) == 0:
auth = default_auth if auth == 'r':
default_path = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
path = input('RSA key [%s]: ' % default_path)
if len(path) == 0:
path = default_path
try:
key = paramiko.RSAKey.from_private_key_file(path)
except paramiko.PasswordRequiredException:
password = getpass.getpass('RSA key password: ')
key = paramiko.RSAKey.from_private_key_file(path, password)
tran.auth_publickey(username, key)
else:
pw = getpass.getpass('Password for %s@%s: ' % (username, hostname))
tran.auth_password(username, pw) # 打开一个通道
chan = tran.open_session()
# 获取一个终端
chan.get_pty()
# 激活器
chan.invoke_shell() interactive_shell(chan) chan.close()
tran.close() if __name__ == '__main__':
run()

更多参见:paramoko源码 https://github.com/paramiko/paramiko 

Alex堡垒机:http://www.cnblogs.com/alex3714/articles/5286889.html 

  

 

Python自动化运维之19、Paramiko模块和堡垒机实战的更多相关文章

  1. Python自动化运维之10、模块之json、pickle、XML、PyYAML、configparser、shutil

    序列化 Python中用于序列化的两个模块 json     用于[字符串]和 [python基本数据类型] 间进行转换 pickle   用于[python特有的类型] 和 [python基本数据类 ...

  2. Python自动化运维之9、模块之sys、os、hashlib、random、time&datetime、logging、subprocess

    python模块 用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需 ...

  3. python自动化运维五:paramiko

    p { margin-bottom: 0.25cm; line-height: 120% } a:link { } paramiko是基于python实现的SSH2远程安全连接,支持认证以及密钥方式, ...

  4. Python自动化运维——IP地址处理模块

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 模块:IPy 功能:辅助我们高效的完成IP的规划工作 安装: wget https://pypi.python.o ...

  5. python自动化运维六:paramiko

    paramiko是基于python实现的SSH2远程安全连接,支持认证以及密钥方式,可以实现远程命令执行,文件传输,中间SSH代理等功能.也就是采用SSH的方式进行远程访问.SSH登陆的方式可以参考之 ...

  6. Python自动化运维:技术与最佳实践 PDF高清完整版|网盘下载内附地址提取码|

    内容简介: <Python自动化运维:技术与最佳实践>一书在中国运维领域将有“划时代”的重要意义:一方面,这是国内第一本从纵.深和实践角度探讨Python在运维领域应用的著作:一方面本书的 ...

  7. Python自动化运维 技术与最佳实践PDF高清完整版免费下载|百度云盘|Python基础教程免费电子书

    点击获取提取码:7bl4 一.内容简介 <python自动化运维:技术与最佳实践>一书在中国运维领域将有"划时代"的重要意义:一方面,这是国内第一本从纵.深和实践角度探 ...

  8. Ansible自动化运维工具及其常用模块

    Ansible自动化运维工具及其常用模块 目录 Ansible自动化运维工具及其常用模块 一.Ansible简介 1. Ansible概述 2. Ansible作用 3. Ansible的工作模块 4 ...

  9. python自动化运维学习第一天--day1

    学习python自动化运维第一天自己总结的作业 所使用到知识:json模块,用于数据转化sys.exit 用于中断循环退出程序字符串格式化.format字典.文件打开读写with open(file, ...

随机推荐

  1. [Audio processing] wav音频文件读取int和double数组的关系

    直接读取wav文件是int数组,但是有一些实现返回的是double数组,还有些输入是double数组:那我们要互相调用的时候还是要看看两者到底有什么关系,其实很简单. 以单身道,16bit为例 /** ...

  2. hdoj 1711 Number Sequence【求字串在母串中第一次出现的位置】

    Number Sequence Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  3. + (void)load和+ (void)initialize有什么用处

    两个方法都可以进行一些类的初始化操作.其中有些小区别.+(void)load 方法只要加入了工程种,进行了编译,且.m中实现了这个方法,都会调用一次,值得注意的时没实现的子类是不会调用的,就算父类实现 ...

  4. RabbitMQ-清空队列中(一个channel或连接中)的Unacknowledged状态的消息

    清空所有:nack 时将参数delivery-tag设为0,multiple设为1. 清空小于等于某delivery-tag的所有消息:nack 时将参数delivery-tag设为正数(介于1和92 ...

  5. today's learning of english 1

    1.curriculum    必修课 主修课 2.sought       seek的过去式 3.blessed with a wonderful marriage   有个幸福美满的婚姻 4.al ...

  6. 统计学习导论:基于R应用——第二章习题

    目前在看统计学习导论:基于R应用,觉得这本书非常适合入门,打算把课后习题全部做一遍,记录在此博客中. 第二章习题 1. (a) 当样本量n非常大,预测变量数p很小时,这样容易欠拟合,所以一个光滑度更高 ...

  7. [置顶] Oracle 11g R2 RAC:使用 srvctl 工具管理 service 资源

    1.使用 srvctl 工具创建 service 资源 srvctl add service -d db_unique_name -s service_name {-r "preferred ...

  8. mysql编码和Java编码相应一览表

    MySQL to Java Encoding Name Translations MySQL Character Set Name Java-Style Character Encoding Name ...

  9. Android---用动画来处理布局的变化

    本文译自:http://developer.android.com/training/animation/layout.html 布局动画一种系统预装的动画,每次布局配置发生变化时,系统会运行它.你所 ...

  10. jquery自定义插件来实现分页的效果

    本节将介绍如何定义自己的jquery插入,实现分页效果,话不多说,.看看达到的效果: 分页插件 实现的代码例如以下: <!DOCTYPE HTML PUBLIC "-//W3C//DT ...