作者 | Andrew
譯者 | qhwdw ? ? ? ? ? 共計翻譯:104 篇 貢獻時間:164 天
由於復刻了 mon 專案到 etbemon[1] 中,我花了一些時間做監視指令碼。事實上監視一些事情通常很容易,但是決定監視什麼才是困難的部分。行程監視指令碼 ps.monitor
是我重新設計過的一個。
對於行程監視我有一些思路。如果你對行程監視如何做的更好有任何建議,請透過評論區告訴我。
給不使用 mon 的人介紹一下,如果一切 OK 該監視指令碼就傳回 0,而如果有問題它會傳回 1,並使用標準輸出顯示錯誤資訊。雖然我並不知道有誰將 mon 指令碼掛進一個不同的監視系統中,但是,那樣做其實很容易實現。我計劃去做的一件事情就是,將來實現 mon 和其它的監視系統如 Nagios 之間的互操作性。
基本監視
ps.monitor tor:1-1 master:1-2 auditd:1-1 cron:1-5 rsyslogd:1-1 dbus-daemon:1- sshd:1- watchdog:1-2
我現在計劃重寫該行程監視指令碼的某些部分。現在的功能是在命令列上列出行程名字,它包含了要監視的行程的最小和最大實體數量。上面的示例是一個監視的配置。在這裡有一些限制,在這個實體中的 master
行程指的是 Postfix 的主行程,但是其它的守護行程使用了相同的行程名(這是那些錯誤的名字之一,因為它太直白了)。一個顯而易見的解決方案是,給一個指定完整路徑的選項,這樣,那個 /usr/lib/postfix/sbin/master
就可以與其它命名為 master
的程式區分開了。
下一個問題是那些可能以多個使用者身份執行的行程。比如 sshd
,它有一個以 root 身份執行的單獨的行程去接受新的連線請求,以及在每個登入使用者的 UID 下執行的行程。因此,作為 root 使用者執行的 sshd 行程的數量將比 root 登入會話的數量大 1。這意味著如果一個系統管理員直接以 root 身份透過 ssh
登入系統(這是有爭議的,但它不是本文的主題—— 只是有些人需要這樣做,所以我們必須支援這種情形),然後 master 行程崩潰了(或者系統管理員意外或者故意殺死了它),這時對於該行程丟失並不會產生警報。當然正確的做法是監視 22 號埠,查詢字串 SSH-2.0-OpenSSH_
。有時候,守護行程的多個實體執行在需要單獨監視的不同 UID 下麵。因此,我們需要透過 UID 監視行程的能力。
在許多情形中,行程監視可以被替換為對服務埠的監視。因此,如果在 25 號埠上監視,那麼有可能意味著,Postfix 的 master
在執行著,不用去理會其它的 master
行程。但是對於我而言,我可以在方便地進行多個監視,如果我得到一個關於無法向一個伺服器傳送郵件的 Jabber 訊息,我可以透過這個來自伺服器的 Jabber 訊息斷定 master
沒有執行,而不需要挨個查詢才能發現問題所在。
SE Linux
我想要的一個功能就是,監視行程的 SE Linux 背景關係,就像監視 UID 一樣。雖然我對為其它安全系統編寫一個測試不感興趣,但是,我很樂意將別人寫好的程式碼包含進去。因此,不管我做什麼,都希望它能與多個安全系統一起靈活地工作。
短暫行程
大多數守護行程在行程啟動期間都有一個相同名字的次級行程。這意味著如果你為了精確地監視一個行程的一個實體,當 logrotate
或者類似的守護行程重啟時,你或許會收到一個警報說有兩個行程執行。如果在重啟期間,恰好在一個錯誤的時間進行檢查,你也或許會收到一個警報說,有 0 個實體。我現在處理這種情況的方法是,在與 alertafter 2
指令一起的次級行程失敗事件之前我的伺服器不發出警報。當監視處於一個失敗的狀態時,failure_interval
指令允許指定檢查的時間間隔,將其設定為一個較低值時,意味著在等待一個次級行程失敗結果時並不會使提示延遲太多。
為處理這種情況,我考慮讓 ps.monitor
指令碼在一個指定的延遲後再次進行自動檢查。我認為使用一個單個引數的監視指令碼來解決這個問題比起使用兩個配置指令的 mon 要好一些。
CPU 使用
mon 現在有一個 loadavg.monitor
指令碼,它用於檢查平均負載。但是它並不能捕獲一個單個行程使用了太多的 CPU 時間而沒有使系統平均負載上升的情況。同樣,也沒有捕獲一個渴望獲得 CPU 的行程進入沉默(例如,SETI at Home 停止執行)(LCTT 譯註:SETI,由加州大學伯克利分校建立的一項利用全球的聯網計算機的空閑計算資源來搜尋地外文明的科學實驗計劃),而其它的行程進入一個無限迴圈狀態的情況。解決這種問題的一個方法是,讓 ps.monitor
指令碼也配置另外的一個選項去監視 CPU 的使用,但是這也可能會讓人產生迷惑。另外的選擇是,使用一個獨立的指令碼,它用來報警任何在它的生命週期或者最後幾秒中,使用 CPU 時間超過指定百分比的行程,除非它在一個豁免這種檢查的行程或使用者的白名單中。或者每個普通使用者都應該豁免這種檢查,因為你壓根就不知道他們什麼時候執行一個檔案壓縮程式。也應該有一個包含排除的守護行程(像 BOINC)和系統行程(像 gzip,有幾個定時任務會執行它)的簡短串列。
對例外的監視
一個常見的程式設計錯誤是在 setgid()
之前呼叫 setuid()
,這意味著那個程式沒有許可權去呼叫 setgid()
。如果沒有檢查傳回程式碼(而犯這種低階錯誤的人往往不會去檢查傳回程式碼),那麼行程會保持較高的許可權。檢查以 GID 0 而不是 UID 0 執行的行程是很方便的。順利說一下,對一個 Debian/Testing 工作站執行的一個快速檢查顯示,一個使用 GID 0 的行程並沒有獲得較高的許可權,但是可以使用一個 chmod 770
命令去改變它。
在一個 SE Linux 系統上,應該只有一個行程與 init_t
域一起執行。目前在執行守護行程(比如,mysqld 和 tor)的 Debian Stretch 系統中,並不會發生策略與守護行程服務檔案所請求的 systemd 的最新功能不匹配的情況。這樣的問題將會不斷發生,我們需要對它進行自動化測試。
對配置錯誤的自動測試可能會影響系統安全,這是一個很大的問題,我將來或許寫一篇關於這方面的單獨的部落格文章。
via: https://etbe.coker.com.au/2017/09/28/process-monitoring/
作者:Andrew[3] 譯者:qhwdw 校對:wxy
本文由 LCTT 原創編譯,Linux中國 榮譽推出