堡垒机python下ssh的使用
【堡垒机更多参考】http://www.cnblogs.com/alex3714/articles/5286889.html
【paramiko的Demo实例】https://github.com/paramiko/paramiko
Win7下paramiko的Demo远程登录执行交互命令:
【下载Demo文件】 https://github.com/paramiko/paramiko
【paramiko更多参考】paramiko模块学习
本机[win7]登录远程Linux服务器
Win7本机IP: 192.168.2.102
远程服务器IP: 192.168.2.105
关于Win7下执行原代码报错问题的解决:
错误现象:TypeError: write() argument must be str, not bytes
问题解决:F:\Django\paramiko-demo\paramiko-master\demos\interactive.py
Linux下paramiko的Demo远程登录执行交互命令:
下载Demo文件
https://github.com/paramiko/paramiko
上传文件到本机Linux服务器:
omc@omc-virtual-machine:~$ cd paramiko_demo/
omc@omc-virtual-machine:~/paramiko_demo$ ll
Linux登录其他的Linux服务器
Linxu本机IP: 192.168.25.110
远程服务器IP: 192.168.25.133
omc@omc-virtual-machine:~/paramiko_demo$ python3 demo.py
Hostname: 192.168.25.133
*** Unable to open host keys file
*** WARNING: Unknown host key!
Username [omc]: root
Auth by (p)assword, (r)sa key, or (d)ss key? [p] p
Password for root@192.168.25.133:
*** Here we go!
Last login: Tue May 1 07:53:03 2018 from 192.168.25.110
[root@localhost ~]#
omc@omc-virtual-machine:~/paramiko_demo$ ssh root@192.168.25.133
The authenticity of host '192.168.25.133 (192.168.25.133)' can't be established.
RSA key fingerprint is SHA256:+v73ij2IHBzxee8o9n5rYkBJPwD96SaEBtxkuGBBCqg.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.25.133' (RSA) to the list of known hosts.
root@192.168.25.133's password:
Last login: Tue May 1 07:44:47 2018 from 192.168.25.1
[root@localhost ~]# logout
Connection to 192.168.25.133 closed.
omc@omc-virtual-machine:~/paramiko_demo$ python3 demo.py
Hostname: 192.168.25.133
*** Host key OK.
Username [omc]: root
Auth by (p)assword, (r)sa key, or (d)ss key? [p] p
Password for root@192.168.25.133:
*** Here we go!
注意:区别于第一次登录,第二次登录可以获取的133服务器的信息,没有了告警
paramiko的Demo分析以及改进
demo.py
interactive.py
paramiko的interactive改进:
import socket
import sys
import time
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): # chan应该是个连接的实例
if has_termios: # 判断win还是Linux
posix_shell(chan) # posix是Linux下的协议标准
else:
windows_shell(chan)
def posix_shell(chan): # chan 就是我们建立的连接实例
import select # IO多路复用,获取事件时会一个个的进行进行搜寻,直到找到那个事件
oldtty = termios.tcgetattr(sys.stdin)
try:
tty.setraw(sys.stdin.fileno())
tty.setcbreak(sys.stdin.fileno())
chan.settimeout(0.0)
cmd = []
f = open('cmd.log', 'a')
while True: # select循环监测
r, w, e = select.select([chan, sys.stdin], [], []) # 3个参数分别为输入,输出,错误信息
if chan in r: # 如果远程有返回命令的结果,进行结果输出
try:
x = u(chan.recv(1024)) # 每次接收1KB的长度
if len(x) == 0: # 长度为0,表示没有接收到
sys.stdout.write('\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) # read()函数,输入一个读取一个发送一个[回车代表命令输入完成可以执行任务]
if(x == '\r'): # Linux下的回车是\r
# print("".join(cmd))
cmd_log_format = "%s-%s-%s\r" % (time.ctime(time.time()), 'root', "".join(cmd))
f.write(cmd_log_format)
cmd = [] # 情况作为下次使用
else:
cmd.append(x)
if len(x) == 0:
break
chan.send(x) # 如果读到了输入内容,则发送到远程进行操作
finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
# thanks to Mike Looijmans for this code
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.decode("utf-8"))
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
注:记录了文件,但是由点小bug,就是文件会记录下左右移动的操作[此时会转换为二进制的内容]