有一些事後日誌的分析工具,可以針對這些成功登入的事件加以設定並提出報告。但是事後分析再好,終究無法挽回已經發生的遺憾。如果能夠在第一時間就知道登入的行為,就可以減少遺憾發生的機會。據我所知,目前並沒有很方便的小工具可以達到這個需求,所以我們只好自己動手。有不少方式可以完成這個目標,今天我要跟各位分享一個相當簡單的方式,那就是利用 syslog/rsyslog 將訊息送到 named pipe 的功能,然後撰寫一個簡單的腳本將相關訊息從 named pipe 中讀出並透過電子郵件即時通知管理者。
我今天選擇的環境是 CentOS 6.2,至於其他的環境,只要依據實際的狀況做調整就可以了。好了,馬上就開始我們今天的目標吧:
- 建立 named pipe
指令是mkfifo /var/run/secure.pipe
- 限制 named pipe 的權限
將群組與全域的權限予以關閉,指令是chmod og-rwx /var/run/secure.pipe
- 修改 syslog/rsyslog 的設定檔
CentOS 6.2 內建的套件是 rsyslog,其設定檔是 /etc/rsyslog.conf 。打開檔案後找到相關位置並加上最後一行# The authpriv file has restricted access. authpriv.* /var/log/secure authpriv.* |/var/run/secure.pipe
如果你的環境使用 syslog 套件,設定上也沒有多大的差別,只要找到相關的設定檔即可。 - 重新啟動 syslog/rsyslog 服務
指令是service rsyslog restart
- 撰寫腳本
建立一個名稱為 monitor.pl 的腳本,內容如下
這個腳本有三個必須注意的地方,第一個當然就是信件通知的對象 ($receiver),另外一個則是哪些 IP 的登入資訊不要通知 (@ip_whitelist) 。最後則是關於訊息的比對指令。 在 CentOS 6.2 上,成功登入的訊息類似如下:#!/usr/bin/perl my $named_pipe = '/var/run/secure.pipe'; my $sender = 'SWatchDog<cyril.hcwang@gmail.com>'; my $receiver = 'cyril.hcwang@gmail.com'; my @ip_whitelist = ('127.0.0.1', '192.168.1.1'); open (SYSLOG, "+<$named_pipe") or die "Couldn't open $named_pipe: $!\n"; while (<SYSLOG>) { if ($_ =~ m/(.*) (\S*) sshd\[(\d*)\]: Accepted (\S*) for (\S*) from (\S*)/) { if (!ip_in_whitelist($6)) { $message = <<END; $5 在 $1 從 $6 登入 $2; END $subject = "[SWatchDog] Session activation report for ".$2; print "sending email to ".$receiver." with message \"".$message."\""; &email($subject, $message); } } } close (SYSLOG); sub email { ($subject, $message) = @_; open(SENDMAIL, "|sendmail -t") or die "Cannot open $sendmail: $!"; print SENDMAIL "From: ".$sender."\n"; print SENDMAIL "Subject: ".$subject."\n"; print SENDMAIL "To: ".$receiver."\n"; print SENDMAIL "Content-type: text/plain\n\n"; print SENDMAIL $message; close (SENDMAIL); } sub ip_in_whitelist { ($ip) = @_; for ($i=0; $i<=$#ip_whitelist; $i++) { if ($ip eq $ip_whitelist[$i]) { return 1; } } return 0; }
而比對指令 $_ =~ m/(.*) (\S*) sshd\[(\d*)\]: Accepted (\S*) for (\S*) from (\S*)/ 就是根據這些訊息而撰寫的。如果在你的環境下訊息格式有所不同,可能就必須調整比對的指令了。Jun 1 16:22:38 xxx sshd[28516]: Accepted publickey for root from 127.0.0.1 port 60873 ssh2
- 增加執行的權限
指令是chmod +x monitor.pl
- 執行腳本
指令是nohup ./monitor.pl >> /var/log/monitor.log 2>&1 &
nohup 可以避免我們登出後程式的執行就被中斷。 - 嘗試登入系統
當我們成功登入系統後應該就可以在設定的信箱收到通知訊息,以下是 gmail 信箱的畫面。
- 加入開機自動執行
我選擇放在 /etc/rc.local 這個檔案,加上下列設定/path_to_monitor.pl/monitor.pl >> /var/log/monitor.log 2>&1
透過 syslog/rsyslog、named pipe 以及 mail,我們輕鬆完成即時監控成功登入系統的事件。這個腳本還有一些可以改進的地方,像是使用其他更即時的通知方式 (msn、簡訊)、提供登入 IP 位址更詳細的資訊(例如這個 IP 位址在哪個地方) 等。只是這種方式雖然簡單,卻有幾個問題必須加以面對,其中一個是每台主機都必須執行這個腳本,在管理上會增加不少負擔。另外一個問題則是腳本一旦停止執行 (或根本沒有執行) 就失去了監測的能力。此外,如果有其他的程式也在讀取這個 named pipe,那麼寫入這個 named pipe 的資料可就不保證會被我們的腳本讀到。所以,named pipe 的權限設定就很重要。
當然,這幾個問題也不是不能解決,只是每台主機自我管理終究還是不夠方便。解決方式之一就是利用 syslog/rsyslog 遠端遞送的功能,把所有相關事件集中到同一台主機,然後在那台主機執行監測的腳本,如此一來就可以減少許多管理的負擔。至於如何將 syslog/rsyslog 事件遞送到遠端,就請有需要的朋友自行參考之前的另外一篇文章了。
沒有留言:
張貼留言