既存の Aurora MySQL 互換クラスターの監査ログを有効化し CloudWatch Logs に出力して CloudWatch Logs Insights でログを抽出する(クエリする)方法

既存の Aurora MySQL 互換クラスターの監査ログを有効化し CloudWatch Logs に出力して CloudWatch Logs Insights でログを抽出する(クエリする)方法を記載します。
2023.05.03

コーヒーが好きな emi です。

どんなシステムでも、何かあったときの調査・トラブルシューティングのために各種ログは保存されていると思います。しかし、「ひとまずログはとっているけど、何かあったときに確認する方法がわからない……」となると困ります。

本ブログでは Aurora MySQL 互換クラスターの監査ログに焦点をあて、

  • 既存の Aurora MySQL 互換クラスターの監査ログを有効化し CloudWatch Logs に出力する方法
  • CloudWatch Logs Insights でログを抽出する(クエリする)方法

を記載します。

検証環境

以下のような環境で検証します。
EC2 インスタンスから mysql コマンドで Aurora MySQL にログインしたりクエリを発行したりして MySQL を操作します。

項目 詳細
エンジンのタイプ Aurora(MySQL Compatible)
エンジンバージョン 5.7.mysql_aurora.2.11.2
キャパシティータイプ プロビジョニング済み: シングルマスター

1. 監査ログの有効化

Aurora MySQL で監査ログを CoudWatch Logs に出力するには、以下 2 つの操作が必要です。

  1. カスタムクラスターパラメーターグループで監査ログを有効化する
  2. DB クラスターの設定で CloudWatch Logs へエクスポートする

まずは、カスタムクラスターパラメーターグループで Aurora MySQL の監査ログを有効化します。

1-1. カスタムクラスターパラメーターグループで監査ログを有効化する

Aurora MySQL の監査ログに関するパラメーターは以下の 4 つがあります。

パラメーター 設定例 設定可能値 概要
server_audit_logging (例)1 ・0(無効)
・1(有効)
高度な監査を有効または無効にします。server_audit_events パラメータが空だと、本パラメーターを 1(有効)にしても監査データはログに表示されません。
server_audit_events (例)CONNECT,QUERY,TABLE CONNECT,QUERY,QUERY_DCL,QUERY_DDL,QUERY_DML,TABLE 記録するイベントを大文字・コンマ区切りで指定します。
server_audit_incl_users (例)user_3,user_4 カンマ区切りのユーザー名リスト アクティビティを記録するユーザー名をカンマ区切りで指定します。
server_audit_excl_users (例)rdsadmin,user_1,user_2 カンマ区切りのユーザー名リスト アクティビティを記録しないユーザー名をカンマ区切りで指定します。

server_audit_logging

Aurora MySQL クラスターに適用されているカスタムクラスターパラメーターグループで、server_audit_logging の値を 1 にし、監査ログを有効化します。

RDS コンソールで対象の Aurora MySQL クラスターをクリックし、[設定] タブで Aurora MySQL クラスターに適用されているクラスターパラメーターグループを確認し、クリックします。

パラメーターグループの画面が開いたら、[パラメーターの編集] をクリックします。

server_audit_logging で検索し、値を 1 に変更します。

server_audit_events

続けて server_audit_events で、記録するイベントを指定します。

記録するイベントの種類 概要
CONNECT 成功した接続、失敗した接続、切断を記録します。ユーザー情報が含まれます。
QUERY すべてのクエリをプレーンテキストで記録します (構文またはアクセス権限エラーで失敗したエラーを含む)。
このイベントタイプを有効にすると、監査データには Aurora が自動的に行う継続的なモニタリングとヘルスチェックに関する情報が含まれます。
QUERY_DCL QUERY と同様ですが、データ制御言語 (DCL) クエリ (GRANT、REVOKE など) のみ返します。
QUERY_DDL QUERY と同様ですが、データ定義言語 (DDL) クエリ (CREATE、ALTER など) のみ返します。
QUERY_DML QUERY と同様ですが、データ操作言語 (DML) クエリ (INSERT、UPDATE、SELECT など) のみ返します。
TABLE クエリ実行の影響を受けたテーブルを記録します。

今回はすべてのイベントを出力するよう、CONNECT,QUERY,TABLE と入力します。

server_audit_incl_users

続けて server_audit_incl_users で、アクティビティを記録するユーザー名をカンマ区切りで指定します。
server_audit_incl_usersserver_audit_excl_users の両方が空 (デフォルト) の場合、すべてのユーザーが監査されます。
今回はすべてのユーザーのアクティビティを記録する設定としますので、値は空のままにします。
システムの要件に合わせて設定してください。

server_audit_excl_users

server_audit_excl_users で、アクティビティの記録から除外するユーザー名をカンマ区切りで指定します。
server_audit_incl_usersserver_audit_excl_users の両方が空 (デフォルト) の場合、すべてのユーザーが監査されます。
今回はすべてのユーザーのアクティビティを記録する設定としますので、値は空のままにします。
システムの要件に合わせて設定してください。

