監査ログ

目次

監査ログの確認

Ver. 3.1.0 から CMSで操作された内容や、CMSで発生したエラーがログとして残り管理画面から確認できるようになりました。 操作した人や、URL、HTTPヘッダーや、送信内容などログ毎に細かく情報が取れますので、何か問題が起きた時の調査に役立ちます。

操作ログはプロフェッショナルライセンス以上になりますが、何かしらエラーが起きた場合のログは、スタンダード版でも確認できるようになっております。

閲覧画面

管理者でルートブログの管理ページにある左側メニューの「監査ログ」から監査ログの閲覧ができます。

監査ログ画面では、ログの一覧が確認でき、ユーザーや期間、ログレベルで絞り込みが行えるようになっています。


監査ログ画面

監査ログ画面


詳細な情報を確認したい場合は、確認したいログの「詳細」ボタンを押すことで確認できます。 この画面では様々な情報が確認でき、右上の「クリップボードにコピー」ボタンを押すことで「JSONデータ」としてコピーすることができます。サポートを受ける際にも非常に有効な手段ですので、ぜひご利用ください。


ログの詳細情報

ログの詳細情報


ログレベル

ログのレベルは全部で以下のものがあります。「INFO(情報)」については、プロフェッショナルライセンス以上でのみ記録されるようになります。ユーザーの操作履歴を残したい場合は、プロフェッショナルライセンス以上をご検討ください。


ログレベル 説明 スタンダード プロ以上
DEBUG(デバッグ) デバッグ情報 ✅ ✅
INFO(情報) エラーではない正常の操作を記憶します ❌ ✅
NOTICE(注意) 特にプログラムを修正する必要はないが、不正操作・不正アクセス(CSRFチェック、アカウントロック時)など ✅ ✅
WARNING(警告) 潜在的な問題。不具合や環境に問題がある可能性があるエラーなど ✅ ✅
ERROR(エラー) データが壊れているなど、不具合や環境に問題がある可能性があるエラー。処理が継続できない場合など ✅ ✅
CRITICAL(重大) 一部機能が使用不能・表示不能になったなどの、ある程度影響範囲が大きいエラーが起きた場合など ✅ ✅
ALERT(警報) データベースに接続できないなど、サイトが表示できない状態で緊急で対応が必要な場合など ✅ ✅
EMERGENCY(緊急) サイトが表示できない状態。基本的には使用していません。 ✅ ✅

通知機能とファイルへの保存

エラーが発生した際、問題にすぐに気がつけるように監査ログ機能には通知機能がついており、設定したログレベル以上のログが発生すると、メールで通知してくれます。 また、データベースにログは保存しているのですが、ファイルにも書き出すことが出来るようになっております。

設定方法

a-blog cms設置ディレクトリにある「.envファイル」で設定を行います。

# エラー通知
ALERT_EMAIL_FROM=info@example.com # エラー通知メールの送信元
ALERT_EMAIL_TO= # エラー通知メールの送信先。空の場合「UID」が一番小さい管理者アカウントのメールアドレスに送信します。
ALERT_EMAIL_BCC= # カンマ区切りで指定
ALERT_REPORTING_LEVEL=WARNING # エラー通知をする最低ログレベルを設定します。(DEBUG|INFO|NOTICE|WARNING|ERROR|CRITICAL|ALERT)

# ロガー
LOGGER_ROTATING_MAX_FILES=60 # ログローテーションの日数を設定します。
LOGGER_MODE=development # (development|production) productionに設定すると、ライセンス切れやデバッグモード時なども、ログとして残します

設定項目 説明 デフォルト値
ALERT_EMAIL_FROM エラー通知メールの送信元 info@example.com
ALERT_EMAIL_TO エラー通知メールの送信先。空の場合「UID」が一番小さい管理者アカウントのメールアドレスに送信します
ALERT_EMAIL_BCC エラー通知メールのBCC
ALERT_REPORTING_LEVEL エラー通知をする最低ログレベルを設定します WARNING
LOGGER_ROTATING_MAX_FILES ログローテーションの日数を設定します 60
LOGGER_MODE productionに設定すると、ライセンス切れやデバッグモード時なども、ログとして残します development

