1. 程式人生 > >安全運維中基線檢查的自動化之ansible工具巧用

安全運維中基線檢查的自動化之ansible工具巧用

i春秋作家:yanzm

原文來自:安全運維中基線檢查的自動化之ansible工具巧用

前幾周鬥哥分享了基線檢查獲取資料的指令碼,但是在面對上百臺的伺服器,每臺伺服器上都跑一遍指令碼那工作量可想而知,而且都是重複性的操作,於是鬥哥思考能不能找到一種方法來實現自動下發指令碼,批量執行,並且能取回執行的結果。對比參考學習某些開源的平臺都有這麼一個特點就是需要安裝客戶端(說白了就是類似後門木馬的外掛),客戶端的相容性適應問題不說,而且全部伺服器都要裝相應的客戶端,明顯超出鬥哥預期的輕量級的實現自動化的初衷,但是辦法總比困難多作為老闆的省錢小能手身輕如燕的鬥哥還真找到一個工具無需安裝客戶端就能實現自動化運維的工具。 
話不多說,鬥哥決定先給大家演示一下ansible如何實現基線檢查指令碼的自動下發,批量執行和結果取回,然後再進一步學習這款工具的安裝和使用,以及後期的自動化思路。

0x01 效果演示



環境說明: 
主控端:192.168.159.55 
節點:192.168.159.92、192.168.159.94 
確保主控端和節點的連通性,主控端/tmp目錄下已建立好需執行的基線檢查指令碼。
 

[PHP] 純文字檢視 複製程式碼

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

#!/bin/bash

 

#主控端生成金鑰

 

ssh-keygen -t rsa

 

#將節點加入/etc/ansible/hosts,增加的可參照下面的格式新增

 

echo "[web]" >> /etc/ansible/hosts

 

echo "192.168.159.92 ansible_ssh_pass=root" >> /etc/ansible/hosts

 

echo "192.168.159.94 ansible_ssh_pass=root"

>> /etc/ansible/hosts

 

#記錄節點金鑰,新增節點參照下面的格式進行新增

 

ssh-keyscan 192.168.159.92 >> /root/.ssh/known_hosts

 

ssh-keyscan 192.168.159.94 >> /root/.ssh/known_hosts

 

#建立playbook

 

touch /etc/ansible/push-ssh.yml

 

echo "---" >> /etc/ansible/push-ssh.yml

 

echo "- hosts: web" >> /etc/ansible/push-ssh.yml

 

echo "  user: root" >> /etc/ansible/push-ssh.yml

 

echo "  tasks:" >> /etc/ansible/push-ssh.yml

 

echo "    - name: ssh-key-copy" >> /etc/ansible/push-ssh.yml

 

echo "      authorized_key: user=root key=\"{{lookup('file','/root/.ssh/id_rsa.pub')}}\"" >> /etc/ansible/push-ssh.yml

 

echo "      tags:" >> /etc/ansible/push-ssh.yml

 

echo "        - sshkey" >> /etc/ansible/push-ssh.yml

 

#執行playbook

 

ansible-playbook /etc/ansible/push-ssh.yml

 

#測試

 

ansible web -m ping

 

#主控端建立指令碼,在節點執行

 

mkdir /tmp/check

 

ansible web -m script -a "/tmp/linux_centos7.sh"

 

#ansible web -m raw -a "ls /tmp/check"

 

#取回指令碼執行結果,儲存在/tmp/check/目錄下

 

result=(`ansible web -m raw -a "ls /tmp/check" | grep dict | awk '{print $1}'`)

 

for i in ${result[@]}

 

do

 

ansible ${i:13:14} -m raw -a "cat /tmp/check/$i" >> /tmp/check/$i

 

done



執行自動化指令碼demo,linux_centos7.sh為建立在主控端的基線檢查指令碼:
 


指令碼執行結束即可在本地的/tmp/check目錄下檢視到節點的執行結果:
 


上述的過程,在面對眾伺服器節點的時候可以省去很多工作量,是不是感覺一下清爽了許多。

but 

