python自動化管理sshy(ssh,ssh-copy-id,ssh-agent)
Python自動化管理sshy介紹
ssh優勢:
安全傳輸文件
登錄
批量執行命令
對於一名剛開始接觸Linux系統管理的工程師來說,他眼里的系統管理的步驟可能是:使用SSH登錄服務器,修改應用相關的配置文件,執行一些Linux命令,重啟相應的進程,最后退出服務器。如果還有更多的服務器,那么,就重復上述過程。
上面這一系列步驟是Linux系統管理的基礎知識,是系統管理的基本功。但是,在實際工作中,一般不會手動對
服務器進行操作,而是使用程序進行自動化管理。即使服務器的數量很少,也推薦大家編寫程序進行自動化。相對於手動管理服務器,自動化管理有許多優點。例如:
1)效率高:
自動化操作效率比手動操作效率高。這里的效率高可以從兩方面來理解:一方面是程序執行的效率比手動操作的效率高;另一方面是指對工程師來說,使用程序可以提高自身的工作效率,減少不必要的時間浪費。即使只有一台服務器,手動操作雖然可以很快完成,但其操作效率也不能與程序相提並論。如果管理的是服務器集群,顯然,人工操作非常不現實,不但效率低下.而且枯操乏味,費時費力。程序的好處是一次編寫,多次運行。雖然在編寫程序的時候,花費的時間可能比單次手動操作的時間多,但是,只要程序編寫完成,就可以多次反復地運行,節省大量時間。
2)不容易犯錯:
俗話說“人無完人”,如果一直使用人工管理的方式管理服務器集群,那么,出錯是不可避免的。工程師會有情緒的變化,也會有身體健康狀況等問題,但程序不會。只要程序編寫完成,並且考慮到了相應的異常,程序總是能夠嚴格一致地執行管理操作。
3)享受樂趣:
從事計算機行業有一個天然的好處,那就是不用進行重復性的工作。有任何重復性的工作,找們都可以通過編寫程序消滅掉。消滅重復性的工作,不但節省工作時間,還能夠獲得更多的樂趣和成就感。以管理服務器集群為例,看到自己編寫的程序、指揮成百上千的服務器按照既定的需求執行操作,是不是有種指點江山、揮斥方遒的感覺?
這一章將會討論如何使用Python批量管理服務器。首先,我們將會介紹批量管理服務器的基礎知識,即SSH協議;隨后,本章會介紹一個Python編寫的批處理工具;然后將會介紹如何在Python程序中對遠程服務器進行操作;在本章的最后,我們會介紹一個非常強大的系統管理工具,即Fabric,這一部分是本章的重點和難點。
一、使用SSH協議訪問遠程服務器
SSH ( Secure Shell)是一種由IETF的網絡工作小組制定、創建在應用層和傳輸層基礎上的安全協議,為計算機上的Shell提供安全的傳輸和使用環境。
1、SSH協議
在互聯網早期,通信都是明文的,如rsh、 FTP、POP和Telnet。一旦通信報文被截獲,內容就泄漏無疑。1995年,芬蘭學者Tatu Ylonen設計了SSH協議。將登錄信息全部加密,成為互聯網安全的一個基本解決方案。這個方案迅速在全世界獲得推廣,目前已經成為Linux系統的標准配。
SSH只是一種協議,存在多種實現,既有商業實現也有開源實現。目前。在Linux下廣泛使用的是OpenSSH,它是一款應用廣泛的開源軟件。本文即將介紹的paramiko是SSH協議的一種Python實現。
SSH除了提供安全的傳輸和登錄以外,還可以進行批量命令執行,使用非常方便。正是由於SSH簡單好用的特點,本章介紹的幾個工具,以及稍后即將介紹的Ansible,都依賴SSH進行遠程服務器的管理。使用SSH的好處非常明顯,既充分利用了現成的機制,又省去了在遠程服務器安裝代理(Agent)程序。因此,諸多自動化工其都依賴SSH。
2、OpenSSH實現
OpenSSH (OpenBSD Secure Shell)是OpenBSD的一個子項目,是SSH協議的開源實現。在服務端,OpenSSH啟動sshd守護進程,該進程默認監聽22端口。客戶端使用用戶名和密碼連接服務端,連接成功以后,OpenSSH返回給用戶一個Shell,用戶可以使用該Shell在遠程服務器執行命令。
在Debian系統中,OpenSSH的服務端默認讀取/etc/ssh/sshd_config中的配置。在生產環境中,為了防止******,一般會修改ssh服務的默認端口號,修改ssh服務默認端口號就是在/etc/ssh/sshd_config中完成的。我們也可以通過該配置文件禁止用戶使用密碼進行認證,只能使用密鑰認證。修改完配置文件以后,執行下面的命令重啟OpenSSH的守護進程才能生效:
對於一名剛開始接觸Linux系統管理的工程師來說,他眼里的系統管理的步驟可能是:使用SSH登錄服務器,修改應用相關的配置文件,執行一些Linux命令,重啟相應的進程,最后退出服務器。如果還有更多的服務器,那么,就重復上述過程。
上面這一系列步驟是Linux系統管理的基礎知識,是系統管理的基本功。但是,在實際工作中,一般不會手動對
服務器進行操作,而是使用程序進行自動化管理。即使服務器的數量很少,也推薦大家編寫程序進行自動化。相對於手動管理服務器,自動化管理有許多優點。例如:
/etc/init.d/ssh restart
OpenSSH的客戶端是一個名為ssh可執行程序,我們可以使用ssh命令連接遠程服務器。如下所示:
[root@python ~]# ssh xgp@localhost
The authenticity of host 'localhost (::1)' can't be established.
ECDSA key fingerprint is bf:c7:de:84:e1:28:f4:d4:7e:41:49:9f:54:dc:e9:83.
Are you sure you want to continue connecting (yes/no)? yes
xgp@localhost's password:
[xgp@python ~]$
如果服務器端不是使用默認的22端口,可以通過SSH命令的-p參數指定建立連接的端口號,格式如下所示:
ssh username@remote_host -p 端口號
我們也可以不進入交互式的Shell,直接使用ssh命令在遠程服務器中執行Linux命令,如下所示:
[root@python ~]# ssh root@192.168.1.80 'date'
root@192.168.79.129's password:
2020年 05月 15日 星期五 15:55:08 CST
s
[root@python ~]#
3、配置ssh的方法:
編輯/etc/ssh/ssh_config
編輯~/.ssh/config
ssh會讀取/etc/ssh/ssh_config文件中的配置。例如,遠程服務器使用的不是默認的22端口號,我們只需要在/etc/ssh/ssh_config進行簡單的配置,就可以在連接遠程服務器時省去指定端口號的參數。除了修/etc/ssh/ssh_config文件以外,更常見的做法是修改用戶home目錄下的~/.ssh/config文件。
查看ssh_config文件
[root@python ~]# find / -name ssh_config #查看找ssh_config 文件
/etc/ssh/ssh_config
[root@python ~]# cat /etc/ssh/ssh_config | awk #
Usage: awk [POSIX or GNU style options] -f progfile [--] file ...
Usage: awk [POSIX or GNU style options] [--] 'program' file ...
POSIX options: GNU long options: (standard)
-f progfile --file=progfile
-F fs --field-separator=fs
-v var=val --assign=var=val
Short options: GNU long options: (extensions)
-b --characters-as-bytes
-c --traditional
-C --copyright
-d[file] --dump-variables[=file]
-e 'program-text' --source='program-text'
-E file --exec=file
-g --gen-pot
-h --help
-L [fatal] --lint[=fatal]
-n --non-decimal-data
-N --use-lc-numeric
-O --optimize
-p[file] --profile[=file]
-P --posix
-r --re-interval
-S --sandbox
-t --lint-old
-V --version
To report bugs, see node `Bugs' in `gawk.info', which is
section `Reporting Problems and Bugs' in the printed version.
gawk is a pattern scanning and processing language.
By default it reads standard input and writes standard output.
Examples:
gawk '{ sum += $1 }; END { print sum }' file
gawk -F: '{ print $1 }' /etc/passwd
例如,我們經常要使用某一個用戶名、端口號訪問某一台遠程服務器。為了省去記住服務器ip的負擔,很多工程師會編寫一個Shell腳本,在腳本中保存用戶名、端口號和ip地址。在下次登錄時,可以省去輸入的煩惱。如下所示:
[root@python ~]# vim /opt/login.sh
#!/usr/bin/bash
ssh test@127.0.0.1 -p 22
[root@python ~]# useradd test
[root@python ~]# passwd test
更改用戶 test 的密碼 。
新的 密碼:
無效的密碼: 密碼少於 8 個字符
重新輸入新的 密碼:
passwd:所有的身份驗證令牌已經成功更新。
[root@python ~]# sh /opt/login.sh
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
ECDSA key fingerprint is bf:c7:de:84:e1:28:f4:d4:7e:41:49:9f:54:dc:e9:83.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts.
test@127.0.0.1's password:
[test@python ~]$
對於這里的需求,還有更好的解決方案。命令會讀取~/.ssh/config文件中配置,因此,我們可以在~/.ssh/config文件中提前配置好訪問遠程服務器的信息。如下所示:
[root@python ~]# cp /etc/ssh/ssh_config -p ~/.ssh/config
[root@python ~]# vim ~/.ssh/config
Host python
ForwardAgent yes
StrictHostKeyChecking no
port 22
User test
Controlpath ~/.ssh/ssh-%r@%h:%p.sock
Host *
StrictHostKeyChecking no
HostName %h
Port 22
User test
Controlpath ~/.ssh/ssh-%r@%h:%p.sock
配置完成后,直接在命令行執行ssh host2就可以使用用戶名test,以及端口號2092登錄到10.166.224.14中。此外,我們還使用通配符的方式定義了ssh默認用戶名與端口號。假設我們要使用用戶名laoyu、端口號2092訪問10.166.226.153,有了前面的配置以后,可以在命令行直接進行登錄。如下所示:
[root@python ~]# ssh python
Warning: Permanently added 'python,fe80::c64e:c937:2ea8:6676%ens33' (ECDSA) to the list of known hosts.
test@python's password:
Permission denied, please try again.
test@python's password:
Last login: Fri May 15 14:34:54 2020 from localhost
[test@python ~]$
可以看到,我們只需要在~/.ssh/config文件中進行簡單的配置就能夠有效提高工作效率。
4、使用密鑰登錄遠程服務器
ssh使用密碼
ssh不使用密碼,使用密鑰
在上面的例子中,我們沒有指定認證的方式,默認使用密碼進行認證。在生產環境中一般不使用密碼認證,一方面是因為密碼認證沒有密鑰認證安全;另一方面,密碼認證每次登錄時都需要輸入密碼,比較繁瑣。使用密鑰認證,省去了輸入密碼的煩惱。因此,在生產環境中,一般會使用密鑰進行登錄。
密鑰登錄的原理也很簡單,即事先將用戶的公鑰儲存在遠程服務器上(~/.ssh/authorized_keys文件)。使用密鑰登錄時,遠程服務器會向用戶發送一段隨機字符串,SSH使用用戶的私鑰加密字符串后發送給遠程服務器。遠程服務器用事先儲存的公鑰進行解密,如果成功,就證明用戶是可信的,直接允許登錄Shell,不再要求密碼。
OpenSSH除了提供服務端的sshd、客戶端的SSH程序以外,還提供了若干與密鑰認證相關的工其。其中,ssh-keygen是用來生成密鑰對的工具。如下所示:
[root@python ~]# ssh-keygen

ssh-keygen執行完以后,用戶的~/.ssh目錄下會存在一個名為id_ rsa的私鑰文件與一個名為id_rsa.pub的公鑰文件。
接下來要做的是將公鑰保存到遠程服務器的~/.ssh/authorized_keys文件中。可以使用下面的命令將公鑰保存到遠程服務器的authorized_keys文件中:
[root@python ~]# ssh root@192.168.1.80 'mkdir -p .ssh && cat >>.ssh/authorized_keys' <~/.ssh/id_rsa.pub
The authenticity of host '192.168.1.80 (192.168.1.80)' can't be established.
ECDSA key fingerprint is SHA256:UbtfIBIs2tGQU1m/SIvSZX72VUQ+r1fH/aIMxVbdobg.
ECDSA key fingerprint is MD5:56:10:49:b1:ae:f6:3c:d3:5e:2d:c5:d9:38:2c:45:e7.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.80' (ECDSA) to the list of known hosts.
root@192.168.1.80's password:
[root@python ~]#
上面的命令是使用Shell腳本的方式將公鑰保存到遠程服務器,除此之外,OpenSSH專門提供了一個名為ssh-copy-id的工具。我們可以使用該工具將公鑰保存到遠程服務器中,這種方式比前面Shell腳本的方式更加方便。如下所示:
[root@python ~]#
[root@python ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.1.80
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.1.80's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '192.168.1.80'"
and check to make sure that only the key(s) you wanted were added.
[root@python ~]# rm -rf ~/.ssh/config
[root@python ~]# ssh 192.168.1.80
Last login: Fri May 15 15:16:23 2020 from 192.168.1.80
[root@python ~]#

配置私鑰認證以后,就可以直接使用私鑰進行登錄。ssh命令會默認讀取~/.ssh/id_rsa這個私鑰文件。如果私鑰文件保存在其他位置,或者是其他名稱,可以使用-t參放指定私鑰文件的地址。如下所示:
ssh test@192.168.1.80 -p 22 -i ~/私鑰文件所在的位置(含文件名)
使用私鑰登錄時需要注意,私鑰文件與遠程服務器中authorized_keys文件的權限都必須為600,否則登錄會出錯,這也是工程師使用私鑰登錄時最容易遇到的錯誤。
測試登陸一下
[root@python ~]# vim ~/.ssh/config
Host python
ForwardAgent yes
StrictHostKeyChecking no
HostName 192.168.1.80
Port 22
User test
Controlpath ~/.ssh/ssh-%r@%h:%p.sock

[root@python ~]# ssh python
test@192.168.1.80's password:
Last login: Fri May 15 14:49:17 2020 from fe80::c64e:c937:2ea8:6676%ens33
[test@python ~]$
查看公鑰是否一致
[root@python ~]# ssh 192.168.1.80
Last login: Fri May 15 15:16:23 2020 from 192.168.1.80
[root@python ~]# cat ~/.ssh/authorized_keys #遠程的
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCWLJAYWCpbRPQX8gDbr2mIyXMw/qEKd46u4QhcaDPY7CeGd/buIGsWsuz+DAcnowk095rIwspGGHOdt54s+aeXGXcsRh7Hpuf0Py20Krim+v2LIUQW8vQSJDj1HiQUSnNQNPT3HAm0aqQp8u2EZ0StLYtf/uYSbg6rSzW08mKwhBQkrP0olWb+hD4ak3LxA05OI/WnanGKqtqjLg+4MbgGK96fY53dKvwrdt9NWiuof3pLgTw9fTvPU6CD+cH4LmRg8IVhthlBRhrXPA7oa8gvupTvpMYdNPPUSBsVR2rBcimrUFwdOpzb6T30C7o566noRd3t3nNxkQ/HrKalo9Bn root@python
[root@python ~]# exit
登出
Connection to python closed.
[root@python ~]# cat ~/.ssh/id_rsa.pub #本地的
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCWLJAYWCpbRPQX8gDbr2mIyXMw/qEKd46u4QhcaDPY7CeGd/buIGsWsuz+DAcnowk095rIwspGGHOdt54s+aeXGXcsRh7Hpuf0Py20Krim+v2LIUQW8vQSJDj1HiQUSnNQNPT3HAm0aqQp8u2EZ0StLYtf/uYSbg6rSzW08mKwhBQkrP0olWb+hD4ak3LxA05OI/WnanGKqtqjLg+4MbgGK96fY53dKvwrdt9NWiuof3pLgTw9fTvPU6CD+cH4LmRg8IVhthlBRhrXPA7oa8gvupTvpMYdNPPUSBsVR2rBcimrUFwdOpzb6T30C7o566noRd3t3nNxkQ/HrKalo9Bn root@python

二、使用ssh-agent管理私鑰
OpenSSH還提供了一個名為ssh-agent的程序,該程序可以簡化SSH私鑰的管理操作。ssh-agent是個長時間持續運行的守護進程(daemon),它的唯一目的就是對私鑰進行高速緩存。
使用ssh-agent有以下幾個好處:
(1)如果我們使用了一個加密的私鑰,那么,使用這個私鑰時將需要輸入密碼才能使用私鑰文件。如果我們使用加密的私鑰並且沒有使用ssh-agent,那么將不得不在每次使用這個私鑰時都輸入密碼。如果使用ssh-agent管理私鑰,只需要在私鑰加入到ssh-agent的那一刻輸入密碼,在之后的使用中都不用輸入私鑰的密碼;
(2)如果我們有多台遠程服務器與多個私鑰文件,使用ssh-agent以后,不用在每次登錄服務器時都使用-i參數指定使用哪一個私鑰文件。ssh-agent將會嘗試使用不同的私鑰文件建立連接。直至成功;
(3)使用ssh-agent可以實現私鑰轉發功能。假設現在有三台服務器,分別是A, B, C。其中,A是我們的控制節點,我們可以在A上直接訪問B,但是我們無法直接訪問C。如果要訪問C,就只能先登最B,再從B登錄C。對於這種情況,是否需要在B中保存用戶的私鑰呢?對於這里的情況,我們可以使用agent forwarding。使用agent forwarding以后,不用將私鑰保存到B服務器上,只需要在A中保存私鑰,在B和C中保存公鑰,便可在A中訪問B與C這兩台服務器。為了使用agent forwarding,我們必須使用ssh-agent管理私鑰。
如果在Windows下使用Xshell進行SSH訪問,要啟動ssh-agent非常簡單,只需要在“連接“-->"SSH“中勾選“使用密碼處理的Xagent (SSH代理)”即可。
(1)先把原先的密鑰刪除並生成新的密鑰
[root@python .ssh]# cd ~/.ssh/
[root@python .ssh]# rm -rf id*
[root@python .ssh]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
dc:57:da:10:e5:1a:8b:15:e3:98:61:d4:02:9f:56:8f root@python
The key's randomart image is:
+--[ RSA 2048]----+
| .o+.=.. |
| o.B.B |
| *.E + |
| . o o O |
| S o = . |
| . |
| |
| |
| |
+-----------------+
[root@python .ssh]# ssh-copy-id -i id_rsa.pub 192.168.1.80
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.1.80's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '192.168.1.80'"
and check to make sure that only the key(s) you wanted were added.
[root@python .ssh]# ssh 192.168.1.80
Enter passphrase for key '/root/.ssh/id_rsa':
Last login: Fri May 15 15:28:54 2020 from fe80::c64e:c937:2ea8:6676%ens33
[root@python ~]# exit
登出
Connection to 192.168.1.80 closed.
現在登陸需要私鑰
(2)使用ssh-agent保存密鑰
在Linux下,直接執行ssh-agent命令啟動ssh-agent即可。啟動以后,使用ssh-add命令將私鑰添加到ssh-agent中。如下所示:
[root@python ~]# ssh-agent bash
[root@python ~]# ssh-add ~/.ssh/id_rsa
Enter passphrase for /root/.ssh/id_rsa:
Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
[root@python ~]#
私鑰添加完成后,可以執行ssh_add -L命令查看哪些私鑰已經被添加到ssh-agent中。如下所示:
[root@python ~]# ssh-add -L
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDsP4VSOhnnCfidbg7e0OAQFcW5wAgPHld9S8KDTWv3X0/LNilYM3RkXQZ10XQ8Mw34i9rXa3SfqaHk6QYHXjNEUv6PEA/rKWY3kLXH9VUVHry4iwt9kVg9PowfccKLXPi8iWpqS7tk5ZEAnxihBtQattMTC44iz9X6hJDEn1r3r3YplJJGilIR+NaYJrM3ltxUBVuoJ82MfHOomhirc37ihLEwNbqRBMPYC4u1SoXDkagFsh0+HcuE0436yEByFxFw87jPmrjl7bgFsPahQsydrXySXOVdCzQJ8WuzJa1RvKr0xmgCjhZKExUYnMGAN9M79UBAyzZf2vUrwvvpPqWd /root/.ssh/id_rsa
啟動ssh-agent以后,當我們嘗試與遠程服務器建立連接時,ssh客戶端將會嘗試使用存儲在ssh-agent中的私鑰與遠程服務器進行認證。
[root@python ~]# ssh 192.168.1.80
Last login: Fri May 15 15:38:28 2020 from 192.168.1.80
[root@python ~]# exit
登出
Connection to 192.168.1.80 closed.
現在因為本地保持了私鑰,所以不需要輸入私鑰了

侵刪
來源:https://blog.51cto.com/14320361/2495683
沈陽治療外陰白斑多少錢:http://www.sdwybb120.com/