10/16/2008

Solaris - log的管理,使用logadm

在開始之前有個故事要和大家分享。有一次我朋友的公司裡有一台Sun的機器疑似crash後重開機,他的第一個反應是去看 messages log,結果使用vi來開啟messages檔時,vi跑了二分多鍾後,丟出一個訊息"檔案太大了,它開不了"。他轉頭問問我怎麼會這樣?於是我接手幫忙處理。執行uptime的結果確認是有重開機過,但為何重開機?則要看messages的內容才會知道,問題是vi開不了messages,所以我只好用tail+more來慢慢看。為什麼開不了呢?一看才知messages這個檔案竟然超過2G,最早的一筆記錄是四年多前的。天呀!
接著想瞭解在機器掛掉之前有誰在線上操作,結果last一跑......約五分鍾後螢幕才開始有東西跑出來。為什麼呢?因為和last相關的檔案wtmpx也超過500MB......。最早的記錄的時間我已經不想知道了。(messages不是有newsyslog會去換檔案嗎?是的,但不知在何時crontab裡已經沒有這一項存在了。唉,天兵管理員!)

早期的Solaris(9 以前)並沒有一個真正可用的log輪替程式來做系統log的管理。所以如果管理員沒有自己做適當的處理, 硬碟空間很容易就被吃光了。不然就會發生像上述的事情,檔案大到很難開啟。
以往的Solaris就只有一支newsyslog的簡單script來做messages的輪替的工作。不然就要自己安裝logrotate的套件來做這一類的工作。雖然logrotate很好用,但總是還要抓下來安裝。不過自從Solaris 9開始,Sun終於聽到使用者的聲音了。

Solaris 9開始提供了一支程式logadm專門用來做系統log的管理工作。個人覺得它和logrotate還有點相像,只是它的設定是一個log檔一行,而logrotate是一個log檔一個區塊。下面就來看看logadm要如何使用。

logadm有一個設定檔/etc/logadm.conf,該檔是一個純文字檔,所以你可以直接用vi去編輯它,或是使用logadm來變更設定。雖然可以直接編輯設定檔,不過使用logadm來變更設定時logadm會檢查語法是否正確,所以建議還是使用指令去變更設定。
Solaris在安裝完成後,root的crontab預設就會有一些東西定期的去執行,其中一個就是logadm。你可以用crontab -l來查 看。所以只要把設定檔寫好後,系統就會自動執行,你也不用再操心了。接下來就來看看logadm要如何使用。
logadm的語法大致上看起來就像下面這個樣子,

logadm /var/adm/sshdlog -p now

第一個參數是log檔的名字(不全然是,後面會說明),這裡我們用的是/var/adm/sshdlog。-p指的是週期(period), 這個值是數字接d(day)、w(week)、m(month)、y(year)。如10d,表10天;2w,表二個星期,14天。m雖然是指月,但實際是三十天哦!它可不會自動分辨大小月。另外還有二個特別的時間值,一個就是上面用的now,另外一個是never 。now就是不管如何,現在馬上給我換掉;never則是永遠都不要換,除非其他條件成立。
logadm的參數很多,下表列出幾個常用的參數

-C n保留的數量,如果沒有指定任何的過期條件,預設為-C 10。
-p n[dwmy] 輪替週期
-s n[bkmg] 檔案大小,當指定的log檔的大小大於等於這個值時就更換。
-z n 使用gzip來壓縮被更換掉的舊檔。
-a log檔更換後要執行的指令。
-b log檔更換前要執行的指令。
-g 新檔案的擁有群組,不給就和原檔案一樣。
-o 新檔案的擁有人,不給就和原檔案一樣。
-m 新檔案的權限,不給就和原檔案一樣。
-w 將此設定寫入設定檔。
-r 將此設定從設定檔中移除。
-V 列出設定檔的內容。

假設apache的error_log,希望每10MB換一次,最少保留8份;另外為了避免浪費空間,舊的檔案要壓縮。下面的範例可以 滿足我們的需求。

# logadm -w /var/apache/logs/error_log -C 8 -s 10m -z0 、
-a 'kill -HUP `cat /var/run/apache2/httpd.pid`'
# logadm -V| grep error
/var/apache/logs/error_log -C 8 -s 10m -z 0 -a 'kill -HUP `cat /var/run/apache2/httpd.pid`'

