本文目錄一覽:
- 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 本質上並不會減少故障的產生,所以在不同的階段合理利用自身掌握的知識解決當前最重要的痛點,千萬不要本末倒置。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/187732.html