完善Linux/UNIX審計(jì) 將每個(gè)shell命令記入日志
原創(chuàng)【51CTO精選譯文】編者按:為了確保服務(wù)器的安全,保留shell命令的執(zhí)行歷史是非常有用的一條技巧。然而,shell雖然有歷史功能,但是這個(gè)功能并非針對(duì)審計(jì)的目的而設(shè)計(jì),因此很容易被用戶篡改或是丟失。本文介紹的步驟能夠幫助你將每個(gè)shell命令記入日志(你可以將本文和bash history logging攻防一文參考著閱讀,看看攻防雙方的思路有何不同)。本文作者David Douthitt是一位經(jīng)驗(yàn)豐富的UNIX和Linux系統(tǒng)管理員,曾做過(guò)Linux發(fā)行版的打包工作,也是《Advanced Topics in System Administration》和《GNU Screen: A Comprehensive Manual》兩本書(shū)的作者。以下為正文:
將用戶執(zhí)行的每個(gè)shell命令記入日志比最初想象的要來(lái)得困難。shell的歷史功能原本旨在幫助用戶使用以前用過(guò)的命令。我們都知道這種使用場(chǎng)合:你剛輸入了一個(gè)長(zhǎng)長(zhǎng)的字段,可是拼錯(cuò)了一個(gè)字符。shell的歷史讓你可以改正這一個(gè)字符,而不必輸入其余的所有字符。
然而, shell歷史很難滿足審計(jì)的目的。換言之,它不是為了確保系統(tǒng)安全而設(shè)計(jì)的。
對(duì)于bash shell來(lái)說(shuō),問(wèn)題顯得尤其困難,因?yàn)樵搒hell的目的是,不管用什么辦法,盡可能為用戶簡(jiǎn)化生活——所以,它擁有所有的“花哨功能”(bells and whistles)。必須顧及所有這些多種功能,并且防止對(duì)歷史文件進(jìn)行更改。
Korn shell比較簡(jiǎn)單,使得保護(hù)shell的歷史比較容易。
如果想要嚴(yán)加保管這些shell的歷史,需要執(zhí)行一系列的步驟。
首先,鎖定shell的歷史文件本身。更改它的屬性,末尾只添加chattr +a .sh_history或chattr +a .bash_history。這樣一來(lái),就不可能刪除或更改文件中的數(shù)據(jù),連用戶都無(wú)法改變屬性——只有root用戶才能改變。
其次,確保歷史變量設(shè)置合理、無(wú)法更改。這些歷史變量包括最重要的HISTFILE、HISTCOMMAND和HISTIGNORE。要做到這一點(diǎn),使用shell的typeset命令,帶-r選項(xiàng),這使得指定的變量擁有只讀屬性。良好的操作規(guī)范是使所有歷史環(huán)境變量都變?yōu)橹蛔x,比如:
export HISTCONTROL= export HISTFILE=$HOME/.bash_history export HISTFILESIZE=2000 export HISTIGNORE= export HISTSIZE=1000 export HISTTIMEFORMAT="%a %b %Y %T %z " typeset -r HISTCONTROL typeset -r HISTFILE typeset -r HISTFILESIZE typeset -r HISTIGNORE typeset -r HISTSIZE typeset -r HISTTIMEFORMAT
HISTTIMEFORMAT是bash shell的擴(kuò)展,將在歷史文件中提供時(shí)間戳。
對(duì)于bash shell來(lái)說(shuō),你需要更改歷史的一些標(biāo)準(zhǔn)選項(xiàng):
shopt -s cmdhist #設(shè)置cmdhist將把多行命令放入到單單一個(gè)歷史行 shopt -s histappend #設(shè)置histappend將確保被添加到歷史文件,而不是像通常的做法那樣覆蓋歷史文件。
另外對(duì)于bash shell來(lái)說(shuō),還要設(shè)置PROMPT_COMMAND:
PROMPT_COMMAND="history -a" typeset -r PROMPT_COMMAND
這是由于bash shell實(shí)際上把歷史寫(xiě)入到內(nèi)存中,歷史文件僅在shell會(huì)話結(jié)束時(shí)加以更新。這個(gè)命令會(huì)把上一個(gè)命令附加到磁盤(pán)上的歷史文件。
最后,創(chuàng)建一個(gè)SIGDEBUG陷阱,將命令發(fā)送到系統(tǒng)日志(syslog)。VMware的ESXi借助自己版本的ash shell已經(jīng)具有這樣的功能。簡(jiǎn)而言之,應(yīng)創(chuàng)建一個(gè)把當(dāng)前命令記入日志(從歷史文件獲取)的函數(shù),然后用logger命令,把它發(fā)送到系統(tǒng)日志。這一步在bash shell和Korn Shell中都適用。
這些步驟有些冗長(zhǎng),不過(guò)在新版的bash和ksh中有一些新的功能特性,讓這一切變得極其容易。GNU Bash在4.1版中添加了記入到系統(tǒng)日志中的功能,只需要編譯shell的時(shí)候開(kāi)啟該功能即可激活。
自推出ksh93以來(lái),Korn Shell就一直具有審計(jì)功能。類(lèi)似bash 4.1,用戶審計(jì)是一項(xiàng)編譯時(shí)功能。想看看你所用的ksh93版本是否安裝了審計(jì)功能,可以執(zhí)行下列命令中的某一條:
echo ${.sh.version} echo $KSH_VERSION
在Ubuntu 10.10中,我得到了來(lái)自ksh93的這個(gè)輸出:
# echo ${.sh.version} Version JM 93t+ 2009-05-01
如果審計(jì)功能開(kāi)啟,特征字符串(JM)還會(huì)有字母A(開(kāi)啟審計(jì)功能),可能還有字母L(開(kāi)啟針對(duì)用戶的審計(jì)功能)。IBM DeveloperWorks和Musings of an OS Plumber都刊有介紹Korn Shell審計(jì)的出色文章。
Bash shell含有審計(jì)功能的可能性也比較小。Ubuntu 10.10上的bash是4.1.5(1)版本。
對(duì)于仍在使用C shell(以及尤其是tsch)的用戶,tcsh有一個(gè)變種名為“tcsh-bofh”,它支持記入到系統(tǒng)日志中。遺憾的是,tcsh-bofh并沒(méi)有得到長(zhǎng)期的維護(hù)。早在2010年1月,tcsh-bofh的FreeBSD端口就從FreeBSD端口樹(shù)(port tree)去除了。
上述信息也可以在shell之外獲取。比如有兩個(gè)命令:lastcomm(來(lái)自Ubuntu Main軟件倉(cāng)庫(kù)中的acct程序包)和auditctl(來(lái)自Ubuntu Universe軟件倉(cāng)庫(kù)中的auditd程序包)。另外, Linux Journal在2002年刊發(fā)過(guò)一篇關(guān)于Linux進(jìn)程統(tǒng)計(jì)的好文章。另外還有rootsh和snoopylogger這兩個(gè)程序包,只是兩者都不在Ubuntu軟件倉(cāng)庫(kù)中。Rootsh好比是typescript的執(zhí)行版本,而snoopylogger是你可以添加到用戶環(huán)境的系統(tǒng)庫(kù)。(這些方法有許多來(lái)自在serverfault.com上所提的一個(gè)問(wèn)題,請(qǐng)參閱這個(gè)帖子。)
原文:Logging every shell command
【編輯推薦】