モード

LOGGER_MODEはデフォルトだと「development」になっています。この状態だと、ライセンスに問題があった場合などログが残らず通知もしてくれないので、本番環境では必ず「production」に設定しましょう。

また本番環境での「LOGGER_MODE」の変更し忘れを防止するため、「development」に設定されている時はダッシュボードと監査ログページに以下の表示がされるようになっています。


ダッシュボード

ダッシュボード


監査ログページ

監査ログページ


ファイルへの保存

デフォルトで、ログはデータベースに書き出されますが、ファイルに書き出すことも可能です。ログの書き出し先は「config.server.php」で設定します。

ファイルに書き出されるログは「NOTICE」以上のログになります。

例えば、ドキュメントルートの一階層上の「logs」ディレクトリに「acms.log」という名前で保存する場合は、以下のように指定します。

define('ERROR_LOG_FILE', '../logs/acms.log');

ログファイルは、1日に1ファイル作成され、ログローテーション日数に指定されたファイル数作成されます。 ログローテーション日数を超えた場合は、古いファイルが削除され新しいファイルが作成されます。

LOGGER_ROTATING_MAX_FILES=60 # ログローテーションの日数を設定します。

以下は、ファイル名を「acms.log」とした場合のログファイル作成例になります。

acms-2023-09-28.log
acms-2023-09-29.log
acms-2023-09-30.log
acms-2023-10-01.log
acms-2023-10-02.log
...

開発者向け

専用モジュールやHookなどを使用して、PHPをカスタマイズしている方もいると思います。 そんな方には、以下の方法を使うことで自分のプログラムにログを追加できるようになります。

基本的な使い方

  • 保存したいログレベルのメソッドを呼び出す
  • 第1引数: メッセージ文字列
  • 第2引数: 保存したい情報(連想配列)
AcmsLogger::[ログレベル](string $message, array $info);

// 例
AcmsLogger::info('xxxを作成しました', [
  'hoge' => 'abc',
  'hoge2' => 200,
]);

use して使う場合

use Acms\Services\Facades\Logger;

Logger::info('xxxx');

コード例

メッセージだけ指定

\AcmsLogger::critical('重大な問題により動作を停止しました');

例外をログとして残す

「Common::exceptionArray()」を第2引数に指定すると、例外の詳細な情報を渡してくれます。

try {
...
} catch ( \Exception $e ) {
    \AcmsLogger::warning($e->getMessage(), \Common::exceptionArray($e));
}

このログは通常のログと同じように表示や通知などに利用できますので、PHPでカスタマイズを行っている方はぜひお試しください。

保持期間・書き込み上限・不正アクセス対策


保持期間・書き込み上限・不正アクセス対策

不正なアクセスによって監査ログが大量に書き込まれ、データベースが肥大化するのを防ぐための機能です。保持期間を過ぎたログの自動削除、同じログの書き込み頻度の制限、記録から除外する接続元の指定、失敗を繰り返す接続元の自動ブロックがあります。

対応バージョン: Ver. 3.2.39 以降で利用できます。

設定のうち、保持期間・書き込み上限・自動ブロックは、a-blog cms 設置ディレクトリにある「.env ファイル」で行います。記録から除外する接続元は管理画面で設定します。

保持期間

保持期間を過ぎた監査ログは、通常のアクセスの終わりに自動で削除されます。

AUDIT_LOG_RETENTION_DAYS=365 # ログを残す日数。0 は無期限
AUDIT_LOG_PURGE_ON_REQUEST=on # off にすると、通常のアクセスでは削除しない

設定項目

説明

デフォルト値

AUDIT_LOG_RETENTION_DAYS

監査ログを残す日数。0 は無期限。数字以外を書いたときも、誤って消さないよう無期限として扱います

365

AUDIT_LOG_PURGE_ON_REQUEST

off にすると、通常のアクセスの終わりの自動削除を行いません

on

書き込み上限

同じ内容の監査ログを、一定の時間枠のあいだに書き込める件数に上限を設けます。同じ接続元から同じログが大量に発生しても、データベースが膨らみません。