當節點沒有python的情況下,上述指令碼是不適用的哦,會出現如下報錯提示。
 


這裡先賣個關子,如何實現節點沒有安裝python的情況下的批量化請繼續往下看,鬥哥決定先帶領大家先來掌握批量指令碼涉及的相關知識,工欲善其事必先利其器。

0x02 ansible介紹以及安裝

Ansible是一款為類Unix系統開發的自由開源的配置和自動化工具,基於Python開發,集合了眾多運維工具(puppet、cfengine、chef、func、fabric,ps:反正鬥哥是沒用過啦)的優點,同時ansible最大的優點是不需要在節點中安裝任何客戶端,它使用SSH來和節點進行通訊。 ansible是基於模組工作的,比如常用的script、command、shell、copy、fetch、raw等模組,同時ansible還支援自定義模組和playbook以適應更豐富的自動化運維場景的需求(得益於python的強大基因)。

step1:準備工作 

主控端:centos7.5(Red Hat Enterprise Linux,CentOS,Fedora和Ubuntu等發行版都預設安裝了python 2.X的直譯器,pip不一定是預設安裝,如果有安裝也需要更新到最新版),具體主控端安裝環境要求如下:
 


ansible的主控端只能安裝在類unix的作業系統上,其他發行版的linux安裝可以詳見ansible中文權威指南-安裝管理主機,本文的安裝方法僅適用於centos系統。

step2:下載和安裝EPEL倉庫 

[root@root tmp]# wget http://dl.fedoraproject.org/pub/ ... latest-7.noarch.rpm 
[[email protected] tmp]# rpm -ivh epel-release-latest-7.noarch.rpm
 


step3:安裝Ansible以及檢視對應的版本 

[[email protected] tmp]# yum -y install ansible 
[[email protected] tmp]# ansible –version
 


到step3 ansible就已經安裝完畢,如果安裝在虛擬機器的強烈建議這裡可以打個快照方便後續的測試除錯。step4和step5步驟後面納入批量化要考慮的需求,但是手工的流程我們先走一遍。

step4:設定用於鑑權的SSH金鑰 

主控端生成ssh的公私鑰,預設生成的金鑰儲存在/root/.ssh資料夾下 
[[email protected] tmp]# ssh-keygen
 


主控端向單個節點下發公鑰: 
[[email protected] tmp]# ssh-copy-id -i [email][email protected][/email]
 


step5:新增Ansible定義的節點到host清單 

在ansible的配置檔案新增host清單,建議根據實際分類對組進行命名。 
[[email protected] tmp]# vi /etc/ansible/hosts
 


step6:在ansible主控端執行命令測試 

[[email protected] tmp]# ansible -m command -a “ifconfig” ‘webservers’
 


以上只是針對單個節點的情況下ansible的基本要達到的條件。

0x03 ansible的基礎用法、模組的使用條件以及playbook的使用

1. Ansible基本語法如下:

ansible <pattern_goes_here> -m <module_name> -a <arguments>

指定操作的節點    指定模組名稱     為模組指定引數

<pattern_goes_here>指的是要操作節點的組名,即/etc/ansible/hosts檔案中定義的節點分類的組名或者具體的節點的IP地址或者域名等; 
-m 用於指定模組的名稱,比如常用的command、script、raw等模組; 
-a 定義模組的引數,比如指定模組command後再-a “date”即可檢視節點的時間,其他使用以此類推。

2. ansible執行結果的顏色含義:

紅色:表示ansible對節點執行的命令出現異常 
綠色:表示ansible對節點執行的命令正常執行,並且沒有對節點產生修改操作。 
黃色:表示ansible對節點執行的命令正常執行,並且對節點產生相應的改動操作。

3. 模組的使用條件:

模組的使用,這裡鬥哥考慮的是條件是節點是否需要python環境。這裡ansible有兩個模組是節點是不需要安裝python環境就可以使用,分別是raw模組和script模組,其他模組的使用都是基於節點有python環境。



具體的模組的使用條件,引數說明可以在使用相關模組的時候再查讀ansible 模組官方文件即可。

