invoke_shell()介紹 (可用來登陸后切換賬戶)
在實際工作中,對於一些服務器,需要通過root賬戶權限來實現一些功能,但有的服務器是進行加固處理的,即沒法直接用root賬戶連接SSH,所以就需要先通過一般用戶 如 ossadm用戶登錄上后,再使用 su root 指令來切換成root賬戶
而在python的paramiko模塊中,直接通過ssh.exec_command(“su root”)是沒辦法直接更改賬戶的,執行進程時將被永久阻塞,所以我們采用另一種執行命令的方法 ssh.invoke_shell()
invoke_shell()方法,用於創建一個子shell進程,這樣所有的操作都可以在該子shell中進行,su切換用戶不受影響,但該方法沒有exec_command那種方便的ChannelFile對象,所有的標准輸出和標准錯誤內容都通過invoke_shell返回對象的recv方法來獲取,每一次調用recv只會從上一次返回的地方開始返回,也沒有直接獲取命令退出狀態的方法,除非自己編寫相應的程序,在此不贅述。
#!/usr/bin/env python # coding:utf-8 from src.utils.config import Config import paramiko import time class SSH: def __init__(self): pass def connect(self, ip, user='admin', password='Qax_skyeye-2021'): ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: ssh.connect(hostname=ip, port=22, username=user, password=password) self.channel = ssh.invoke_shell() time.sleep(0.1) except paramiko.ssh_exception.AuthenticationException: print('Failed to login. ip username or password not correct.') exit(-1) def execute(self,command,end_with="# "): """ command:要執行的命令 end_with:輸出結束的標志,例如當指令執行結束后,Linux窗口會顯示# """ command = command + "\n" print("command is: %s" % command) self.channel.send(command) buff = '' while not buff.endswith(end_with): resp = self.channel.recv(9999) buff += resp.decode('utf-8') print("output is: %s" % buff) return buff def use_dia(self,dia_password=r"xxxxxxxxxx@1"): """ 使用admin用戶登錄后,是一個受限shell。 """ try: self.execute("dia",end_with="Password: ") self.execute(dia_password) except: print("Failed to switch to root by dia") exit(-1) def close(self): self.ssh.close() def get_ssh(): conf = Config() username = conf.sensor_username password = conf.sensor_password ip = conf.sensor_ip my_ssh = SSH() my_ssh.connect(ip,username,password) return my_ssh if __name__ == "__main__": my_ssh = get_ssh() my_ssh.use_dia() my_ssh.execute("whoami") print("ok")
參考鏈接:https://blog.csdn.net/weixin_42252770/article/details/99697415