本文目录一览:
1、python用ssh连接时,只用ip和用户名但是不需要用到密码,该怎么编程?谢
2、如何用python开发一个ssh客户端工具
3、使用python 实现SSH登录设备时出现问题?
4、请教下python3 上如何实现级联ssh?
5、纯干货!python 在运维中的应用 (一):批量 ssh/sftp
python用ssh连接时,只用ip和用户名但是不需要用到密码,该怎么编程?谢
局域网内有一百多台电脑,全部都是linux操作系统,所有电脑配置相同,系统完全相同(包括用户名和密码),ip地址是自动分配的。现在有个任务是在这些电脑上执行某些命令,者说进行某些操作,比如安装某些软件,拷贝某些文件,批量关机等。如果一台一台得手工去操作,费时又费力,如果要进行多个操作就更麻烦啦。
或许你会想到网络同传, 网络同传是什么?就是在一台电脑上把电脑装好,配置好,然后利用某些软件,如“联想网络同传”把系统原样拷贝过去,在装系统时很有用,只要在一台电脑上装好,同传以后所有的电脑都装好操作系统了,很方便。同传要求所有电脑硬件完全相同,在联想的电脑上装的系统传到方正电脑上肯定会出问题的。传系统也是很费时间的,根据硬盘大小,如果30G硬盘,100多台电脑大约要传2个多小时,反正比一台一台地安装快!但是如果系统都传完了,发现忘了装一个软件,或者还需要做些小修改,再同传一次可以,但是太慢,传两次半天时间就没了。这时候我们可以利用ssh去控制每台电脑去执行某些命令。
先让我们回忆一下ssh远程登录的过程:首先执行命令 ssh username@192.168.1.x ,第一次登录的时候系统会提示我们是否要继续连接,我们要输入“yes”,然后等一段时间后系统提示我们输入密码,正确地输入密码之后我们就能登录到远程计算机,然后我们就能执行命令了。我们注意到这里面有两次人机交互,一次是输入‘yes’,另一次是输入密码。就是因为有两次交互我们不能简单的用某些命令去完成我们的任务。我们可以考虑把人机交互变成自动交互,python的pexpect模块可以帮我们实现自动交互。
如何用python开发一个ssh客户端工具
1)通过paramiko的ssh模块连接指定主机;
2) 通过SSHClient.exec_command在远程主机上执行命令;
3)通过exec_command返回的stdout,stdin,stderr进行交互;
4)保存成功连接的主机信息(session),可以通过ls命令查看, session id命令,直接启动新连接;
5)可在windows和linux下运行,写程序时需要注意他们的差别。
代码ssh.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os,sys
import paramiko
import threading
import platform
curr_ssh = None
curr_prompt = ""
#使用说明
def printUsage():
print " !ls :list sessions."
print " !session id :connect session."
print " !conn host user password:connect host with user."
print " !exit :exit."
#连接
def conn(ip,username,passwd):
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip,22,username,passwd,timeout=5)
print "Connect to ",ip," with ",username
global curr_prompt
curr_prompt=username+"@"+ip+""
return ssh
except:
return None
#加载以前的连接信息
sessiOns=[]
def loadSessions():
global sessions
try:
f = open("sessions")
sessions = f.readlines()
f.close()
except:
pass
#执行本地命令,ssh.py的命令
def exe_cmd_local(cmd):
if(cmd == "!ls"):
loadSessions()
global sessions
i=0
print "Sessions:"
for s in sessions:
print"[%d] %s" %(i,s)
i+=1
else:
vals = cmd.split(' ')
if(vals[0]=="!session"):
id = (int)(vals[1])
if(idlen(sessions)): os_name="platform.system()" new_console_cmd="" if(os_name="=" "linux"):="" .="" ssh.py="" "="" +="" sessions[id]+"\""="" elif(os_name="=" "windows"):="" sessions[id]="" os.system(new_console_cmd)="" else:="" print="" "didn't="" hava="" sessoin="" ",vals[1]="" elif(vals[0]="="!conn"):" global="" curr_ssh="" f="open("sessions","a")" line="vals[1]+"" "+vals[2]+"="" "+vals[3]+"\n"="" f.write(line)="" f.close()="" #在ssh连接的主机上执行命令="" def="" exe_cmd_ssh(ssh,cmd):="" if(ssh="=" none):="" cOnnect="" to="" a="" server.="" use="" '!conn'="" please."="" return="" stdin,="" stdout,="" stderr="ssh.exec_command(cmd)" #stdin.write("y")="" #简单交互,输入="" ‘y’="" #屏幕输出="" stdout.read()="" stderr.read()="" #入口函数="" if="" __name__="='__main__':" loadsessions()="" if(len(sys.argv)="=4):" printusage()="" while="" true:="" cmd="raw_input(curr_prompt)" if(len(cmd)="=0):" cOntinue="" if(cmd="=" "!exit"):="" if(curr_ssh="" !="None):" curr_ssh.close();="" break="" if(cmd[0]="=" '!'):="" exe_cmd_local(cmd)="" exe_cmd_ssh(curr_ssh,cmd)="" pre=""
使用python 实现SSH登录设备时出现问题?
解决了啊,不过不是用的
stdin,stdout,stderr=client.exec_command('show arp;show clock')
用这种方法只能弄一条命令
用下面这个
chan= client.invoke_shell()
chan.send('en\n')
chan.send("password\n")
chan.send('show log\n')
result = chan.recv(100000).decode()
用了这个可能还有别的问题,试试吧,不行再讨论
请教下python3 上如何实现级联ssh?
首先,我的windows系统上有python2和python3。使用下面命令切换到python3:
activate py3
1
接着使用下面命令下载相关模块:
pip install ecdsa
pip install Crypto
pip install paramiko
1
2
3
连接服务器操作:
# -*- coding: utf-8 -*-
import paramiko
# 服务器相关信息,下面输入你个人的用户名、密码、ip等信息
ip = ""
port = 22
user = ""
password = ""
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 建立连接
ssh.connect(ip,port,user,password,timeout = 10)
#输入linux命令
stdin,stdout,stderr = ssh.exec_command("pwd")
# 输出命令执行结果
result = stdout.read()
print(result)
#关闭连接
ssh.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
如下,运行该程序,可以看到控制台输出的结果:
纯干货!python 在运维中的应用 (一):批量 ssh/sftp
日常工作中需要大量、频繁地使用ssh到服务器查看、拉取相关的信息或者对服务器进行变更。目前公司大量使用的shell,但是随着逻辑的复杂化、脚本管理的精细化,shell已经不满足日常需求,于是我尝试整合工作中的需求,制作适合的工具。 由于管理制度的缺陷,我以工作流程为核心思考适合自己的运维方式,提升工作效率,把时间留给更有价值的事情。 完整代码在最后,请大家参考。
生产:4000+物理服务器,近 3000 台虚拟机。
开发环境:python3.6、redhat7.9,除了paramiko为第三方模块需要自己安装,其他的直接import即可。
批量执行操作是一把双刃剑。批量执行操作可以提升工作效率,但是随之而来的风险不可忽略。
风险案例如下:
挂载很多数据盘,通常先格式化硬盘,再挂载数据盘,最后再写入将开机挂载信息写入/etc/fstab文件。在批量lsblk检查硬盘信息的时候发现有的系统盘在/sda有的在/sdm,如果不事先检查机器相关配置是否一致直接按照工作经验去执行批量操作,会很容易造成个人难以承受的灾难。
在执行批量操作时按照惯例:格式化硬盘-挂载-开机挂载的顺序去执行,假设有的机器因为某些故障导致格式化硬盘没法正确执行。在处理这类问题的时候通常会先提取出失败的ip,并再按照惯例执行操作。运维人员会很容易忽略开机挂载的信息已经写过了,导致复写(这都是血和泪的教训)。
所以,为了避免故障,提升工作效率,我认为应当建立团队在工作上的共识,应当遵守以下原则:
当然,代码的规范也应当重视起来,不仅是为了便于审计,同时也需要便于溯源。我认为应当注意以下几点:
1、ssh no existing session,sftp超时时间设置:
在代码无错的情况下大量ip出现No existing session,排查后定位在代码的写法上,下面是一个正确的示例。由于最开始没考虑到ssh连接的几种情况导致了重写好几遍。另外sftp的实例貌似不能直接设置连接超时时间,所以我采用了先建立ssh连接再打开sftp的方法。
2、sftp中的get()和put()方法仅能传文件,不支持直接传目录:
不能直接传目录,那换个思路,遍历路径中的目录和文件,先创建目录再传文件就能达到一样的效果了。在paramiko的sftp中s方法可以获取远程路径中的文件、目录信息。那么我们可以写一个递归来遍历远程路径中的所有文件和目录(传入一个列表是为了接收递归返回的值)。
python自带的os模块中的os.walk()方法可以遍历到本地路径中的目录和文件。
3、多线程多个ip使用s方法时无法并发。
改成多进程即可。
4、多个ip需要执行相同命令或不同的命令。
由于是日常使用的场景不会很复杂,所以借鉴了ansible的playbook,读取提前准备好的配置文件即可,然后再整合到之前定义的ssh函数中。
同时,我们还衍生出一个需求,既然都要读取配置,那同样也可以提前把ip地址准备在文件里。正好也能读取我们返回的执行程序的结果。
参数说明:
密码认证:
公钥认证:
可以配合 grep,awk 等命令精准过滤。
个人认为 Python 在初中级运维工作中的性质更像是工具,以提升工作效率、减少管理成本为主。可以从当前繁琐的工作中解脱出来,去 探索 更有价值的事情。python 本质上并不会减少故障的产生,所以在不同的阶段合理利用自身掌握的知识解决当前最重要的痛点,千万不要本末倒置。