ここまで設定値を入力したら、[変更のプレビュー] をクリックします。

上記画像のように新しい値が確認できます。確認したら、[変更の保存] をクリックして変更を保存してください。

パラメータは動的なので、DB クラスターを再起動する必要はありません。

1-2. デフォルトクラスターパラメーターグループを利用している場合

デフォルトクラスターパラメーターグループを利用している場合、パラメーターが変更できません。
エンジンバージョンを確認して新たにカスタムパラメーターグループを作成し、パラメーターを変更して、Aurora MySQL クラスターに紐づけます。

既存の Aurora MySQL クラスターでカスタムクラスターパラメーターグループを利用しており「1-1. カスタムクラスターパラメーターグループで監査ログを有効化する」を実施した場合は、「1-2. デフォルトクラスターパラメーターグループを利用している場合」の操作を行う必要はありません。

DB クラスターパラメータグループと DB クラスターの関連付け

RDS コンソール画面左ナビゲーションペインで [パラメーターグループ] を選択し [パラメーターグループの作成] をクリックします。

項目 説明
パラメーターグループファミリー Aurora MySQL のエンジンバージョンと合致するものを選択します。
タイプ 「DB Parameter Group」もしくは「DB Cluster Parameter Group」が選択できます。今回はクラスターパラメーターグループを作成するので「DB Cluster Parameter Group」を選択します。
グループ名 カスタムクラスターパラメーターグループにつける名前を指定します。
説明 このカスタムクラスターパラメーターグループに関する説明を記載します。


最後に [作成] をクリックして、カスタムクラスターパラメーターグループを作成します。

カスタムクラスターパラメーターグループが作成できました。
続いて作成したカスタムクラスターパラメーターグループを Aurora MySQL クラスターに紐づけるように Aurora MySQL クラスターを変更します。
Aurora MySQL クラスターが起動していないと変更ができませんので、起動しておいてください。

対象の Aurora MySQL クラスターを選択し、[変更] をクリックします。

「追加設定」までスクロールし、新たに作成したカスタムクラスターパラメーターグループを選択します。

画面最下部までスクロールし、[続行] をクリックします。

変更のサマリーが表示されます。
パラメーターグループが変更されていることを確認し、変更のスケジュールを選択します。
今回は [すぐに適用] を選択し、[クラスターの変更] をクリックします。

画面上部に緑のバーで「正常に変更しました」と表示されたら OK です。[設定] タブで DB クラスターのパラメーターグループがカスタムクラスターパラメーターグループになっているはずです。

デフォルトのパラメータグループをカスタムパラメータグループに変更した場合、DB インスタンスを手動で再起動して新しいグループを適用する必要があるとドキュメントに記載があるため、DB インスタンスを選択して [アクション] - [再起動] から再起動しておいてください。

これでカスタムクラスターパラメーターグループが適用されました。
あとは「1-1. カスタムクラスターパラメーターグループで監査ログを有効化する」の項目を参考にカスタムクラスターパラメーターグループのパラメーターを変更して、監査ログを有効化してください。

ここまでの設定で、監査ログの有効化が完了しました。

補足:CloudWatch Logs にログをエクスポートせず、コンソールから簡易的に監査ログを確認する

カスタムクラスターパラメーターグループで監査ログを有効化すると、CloudWatch Logs にエクスポートしていなくてもコンソール上で簡易的に監査ログを表示することができます。
Aurora の DB インスタンスを選択した状態で [ログとイベント] タブを選択し画面下部にスクロールすると、監査ログが確認できます。

監査ログは 4 つのログファイルに並行に書き込まれており、順番には並んでいません。

ログを選択し、[表示] もしくは [見る] を選択するとコンソール上で監査ログを表示できます。

[ダウンロード] を選択すると、UTF-8 形式のカンマ区切り (CSV) ファイルとしてダウンロードできます。

監査ログは、各 DB インスタンスのローカル (一時) ストレージに別々に保存されます。
ログの最大サイズは合計で 100 MB です。この制限に達すると、Aurora はファイルをローテーションし、4 つの新しいファイルを生成します。
コンソールから見たところ、ログが出ていなくても 30 分ごとに新たなログファイルが作られ、すべてのファイルの容量の合計が 100 MB に到達すると、古いものから消えていくようです。

2. CloudWatch Logs へのエクスポート

有効化した監査ログを CloudWatch Logs へエクスポートする設定をしていきます。

2-1. DB クラスターの設定「ログのエクスポート」で「監査ログ」にチェックを入れる

DB クラスターの設定「ログのエクスポート」で「監査ログ」にチェックを入れます。
Aurora MySQL クラスターが起動していないと変更ができませんので、起動しておいてください。
対象の Aurora MySQL クラスターを選択して、[変更] をクリックします。

「追加設定」までスクロールし、「ログのエクスポート」で「監査ログ」にチェックを入れます。

画面最下部までスクロールし、[続行] - [クラスターの変更] をクリックして設定を保存します。

