5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AuroraのIAM認証はCloudTrailに監査ログが残らない(なりすましに注意)

Posted at

TL;DR

  • aws rds generate-db-auth-tokenコマンドはCloudTrailに残らない
  • 上記で発行されるトークンでmysqlコマンドで接続してもCloudTrailに残らない
  • AWS管理ポリシーのPowerUserAccessAdministratorAccessは、任意のユーザー名でAurora IAM認証ができる

はじめに

AuroraのIAM認証とは、DBユーザーにパスワードを設定せず、代わりにIAMで認証できる機能です。

MySQLの場合、通常のユーザー作成は

CREATE USER 'username'@'%' IDENTIFIED BY 'password';

ですが、IAM認証を使う場合は

CREATE USER 'username'@'%' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';

とします。また、別途IAM User等でAction rds-db:connectを許可します。

そうすると、次の2つのコマンドで接続できます。

TOKEN="$(aws rds generate-db-auth-token --hostname "$HOST" --port 3306 --username "$USER")"
MYSQL_PWD="$TOKEN" mysql -h "$HOST" -u "$USER"

トークンを生成し、mysqlコマンドでパスワードの代わりにトークンを使うだけです。超便利!

問題1: 他のユーザーになりすましできちゃった...!

そこで既存のAuroraでIAM認証を使おうと思いました。

このAuroraは開発者が接続することもあるため、以前からDBユーザーを個人ごとに作成し、さらに監査ログ(Audit Log)を有効化することで、誰がどんなクエリを実行したかを記録していました。

さっそく太郎くんと花子さんのユーザーをIAM認証で作成します。

CREATE USER 'taro'@'%' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
CREATE USER 'hanako'@'%' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';

ある日太郎くんがうっかり花子さんの名前で先ほどのコマンドを実行すると、なんと接続が成功してしまいました!

HOST='xxx'
USER='hanako' # うっかり花子にしちゃった!
TOKEN="$(aws rds generate-db-auth-token --hostname "$HOST" --port 3306 --username "$USER")"
MYSQL_PWD="$TOKEN" mysql -h "$HOST" -u "$USER"

原因は単純でした。IAM Policyで任意のユーザー名を許可してしまっていたのです。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "rds-db:connect",
      "Resource": "arn:aws:rds-db:ap-northeast-1:*:dbuser:*/*",
      "Effect": "Allow"
    }
  ]
}

Resourceは

"arn:aws:rds-db:ap-northeast-1:{アカウントID}:dbuser:{DBインスタンスの識別子}/{ユーザー名}"

という形式なので、DBユーザー名をtaroに限定したい場合は次のようになります。

"arn:aws:rds-db:ap-northeast-1:{アカウントID}:dbuser:{DBインスタンスの識別子}/taro"

IAM User名に一致させたい場合は

"arn:aws:rds-db:ap-northeast-1:{アカウントID}:dbuser:{DBインスタンスの識別子}/${aws:username}"

AssumeRoleされるRoleなら

"arn:aws:rds-db:ap-northeast-1:{アカウントID}:dbuser:{DBインスタンスの識別子}/${aws:SourceIdentity}"

などが使えます。

これで太郎くんと花子さんは自分への「なりすまし」に怯えなくて済むようになりました。めでたしめでたし... とはならなかったのです。

問題2: PowerUserAccessで許可されちゃってる〜

このアカウントでは複数の管理者が、AWS管理ポリシーのPowerUserAccessAdministratorAccessを持っていました。

試しにPowerUserAccessを持つ管理者がtaroで接続を試みると、なんと成功してしまいました!

HOST='xxx'
USER='taro'
TOKEN="$(aws rds generate-db-auth-token --hostname "$HOST" --port 3306 --username "$USER")"
MYSQL_PWD="$TOKEN" mysql -h "$HOST" -u "$USER"

いえ、そんなに驚くことではないかもしれません。先ほどと同様、PowerUserAccessrds-db:connectが任意のユーザー名で許可されているだけです。それを拒否すれば良いので、例えばIAMやSCPEffect: Denyでいい感じのルールを入れましょう。

ただ、会社やサービスによっては、諸般の事情でこれがちょっと面倒くさい場合もあります...(SSOを使っている等。できるけど少し大変、というニュアンス)

問題3: CloudTrailに記録されない!?

そこで管理者は妥協を考えました。「なにかあったときに監査ログでなりすましを確認すればいいや!」

前述の通りAuroraの監査ログ(Audit Log)は有効化しています。さらにAWSではCloudTrailで、全てのAPI Callを記録できます。

CloudTrailが設定してあることを確認して、管理者はふたたびtaroで接続しました。

HOST='xxx'
USER='taro'
TOKEN="$(aws rds generate-db-auth-token --hostname "$HOST" --port 3306 --username "$USER")"
MYSQL_PWD="$TOKEN" mysql -h "$HOST" -u "$USER"

ところが、CloudTrailにログが出てきません。全てのAPI Callが記録されるはずなのに...

そこで試しにPCのインターネット接続を切って3行目のコマンドを実行したところ、なんと成功してしまいました。

aws rds generate-db-auth-token --hostname "$HOST" --port 3306 --username "$USER"

そうです。このコマンドはトークンを生成するだけで、API Callは行っていませんでした。IAM認証は4行目のmysqlへの接続時に行われていたのです。

では、その4行目でCloudTrailにログはでないのでしょうか?

MYSQL_PWD="$TOKEN" mysql -h "$HOST" -u "$USER"

残念ながらログは出ませんでした。これは完全な推測ですが、Auroraの内部でIAM認証が行われているからだと思います。

というわけで、CloudTrailでなりすましを確認することはできないので、管理者は頑張ってIAMで制御することにしましたとさ。

おわりに

以上のストーリーはフィクションですが、AuroraのIAM認証で接続してもCloudTrailに何も残らないことはサポートに確認しました。その際、「他のお客様からもご要望いただいており、本ケースについても担当部署にフィードバックするが、実装有無および時期はお約束できない」旨もご返信いただきました。今後に期待ですね。

ということで、現時点でAuroraのIAM認証を使う際は十分お気をつけください。

駄文をお読みいただきありがとうございました。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?