然後是access_log,由於log要留做分析使用,所以最少要保留2個月:也為了避免單一檔案太大,所以每個星期要換一個新的檔案。

# logadm -w /var/apache/logs/access_log  -C 9 -p 1w 、
-a 'kill -HUP `cat /var/run/apache2/httpd.pid`'
# logadm -V|grep acce
/var/apache/logs/access_log -C 9 -p 1w -a 'kill -HUP `cat /var/run/apache2/httpd.pid`'

logadm在檔案名稱部份也支援*,?,{}。所以上面的例子也可以改成下面的方式

# logadm -w apache_log -C 9 -p 1m 、
-a 'kill -HUP `cat /var/run/apache2/httpd.pid`' /var/apache/logs/{access,
error}_log
# logadm -V| grep apache_log
apache_log -C 9 -a 'kill -HUP `cat /var/run/apache2/httpd.pid`' -p 1m /var/apache/logs/access_log /var/apache/logs/error_log

這個例子好像和前面講的不太一樣,-w 後面接的不再是檔案名稱,取而代之的是apache_log。其實apache_log這是一個自取的識別字,logadm會自動判斷你給的識別字是否為檔案名稱(開頭是否為/);如果是,你可以省略後面的檔案名稱參數。如果不是則後面的檔案名稱就一定要給。前面二個例子的識別字我們都用檔案名稱來代替,而這個例子因為有多個目的檔案,所以要特別再取一個識別字。
當全部都設定好之後,只要直接執行logadm不用加任何的參數,logadm會自動去讀取/etc/logadm.conf,並將符合條件的 log檔進行更換。系統安裝好後root的crontab即已排定每天的3:10會執行logadm,所以只要等時間到log自然就會被換掉。


Solaris預設有幾個系統的log檔已經幫你設定好檔案輪替了,但/var/adm/wtmpx這個檔案並沒有被設定做輪替,所以建議可以把這個檔也加進去給logadm管理。

# logadm -w /var/adm/wtmpx -C 6 -p1m

上面的指令每個月換一次檔,共保留6個月。如果你要看歷史檔的話,只要執行如下的指令就可以了。

# last -f /var/adm/wtmpx.0 

Solaris 9也開始使用ssh的連線方式,但是預設卻沒有產生log檔,下面的範例示範如何手動使ssh產生log檔,並且設定相關的輪替機制。

首先確認,sshd使用的Facility和Level。

# egrep 'Faci|Level' /etc/ssh/sshd_config
SyslogFacility auth
LogLevel info

修改/etc/syslog.conf,加入下方auth.info那一行,存檔後再產生/var/adm/sshdlog這個檔。

# cp /etc/syslog.conf /etc/syslog.conf.orig
# vi /etc/syslog.conf
*.err;kern.notice;auth.notice /dev/sysmsg
*.err;kern.debug;daemon.notice;mail.crit /var/adm/messages
auth.info /var/adm/sshdlog
# touch /var/adm/sshdlog

然後重起syslogd,solaris 9和Solaris 10的方式並不相同。

Solaris 9
# /etc/init.d/syslog stop; /etc/init.d/syslog start
Solaris 10
# svcadm disable system-log ; svcadm enable system-log
或是直接refresh
# svcadm refresh system-log

設定sshdlog每個月換一次,保留3個月,並啟用壓縮。

# logadm -w /var/adm/sshdlog -C3 -p 1m -z 0 -a 'kill -HUP `cat /var/run/syslog.pid`'
# logadm -V| grep sshd
/var/adm/sshdlog -C 3 -p 1m -z 0

要看歷史檔的話,使用gzcat或gzip -dc就可以了。

# gzcat sshdlog.0.gz
# gzip -dc sshdlog.1.gz