4. playbook初識:

playbook其實就是ansible各個模組的組合使用,用專門的yaml語言將一個或多個模組合併在一個playbook裡面的組合使用。playbook具體由playbook的角色以及playbook的角色要執行的任務task兩部組成,一個playbook由一個或者多個角色(play)組成,一個角色(play)可以包含多個任務(task)。playbook的基本構成看下圖:
 



呼叫playbook命令的格式:[[email protected] tmp]#ansible-playbook+引數[options]+playbook檔案路徑。

栗子: 建立如下playbook:
 



執行playbook,–tags可指定具體要執行的task: 
[[email protected] tmp]# ansible-playbook –tags t2 playbook.yml
 



驗證執行情況:





0x04 實際問題中自動化的思考

這裡鬥哥想從實際的需求以及遇到的問題出發來達到輕量級地實現自動化的目標。基於ansible這個開源神器,我們不用直接瞭解底層ssh的通訊原理以及python實現的模組化。在使用ansible這個工具時我們要考慮的批量化需求詳見下圖分析。
 



1.基礎環境和條件

●基線檢查指令碼(漏斗公總號回覆基線自動化運維可得,當然鬥哥手上還有其他作業系統的、中介軟體、資料庫等眾多基線指令碼,不同的節點執行的指令碼的組合不同,這個也需做好分類)

●安裝好ansible的主控端主機一臺,安裝在虛擬機器的可以在0x02的step3儲存快照。

●需要檢查的節點清單(確保開放ssh埠,不是預設22埠的話另分類出來這裡暫不做考慮、節點root許可權的賬號密碼)


2.主控端的公鑰需要批量下發

主控端通過ssh-keygen命令生成公私鑰後,公鑰需要下發到節點才可實現主控端對節點的控制,0x02中的是單個節點的公鑰下發,並且需要人機互動鍵入節點ssh密碼,顯然不適合面對多個節點的下發。 
這裡鬥哥的解決方案是通過expect來實現自動化的互動,以下指令碼適用條件於節點無python環境,且節點密碼一致的情況。

[[email protected] tmp]# ./demo
 

[PHP] 純文字檢視 複製程式碼

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

#!/bin/bash

#生成金鑰

ssh-keygen -t rsa

#節點IP以及密碼批量發下

SERVERS="192.168.159.88 192.168.159.89"

PASSWD="root"

function sshcopyid

{

expect -c "

set timeout -1;

spawn ssh-copy-id $1;

expect {

       \"yes/no\" { send \"yes\r\";exp_continue; }

       \"password:\" { send \"$PASSWD\r\";exp_continue; }

               };

    expect eof;

       "

}

for server in $SERVERS

do

   sshcopyid $server

done



3.基線檢查指令碼的批量

指令碼適用範圍:節點未安裝python環境,主控端事先建立好要執行的基線指令碼。這裡鬥哥只是使用了ansible的raw和script這兩個模組。
 

[PHP] 純文字檢視 複製程式碼

?

01

02

03

04

05

06

07

08

09

10

#主控端建立/tmp/check資料夾用於存放取回的指令碼執行結果

mkdir /tmp/check

#使用script模組執行指令碼

ansible web -m script -a "/tmp/linux_centos7.sh"

#使用raw模組檢視指令碼執行的結果並匯出儲存在主控端

result=(`ansible web -m raw -a "ls /tmp/check" | grep dict | awk '{print $1}'`)

for i in ${result[@]}

do

ansible ${i:13:14} -m raw -a "cat /tmp/check/$i" >> /tmp/check/$i

done



以上就是鬥哥梳理的整個自動化的流程,拆分每個步驟,針對各個坑點逐一擊破,從而實現自動化過程和思考。其實ansible還可以跟其他工具相結合使用,比如和Jenkins結合實現視覺化等。如果你有疑問或者不同的見解,歡迎給鬥哥留言,期待和大家的交流。

大家有任何問題可以提問,更多文章可到i春秋論壇閱讀喲~