bashのhistoryをsyslog出力、jenkinsでビルド

こんにちは。小宮です。
セキュリティ関連のお仕事で「実行コマンドを記録したい」という要望が最近多くなってきました。
何種類か方法はあると思いますが、今回はbash_historyに時刻を入れて一つのログにまとめてみたいと思います。

これやったあと便利に感じたのはメンテナンスの時作業時刻を報告する場合にログをgrepで解決可能というところです。

jenkinsでビルドするのは、最近はやりの継続的インテグレーションということでやってみました。
最初は心理的な障壁があったんですがやってみると結構楽で手順のもれがないので良いと思いました。
脆弱性の対応で何回かビルドすることになりましたがjenkinsジョブになってるのは便利でした。

CentOS6.5です。
jenkinsさんのジョブは以下のとおりです。
単にパラメータつきのシェルの実行です。

TARGETにしたパラメータは以下です。
http://vault.centos.org/6.5/updates/Source/SPackages/bash-4.1.2-15.el6_5.2.src.rpm

upgradeした時に以下に変わりました。ジョブはバージョン毎に別にしてます。
http://vault.centos.org/6.6/os/Source/SPackages/bash-4.1.2-29.el6.src.rpm

${HOME}/var/lib/jenkinsです。

ソースRPM落として入れて
ソースアーカイブ解凍して
sedしてパッチ作って
作ったパッチあてられるようにspecファイルsedして
ビルドする
という流れになっております。
diffでディレクトリまるごとパッチ作るオプションは-crNだったことを調べて知りました。
パッチは敢えて載せると以下のとおりです。

ログフォーマットはこちらのurlを参考に親プロセスIDとSUしたPID等を載せるように変えました。(監査的な追いやすさがあがるかなと思いまして)

ファシリティがlocal6にかえてあります。rsyslog.confで以下のようにする想定です。

別途yumのupdate対象からbashをはずす必要はあると思います。(yum-updatesd有効な場合は後からyum.confexclude=bash*するなど)
あとからやらないとレシピ回す時にカスタムbashにupdateされなくなったりするので注意が必要です。
Chef(yum)で入れるときに、options "--disablerepo=base,updates"を入れる必要がありました。他リポジトリのパッケージでupdateされない対策です。他にはChefでレシピ流す時のrun_listの順序内でカスタムリポジトリを入れるレシピを先頭にしないとリポジトリが無いと判断されてinstallやupgradeされないという現象が起こりえます。

RPMSignというプラグインつかってgpg署名してカスタムyumリポジトリにscpしたりしてます。他にプラグインはSSHpluginを入れました。

gpg鍵とパスフレーズをシステム設定で設定しといて、
ジョブでは鍵選んでコマンドラインオプションのとこに署名するパッケージのフルパス書きます(ワイルドカード可)。

実際どのようにログが出るかといいますと、以下のようになります。

scpするのとyumリポジトリのメタデータの差分作るジョブは別につくっていて、
scp別にするのはパッケージのビルドに失敗して微妙に変な名前がついた場合に消す手間を省きたかったんです。

bash_historyは改ざんされるリスクがあるのでリアルタイムに別のサーバに転送するなど対策がまだ必要で
方法としてはrsyslogやsyslog-ngやtd-agentなどがあるかと思いますが、超長くなるので省略します。

jenkinsさんは自動的にいろいろしてくれるし暗黙の手順がなくなるので便利ですね。いろいろ勉強になりました。
jenkinsのことを社内の開発の平形さんに教えていただきました。ありがとうございました。おかげさまで心理的な障壁が減りました。

余談ですが、
bashじゃないやつを使いたいしbashだけ使うような運用でカバーしきれないという話だと、
psacct(RHEL系)かpacct(Debian系)いれてlastcomm--user等のオプションつけて確認のち各ユーザのhistory確認する等になるのかなと思います。たぶん。
ちょっとググったら/etc/profile に script コマンドの自動起動をしこんでいる人がいました。起きたことを把握するのには便利そうですが個人的にはパッケージでできる範囲が嬉しいなと思いました。
デフォルトだとhisotryには時刻が出ないのでbash以外のシェルで時刻を出すようにするにはそれぞれの方法があるようでして、ググったところ以下Linkの通りでした。
tcshのhistoryに日付を入れる – Toolbox
zshの履歴でコマンド実行時刻を見れるようにする – Qiita
上記以外のをお使いの方は自己責任で調べていただければと。
ちなみに今回bashは改造してsyslogに出してるので必要ないのですが、そういうのせずに各々のhistoryファイルに時刻出したい場合は3.0以降ならシェル変数「HISTTIMEFORMAT」を設定するとよいようです。あとshとcshはヒストリを編集できないようなので時刻だしたりは無理そうな気がします。
あとhistoryファイルの改ざんを検知可能にしておくという目的を果たすにはauditdなどが必要でしょうか。
auditdはルールちゃんと決めるのとまともな運用を考えるのは手間がかかりそうというかログの可読性がアレなこともあってちゃんと使ったことないです。

参考:
the syslog recorded history history – C – C Program Develop
[技術ブログvol.2] psacctパッケージでプロセスアカウンティング | 技術情報ブログ | マネージドホスティングのディーネット
Linux/UNIX 上でコマンドの実行履歴を残す方法 – drk7jp
historyコマンドの結果に日時も表示できるようにする – takami_hirokiの日記

では読んでいただいてありがとうございました。

おすすめ記事