Linuxをデータベースに変える:osqueryによるセキュリティクエリと監視

Security tutorial - IT technology blog
Security tutorial - IT technology blog

数百台のLinuxサーバー管理という悪夢

想像してみてください。上司から、最新のCVE脆弱性を確認するために200台のサーバーのNginxバージョンを即座にリストアップするよう求められたとします。手動でBashスクリプトやssh loopを使っていると、乱雑なデータをgrepawkで処理するだけで午後が丸ごと潰れてしまうでしょう。

psnetstatlsofといった各ツールは、それぞれ異なるテキスト形式で結果を返します。レポート作成のためにこれらのデータを標準化するのは、まさに苦行です。osqueryは、オペレーティングシステムをリレーショナルデータベースとして扱うことで、この問題を解決します。シェルスクリプトに苦労する代わりに、SQLを書くだけで済むのです。

なぜosqueryは特別なのか?

osqueryの価値を理解するために、現在の一般的な監視手法と比較してみましょう。

  • 従来のCLI (top, netstat): 高速で標準搭載されていますが、スケールしません。500ノードから同時にデータを取得するのは不可能です。
  • ログアグリゲーター (ELK, Splunk): データの蓄積に優れ、グラフも綺麗です。しかし、リソースコストが非常に高く、データには遅延(事後確認) feather 伴います。
  • osquery: リアルタイムクエリ、標準化されたデータ、そして非常に軽量です。システムに対してあらゆる質問を投げることができ、数ミリ秒で結果を受け取れます。

「OSをクエリする」という力

osquery(Facebookによって開発)は、システムの構成要素を200以上のデータテーブルに抽象化します。実行中のプロセスからカーネルモジュール、ネットワーク接続まで、すべてがSQLテーブルに収まっています。

netstat -tulpnの膨大なパラメータを覚える代わりに、SELECT * FROM listening_ports;を実行するだけです。結果はクリーンなテーブル形式で返され、JSONとして出力して他のシステムと連携させるのも簡単です。

実践的なLinuxへのosquery導入

以下はUbuntuでのクイックインストール手順です。RHEL/CentOS系の場合は、yumdnfに読み替えてください。

1. エージェントのインストール

まず、最新のセキュリティアップデートを受け取るために公式リポジトリを追加します。

export OSQUERY_KEY=14841204C457537ED9F7D182915B1051F6F3CFC5
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys $OSQUERY_KEY
sudo add-apt-repository 'deb [arch=amd64] https://pkg.osquery.io/deb deb main'
sudo apt update && sudo apt install osquery -y

2. osqueryiによる対話型クエリ

osqueryiは、迅速なトラブルシューティングに最適なツールです。MySQLやPostgreSQLのシェルと全く同じように動作します。

osqueryi

サーバーで最もRAMを消費している上位5つのプロセスを確認してみましょう:

SELECT name, pid, (resident_size / 1024 / 1024) AS ram_mb 
FROM processes 
ORDER BY resident_size DESC LIMIT 5;

3. 実戦的な3つのセキュリティシナリオ

これらは、私がインシデントレスポンス(事後対応)の際によく使用するコマンドです。

パスワードのないユーザーを検出する:
攻撃者はアクセス権を維持するために、隠しユーザーを作成したりパスワードを削除したりすることがあります。このクエリでそれらを暴き出します:

SELECT * FROM users WHERE password = '';

リバースシェルの探索:
このコマンドは、ローカルホスト以外にインターネット接続を行っているプロセスを探します:

SELECT p.name, pos.remote_address, pos.remote_port 
FROM process_open_sockets AS pos 
JOIN processes AS p ON pos.pid = p.pid 
WHERE pos.remote_address NOT IN ('127.0.0.1', '::1', '0.0.0.0', '');

設定ファイルの変更を追跡する:
過去24時間以内に/etc内のファイルを修正したのが誰かを確認します:

SELECT path, mtime, uid FROM file 
WHERE path LIKE '/etc/%' AND mtime > (strftime('%s', 'now') - 86400);

ちょっとしたヒント:ログデータ用の管理アカウントを設定する際は、弱いパスワードを避けてください。私はよくPassword Generatorを使用して20文字のランダムな文字列を生成しています。このツールはブラウザ上でローカルに動作するため、エンジニアにとっても安全です。

osquerydによる自動監視

継続的な監視には、osqueryd(デーモン)が必要です。スケジュールに従ってクエリを実行し、ログを中央に送信します。

デフォルトで、osqueryには「ウォッチドッグ」機能があります。クエリがCPUの12%以上、またはRAMの200MB以上を消費すると、サーバーを保護するために自動的に中断されます。これにより、重要な本番環境(Production)にも安心してデプロイできます。

1時間ごとにルートキットのマルウェアをチェックするための/etc/osquery/osquery.confの設定例:

{
  "schedule": {
    "rootkit_check": {
      "query": "SELECT * FROM kernel_modules WHERE status != 'Live';",
      "interval": 3600
    }
  }
}

パフォーマンス最適化のヒント

osquery is 非常に最適化されていますが、粗末なSQLはシステムをハングさせる可能性があります。3つの黄金律を覚えておきましょう:

  1. fileテーブルで SELECT * を絶対に行わない: MD5ハッシュを計算するためにハードディスク全体をスキャンすると、サーバーが悲鳴を上げます。/bin/sbinなどの重要なディレクトリのみをスキャンしてください。
  2. JOINを賢く使う: 他のテーブルとJOINする前に、必ずメインテーブルでデータをフィルタリングしてください。
  3. イベントベースの活用: 定期的なスキャン(ポーリング)の代わりに、_eventsテーブルを使用して変更イベントのみを受け取るようにします。

おわりに

osqueryは単なるツールではなく、現代的な管理の考え方そのものです。すべてのパラメータを標準のSQLに落とし込むことで、CI/CDパイプラインやSOCダッシュボードへの統合が容易になります。大規模なサーバークラスターを管理しているなら、ぜひ今日からosqueryを試してみてください。インフラの制御がこれほどまでに楽になると実感できるはずです。

Share: