[アップデート] Amazon RDS for SQL Server の SQL Server Audit ログを CloudWatch Logs に直接配信できるようになりました
いわさです。
Amazon RDS for SQL Server では SQL Server Audit を使って、データベースエンジン上で発生したイベントを記録することができます。
SQL Server Audit は SQL Server のネイティブな監査の仕組みで、ログインの試行やストアドプロシージャの呼び出し、オブジェクトの作成・削除などのイベントを追跡・記録できます。
これまで RDS for SQL Server で SQL Server Audit を利用する場合、監査ログの出力先は S3 バケットのみでした。
S3 に保存されたログからログイン失敗回数を検出してアラートを上げたい場合などは、S3 イベント通知で Lambda を起動したり、Athena で定期的にクエリを実行する仕組みを自前で構築する必要がありました。
先日のアップデートで、SQL Server Audit ログの出力先として CloudWatch Logs が選択できるようになりました。
S3 の代わりに CloudWatch Logs へ配信することも、S3 と CloudWatch Logs の両方に同時配信することも可能です。
CloudWatch Logs に配信できるようになったことで、メトリクスフィルターを使って「ログイン失敗が一定回数を超えたらアラーム」のような監視が CloudWatch の標準機能だけで実現できるようになります。
今回こちらを確認してみたので紹介します。
実際に確認してみる
では早速、オプショングループの設定を確認してみましょう。
オプショングループで CloudWatch 配信を有効化する
RDS コンソールからオプショングループを開き、SQLSERVER_AUDIT オプションを追加します。

「監査ログの送信先」セクションに S3 と CloudWatch のチェックボックスがあり、今回追加された CloudWatch にチェックを入れます。
S3 は従来通り IAM ロールと S3 バケットの指定が必要ですが、CloudWatch を有効にすると「CloudWatch の設定」セクションが表示され、IAM ロールとして RDS サービスリンクロールが自動的に設定されます。

利用者側で IAM ロールを用意する必要がないのでセットアップがシンプルですね。
公式ドキュメントによると、CloudWatch への配信は RDS が自動で管理するとのことです。
CloudWatch publishing does not require a customer IAM role. When PUBLISH_TO_CLOUDWATCH is true, Amazon RDS manages delivery of the audit logs to Amazon CloudWatch Logs for you — you don't need to create or attach any IAM role or permissions for it.
なお、送信先は CloudWatch のみ、S3 のみ、または両方を選択可能ですが、少なくとも 1 つの送信先は設定する必要があります。
DB インスタンスにオプショングループを適用する
対象のオプショングループを DB インスタンスに適用します。
今回は SQL Server 2025 Standard Edition(17.00.4055.5.v1)の DB インスタンスを東京リージョンで用意しています。