対象の Aurora MySQL クラスターを選択し、[設定] タブの「発行されたログ」セクションで「監査」と表示されていることを確認します。

以上の設定が完了すると、CloudWatch Logs に /aws/rds/cluster/(DB 識別子)/audit という名前で監査ログのロググループが存在しているはずです。
CloudWatch のコンソールで [ログ] - [ロググループ] に移動し、監査ログのロググループが存在することを確認してください。

2-2. CloudWatch Logs の保持設定を編集

ロググループの「保持期間」を確認すると「失効しない」となっています。
この状態ですと監査ログが CloudWatch Logs にたまり続けてしまうので、ログの保持設定を編集しておきます。
監査ログのロググループを選択し、[アクション] - [保持設定を編集] をクリックします。

以下のようにログの保持期間が選択できます。

今回は 1 週間とします。
1 週間以上前の古いログが保存されている場合、古いログは削除されますので注意してください。

[保存] をクリックして保存します。
ロググループの「保持期間」が「1 週間」となっていれば OK です。

CloudWatch Logs Insights で監査ログを見る(クエリする)

CloudWatch Logs に出力した監査ログを、CloudWatch Logs Insights という機能を使って抽出(クエリ)していきます。

CloudWatch Logs Insights で実行するクエリについては以下のブログも併せて参照ください。

CloudWatch Logs の画面左のナビゲーションペインから「ログのインサイト」をクリックします。

右上で、いつの時点のログを検索するか、期間を指定します。
ロググループを選択し、ログを抽出するクエリを記載します。
今回はデフォルトで記載されている以下のクエリを実行します。

fields @timestamp, @message, @logStream, @log
| sort @timestamp desc
| limit 20

これは

  • @timestamp@message@logStream@log というフィールドを、
  • @timestamp の降順(desc、最新から古い方へ)で、
  • 20 件まで抽出する

というクエリです。実行結果は以下のように新しいログから 20 件表示されます。

ログの行をクリックすると、ログの中身を表示できます。

出力結果は [結果をエクスポート] から

  • クリップボードにコピー(Markdown)
  • クリップボードにコピー(CSV)
  • クリップボードにコピー(JSON)
  • テーブルをダウンロード(CSV)
  • テーブルをダウンロード(JSON)
  • テーブルをダウンロード(XLSX)

の形式でコピーまたはダウンロードできます。

監査ログファイルの @message には、次のカンマ区切りの情報が順番に表示されています。

フィールド 説明
timestamp 記録されたイベントの UNIX タイムスタンプ (マイクロ秒の精度)
serverhost イベントが記録されている DB インスタンスの名前
username 接続されたユーザー名
host ユーザーの接続元のホスト
connectionid 記録されたオペレーションの接続 ID 番号
queryid クエリ ID 番号。リレーショナルテーブルイベントと関連するクエリの検索に使用できる。TABLE イベントの場合、複数の行が追加される
operation 記録されたアクションの種類。値は CONNECTQUERYREADWRITECREATEALTERRENAMEDROP のいずれか
database USE コマンドにより設定されたアクティブなデータベース
object QUERY イベントの場合はデータベースが実行したクエリ、TABLE イベントの場合はテーブル名
retcode 記録されたオペレーションのリターンコード

この出力情報をもとに、parse クエリで少しクエリ結果を見やすくします。

parse "*,*,*,*,*,*,*,*,*,*" as timestamp,serverhost,username,host,connectionid,queryid,operation,database,object,retcode
| limit 20

以下のように、@message フィールドの中身をよりわかりやすく表示できていると思います。

次はユーザー名 admin で出力結果をフィルタします。

parse "*,*,*,*,*,*,*,*,*,*" as timestamp,serverhost,username,host,connectionid,queryid,operation,database,object,retcode
| filter username = 'admin'

以下のように、admin ユーザーのアクティビティに関するログが抽出できました。
object セクションを見ると、select * from mysql.user;show databases; などのクエリを実行したことがわかります。

次は接続元ホスト別のログ数のカウントを出力します。

parse "*,*,*,*,*,*,*,*,*,*" as timestamp,serverhost,username,host,connectionid,queryid,operation,database,object,retcode
| stats count() by host

localhost からの接続は 678 件、172.31.30.81 からの接続は 24 件あることがわかります。
172.31.30.81 は mysql コマンドで接続している EC2 インスタンスのプライベート IP アドレスです。

次は、1 分ごとのログ件数をグラフにします。

parse "*,*,*,*,*,*,*,*,*,*" as timestamp,serverhost,username,host,connectionid,queryid,operation,database,object,retcode
| stats count () by bin(1m)

bin 関数については以下も参照ください。

以下のように 1 分間のログ数を 1 分ごとに出力できています。
12:14 の 1 分間で 457 件、12:13 の 1 分間で 460 件のログが出力されていることがわかります。

[可視化] タブを選択すると、以下のようにグラフを表示することができます。

おわりに

Aurora MySQL 互換クラスターの監査ログを出力するところからクエリするまでを記載してきました。
お役に立てば幸いです。

参考