i春秋作家:yanzm
原文來自:安全運維中基線檢查的自動化之ansible工具巧用
前幾周斗哥分享了基線檢查獲取數據的腳本,但是在面對上百台的服務器,每台服務器上都跑一遍腳本那工作量可想而知,而且都是重復性的操作,於是斗哥思考能不能找到一種方法來實現自動下發腳本,批量執行,並且能取回執行的結果。對比參考學習某些開源的平台都有這么一個特點就是需要安裝客戶端(說白了就是類似后門木馬的插件),客戶端的兼容性適應問題不說,而且全部服務器都要裝相應的客戶端,明顯超出斗哥預期的輕量級的實現自動化的初衷,但是辦法總比困難多作為老板的省錢小能手身輕如燕的斗哥還真找到一個工具無需安裝客戶端就能實現自動化運維的工具。
話不多說,斗哥決定先給大家演示一下ansible如何實現基線檢查腳本的自動下發,批量執行和結果取回,然后再進一步學習這款工具的安裝和使用,以及后期的自動化思路。
0x01 效果演示
環境說明:
主控端:192.168.159.55
節點:192.168.159.92、192.168.159.94
確保主控端和節點的連通性,主控端/tmp目錄下已創建好需執行的基線檢查腳本。
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
[root@root tmp]# rpm -ivh epel-release-latest-7.noarch.rpm

step3:安裝Ansible以及查看對應的版本
[root@root tmp]# yum -y install ansible
[root@root tmp]# ansible –version

到step3 ansible就已經安裝完畢,如果安裝在虛擬機的強烈建議這里可以打個快照方便后續的測試調試。step4和step5步驟后面納入批量化要考慮的需求,但是手工的流程我們先走一遍。
step4:設置用於鑒權的SSH密鑰
主控端生成ssh的公私鑰,默認生成的密鑰保存在/root/.ssh文件夾下
[root@root tmp]# ssh-keygen

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

step5:添加Ansible定義的節點到host清單
在ansible的配置文件添加host清單,建議根據實際分類對組進行命名。
[root@root tmp]# vi /etc/ansible/hosts

step6:在ansible主控端運行命令測試
[root@root 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命令的格式:[root@root tmp]#ansible-playbook+參數[options]+playbook文件路徑。
栗子: 創建如下playbook:

執行playbook,–tags可指定具體要執行的task:
[root@root 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環境,且節點密碼一致的情況。
[root@root tmp]# ./demo
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這兩個模塊。
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春秋論壇閱讀喲~