在網格審計數據庫
已發表: 2018-09-29由於 SendGrid 最近成為一家上市公司,我們需要對數據庫子集的所有更改擁有完整的審計日誌。 該子集包括一些沒有看到大量流量的小型實例,還包括一些對我們的客戶門戶正常運行時間和註冊流程至關重要的舊集群。
這也影響了一些對正常運行時間要求很高的數據存儲,並且需要在線推出(無需停機寫入)。 有了外部截止日期,並且了解了項目的範圍,我們開始製定計劃。
在規劃階段,我們確定了一些需要回答的未解決問題:
- 就可以做到這一點的軟件而言,我們有哪些選擇?
- 預計會有什麼性能影響,我們可以提前測試多少?
- 我們能否在不停機的情況下實現寫入可用性?
選擇,選擇
在 SendGrid,我們為任何大型或跨團隊項目遵循設計藍圖流程。 該項目涉及多個團隊作為利益相關者,包括:
- 內部審計團隊負責定義哪些數據存儲在此合規控制範圍內,並在審計時間收集證據
- InfoSec作為團隊將分析和處理從這些數據庫審計日誌中得出的事件響應
- DB Ops作為編寫代碼的團隊,負責將這一新功能部署、管理和調整到範圍內的數據庫中
我著手編寫這個藍圖,並確保它得到了所有利益相關者的審查並得到了我們的架構團隊的批准。 儘管幾年前我對 MySQL 中的審計日誌進行了一些研究,並且對選項的前景有所了解,但我不想帶著偏見來處理這個項目,並且仍然想調查不止一個選項,並為每個人提供一個可靠的案例,說明為什麼我們會選擇一種解決方案而不是另一種。
這個藍圖很不尋常,因為我在研究業務需求的解決方案的同時編寫它。 所以我知道在我們做一些研究的時候會填寫很多細節。
我們的選擇是:
- Percona 審計插件
- Mcafee MySQL 審計
雖然這些不是市場上唯一的選擇,但我們認為它們是最接近我們的規模和 devops 實踐的,可以保證將它們包含在實際的烘焙中。 市場上的其他商業選擇沒有通過該標準被包含在基準中。
後者是最近才由 Mcafee 開源的一個較新的解決方案,並且非常有趣,因為它聲稱支持 Percona 插件不支持的表級過濾。 由於我們知道我們的一個範圍內的集群實際上需要審核總共 300 個表中的大約 24 個,因此這似乎是一個足夠有價值的功能,可以使 Mcafee 插件成為競爭者。
另一方面,Percona Audit 插件是該功能使用最廣泛的開源解決方案。 它是內置的,但在我們已經使用的 Percona Server 中被禁用。 但是,它不提供對事件的表級過濾,這意味著我們需要在數據庫層之外執行此操作。
烤過
在 Pythian 合作夥伴團隊的幫助下,我們開始了烘焙比較。 首先,我們比較瞭如何安裝和調整每個選項。 團隊很快確定我們需要權衡取捨。 雖然 Mcafee 插件本身支持表過濾器,但它不支持使用 rsyslog 作為流式傳輸其事件的方法。 這意味著如果我們要使用它,我們必須將文件本地寫入磁盤,並且必須管理將它們發送到監控堆棧。
這被認為是不可取的,因為它很可能會增加使用審計插件的性能損失。 在本地寫入審計事件,然後通過單獨的進程再次讀取它們會從我們的實際生產流量中移除 IOPS 容量,並增加數據庫實例的風險,因為這意味著我們必須管理磁盤上這些文件的大小,以免它們膨脹並導致數據庫停機時間。
妥協的另一方面是 Percona 插件。 它支持將事件本地發送到 syslog,但不提供任何表過濾器。 我們知道這意味著範圍內更繁忙的集群將發送大量事件,其中大部分實際上並不是來自我們要審核的表。 這給 InfoSec 監控堆棧的 syslog-receive/logstash 層帶來了風險。 由於 DB ops 無權訪問它,這意味著該項目的成功是共享所有權的努力。
最終,我們決定使用移動部件較少的解決方案,併計劃我們的部署,以便儘早了解是否需要橫向擴展 Logstash 以處理每秒過濾數千個事件。 因此決定繼續使用 Percona 的審計插件。
部署規劃
安裝範圍
我們決定通過在給定集群中的所有節點上安裝和啟用插件來保持此部署的簡單性,這意味著我們無需在集群中的寫入節點更改時編排打開或關閉審計工具。 我們並不擔心複製流會在應用更改時導致重複事件,因為插件在設計上不會記錄複製流更改。
沒有停機時間
我們希望這是一個無縫部署,不會在受影響的集群中停機。 這將大大減少我們需要與使用這些集群的交付團隊進行的計劃和編排工作,並大大減少對客戶的影響。 但我們還希望插件將其事件發送到特定設施上的 rsyslog,並使用自定義配置將事件發送到 InfoSec 團隊的 syslog 聚合服務器。 Percona 將其中一些配置記錄為不是動態的,這表明當我們使用所需的審計插件配置重新啟動 mysql 實例時,該項目範圍內的每個實例都可能會導致一些停機時間。
我們開始在我們的暫存環境中使用專用測試實例部署插件時測試不同的操作順序,並且能夠證明,如果我們的配置管理首先放置所有必要的配置,然後運行加載插件命令,該命令將啟動所需的配置。
事實證明,這有助於簡化完成該項目的計劃並縮短在生產中發布它的時間,為我們爭取時間來微調事件過濾以及與安全團隊合作進行分析和檢測。
使用配置管理
我們使用廚師食譜來管理我們的數據庫,因此顯然我們計劃使用廚師來部署、調整和監控審計插件。 但是由於只需要在我們集群的一個子集中啟用它,這意味著我們需要一種方法來控制它的啟用位置,以免與我們的業務目標不相關的數據妨礙我們的日誌存儲。
為了管理 MySQL 數據庫,我們使用包裝說明書模型來管理配置。 核心“基礎”說明書定義了數據庫實例的大部分外觀,然後每個集群說明書將其包裝起來以修改屬性或添加與特定集群相關的配置。 這種設計使添加大量代碼變得容易,這些代碼將創建所需的配置文件,然後將插件加載到一個新配方中,然後我們可以根據廚師屬性打開和關閉。 我們還決定,鑑於我們所做的更改範圍,這保證了將此代碼作為新的次要版本的食譜發布。

