Aurora MySQL × VPC制御 × CloudWatchアラームで不正アクセスを検知する監視構成

1. はじめに

1-1. 背景

あるシステムで、2つのVPCから同一のAurora MySQLにアクセスする構成を採用しました。
VPC A はアプリケーションが動作する環境で、非人格ユーザーによる自動アクセスが行われます。
一方、VPC B は運用者の作業環境で、人格ユーザーによる手動操作が中心です。
このような中で、VPC B から非人格ユーザー(例:systemuser)による接続は許可せず、かつ試行を検知したいという要件が発生しました。

1-2. 実装した内容

一般的なRDS接続制御ではセキュリティグループなどのネットワーク設定を用いますが、今回の要件ではそれだけでは不十分でした。
VPC B からの人格ユーザーは許可しつつ、非人格ユーザーの接続試行のみを検知・通知したいという条件を満たすため、Aurora MySQL の audit ログを活用。
ログに出力されるユーザーや接続元情報をもとに、CloudWatch Logsとアラームを組み合わせた監視構成を実現しました。

※後で分かったのですが、IAMデータベース認証という機能でもこの仕組みを作ることは可能そうでした。こちらの方がシンプルで作りやすいかもしれません^^;
参考:https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/UsingWithRDS.IAMDBAuth.html

2. 構成概要

構成図はこちら。

本構成では、2つのVPCからAurora MySQLにアクセスする環境において、アクセス元とユーザー種別による制御と監視を実現しています。

  • VPC A(アプリ用):systemuser による接続を許可
  • VPC B(運用者用):user のみ接続を許可、systemuser の接続は拒否対象
  • Aurora auditログ を CloudWatch Logs に出力
  • VPC B から systemuser での接続試行を ログで検出
  • 該当ログに一致した場合は CloudWatch Alarm で通知

3. Aurora の監査ログ設定

VPC別アクセスの監視のために、監査ログ(audit log)を有効化します。Aurora MySQLでは、クラスターパラメータグループを修正することで設定可能です。

設定手順(MySQL互換の場合):

  • 対象のクラスターパラメータグループに以下を設定:
    • server_audit_logging = 1(監査ログの有効化)
    • server_audit_events = ‘CONNECT’(接続イベントの記録)
  • 変更後、DBクラスタにパラメータグループを適用し再起動

ログ出力先:

  • CloudWatch Logs に出力されるよう、RDSログの出力設定で audit ログを有効化
    設定箇所は Monitoring > Additional monitoring settings のトグルをオープンしたところにあります。

この設定により、どのIP アドレスから・どのユーザーで接続したかを記録できるようになります。

4. CloudWatch Logs での検知ロジック

監査ログを有効化しただけでは、異常な接続試行を検知することはできません。
本構成では、CloudWatch Logs に出力された audit ログに対してフィルタをかけ、特定条件を満たすログのみを抽出・通知しています。

ログ監視の方法

  • Aurora の監査ログは CloudWatch Logs のロググループに出力されます。
  • この log group に対して Metrics Filter を設定し、該当のログ出力をCloudwatch Metricsに変換します。

特定のユーザー(systemuser)が、VPC BのプライベートIP帯(例:10.0.0.0/24)から接続しているかどうかを判定します。

フィルタパターン例

以下のような CloudWatch Logs のフィルタパターンを使い、対象の接続ログを抽出します

%systemuser,10\.0\.0\.[0-9],|systemuser,10\.0\.0\.[0-9][0-9],|systemuser,10\.0\.0\.1[0-9][0-9],|systemuser,10\.0\.0\.2[0-5][0-5],%

このフィルタは文字列ベースで一致を取るため、ログの形式に合わせてカンマ区切りやフィールド順序も考慮が必要です。Aurora MySQLのauditログの形式を確認し、適切な形式のフィルタパターンを設定してください。

5. CloudWatch アラームの設定

Metrics Filterで指定したメトリクスに対してCloudWatchアラームの作成を行います。アラートの閾値は1以上とし、欠損データは正常とみなす設定とします。

これでCloudWatchアラームの設定も完了です。

動作確認

まずは構成図の通りにVPCの作成を行います

VPC-AとVPC-Bに相当するVPCをそれぞれ作成します。

VPC-BからVPC-Aに対するRDSに接続するため、VPC Peeringも作成します。

VPC-AとVPC-Bの間でルーティングが正しく行われるよう、RouteTableの設定も忘れずに。
写真上がVPC-A、下がVPC-BのRouteTableの一例です。

Engine versionは8.0.mysql_aurora.3.08.2を使用しています。カスタムクラスターパラメータグループを指定する以外は、ほぼデフォルトの設定です。

