1. paramiko模塊的簡單簡單介紹
paramiko是一個用於做遠程控制的模塊,使用該模塊可以對遠程服務器進行命令或文件操作,值得一說的是,fabric和ansible內部的遠程管理就是使用的paramiko來現實。
假設你已經在vm上搭建好了Ubuntu,現在安裝這個模塊 pip3 install paramiko ....等待安裝完成r如果你的網速不夠快的話可以使用國內的安裝源 pip install paramiko -i https://pypi.tuna.tsinghua.edu.cn/simple
現在你已經安裝這個模塊成功了,在你Ubuntu中vim創建一個python文件就叫paramiko.py,然后用paramiko生成一個實例
1 import paramiko 2 3 ssh = paramiko.SSHClient() # 4 #ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 5 ssh.connect('192.168.1.108', 22, 'alex', '123456') 6 stdin, stdout, stderr = ssh.exec_command('ifconfig') #stdin標准輸入 stdout標准輸出 stderr 標准錯誤
7 print (stdout.read().decode("utf-8"))
8 ssh.close();
然后用 python3 調用這個文件
python@ubuntu:~/Desktop/01_python$ python3 ssh_paramiko.py ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.146.137 netmask 255.255.255.0 broadcast 192.168.146.255 inet6 fe80::4b70:fb40:7a4:c087 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:a9:86:20 txqueuelen 1000 (以太網) RX packets 6105 bytes 6070483 (6.0 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 3832 bytes 388625 (388.6 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (本地環回) RX packets 526 bytes 53778 (53.7 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 526 bytes 53778 (53.7 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
此時我們發現paramiko這個模塊已經連接192.168.146.137這台機器並執行了 ifconfig命令
但是我們發現,執行一次這個命令連接一次這個機器,我們需要一直連接這個機器,去交互
我們先找到這個paramiko這個模塊
sudo find / -name paramiko
然后打開這個路徑
/home/python/.local/lib/python3.6/site-packages/paramiko
python@ubuntu:~/.local/lib/python3.6/site-packages/paramiko$ ls agent.py file.py pipe.py sftp.py auth_handler.py hostkeys.py pkey.py sftp_server.py ber.py __init__.py primes.py sftp_si.py buffered_pipe.py kex_curve25519.py proxy.py ssh_exception.py channel.py kex_ecdh_nist.py py3compat.py ssh_gss.py client.py kex_gex.py __pycache__ transport.py common.py kex_group14.py rsakey.py util.py compress.py kex_group16.py server.py _version.py config.py kex_group1.py sftp_attr.py _winapi.py dsskey.py kex_gss.py sftp_client.py win_pageant.py ecdsakey.py message.py sftp_file.py ed25519key.py packet.py sftp_handle.py
發現這個目錄下沒有一個叫demo的文件 那么我們去github取下載 https://github.com/paramiko/paramiko
下載安裝之后找到demo.py去執行它

python@ubuntu:~/paramiko-master$ cd demos/ python@ubuntu:~/paramiko-master/demos$ ls cmd.log demo.log demo_server.py demo_simple.py interactive.py rforward.py user_rsa_key demo_keygen.py demo.py demo_sftp.py forward.py __pycache__ test_rsa.key user_rsa_key.pub python@ubuntu:~/paramiko-master/demos$ python3 demo.py Hostname: 192.168.146.137 *** WARNING: Unknown host key! Username [python]: python Auth by (p)assword, (r)sa key, or (d)ss key? [p] p Password for python@192.168.146.137: *** Here we go! Welcome to Ubuntu 18.10 (GNU/Linux 4.18.0-25-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage 0 packages can be updated. 0 updates are security updates. Your Ubuntu release is not supported anymore. For upgrade information, please visit: http://www.ubuntu.com/releaseendoflife New release '19.04' available. Run 'do-release-upgrade' to upgrade to it. Last login: Wed Sep 25 22:02:09 2019 from 192.168.146.1 python@ubuntu:~$
此時我們就可以連上這台機器並可以執行命令
但是體驗不是很友好
那么此時我們打開我們剛下載的paramiko這個文件 的demo.py看看它里面是怎么幫我們實現的
OK paramiko模塊先說到這里
Next 放大招
現在我們就用django開始設計堡壘機的表結構和前端頁面建議搭建先看下開源的jumpserver堡壘機
大家創建完表結構,然后makemigrations migrate creatsuperuser 然后登陸 django后台成功之后
應該是這樣的
接下來我們創建一個backgend的python包用來放執行的腳本 然后創建一個python文件,來做堡壘機和主機之間的交互
代碼如下
1 #__user: xuening 2 #__data: 2019/9/22 0022 3 4 import getpass,os #getpass模塊提供了平台無關的在命令行下輸入密碼的方法 5 import subprocess 6 # from unedit_server import models 7 from django.contrib.auth import authenticate 8 9 class UserPortal(object): 10 """用戶命令行端交互入口""" 11 12 def __init__(self): 13 self.user = None 14 15 def user_auth(self): 16 """完成用戶登錄認證""" 17 retry_auth = 0 18 while retry_auth < 3: 19 username = input("Username:").strip() 20 if len(username) == 0:continue 21 password = getpass.getpass("Passwrod:").strip() 22 if len(password) == 0: 23 print("Password cont be null") 24 continue 25 user = authenticate(username=username,password=password) 26 if user : 27 self.user = user 28 print("Welcome login ...") 29 return 30 else: 31 print("invalitd username or password!") 32 retry_auth += 1 33 else: 34 exit("Too many attempts") 35 def interactive(self): 36 """交互函數""" 37 38 self.user_auth() 39 if self.user: #用戶認證成功 40 exit_flag = False 41 while not exit_flag: 42 # print(self.user.bind_hosts.select_related()) 43 for index,host_group in enumerate(self.user.host_groups.all()): 44 print("%s, %s[%s]"%(index,host_group.name,host_group.bind_hosts.all().count())) # 打印用戶管理的主機名稱和,所屬組的個數 45 46 print("%s 未分組主機【%s】"%(index+1,self.user.bind_hosts.select_related().count())) 47 user_input = input("Choose group:").strip() 48 if len(user_input) == 0:continue 49 if user_input.isdigit(): 50 user_input = int(user_input) 51 if user_input >= 0 and user_input < self.user.host_groups.all().count(): 52 selected_hostgroup = self.user.host_groups.all()[user_input] # 選擇分組 53 elif user_input == self.user.host_groups.all().count(): # 選中了未分組的那組主機 54 selected_hostgroup =self.user 55 else: 56 print("invilid host group") 57 continue 58 while True: 59 for index,bind_host in enumerate(selected_hostgroup.bind_hosts.all()): 60 print("%s %s IP:%s POrt:%s,IDC:%s"%(index,bind_host.host.hostname, 61 bind_host.host.ip_addr, 62 bind_host.host.port, 63 bind_host.host.idc)) # 打印分組里主機的所有 64 65 user_input2 = input("Choose host:").strip() # 選擇主機 66 if user_input2.isdigit(): 67 user_input2 = int(user_input) 68 if user_input2 >= 0 and user_input2 < selected_hostgroup.bind_hosts.all().count(): 69 selected_hosthosts = selected_hostgroup.bind_hosts.all()[user_input2] 70 print("login host",selected_hosthosts) 71 login_cmd = 'sshpass -p {password} ssh {user}@{ip_addr} -o "StrictHostKeyChecking no"'.format(password=selected_hosthosts.host_user.password, 72 user=selected_hosthosts.host_user.username, 73 ip_addr=selected_hosthosts.host.ip_addr) 74 ''' 去數據庫取出主機的密碼 用戶名 IP地址 75 -o "StrictHostKeyChecking no" 因為這個程序是調用ssh登錄到遠程主機, 76 當使用ssh登錄時,需要輸入yes or no ,但是在python腳本中沒法輸入yes 77 和no,所以 -o "StrictHostKeyChecking no" 78 這個命令就可以直接輸入yes 79 sshpass 是直接幫助輸入密碼的 但是需要在堡壘機中安裝 它 sshpass -p 密碼 ssh -p 1000 root@192.168.11.11 80 81 82 ''' 83 84 print(login_cmd) 85 ssh_instance = subprocess.run(login_cmd, shell=True) # 通過 subprocess命令 去 登錄,切換到要管理的那台主機 86 """subprocess模塊 命令處理 87 這里直接給出大佬的文章 他的文章已經足夠入門 其他可參看文檔 88 89 Python標准庫06 子進程 (subprocess包)另外給出代碼 90 1 import subprocess 91 2 92 3 res = subprocess.Popen("dir", shell=True, stdout=subprocess.PIPE) # 使用shell解釋dir程序並使用管道將結果寫入標准輸出stdout 93 4 print(res.stdout.read().decode('gbk')) # 使用read()方法從stdout讀出結果 該方法也適用stdin和stderr""" 94 print("------------logout---------") 95 elif user_input2 == "b": 96 break 97 98 99 100 if __name__ == '__main__': 101 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Eat_bee_dung.settings') #配置堡壘機的django環境 102 import django 103 django.setup() 104 105 from unedit_server import models 106 107 108 protal = UserPortal() 109 protal.interactive() 110 111 112 # 簡單說下這個程序的運行流程 首先把我們寫好的程序拷入到堡壘機中 然后運行他 然后運維人員先登錄到堡壘機, 113 # 然后去查看他的有權限管理的主機 當用戶選擇了他管理的主機,然后堡壘機直接去連接那台主機 114 # 然后再去操作他
一定記得要現在堡壘機中安裝sshpass軟件 https://sourceforge.net/projects/sshpass/
現在我們將我們寫好的軟件復制到堡壘機中,
大家會發現一個問題 就是我們可以通過堡壘機登錄到我們的主機上,但是我們也可以操作堡壘機,那我們如何限制運維人員不能操作堡壘機呢
我拿我虛擬機上的Ubuntu演示
首先找到當前用戶目錄下的 etc/passwd 文件 然后打開它 然后找到要修改的用戶
所以我們這個時候可以先創建一個堡壘機專用的賬戶,讓運維人員通過只能通過這個用戶去堡壘機,而且運維人員還不能在這個用戶上去干別的事情
好 此刻你已經在你的虛擬機上重新創建了一個新用戶
然后打開用戶目錄下的 .bashrc
.bashrc 文件是用戶環境變量配置文件 當用戶登錄時 默認執行的一些操作都在這個文件里面配置
那么 我們可以修改 . bashrc 文件 讓它 去執行我們讓它執行的操作
在這里忘了一點 我們還應該添加一個 logout 我們退出的時候,也從這個賬戶上退出 如果不加的的話我們退出的話 我們還在這個賬戶上 這樣的話 假如堡壘機會被別人破壞
我們將這條指令插入到 .bashrc 文件 保存退出 ok
然后你去登錄你這個堡壘機賬戶 就會默認執行我們用戶登錄交互程序
此時我的主機沒有打開 不能登錄 所以顯示的是這個效果
現在我們的工作已經完成一半 那么我們下回分解