我們還確保在屬性設置為 false 時讓 chef 刪除任何相關的 sensu 檢查並關閉審計流。 這是為了確保如果集群被認為不再在範圍內或由於任何間歇性原因需要停止時,廚師可以做正確的事情,因此我們不需要手動更改節點以反映屬性更改。
監控
你不能宣布你沒有監控的東西成功。 但監控也不僅僅是進行一些有意義的檢查,而不考慮我們正在監控哪些失敗案例,以及我們期望在某天對這些檢查失敗採取什麼行動。 所以我開始計劃這個管道中的監控,考慮到兩件事
- 我們需要就這個系統中明確的所有權範圍達成一致,特別是因為它跨越了兩個團隊的職責,並有單獨的待命輪換
- 為此添加的任何新檢查都需要附帶我們在檢查中鏈接到的運行手冊,解釋此檢查失敗的原因以及如何修復它
鑑於這兩條規則,我繼續添加非常具體的檢查。 在這一點上,我還考慮添加端到端的“綜合”檢查,但我已經避免這樣做,因為這裡的端到端檢查將無法準確告訴我們系統的哪個部分失敗,這意味著我們將很難時間甚至用它尋呼合適的團隊。 而且我不支持在晚上“以防萬一”尋呼人們
我們決定監控以下內容:
- 檢查審計插件的實時 mysql 配置以確保
- 該插件處於活動狀態
- audit_log_policy設置為QUERIES
此檢查確認範圍內的數據庫沒有動態更改其配置,因為這些設置是動態的並且可能在磁盤上的my.cnf文件之外更改。
- 檢查我們將日誌發送到監控堆棧的端口,以確保數據正在流動。 基本上,確保系統日誌流的另一端正常工作。 此檢查被處理為所謂的聚合檢查,因此它不會嚴重地向 InfoSec 團隊發送消息
一路上的障礙
審計插件配置
該項目的初始迭代之一旨在利用audit_log_exclude_commands功能將我們發出的事件限制為僅數據或模式操作。 我們很快了解到,此配置所基於的列表比預期的要長得多。
rsyslog 配置
這是我在這個項目之前不知道的事情。 Rsyslog 配置幾乎是它自己的語言。 例如:
- 在遠程目標前面使用第二個@通過 TCP 而不是 UDP 發送日誌。 我們想利用這個設施來提供更多的保證日誌正在交付。
- rsyslog 有一個專門的頁面,介紹如何配置它以實現可靠轉發,這對我這樣的工具新手非常有用。
- 默認情況下,rsyslog 還將其數據發送到/var/log/messages ,這在我的情況下是不可取的,因為這是很多事件。 如果您需要使您正在使用的設施不這樣做,則必須將local5.* ~添加到配置的末尾
消防演習
稍後我將討論範圍內數據庫的性能影響,但由於 rsyslog 被用作此設計的關鍵部分,因此我們還需要練習 rsyslog 在其遠程目標不可用或沒有響應時的行為方式。 做到這一點的最好方法是在生產中使用 iptables 規則在我們知道的具有高事務吞吐量的數據庫之一上中斷通信,因此每秒有大量的審計事件。 以下是消防演習的結果。
- 確認審計事件流經指定的 TCP 端口
- 使用 iptables 規則刪除該端口上的所有流量/sbin/iptables -A OUTPUT -p tcp –dport {PORT-NUMBER-HERE} -j DROP
- 在 rsyslog 的配置中觀察已配置WorkDirectory中的磁盤寫入活動和文件。 文件名將基於接收這些事件的設施的ActionQueueFileName
正如預期的那樣,文件開始在此目錄中假脫機。 我們看到磁盤 IOP 活動激增。 一旦定義隊列名稱的文件數量總計為 ActionQueueMaxDiskSpace 的值, rsyslog停止創建這些文件,磁盤 IOP 標準化,很明顯我們現在正在 rsyslog 層的地板上丟棄事件。 更令人印象深刻的是,在我們刪除了可飲用規則後,rsyslog 將所有已假脫機的事件重新發送到磁盤,因此只要我們不超過假脫機大小,我們的分析存儲就不會丟失事件。 我們從那個實驗中學到了一些東西
- rsyslog 的行為與記錄一致。 總是更好地通過第一手實驗證明這一點
- 我們很可能需要根據每個集群生成的事件量為每個集群定義不同的隊列磁盤空間。 由於在磁盤上排隊會增加 IOP 容量和磁盤容量的風險,因此我們需要定期重新審視並重新檢查
在下一篇文章中,我將討論在將這個項目部署到生產環境後我們的觀察結果,以及是什麼讓這個項目盡可能地不破壞生產環境。