VPC-Bからのアクセスを許可するように、セキュリティグループの設定も忘れずに。

Aurora MySQL内部には上の画像の通り、ユーザーを追加しています。
ポイントは、”systemuser”はVPC-A内部のホストからのみアクセス権限を与えている点です。
これにより、VPC-Bからsystemuserを使ったDBアクセスを制限しています。

一方で”user”は全てのホストからアクセスを許可しているため、VPC-Bからのアクセスを可能としています。

これで下準備は完了です。
3. Aurora の監査ログ設定〜5. CloudWatch アラームの設定 が正しく行われていれば、「VPC-Bからsystemuserを使ってDBにアクセスした」場合にのみ、Cloudwatchアラートが発報されることになります。

以下のそれぞれのケースにおいて、DBへのアクセスを試みます。

  1. VPC-Aからsystemuserを使ってアクセス
  2. VPC-Bからuserを使ってアクセス
  3. VPC-Bからsystemuserを使ってアクセス

1. VPC-Aからsystemuserを使ってアクセス

CloudShellを使って、VPC-Aにenvironmentを作成し、そこからMySQLへのアクセスを試みます。

CloudShellの環境に割り当てられているIPアドレスの確認です。172.31.33.95というアドレスが割り当てられています。

~ $ ip addr show ens7
5: ens7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 06:2a:e2:86:3a:7f brd ff:ff:ff:ff:ff:ff
    altname enp0s7
    altname eni-05129ae46b2fed4b5
    altname device-number-2.0
    inet 172.31.33.95/20 scope global ens7
      valid_lft forever preferred_lft forever

Aurora MySQLへの接続も問題なくできました。

~ $ mysql -h database-1.cluster-ce4e4an4tq1t.ap-northeast-1.rds.amazonaws.com -P 3306 -u systemuser -p                                                                                                                                                                                                                           
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 587
Server version: 8.0.39 8bc99e28

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]>
MySQL [(none)]>

CloudWatch Logsにもログが出力されています。
一方でアラームは正常状態のままでした。

2. VPC-Bからuserを使ってアクセス

同様に、CloudShellにVPC-Bの環境を作成します。

IPアドレスが10.0.0.12に変わっていることが確認できます。

~ $ ip addr show ens7
5: ens7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 06:35:6d:b3:4a:71 brd ff:ff:ff:ff:ff:ff
    altname enp0s7
    altname eni-01567050a8f05e7a1
    altname device-number-2.0
    inet 10.0.0.12/28 scope global ens7
      valid_lft forever preferred_lft forever

このパターンではhostに制限をかけていないuserというDBユーザーを使用してAurora MySQLにアクセスを行いました。
こちらも問題ありません。

~ $ mysql -h database-1.cluster-ce4e4an4tq1t.ap-northeast-1.rds.amazonaws.com -P 3306 -u user -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 676
Server version: 8.0.39 8bc99e28

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]>

CloudWatch Logsにもログが出力されています。
一方でアラームは正常状態のままでした。1. のケースと結果は変わりません。想定通りの動作です。

3. VPC-Bからsystemuserを使ってアクセス

最後に、アラート検知として対処したい「VPC-Bからsystemuserを使ってアクセス」の場合を検証してみます。

クライアントのIPアドレスは、10.0.0.10です。

~ $ ip addr show ens7
5: ens7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 06:6b:38:48:72:d1 brd ff:ff:ff:ff:ff:ff
    altname enp0s7
    altname eni-0a1aa44a5fd48b96c
    altname device-number-2.0
    inet 10.0.0.10/28 scope global ens7
       valid_lft forever preferred_lft forever

systemuserでAurora MySQLにログインを試みたところ、アクセスが拒否されたことがわかります。

systemuserはVPC-A内部のホストからのみアクセスが許可されている状況なので、想定通りの動作となります。

~ $ mysql -h database-1.cluster-ce4e4an4tq1t.ap-northeast-1.rds.amazonaws.com -P 3306 -u systemuser -p
Enter password: 
ERROR 1045 (28000): Access denied for user 'systemuser'@'10.0.0.10' (using password: YES)

Cloudwatch LogsにもFAILED_CONNECTのログが出力されています。

さらに、同時にCloudwatch Alarmの状態も変化しました。

たしかに、VPC-Bかつ、systemuserのログインという状況でのみ、アラートが発報されることを確認できました。

トリッキーな構成ではありますが、「RDSのログインユーザーまで確認して、アラート通知を受け取りたい」というケースでも仕組みを作れば実現できることを確認できました。

コメント

タイトルとURLをコピーしました