一下子又是几个月没写呢。总是觉得没东西值得写到blog上,但是又总觉得有代码需要 码。想想还是把这点小东西写一下吧。
最近一台大家共着用的服务器被人误重启了。本来为了防着这种事情发生,我已经很限制 root权限的分发了。但是偏偏那个人用到的脚本非要root来跑(鄙视一下写脚本的人), 没办法,只好给他了root。结果呢,服务器误重启,大概是他手抖了吧。
既然没办法不给root,那么只好想些别的辙来确保服务器的运行。
记录root命令到syslog
这个是为了可以找苦主。以前的服务器上,大家都是root,重启了,谁跑的命令都不知道 ,太糟糕。事后想找个人骂都找不到。
稍稍google了下,在zshrc
里面加上了这么一段
zshaddhistory() {
cmd=${1%%$'\n'}
print -sr -- $cmd
LASTCMD="${(pj:\\\n:)${(f)1}}"
first_arg=${${(z)LASTCMD}[1]}
( [[ `id -u $USER` -eq 0 ]] || [[ $first_arg == sudo ]] ) && logger -t "$USER@${TTY/\/dev\/}[$PWD]" $LASTCMD
}
写得很烂,因为我懒。值得注意的是print -sr -- $cmd
是输出命令到
~/.zsh_history
而不是屏幕。最后一句很简单,如果执行用户是root,或者命令的第
一个词是sudo
,那么就把命令记录到syslog里面去。输出大概是这个样子
Apr 5 06:26:43 bunker root@pts/22[/root]: source .zshrc.local
这只是事后药,而且缺点也很明显,如果用户输入的sudo不在句首,就无法记录了。懒得 管了,咱zsh也就这水准。。。
用alias来防止误重启
好了,怎么防止root用户手一抖就reboot了呢?
失败的方案:
-
替换
/sbin/{reboot,halt,shutdown}
:这个太坑人,这些文件不是我们应该碰的。 用包管理装上的文件,除了/etc/
底下的,其他都是我不想碰的。 -
自己写个wrapper脚本,放到路径里面
/sbin
的前面:先不说脚本的维护,光是路径 里面有同样名字的可执行文件,这就很糟糕了。
我的方案:root用户的zshrc
里面加
confirm_yes() {
sure=$(dialog --stdout --inputbox "Are you sure that you want to run '$1' command? Type YES to confirm." 10 50)
[[ $sure == YES ]] && $1
}
for c in reboot halt shutdown; do alias $c="confirm_yes $c"; done
这样用户在输入危险的关机命令的时候,会跳出来一个dialog提示输入大写YES来确认,否 则命令不会被执行。完全不需要另外写wrapper。
参考
http://jablonskis.org/2011/howto-log-bash-history-to-syslog/