Aurora MySQLでIAM認証する手順と検証メモ
Aurora MySQLでIAM認証を検証したので、備忘録を兼ねて諸々メモ。
AuroraのIAM認証とは?
DBユーザーに、個別のパスワード入力の代わりにIAMクレデンシャルで認証する機能。
DBごと、ユーザーごとのパスワード管理が不要になる。
スロットルのリスクがあるためアプリケーションの認証には不向きだが、運用に伴う人による認証については一考の価値がある。
Aurora側での設定
- クラスターでIAM認証を有効化しておく。マネジメントコンソールでいうと、インスタンス設定(≠クラスター設定)の以下が該当設定。
- データベースで、IAM認証を有効にしたDBユーザーを作成する。IAM認証は、あくまでこのDBユーザーに対して、AWSプロファイルのIAMクレデンシャルでログインする行為であって、DBユーザーがないと機能しない点に注意。
CREATE USER ssotest IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
踏み台インスタンスでの設定
- DB接続用のmysqlクライアントを事前にインストールしておく。
- 実は微妙にハマリポイント。Amazon Linux 2で普通に
sudo yum install mysql
とすると、MariaDB互換クライアントがインストールされる(Amazon Linux 1だとMySQL純正クライアントが入る)のだが、MariaDB互換クライアントを使う場合、公式ドキュメントに記載のオプションではログインできない(後述の通り、別のオプションを使えば行けるが、そこに辿り着くまで大分かかった)。 - MySQL純正クライアントをインストールしてもよいが、アークテクチャーを選んでローカルインストールなど若干面倒くさい手順が必要になるので、ここでは一行で済むMariaDB互換をインストールする。
- 実は微妙にハマリポイント。Amazon Linux 2で普通に
- IAM認証時は、TLS接続設定に関わらずAuroraのCA証明書が必要になるので、ホームディレクトリあたりにwgetしておく。
- 少し前は
rds-ca-2019-root.pem
だったが、いつのまにか変わったらしい。リージョンごとの差異を吸収する
- 少し前は
% wget https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
権限付与の方針決定
- DBへのアクセスは一般に、パブリックアクセスは勿論、任意の端末からの接続を禁止するために、VPC内の特定のEC2インスタンス(踏み台)からのアクセスにセキュリティグループで縛ることが多いと思う。そうでないパターンも当然あり得るが、ここでは一応、踏み台パターンを前提とする。
- IAM認証には接続トークンの生成が必要になるが、踏み台からのIAM認証パターンは以下の二種類が考えられる。違いは、「誰の権限で・どこでトークンを生成するか」の観点。
- 踏み台のインスタンスプロファイル(ロール)にIAM認証を許可するポリシーを付与。接続トークンは踏み台内で生成して環境変数に格納。
- 踏み台には権限を付与せず、それ以外のIAMロールにIAM認証を許可するポリシーを付与。接続トークンは別端末で生成してコピペ。
- 具体的には、以下のようなポリシーをどこのロールに割り当てるかの話になる。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds-db:connect"
],
"Resource": [
"arn:aws:rds-db:ap-northeast-1:123456789012:dbuser:test-cluster/ssotest"
],
"Condition": {
"ForAnyValue:StringLike": {
"aws:PrincipalOrgPaths": "o-oXXXXXXXXX/r-YYYY/ou-ZZZZZZZZZZZZZ/*"
}
}
}
]
}
- プロコンはざっくり以下のようなイメージ。今回は踏み台の多系統化を避けて「別のIAMロール案」とする。具体的にはAWS SSOを使い、アクセス権限セットに
rds-db:connect
を付与する。
インスタンスプロファイル案 | 別のIAMロールに付与する案 | |
---|---|---|
利点 | 認証操作がシンプル | 踏み台は一系統でよい |
欠点 | 権限ごとに踏み台を分岐する必要がある | トークンを持ち込む必要がありひと手間かかる |
接続
- まずは認証トークン取得。前述の方針に従い、今回はAWS SSOでログイン後、踏み台の外でトークンを取得する(踏み台でトークン生成コマンドを叩くと、踏み台のインスタンスプロファイルの権限内で生成され、今回だとどこにも接続できないことになるため)。
% aws sso login --profile ssotest-profile
% aws rds generate-db-auth-token \
> --hostname hoge \
> --region ap-northeast-1 \
> --port 3306 \
> --username ssotest \
> --profile ssotest-profile
- トークンが生成されたら、クリップボードにコピーする。本来は環境変数に格納するのが楽なのだが、今回は踏み台に持ち込む必要上、コピペで対応する。
- 踏み台にSSM Sessions Manager等でログイン後、DB接続を実行する。ここではMariaDB互換クライアントのパターンを使用するが、参考までにMySQL純正クライアントのパターンも併記しておく。
% TOKEN='(先程取得したトークンの文字列をそのままコピペ)'
% mysql -h <Auroraエンドポイント>.ap-northeast-1.rds.amazonaws.com \
> --port=3306 \
> --user=ssotest \
> --password=$TOKEN \
> --ssl-ca=~/global-bundle.pem \
> --default-auth=mysql_clear_password
% mysql -h <Auroraエンドポイント>.ap-northeast-1.rds.amazonaws.com \
> --port=3306 \
> --user=ssotest \
> --password=$TOKEN \
> --ssl-ca=~/global-bundle.pem \
> --enable-cleartext-plugin
無事繋がったら完了。
なかなかMySQLのプロンプトが出ないな?という場合は、セキュリティグループを見直してみることをお薦めする。ちゃんと3306が許可されてるかとか、Aurora側でEC2側セキュリティグループをIngressに含めているか、など。
Access Deniedの際は以下のようなエラーが即時返ってくるので、そうでない場合はまずネットワークを疑う。
ERROR 1045 (28000): Access denied for user 'ssotest'@'XXX.XXX.XXX.XXX' (using password: YES)
小ネタ
- トークンは15分だけ有効。
- 一度生成したらいつでもどこでも再利用できるわけではなく、一定期間で切れるようになっている。
- 別アカウントで取得したトークンは使えない。
- IAMポリシーがどうあれ、アカウントをまたいでトークンを再利用することはできない。例えば、開発アカウントでたまたま
rds-db:connect
権限を持っていてトークンを生成できたとしても、それを使って本番アカウントのDBにログインすることができないようになっている。
- IAMポリシーがどうあれ、アカウントをまたいでトークンを再利用することはできない。例えば、開発アカウントでたまたま
- 「インスタンスプロファイル案」を選択して踏み台からトークンを生成する場合、当たり前だが、RDSのAPIエンドポイントへの経路が必要になる。
- 踏み台のEgressをガチガチに縛っている場合は、VPCエンドポイントが必要になるかも。
- AdministratorAccessなど、
iam:*
を保持している権限だと、ポリシー内容に拘わらず全部接続できてしまう。- 検証する際は注意しておかないと、想定した挙動にならなくて時間を無駄にする。
- AWS SSOでも使える。
- 今は改修されているが、以前は公式ドキュメントに「DBユーザー名はロール名と同じにせよ」という誤記があり、ロール名にアカウントごとのランダム文字列が付記されるAWS SSOでは運用上成立しないように見えていたが、原文は"Make sure the specified database user name is the same as a resource in the IAM policy for IAM database access."なので単なる誤訳だったらしい。
- Resourceの部分はワイルドカードを使える。つまり、
"Resource": [
"arn:aws:rds-db:ap-northeast-1:123456789012:dbuser:test-cluster/ssotest"
],
は、要件に応じて、以下のようにも書き変えることができる。
"Resource": [
"arn:aws:rds-db:*:*:dbuser:*/ssotest"
],
ただし、このままだといささか範囲が広すぎるので、せめてOrganizationsで縛るくらいはしておくこと。要件によっては、対象アカウントを本番とそれ以外に分けたり、対象クラスターを分けたりとかもあるかも知れない。
"Condition": {
"ForAnyValue:StringLike": {
"aws:PrincipalOrgPaths": "o-oXXXXXXXXX/r-YYYY/ou-ZZZZZZZZZZZZZ/*"
}
}
Author And Source
この問題について(Aurora MySQLでIAM認証する手順と検証メモ), 我々は、より多くの情報をここで見つけました https://qiita.com/itsuki3/items/246e785192bb64485203著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .