サーバーを運用していると、無数のログが絶え間なく生成されます。これらのログは、システムの健全性を把握し、問題発生時の原因を追跡し、セキュリティの脅威を検出するための不可欠な情報資産です。しかし、デフォルト設定のままでは、ログはテキストファイルとして/var/log
ディレクトリに散在して保存されるため、特定の情報を検索したり、統計を取ったりといった、意味のあるデータとして活用することは困難です。この問題を解決するために登場したのが、「集中ログ管理システム」という考え方です。
本記事では、Ubuntuに標準でインストールされている強力なログ処理システムであるrsyslogを活用し、単にログをファイルに保存するレベルを超え、必要なログだけを選別(フィルタリング)し、それをリレーショナルデータベース(MySQL/MariaDB)に体系的に保存する方法を詳しく解説します。このプロセスを通じて、あなたは散在していたログを強力なデータ資産に変える第一歩を踏み出すことになります。
この記事を最後まで読めば、以下のことができるようになります:
- rsyslogのモジュールシステムを理解し、DB連携モジュールをインストールする。
- ログ保存用のデータベースとユーザーアカウントを設定する。
- rsyslogの基本および高度なフィルタリングルール(RainerScript)を使い、目的のログだけを正確に抽出する。
- フィルタリングしたログをリアルタイムでデータベースに挿入するようrsyslogを設定する。
- 設定が正しく動作しているかを確認し、基本的な問題をトラブルシューティングする。
このプロセスは、単にログをDBに入れる技術的な手順だけでなく、大規模システムのログをいかに効率的に管理し、分析のための基盤をどう構築するかという洞察を提供します。さあ、テキストファイルの中で眠っているログに、新たな命を吹き込みましょう。
準備:必要なものの確認
本格的な設定に入る前に、円滑な進行のためにいくつかの準備が必要です。以下の項目が揃っているか確認してください。
- Ubuntuサーバー:Ubuntu 18.04 LTS, 20.04 LTS, 22.04 LTSまたはそれ以降のバージョンがインストールされたサーバー。このガイドは、ほとんどのDebian系Linuxディストリビューションでも同様に適用可能です。
- Sudo権限:パッケージのインストールやシステム設定ファイルの編集が必要なため、
sudo
コマンドを実行できる管理者権限を持つアカウントが必要です。 - データベースの選択:このガイドでは、最も広く利用されているオープンソースデータベースであるMariaDBを基準に説明します。MySQLを使用する場合も、手順はほぼ同じです。PostgreSQLを使用したい場合は、関連パッケージ名(
rsyslog-pgsql
)を変更するだけで対応できます。 - 基本的なLinuxコマンドの知識:
apt
,systemctl
, テキストエディタ(nano
やvim
)の使用法など、基本的なLinuxコマンドに慣れていることを前提とします。
すべての準備が整ったら、最初のステップであるデータベースとrsyslogモジュールのインストールから始めましょう。
ステップ1:データベースとrsyslogモジュールのインストール
rsyslogがログをデータベースに送信するには、rsyslogがデータベースと「対話」するための「通訳者」の役割を果たすモジュールが必要です。MariaDB/MySQLの場合、rsyslog-mysql
というパッケージがこの役割を担います。また、ログを保存するデータベースサーバー自体もインストールする必要があります。
1.1. MariaDBサーバーのインストール
すでにデータベースサーバーが稼働している場合は、このステップをスキップしてください。新規にインストールする場合は、次のコマンドをターミナルに入力してMariaDBサーバーをインストールします。
sudo apt update
sudo apt install mariadb-server -y
インストールが完了すると、MariaDBサービスは自動的に起動します。次のコマンドでサービスのステータスを確認し、正常に実行中であることを確認します。
sudo systemctl status mariadb
出力結果にactive (running)
という文字列が表示されれば、インストールと起動は成功です。
1.2. rsyslog MySQLモジュールのインストール
次に、rsyslogがMariaDBと通信できるように、rsyslog-mysql
パッケージをインストールします。このパッケージは、rsyslogの出力モジュール(Output Module)の一つであるommysql
を提供します。
sudo apt install rsyslog-mysql -y
インストールは非常に簡単です。この小さなパッケージ一つが、rsyslogの能力をファイルシステムの枠を超えて拡張させる鍵となります。
ステップ2:ログ保存用データベースの設定
次に、ログを保存するための「倉庫」を作成します。セキュリティ上、rsyslog専用のデータベースとユーザーアカウントを作成することが推奨されます。これにより、rsyslogアカウントが他のデータベースに影響を与えるのを防ぐことができます。
2.1. MariaDBへの接続とセキュリティ設定
まず、rootユーザーとしてMariaDBに接続します。
sudo mysql -u root
初めてインストールした場合は、初期セキュリティ設定を行うことを強くお勧めします。mysql_secure_installation
スクリプトを実行し、rootパスワードの設定や匿名ユーザーの削除などを行います。
sudo mysql_secure_installation
2.2. データベースとユーザーの作成
MariaDBプロンプト(MariaDB [(none)]>
)で、以下のSQLクエリを順に実行し、rsyslog用のデータベースとユーザーを作成します。
1. データベースの作成: ログを保存するための`Syslog`という名前のデータベースを作成します。
CREATE DATABASE Syslog CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
2. ユーザーの作成と権限付与: `rsyslog_user`というユーザーを作成し、このユーザーが`Syslog`データベースに対してのみ全ての操作を行えるよう権限を付与します。`'your-strong-password'`の部分は、必ず強力なパスワードに変更してください。
CREATE USER 'rsyslog_user'@'localhost' IDENTIFIED BY 'your-strong-password';
GRANT ALL PRIVILEGES ON Syslog.* TO 'rsyslog_user'@'localhost';
3. 変更の適用: 変更した権限をシステムに即時反映させます。
FLUSH PRIVILEGES;
4. 終了: MariaDBプロンプトを終了します。
EXIT;
2.3. ログテーブルスキーマの作成
rsyslogは、どのような構造のテーブルにログを保存すべきか、あらかじめ定義されたスキーマを持っています。幸いなことに、rsyslog-mysql
パッケージをインストールすると、このスキーマを作成するためのSQLスクリプトファイルが一緒に提供されます。私たちは、このスクリプトを先ほど作成した`Syslog`データベースで実行するだけです。
スクリプトファイルは通常/usr/share/doc/rsyslog-mysql/
ディレクトリにあります。次のコマンドで、このスクリプトを`Syslog`データベースに適用します。
sudo mysql -u rsyslog_user -p Syslog < /usr/share/doc/rsyslog-mysql/createDB.sql
コマンドを実行すると、上で設定した`rsyslog_user`のパスワードを尋ねられます。パスワードを正確に入力すると、何もメッセージが表示されずにコマンドが終了します。これが正常な状態です。
確認のために、`Syslog`データベースにどのようなテーブルが作成されたかを見てみましょう。
sudo mysql -u rsyslog_user -p -e "USE Syslog; SHOW TABLES;"
実行結果としてSystemEvents
とSystemEventsProperties
という2つのテーブルが表示されれば、データベースの準備は完璧に完了です。SystemEvents
テーブルが、私たちのログがこれから積み重ねられていく場所となります。
ステップ3:rsyslogの設定 - フィルタリングとDB連携
ここが最も重要なステップです。rsyslogの設定ファイルを編集し、特定の条件に合致するログだけをフィルタリングしてMariaDBに送信するように設定します。rsyslogの設定は/etc/rsyslog.conf
ファイルと/etc/rsyslog.d/
ディレクトリ内の.conf
ファイル群で構成されています。システムの基本設定を汚さず、メンテナンスを容易にするため、私たちは/etc/rsyslog.d/
ディレクトリ内に新しい設定ファイルを作成する方法を採用します。
60-mysql.conf
という名前で新しい設定ファイルを作成します。
sudo nano /etc/rsyslog.d/60-mysql.conf
このファイルの中に、rsyslogに対して何を、どのように、どこへ送るかを指示する内容を記述していきます。
3.1. 基本概念:RainerScript
最新のrsyslogは、RainerScriptという先進的なスクリプトベースの設定構文を使用します。これは旧来のfacility.priority
形式よりもはるかに柔軟で強力なフィルタリングと制御を可能にします。私たちはこのRainerScriptを使ってフィルタリングルールを作成します。
RainerScriptのフィルタリングは、基本的にif ... then ...
という構造に従います。
if <条件文> then {
<実行するアクション>
}
ここで「条件文」はログメッセージの様々なプロパティ(プログラム名、ホスト名、メッセージ内容など)に基づいて作られ、「実行するアクション」は、該当するログを特定のファイルに保存したり、別のサーバーに転送したり、あるいは私たちがこれから行うようにデータベースに挿入したりする操作を定義します。
3.2. 設定ファイルの作成:全てのログをDBに送信(基本)
まず、フィルタリングなしで全てのログをDBに送信する最も簡単な設定から始めます。これにより、DB接続が正しく機能するかどうかを確認できます。60-mysql.conf
ファイルに以下の内容を入力してください。
# #####################################################################
# ## MySQL/MariaDBへログを送信するための設定 ##
# #####################################################################
# 1. ommysqlモジュールをロードします。
# この行は、rsyslogにMySQLデータベースとの通信方法を教えます。
module(load="ommysql")
# 2. 全てのログ(*)を対象にデータベースへ送信するアクション(action)を定義します。
# 書式: *.* action(type="ommysql" server="サーバーアドレス" db="データベース名"
# uid="ユーザー名" pwd="パスワード")
#
# 下記の'your-strong-password'の部分は、ステップ2で設定したDBパスワードに必ず変更してください。
action(
type="ommysql"
server="127.0.0.1"
db="Syslog"
uid="rsyslog_user"
pwd="your-strong-password"
)
上記の設定は非常に直感的です。
module(load="ommysql")
: MySQLモジュールを有効化します。action(...)
: 全てのログ(ここではフィルタがないため*.*
に相当)に対して指定されたアクションを実行するよう指示します。type="ommysql"
: アクションの種類がMySQL DBへの書き込みであることを明記します。server
,db
,uid
,pwd
: ステップ2で設定したデータベース接続情報を正確に入力します。
3.3. 設定ファイルの作成:フィルタリングの適用(核心)
いよいよ、このガイドの核心テーマである「フィルタリング」を適用します。全てのログをDBに保存すると、膨大な量のデータを生成し、ストレージを浪費するだけでなく、本当に重要な情報を見つけにくくしてしまいます。特定の条件に合致するログだけをDBに保存するようにルールを追加しましょう。
例えば、「SSH(sshd)関連のログと、カーネル(kernel)メッセージのうち、重要度(severity)が'warning'以上のログだけをDBに保存したい」という要件があるとします。
既存の60-mysql.conf
ファイルの内容を以下のように修正または新規作成します。
# #####################################################################
# ## 特定のログをフィルタリングしてMySQL/MariaDBへ送信するための設定 ##
# #####################################################################
# 1. ommysqlモジュールのロード
module(load="ommysql")
# 2. フィルタリングルールとDB保存アクションの定義
# RainerScriptのif-then構文を使用します。
if ( \
# 条件1: プログラム名(programname)が'sshd'である、または
$programname == 'sshd' \
or \
# 条件2: プログラム名(programname)が'kernel'であり、かつ
# ログの重要度(syslogseverity)が4('warning')以下の場合
# (重要度は数字が小さいほど高い: 0=emerg, 1=alert, 2=crit, 3=err, 4=warning)
($programname == 'kernel' and $syslogseverity <= 4) \
) then {
# 上記の条件に合致したログに対してのみ、以下のアクションを実行します。
action(
type="ommysql"
server="127.0.0.1"
db="Syslog"
uid="rsyslog_user"
pwd="your-strong-password"
)
# stop: このルールにマッチしたログは、これ以降の他のルールでは処理されません。
# DB保存後に/var/log/syslogなどにも重複して保存されるのを防ぎたい場合に便利ですが、
# ここではデフォルトのログファイルにも残すため、コメントアウトしておきます。
# stop
}
この設定の核心はif (...) then { ... }
ブロックです。
$programname
: ログを生成したプロセス/プログラムの名前を保持するrsyslogの組み込み変数(プロパティ)です。$syslogseverity
: ログの重要度を数値で表す変数です。(0: Emergency, 1: Alert, ..., 6: Informational, 7: Debug)==
,or
,and
,<=
: 一般的なプログラミング言語と同様の比較演算子や論理演算子を使い、複雑な条件式を作成できます。action(...)
: このaction
は、if
の条件文を通過したログにのみ適用されるようになります。
その他のフィルタリング例:
- 特定のメッセージを含むログだけを保存する(例: 'Failed password'):
if $msg contains 'Failed password' then { ... }
- 特定のホストからのログだけを保存する:
if $hostname == 'web-server-01' then { ... }
- CRONジョブのログを除外して保存する:
if not ($programname == 'CRON') then { ... }
このように、RainerScriptを活用すれば、ほとんどあらゆる種類のログフィルタリングシナリオを実装できます。あなたのシステム環境と監視目的に合わせて、フィルタリング条件を自由自在に修正・組み合わせてみてください。
ステップ4:設定の適用と検証
設定ファイルの作成が完了したら、次はこの新しい設定をrsyslogに読み込ませ、意図通りに動作するかを確認する番です。
4.1. 設定ファイルの構文チェック
サービスを再起動する前に、作成した設定ファイルに文法的な誤りがないか確認することをお勧めします。エラーがある状態でサービスを再起動すると、rsyslogが異常終了する可能性があります。次のコマンドで構文チェックを実行します。
sudo rsyslogd -N1
もし「rsyslogd: version ..., config validation run (level 1), master config /etc/rsyslog.conf OK.
」のようなメッセージが表示され、エラーが見当たらなければ、構文は正常です。エラーが表示された場合は、エラーメッセージが指し示すファイルと行番号を確認して修正してください。
4.2. rsyslogサービスの再起動
構文チェックをパスしたら、変更した設定を適用するためにrsyslogサービスを再起動します。
sudo systemctl restart rsyslog
再起動後、サービスが正常に実行されているかステータスを確認します。
sudo systemctl status rsyslog
active (running)
の状態であることを確認し、エラーログが出力されていないか注意深く確認してください。
4.3. データベースの確認
最も確実な検証方法は、データベースにログが実際に蓄積されているかを直接確認することです。
フィルタリングルールに合致するようなログを意図的に発生させてみましょう。例えば、SSH接続を試みたり(成功・失敗問わず)、システムを再起動してカーネルメッセージを生成させたりします。少し待ってから、MariaDBに接続し、SystemEvents
テーブルの内容を照会します。
sudo mysql -u rsyslog_user -p
DBに接続後、次のクエリを実行します。
USE Syslog;
SELECT ID, ReceivedAt, FromHost, SysLogTag, Message FROM SystemEvents ORDER BY ID DESC LIMIT 10;
このクエリは、直近に保存されたログ10件を表示します。もしSSH(sshd)やカーネル(kernel)関連のログがテーブルに表示されれば、あなたの設定は成功です!データが表示されない場合は、次のトラブルシューティングのセクションを参考にしてください。
トラブルシューティング
設定後にログがDBに届かない場合、以下の点を確認してみてください。
- rsyslogのステータスとログの確認:
sudo systemctl status rsyslog
またはsudo journalctl -u rsyslog
コマンドを実行し、rsyslog自体のエラーメッセージを確認します。「cannot connect to mysql server」のようなDB接続エラーメッセージがないか探してください。 - DB接続情報の確認:
60-mysql.conf
ファイルに入力したデータベース名、ユーザー名、パスワード、サーバーアドレスが正確か再度確認します。特にパスワードのタイプミスはよくある間違いです。 - ファイアウォールの確認: rsyslogとデータベースが別々のサーバーにある場合、ファイアウォール(
ufw
,iptables
など)がデータベースのポート(デフォルトは3306)への接続を許可しているか確認する必要があります。 - フィルタリング条件の確認: 設定したフィルタリング条件が厳しすぎて、現在システムで発生しているログが一つもマッチしていない可能性はないか確認します。テストのため、一時的にフィルタリング条件を外し、全てのログ(
*.*
)を送信する設定に変更して、DB接続自体に問題がないかをまず確認するのが良い方法です。 - SELinux/AppArmor: 稀なケースですが、SELinuxやAppArmorのようなセキュリティモジュールがrsyslogのネットワーク接続をブロックしている可能性があります。関連ログ(
/var/log/audit/audit.log
や/var/log/syslog
)を確認し、権限拒否(permission denied)メッセージがないか探してみてください。
結論と次のステップ
おめでとうございます!これであなたは、Ubuntuサーバーで発生するログをリアルタイムでフィルタリングし、データベースに保存するシステムを構築することに成功しました。これにより、単なるテキストファイルの羅列だったログを、SQLクエリを通じて検索、ソート、集計が可能な構造化データへと変換しました。これは、システム監視、セキュリティ分析、障害対応能力を一段高いレベルへと引き上げる重要な基盤となります。
ここで立ち止まらないでください。次のステップに進むことができます:
- ログの可視化: GrafanaやMetabaseのようなダッシュボードツールをデータベースに接続し、時間経過に伴うエラー発生の推移、ログイン試行IPの分布など、ログデータを視覚的に分析できます。
- 高度なテンプレートの使用: rsyslogのテンプレート機能を使えば、データベースに保存されるログの形式を完全にカスタマイズできます。特定の情報だけを抽出して別のカラムに保存するなど、高度な活用が可能です。
- ログ集中管理の拡張: 複数台のサーバーで発生するログを一台の集中rsyslogサーバーに転送し、この中央サーバーがフィルタリングとデータベースへの保存を行うように構成することで、全社的なログ管理システムを構築できます。
今日学んだrsyslogのフィルタリングとDB連携機能は、ほんの始まりに過ぎません。rsyslogは非常に柔軟で強力なツールです。公式ドキュメントを参考に、あなたの環境に合わせた、より洗練されたログ管理パイプラインを構築してみてください。
0 개의 댓글:
Post a Comment