オプショングループが同期されればすぐに監査ログの配信が開始されます。DB インスタンスの再起動は不要です。
SQL Server Audit を作成する
オプショングループの設定が完了したら、DB インスタンスに接続して SQL Server Audit のオブジェクトを作成します。
オプショングループの SQLSERVER_AUDIT はログファイルを S3 や CloudWatch に転送するための RDS 側の設定であり、「何を監査するか」は SQL Server 内で定義する必要があります。オンプレミスの SQL Server と同じ手順ですね。
RDS for SQL Server では Audit の出力先に TO FILE を指定し、パスは D:\rdsdbdata\SQLAudit\ を使います。
$ sqlcmd -S hoge0806sqlserver.cpnu9ipu74g4.ap-northeast-1.rds.amazonaws.com,1433 -U admin -P ****** -C -Q "CREATE SERVER AUDIT [hoge-audit] TO FILE (FILEPATH = 'D:\rdsdbdata\SQLAudit\', MAXSIZE = 10 MB) WITH (QUEUE_DELAY = 1000, ON_FAILURE = CONTINUE)"
$ sqlcmd -S hoge0806sqlserver.cpnu9ipu74g4.ap-northeast-1.rds.amazonaws.com,1433 -U admin -P ****** -C -Q "ALTER SERVER AUDIT [hoge-audit] WITH (STATE = ON)"
$ sqlcmd -S hoge0806sqlserver.cpnu9ipu74g4.ap-northeast-1.rds.amazonaws.com,1433 -U admin -P ****** -C -Q "CREATE SERVER AUDIT SPECIFICATION [hoge-audit-spec] FOR SERVER AUDIT [hoge-audit] ADD (FAILED_LOGIN_GROUP), ADD (SUCCESSFUL_LOGIN_GROUP), ADD (DATABASE_OBJECT_CHANGE_GROUP) WITH (STATE = ON)"
サーバー監査を作成し、ログインの成功・失敗やデータベースオブジェクトの変更を記録対象としています。
なお、RDS for SQL Server の Audit では出力先に TO APPLICATION_LOG は使えず、TO FILE のみ利用可能です。ファイルの最大サイズは 2MB〜50MB の範囲で指定する必要があります。
監査イベントを発生させる
検証のため、意図的にログイン失敗を発生させてみます。
$ sqlcmd -S hoge0806sqlserver.cpnu9ipu74g4.ap-northeast-1.rds.amazonaws.com,1433 -U fakeuser -P fakepass -C -Q "SELECT 1"
mssql: login error: Login failed for user 'fakeuser'.
続いてテーブルも作成してみます。
$ sqlcmd -S hoge0806sqlserver.cpnu9ipu74g4.ap-northeast-1.rds.amazonaws.com,1433 -U admin -P ****** -C -Q "CREATE DATABASE hogedb"
$ sqlcmd -S hoge0806sqlserver.cpnu9ipu74g4.ap-northeast-1.rds.amazonaws.com,1433 -U admin -P ****** -C -d hogedb -Q "CREATE TABLE piyo (id INT PRIMARY KEY, name NVARCHAR(100))"
CloudWatch Logs でログを確認する
しばらく待った後、CloudWatch Logs を確認してみます。
ログは以下のロググループに出力されます。
/aws/rds/instance/hoge0806sqlserver/sqlaudit

ロググループが自動的に作成されていますね。作成時刻は 8 分前とあるので、オプショングループの適用とほぼ同時に作られたようです。
ログストリーム名は {DBインスタンス名}.node1.{Audit名} という形式になっていました。今回の場合は hoge0806sqlserver.node1.hoge-audit です。
ログイベントのフィルターに LGIF と入力してログイン失敗のイベントを探してみます。

action_id が LGIF(Login Failed)のイベントが記録されていることが確認できました。
server_principal_name に対象ユーザー、client_ip に接続元 IP、application_name に接続アプリケーション(今回は sqlcmd)、statement にはログイン失敗の理由まで含まれています。
host_name が MacBookPro になっているのは接続元マシンのホスト名ですね。
ログイン失敗した際の接続元 IP やアプリケーション名、実行された SQL ステートメントまで記録されていることがわかります。
これが CloudWatch Logs に配信されるので、メトリクスフィルターで action_id が LGIF のイベント数を集計すれば、ログイン失敗回数の閾値アラームが簡単に作れますね。
S3 と CloudWatch の両方を有効にした場合
S3 と CloudWatch の両方を送信先として設定した場合、監査ログの公開は両方へのアップロードが完了して初めて「完了」としてマークされるとのこと。
片方だけにアップロードされてもう片方は欠損している、ということは起きない設計になっているようです。
なお、Multi-AZ(Always On)構成の場合、プライマリとセカンダリのノードがそれぞれ別のログストリームに書き込むようです。ノード識別子によって区別されるので、どちらのノードで発生したイベントなのかも判別できますね。
さいごに
本日は Amazon RDS for SQL Server の SQL Server Audit ログを CloudWatch Logs へ配信する機能が追加されたので確認してみました。
これまで S3 のみだった監査ログの出力先に CloudWatch Logs が加わったことで、ログイン失敗の検出やオブジェクト変更の追跡がメトリクスフィルター + アラームで手軽に実現できるようになりました。
IAM ロールの設定が不要で RDS サービスリンクロール経由で自動配信してくれる点も、セットアップの手間が少なくて良いですね。
S3 に溜めて長期保存しつつ、CloudWatch で日常的にモニタリングする、という使い分けも両方有効にするだけで実現できるので、監査ログの運用がだいぶ楽になりそうです。







