前回、実行したログをsyslogで記録させるSnoopy Loggerを紹介したのだが、今回紹介する機能はbashを利用してそれと同じような事が出来る。
そう、bashでは4.1以降だとhistoryをsyslogに出力出来るようになっている。
…ただ、どうやらセキュリティの問題(コンソールで実行したコマンドにパスワードが入っていたりなど?真偽は不明)もあるようで、ディストリビューションに入っているbashではこの機能はオミットされているようだ。
そのため、この機能を使うにはbashを別途コンパイルする必要がある。
今回は、こちらのサイトの内容を元にCentOS 7上でこの作業を行っていく。
1.前提となるパッケージのダウンロード
コンパイルを行うにあたって、前提となるパッケージをダウンロードしておく。
必要になるのはgccとmake。
yum -y install gcc make
2.コンパイル
まずはbashのソースをこちらからダウンロードしてくる。
ダウンロードするのは、2015年3月時点において最新版の4.3.30とする。
wget http://ftp.gnu.org/gnu/bash/bash-4.3.30.tar.gz
tar xzvf bash-4.3.30.tar.gz
cd bash-4.3.30
そのままコンパイルしても機能が有効化されないため、「config-top.h」の110行目に、以下のように一行追記する。
また、自身の環境に応じて112行目のファシリティ、113行目のプライオリティを変更すると良いだろう。
ファシリティ、プライオリティで設定出来る値はこちらを参考にてもらいたい。
なお、初期設定ではファシリティはUSER、プライオリティはInfoとなっている。
Before
/* Define if you want each line saved to the history list in bashhist.c:
bash_add_history() to be sent to syslog(). */
/* #define SYSLOG_HISTORY */
#if defined (SYSLOG_HISTORY)
# define SYSLOG_FACILITY LOG_USER
# define SYSLOG_LEVEL LOG_INFO
#endif
/* Define if you want to include code in shell.c to support wordexp(3) */
/* #define WORDEXP_OPTION */
/* Define as 1 if you want to enable code that implements multiple coprocs */
#ifndef MULTIPLE_COPROCS
# define MULTIPLE_COPROCS 0
After
/* Define if you want each line saved to the history list in bashhist.c:
bash_add_history() to be sent to syslog(). */
/* #define SYSLOG_HISTORY */
#define SYSLOG_HISTORY
#if defined (SYSLOG_HISTORY)
# define SYSLOG_FACILITY LOG_USER
# define SYSLOG_LEVEL LOG_INFO
#endif
/* Define if you want to include code in shell.c to support wordexp(3) */
/* #define WORDEXP_OPTION */
/* Define as 1 if you want to enable code that implements multiple coprocs */
#ifndef MULTIPLE_COPROCS
# define MULTIPLE_COPROCS 0
以下は、ファシリティを「local6」、プライオリティを「Debug」にした例。
/* Define if you want each line saved to the history list in bashhist.c:
bash_add_history() to be sent to syslog(). */
/* #define SYSLOG_HISTORY */
#define SYSLOG_HISTORY
#if defined (SYSLOG_HISTORY)
# define SYSLOG_FACILITY LOG_LOCAL6
# define SYSLOG_LEVEL LOG_DEBUG
#endif
/* Define if you want to include code in shell.c to support wordexp(3) */
/* #define WORDEXP_OPTION */
/* Define as 1 if you want to enable code that implements multiple coprocs */
#ifndef MULTIPLE_COPROCS
# define MULTIPLE_COPROCS 0
基本的には、デフォルトのままではなく上記のようにファシリティ、プライオリティを指定した方がいいだろう。
ファイル編集後、コンパイルを行う。
./configure
make
make install
作成したファイルは「/usr/local/bin」に格納されるので、存在している事を確認する。
ls -la /usr/local/bin/bash
それでは、実際に ログが出力される事を確認しよ。
「/etc/rsyslog.conf」を開き、75行目辺りに以下の行を追記する。
# Save Command History
ファシリティ.プライオリティ /var/log/ログファイル名
実際に設定した場合の例が以下。
# Save Command History
local6.debug /var/log/history.log
上記設定後、rsyslogの再起動を行う。
systemctl restart rsyslog
rsyslog再起動後、コンパイルしたbashに切り替えを行い、コマンドの実行ログが記録される事を確認する。
/usr/local/bin/bash
ls -la
cat /var/log/history.log
無事、実行したコマンドがログとして記録されている。
3.既存のbashを入れ替える
既存のbashを置き換えるため、「/etc/passwd」を編集し、rootユーザのログインシェルを「/usr/local/bin/bash」に切り替える。
sed -i '/root/ s|/bin/bash|/usr/local/bin/bash|g' /etc/passwd
上記コマンド実行後、再度サーバにログインを行う。
無事ログインできることを確認したら、いままで接続していたセッションをクローズする。
新しいセッションのみになったら、バックアップを取得の上、「/bin/bash」に「/usr/local/bin/bash」をコピーする。
cp /bin/bash /tmp/bash
cp /usr/local/bin/bash /bin/bash
ファイルの上書き後、「/etc/passwd」を再度編集する。
sed -i '/root/ s|/usr/local/bin/bash|/bin/bash|g' /etc/passwd
無事にログインでき、コマンドがログに出力されることを確認する。
4.パッケージ管理ソフトの対象外とする
さて、これで無事に設定はできたのだが、このままだとパッケージ管理ソフト(yumなど)でアップデートを行った際に上書きされてしまい、またログに記録されないようになってしまう。
そのため、以下のコマンドを実行しbashをyumの対象から除外する設定を行う。
echo "exclude=bash*" >> /etc/yum.conf
※脆弱性が出た場合、自分でコンパイルする必要があります。
これで、無事に実行コマンドをログに記録できるようになった。