なぜ.bash_historyだけでは監視が不十分なのか?
働き始めたばかりの頃、手痛い失敗を経験しました。誰かが設定ファイルを誤って編集したせいで、データベースサーバーがダウンしてしまったのです。犯人を探そうと意気揚々とSSHでログインし、historyコマンドを打ちましたが、画面には何も表示されませんでした。
犯人は証拠を消すために、手早くhistory -cを実行していたのです。また、複数のセッションを同時に使用しているだけでも、Linuxのデフォルトのログは簡単に上書きされ、データが失われてしまいます。デフォルトのコマンド履歴は非常に脆弱なのです。
5〜10人がアクセスするシステムを管理しているなら、より低いレイヤーでのログ記録ソリューションが必要です。ユーザーが意図的に隠そうとしても、すべてのコマンドを捕捉できなければなりません。そこで私が選んだのが、Snoopy LoggerとGrafana Lokiの組み合わせです。
Snoopy Logger — ターミナルの「ドライブレコーダー」
Snoopy Loggerは、シェルスクリプトや重いバックグラウンドソフトではありません。本質的には、LD_PRELOADメカニズムを通じてシステムのexecve()関数に直接介入する共有ライブラリ(shared library)です。
lsやrmからバックグラウンドで実行されるスクリプトに至るまで、新しいプロセスが起動するたびに、Snoopyは即座にそれを捕捉してsyslogへ送ります。私がこれを利用し続けている理由は以下の通りです:
- 詳細な記録:ユーザーID (UID)、ターミナル (TTY)、カレントディレクトリ (CWD)、および実行された元のコマンド。
- 回避不能:ユーザーは通常、履歴を削除するような方法でこれを無効化したりバイパスしたりすることはできません。
- 優れたパフォーマンス:毎分何千ものコマンドを処理しているシステムでも、CPU使用率は0.1%未満に抑えられます。
集中管理型のデプロイモデル
以前は、各サーバーにSSHでログインし、tail -f /var/log/auth.logを実行してエラーを確認していました。しかし、この方法はあまりにも手作業が多く、時間がかかります。現在は、Promtailを経由してすべてのログをGrafana Lokiに集約しています。
Lokiはログの圧縮率が非常に高く、プレーンテキストでの保存と比較して最大80%の容量を節約できます。調査が必要なときは、Grafanaのダッシュボードを開き、サーバー名やユーザー名でフィルタリングするだけで、すべての行動が一目瞭然になります。
詳細な実装手順
ステップ 1: Snoopy Logger의 インストール
UbuntuやDebianなら、コマンド一つでインストールできます:
sudo apt update && sudo apt install snoopy -y
「カメラ」が記録を開始したか確認するために、いくつかコマンドを入力してからシステムログをチェックしてみましょう:
# コマンドを実行してみる
cat /etc/passwd
# すぐにログを確認する
sudo tail -f /var/log/auth.log | grep snoopy
出力されるログには、実行者のUIDや実際に実行された正確なコマンドなど、完全な識別情報が含まれています。
ステップ 2: ログ転送のためのPromtail設定
Snoopyはローカルにログを記録し、PromtailはログをLokiサーバーに転送する「配送業者」の役割を担います。以下の内容で/etc/promtail/config-snoopy.yamlファイルを作成します:
server:
http_listen_port: 9080
positions:
filename: /tmp/positions.yaml
clients:
- url: http://<LOKI_SERVER_IP>:3100/loki/api/v1/push
scrape_configs:
- job_name: snoopy_monitoring
static_configs:
- targets:
- localhost
labels:
job: snoopy_logs
host: prod-web-01
__path__: /var/log/auth.log
Promtailを起動して、監視センターへのデータ転送を開始します。
ステップ 3: Grafanaでのデータのクエリと解析
GrafanaのExplore画面で、データソースにLokiを選択します。シンプルなLogQLを使用して、Snoopyのログをフィルタリングします:
{job="snoopy_logs"} |= "snoopy"
私の経験では、LogQLのpattern関数を使うのがおすすめです。これにより、UID、実行ディレクトリ、コマンドを個別のカラムとして分離できます。生テキストを読むよりも、ダッシュボードでの視認性が格段に向上します。
運用における実戦的なアドバイス
大規模なシステムで実際に運用すると、データのノイズに関する問題が発生しがちです。システムを最適化するための3つの注意点を挙げます:
1. ログ容量の管理
デフォルトではSnoopyはすべてを記録します。サーバーで毎分何百ものcronジョブが実行されている場合、ログファイルは急速に肥大化します。/etc/snoopy.iniを設定して、不要なユーザーを除外するように構成すべきです。
# 重要でないシステムユーザーのログを除外する
[snoopy]
filter_chain = "exclude_uid:100,101"
2. データの整合性の確保
Snoopyは強力ですが、攻撃者がroot権限を奪取した場合、ローカルログを削除される可能性があります。そのため、Lokiへのリアルタイムなログ転送は必須です。ログが元のサーバーを離れてしまえば、攻撃者がLokiに記録された痕跡を消去する術はありません。
3. 自動アラートの設定
問題が発生してからログを確認するのでは遅すぎます。私は通常、Grafanaでアラートを設定し、rm -rf /やchmod 777のような機密性の高いコマンドが実行されたり、秘密鍵が含まれるディレクトリにアクセスがあったりした場合、すぐにTelegramで通知を受け取れるようにしています。
結論
Snoopy LoggerとGrafana Lokiの組み合わせは、Linuxシステムに絶対的な透明性をもたらします。障害の追跡だけでなく、セキュリティ監査における重要な証拠としても機能します。
重要なインフラを管理しているなら、ぜひ今日からこのモデルを導入してみてください。サーバーで「誰が何をしたか」わからずに眠れない夜から解放されるはずです。成功を祈ります!

