大神教你DIY高性能運維堡壘體系
不怕出問題,就怕出問題找不到原因
運維團隊一般會有個需求就是記錄運維或者開發同事在伺服器上的操作記錄,比如進行一些常規審核或者是伺服器被黑了、伺服器日誌被刪的情況需要知道發生過什麼事情,今天和大家分享下我們現在的伺服器的shell和mysql操作日誌記錄的DIY方案。
團隊內部之前有測試過一些堡壘機硬體,但終端操作方面不夠人性化,不夠靈活,而且價格昂貴,硬體容易形成單點故障。當然也接觸過一些開源的方案,比如可以直接用ttyrec對終端進行錄製,並且支持文本匹配,但是在實際使用中發現過嚴重bug,還有另外一些openssh的修改方案也不盡人意。
鑒於上述問題,我們針對bash和mysql的代碼進行簡單的修改來實現一個低成本、實用性能高的日誌審計方案。
先上兩張效果圖
伺服器日誌:
遠程日誌中心web後台:
上面截圖前面一部分是mysql的操作日誌,後面部分是shell操作日誌。具體解決方案請往下走。
>>>>
解決方案
整體架構如下圖:
下面來「開源」這個解決方案,希望對大家有小小幫助。
1、linux bash審計
大家應該有聽說過網路說的bash修改方案,我們從2011年開始使用,中間經歷過很多bug,修復和優化過多次版本,下面會詳細地給出我們現在的線上方案。現在的功能支持大致如下:
同一系統用戶精確到具體人員的shell操作記錄
支持遠程通過ssh IP 「command」執行和scp時候的日誌記錄
支持不同系統用戶進行切換時候能繼續記錄日誌
新支持mysql的操作日誌
上述每一個功能列表都是經過多次實踐出來的需求,雖然不是非常完美,但是如果不是刻意來逃避日誌記錄的話,基本可以滿足大家的需求,上述的記錄對應的人員是指多個人同時使用同一個系統帳號的情況,比如root帳號。
1.1 基本功能實現
基本功能就是需要記錄到每個人的操作記錄,網路上有個方案雛形,修改bashhist.c文件,701行左右修改bash_syslog_history函數,修改完之後內容:
然後重新編譯安裝即可。
上面取的是NAME_OF_KEY這個系統變數,我們稱之為指紋,用這個變數來對應到具體的人員,然後將對應的操作記錄到syslog。如果沒有取到這個變數的話,/var/log/messages那裡這個變數就顯示為空了,只知道是某個系統帳號在執行,但無法精確到個人。
1.2. 指紋變數處理
接下來重點就是處理NAME_OF_KEY這個指紋變數,原理也比較簡單,每個人登錄系統的時候,我們讓他自動執行一個腳本,然後設置這個變數為具體人就可以了。
別說有人還在利用密碼登錄Linux伺服器,太不專業了-_-
在這個文件裡面~/.ssh/authorized_keys加key的時候,第三列設置為具體的人員,我們是用工號@姓名拼音的模式,然後通過腳本進行處理即可。
腳本路徑 /etc/bash_ywjt,內容:
上面的邏輯比較簡單,首先我們還需要開啟sshd的debug模式,在/etc/ssh/sshd_config文件加入:
還可以針對複雜的情況進一步的進行邏輯處理,比如su進行用戶切換的時候,核心思想是跟蹤PID變數,跟蹤的變數主要是/var/log/secure裡面的sshd[ID_NUM]裡面的關鍵詞和ps –ef|grep ID_NUM顯示的第一二列的ID號,進行不斷的匹配跟蹤即可找到最原始的是哪個ID號。
然後在/etc/profile裡面進行載入:
不過這樣還不夠,我們需要支持遠程執行時候也記錄的話就需要在~/.bashrc文件裡面再加入一行,注意不能放在~/.bash_profile,兩個文件雖然都是載入用戶腳本,但是有差異的。在裡面加入的內容:
這個邏輯是BASH_EXECUTION_STRING這個變數在本地執行和遠程執行時候是不一樣的,我們先進行變數判斷,然後再做對應的處理即可,加完了就會發現遠程執行時候也有日誌記錄了(馬賽克處是來源IP):
這樣就基本完成了shell操作記錄的核心功能。
2、Mysql操作日誌
很早以前找過相關的mysql插件,也嘗試過audit之類的方案,但結果不是我們需要的效果,我們需要的是運維方面在伺服器上的mysql操作,和mysql的binlog等日誌不是同一個事情,而且和.mysql_history記錄的也不一樣,我們需要精確到同一系統用戶的不同人員。
以下mysql版本是指Percona-Server-5.5。
2.1 初步解決
mysql自帶了syslog日誌功能,但是需要手動配置開啟,配置比較簡單:
在/etc/my.cnf裡面的client欄位加上syslog即可。
效果看起來也還滿意,在/var/log/messages會有相關日誌:
但是這樣會存在三個問題
1)在mysqldump時候會報錯:
2)可以輕易地繞過這個日誌,在敲mysql命令行的時候加個參數--no-defaults即可。
3)日誌裡面只有是root帳號操作的,沒有體現出具體是某個人操作的。
解決這幾個問題還得靠開源的優勢進行代碼修改。
2.2 源碼開啟
我們可以在源碼裡面就把syslog這個開關開啟,比較容易,找到client/mysql.cc這個文件,開關邏輯比較簡單,找到以下代碼:
看意思這裡opt_syslog值就是個開關,wirte_syslog就是功能函數,找到static my_bool定義那裡,把opt_syslog的bool值改為1,然後重新編譯即可。
這樣把上面的前面兩個問題解決了。
2.3 互動式記錄
單純那樣改會發現還有個小問題,就是在shell終端下面直接mysql可以用-e進行命令操作,比如:
但是按照之前那樣開啟syslog也無法記錄日誌。我們是有記錄shell操作記錄的,這個問題可以忽略,不過一定要顯示的話也是有辦法的,繼續修改代碼。
稍微看下邏輯分析可以看到是需要滿足connect_flag == CLIENT_INTERACTIVE才寫日誌,找到CLIENT_INTERACTIVE的定義:
原來這個就是交互模式的定義,所以我們把這個「與」條件去掉即可,改為這樣:
然後再重新編譯,發現順利解決msyql –e執行命令的歷史記錄了。
2.4 海量日誌問題
在實際環境中會有新的問題,比如導入sql語句時候,會生成同樣大小的日誌,比如導入2G的sql,會生成2G的日誌,這樣明顯不符合我們的需求。
想到我們已經有bash審核了,-e執行時候可以忽略記錄,但是如果在mysql裡面通過source命令引用sql語句時候同樣有這個問題,所以還得繼續改代碼。
找到write_syslog函數,正式寫日誌時候是用的syslog函數,裡面有個for循環的邏輯,意思是當sql語句很大時候,需要「切割」一下再寫入,所以從這裡入手,把syslog改為定義的MAX_SYSLOG_MESSAGE長度之內就寫,超過的話就直接忽略。
另外之前說需要精確到不同人員,所以我們引入了我們的bash審核裡面的指紋,變數NAME_OF_KEY,然後在mysql.cc裡面引入即可。關鍵修改如下:
搞定,這樣導入一個2G的sql語句,生成不到2m的日誌,一些sql數據的話就忽略截斷了。
2.5 自定義參數
這樣雖然是在源碼裡面寫死了一定有日誌,但是還是可以提供一個備用的參數來取消這個功能。
在參數定義那裡改動,把之前的syslog改為這樣:
這樣就是一個no-syslog的取消開關了,用法就是在my.cnf裡面添加欄位:
這段修改是可選的,可以忽略。
3、遠程日誌中心
上述日誌全部是通過syslog服務記錄到/var/log/messages文件,更合理的是再傳輸到遠程的日誌中心來統一備案管理。
這個方法比較簡單,在/etc/rsyslog.conf裡面加入配置:
重啟rsyslog服務之後,所有的日誌就會同時發送一份到LOGSERVER_IP這個伺服器,這裡之前另外有個bash版本是內嵌了日誌發送的功能,用的udp協議,不會對命令操作有卡頓,不過沒用在線上。
最後我們在日誌伺服器可以搭建個splunk或者開源的logstash日誌分析平台即可。關於日誌系統,後續我們再詳細介紹下我們現在的CDN日誌系統。
4、內網日誌攔截
這個段落是額外的參考,我們的定製系統是寫死了配置全部發送到公網的某一台日誌中心伺服器,但是我們內網機房也有很多伺服器,這樣會導致在日誌中心那裡無法查看原始的內網IP,只有辦公網的出口IP,而且不方便每個機器都去更改日誌中心的IP,那樣會很容易漏掉,解決辦法是進行「日誌劫持」。
在我們的juniper防火牆那裡進行日誌攔截,然後轉發到內網的一個日誌中心即可,參考配置:
這樣是在辦公網搭建了另外一個日誌中心伺服器,攔截轉發之後也就可以識別到具體的來源的內網IP了。
>>>>
總結
這個遠程日誌中心平台是挺有必要搭建一個,像有時候伺服器上不去了,我們可以上這個日誌中心進行日誌查詢,看發生什麼事情了,另外就是假如機器被別人拿到許可權了,我們可以在這裡看到原始日誌。當然我們機器是都安裝了ossec和lynis會進行安全系統層的安全掃描,不過保留一份原始的日誌是必不可少的。
作者 :金龍;來源:運維軍團
※一文幫你秒懂區塊鏈
※安卓惡意軟體Skygofree監控能力前所未有;華為美國之路充滿坎坷
TAG:ServiceHot |