AUDIT_LOG_RATE_LIMIT_PER_IP=10 # 同じ接続元・同じログの、時間枠あたりの上限
AUDIT_LOG_RATE_LIMIT_GLOBAL=100 # 接続元を問わない同じログの、時間枠あたりの上限
AUDIT_LOG_RATE_LIMIT_WINDOW=60 # 時間枠(秒)

設定項目

説明

デフォルト値

AUDIT_LOG_RATE_LIMIT_PER_IP

同じ接続元・同じログの、時間枠あたりの上限。0 で無効

10

AUDIT_LOG_RATE_LIMIT_GLOBAL

接続元を問わない同じログの、時間枠あたりの上限。0 で無効

100

AUDIT_LOG_RATE_LIMIT_WINDOW

時間枠(秒)。0 にすると書き込み上限はすべて無効になります

60

上限を超えた最初の 1 件は、省略が始まったことが分かる印を付けて書き込まれ、以降は時間枠が切り替わるまで書き込まれません。ログイン中のユーザーの操作の記録(INFO)は、上限の対象外です。

記録から除外する接続元

監視ツールなど、記録が不要な接続元を指定できます。管理画面の「コンフィグ」の「監査ログ」で、1 行に 1 件ずつ IP アドレスまたは CIDR を指定します。指定できるのは 100 件までです。IPv4 は /16、IPv6 は /48 より広い範囲は指定できません。

指定した接続元からの、ログインしていない状態の NOTICE 以下の記録は保存されません。ログインしている状態の記録や、WARNING 以上の記録は、これまでどおり保存されます。

除外する接続元は、後述の自動ブロックの対象外にはなりません。

セキュリティイベント

CSRF トークンの不一致やログインの失敗など、セキュリティに関わる出来事は「セキュリティイベント」として、種類を付けて NOTICE で記録されます。監査ログの一覧では、種類で絞り込めます。

次のイベントは、同じ接続元から繰り返し発生した回数が数えられ、自動ブロックの判定に使われます。

イベント

内容

post.invalid_route

不正なルートからの POST

post.broken_takeover

POST データの takeover が復元できなかった

csrf.token_mismatch

CSRF トークンの不一致

csrf.referer_mismatch

管理ドメイン・サイトのドメイン以外のリファラー

login.failed

ログインの失敗

login.locked

ログインのロック

login.unknown_email

存在しないメールアドレスでのログイン

login.invalid_code

認証コードの誤り

tfa.failed

二段階認証の失敗

tfa.locked

二段階認証のロック

tfa.recovery_failed

二段階認証のリカバリーの失敗

password_reset.unknown_email

存在しないメールアドレスでのパスワード再設定

password_reset.invalid_link

不正なパスワード再設定リンク

attachment.rejected

不正な添付ファイルの拒否(アップロード由来でないなど)

同じ接続元から、数えるイベントが短時間に繰り返し発生すると(ブロックの閾値の 3 分の 1 に達したとき)、security.burst というイベントが 1 回記録されます。ログインの打ち間違いのように、1 件ずつでは正規の利用者にも起きるイベントを、繰り返したときだけまとめて知らせるためです。

自動ブロック

同じ接続元から、数えるイベントが閾値に達すると、その接続元からの「ログインしていない状態の POST」を、一定の時間、429 で受け付けなくなります。GET リクエストと、ログイン中のリクエストは止めません。

SECURITY_IP_BLOCK_THRESHOLD=30 # ブロックする回数。0 はブロックしない
SECURITY_IP_BLOCK_TRIAL_TIME=10 # 回数を数える時間(分)
SECURITY_IP_BLOCK_TIME=30 # ブロックする時間(分)

設定項目

説明

デフォルト値

SECURITY_IP_BLOCK_THRESHOLD

回数を数える時間のあいだに、この回数に達した接続元をブロックします。0 はブロックしません

30

SECURITY_IP_BLOCK_TRIAL_TIME

回数を数える時間(分)

10

SECURITY_IP_BLOCK_TIME

ブロックする時間(分)

30

数字以外の値を書いたときは、ブロックしない設定(0)として扱います。