logadm預設更換檔案的動作是1.把原檔案改名,2.產生一個和原檔名一樣的檔案。這樣子的行為對常見的log檔,如syslog, messages等不成問題。因為我們可以送HUP的信號給syslogd請它重讀設定檔,所以它可以知道舊檔已經被更換了,然後會把log送到新的檔案去。多數的AP都可以使用如上述的方式來進行檔案的更換,但不是所有AP都吃這一套哦!有些AP需要重新啟動才可以。但問題來了,有人會遇到一種狀況是AP是24hr運作,不能隨便重啟。....這可怎麼辦才好?logadm還有一個參數-c,它會把舊檔的內容複製成新的檔案,然後再把舊檔的內容清空,而不是重新產生一個新的檔案來取代舊的檔案。你可以試試下面的方法來輪替sshdlog。並比較和上述方式的不同。

logadm -w /var/adm/sshdlog -C 3 -p 1m -z0 -c 

有些AP本身即提供log檔案的輪替功能,如果你使用的是Solaris 10的話,系統的Fault Management的log就是使用fmadm來進行檔案輪替的。遇到像這一種AP,建議使用AP的指令來更換log檔,而不要使用logadm來做。但是logadm為了統一管理log的輪替,提供了一個-M參數來允許使用者自定指令來更換檔案。
下面的範例節錄自Solaris 10的logadm.conf,如果有需要你可以參考它是怎麼做的。

/var/fm/fmd/errlog -M '/usr/sbin/fmadm -q rotate errlog && mv /var/fm/fmd/errlog.0- $nfile' -N -s 2m

還有一些AP會不定期或定期的產生不同檔名的log檔,如oracle的trace檔。這一種型式的log檔就比較難使用logadm來做管理了。比較好的方法是自己寫個script來處理這些檔案。下面的範例是我想到比較簡單的方法提供給你做參考,若你有更好的方式別忘了要跟我分享哦!

假設有一支程式叫APservd,log檔存放的位置在/var/APservd/log下,它每個小時都會產生像這樣子的log, APservd_yyyyMMDD_HHmm.log。所以它一天的log檔的數量應該有24個,長的像下面這個樣子。

APservd_20061005_0000.log
APservd_20061005_0100.log
APservd_20061005_0200.log
......
APservd_20061005_2200.log
APservd_20061005_2300.log

於是我們寫一個script把每天24個檔都tar起來成為APservd_log.tar,然後再用logadm對APservd_log.tar來做輪替的動作 。這個script的內容如下,

# cat /root/bin/arch_AP_log.sh
#!/bin/sh
cd /var/APservd/log
/usr/sbin/tar -cf APservd_log.tar `/usr/bin/find . -type f -name "APservd*log"`
#/usr/bin/find . -type f -name "APservd*log" -exec rm -f {} \;

script的內容很簡單,最主要的是find的部份,你應該要自行修改成適合你的條件。如加上-mtime或是! -name "*tar*" 來避免檔名有tar這個字眼的檔被加進去。最後一行是把tar起來的檔案都刪掉,這一行find的條件和第三行的一樣。你應 該確定script執行都無誤後,再把#號拿掉。
最後是加一條設定進去logadm.conf

# logadm -w /var/APservd/log/APservd_log.tar -C 10 -a '/root/bin/arch_AP_log.sh' -p now

指令的參數-p後加的是now,所以每天執行時都會更換APservd_log.tar檔案,然後把所有的log檔再做成APservd_log.tar 在這裡應該有24個檔。你也可以把-p的時間改成你要的週期,如1w,那每次被tar起來的檔案應該就有7*24=168個檔,所保留的檔案則有10個星期。你可以使用logadm -v來看一下logadm是怎麼做的。

logadm比較常用的方法大概就這個樣子了,當然還有其他的參數我並沒有介紹,有需要的話自己看一下man page應該有所幫助。

以資訊安全的觀點來看,log檔能保留的時間是越長越好。不過實際上很多人出問題後並不會去看log,或是相關的log跟本就看不懂,更遑論會去關心log到底留多久,以及現行存放log方式的安全性如何了。如果你們部門正打算申請ISO 27001 (前身為BS 7799)的資安認證的話,這些東西值得你花點心思去處理。

1 則留言:

Unknown 提到...

A note regarding rotation of FMA logs. While 'fmadm rotate' is provided, it is not the best method for log rotation. You are correct that 'logadm' should be used to guarantee history is preserved. See my entry on this at http://blogs.sun.com/sdaven/fma_log_files