はじめに
2018/09/27 付の公開で、こんな記事が出ました。
https://aws.amazon.com/jp/about-aws/whats-new/2018/09/amazon-rds-postgresql-now-supports-iam-authentication/
Amazon RDS の PostgreSQL インスタンスで、IAM 認証ができるようになったみたいです。
早速試してみました。
やってみた
前提: 検証した環境
接続対象
- ap-northeast-1 / PostgreSQL 10.4
- us-west-2 / PostgreSQL 10.5
手元
- PostgreSQL 10.5 / Ubuntu 16.04
1. RDS for PostgreSQL インスタンスの作成
- 今まで触ったことない人が初期状態で割り当てられる VPC だと疎通ができないので注意しましょう
- VPC に IGW をアタッチしましょう
- セキュリティグループで、接続元から許可を追加しましょう
- 初期状態で allow されているのは、コンソールにログイン中の IP のご様子
2. IAM ポリシーの作成
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html
- 日本語版を見ると小さく書いてあるので注意ですが、ユーザ名ないしはロール名 がDBのユーザ名と一致する必要があります。
- ポリシーを作成後、割り当てるユーザの名前と、この後作る DB 側のユーザ名が一致するようにしましょう
- また、未検証ですが、「あまりにも名前が長すぎる」とだめかもしれません。
- ポリシー作成時、warning が出ますが、 RDS の MySQL インスタンスでも同じようになります。
まだ IAM 認証自体がポリシー編集画面に統合されてなさそうです。気にせず行きましょう - ポリシーは下記の並び順になります。
rds-db
な点、dbuser
な点に注意しつつ作成しましょう
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "rds-db:connect" ], "Resource": [ "arn:aws:rds-db:リージョン:アカウント(数字):dbuser:リソース ID/ユーザ名" ] } ] }
3. DB 側のユーザ作成
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.DBAccounts.html
- インスタンス作成時に指定した DB の名前と、ユーザ名を使ってログインし、IAM 認証したいユーザを作ります。
- 上記「IAM ポリシーの作成」で作成したユーザと同じ名前にします。
- 以下は適宜読み替えてください
- YOUR_INSTANCE_HOSTNAME : エンドポイント
- masteruser : ユーザ名
- testdb : DB 名
- testdb1003 : 予め作成しておいた IAM ユーザと同じユーザ名
$ psql -h YOUR_INSTANCE_HOSTNAME -U masteruser -d testdb ユーザー masteruser のパスワード: psql (10.5 (Ubuntu 10.5-1.pgdg16.04+1)、サーバー 10.4) SSL 接続 (プロトコル: TLSv1.2、暗号化方式: ECDHE-RSA-AES256-GCM-SHA384、ビット長: 256、圧縮: オフ) "help" でヘルプを表示します。 testdb=> CREATE USER "testdb1003" WITH LOGIN; CREATE ROLE testdb=> GRANT rds_iam TO "testdb1003"; GRANT ROLE
4. 手元の準備
- PostgreSQL のクライアントをインストールしておく
- 今回、インスタンス側は 10.4R と 10.5R で、手元は 10.5 を使いました。
- 手元のインストール方法は https://www.postgresql.org/download/linux/ubuntu/ を参考にしました
- AWS CLI の導入
- rds-combined-ca-bundle.pem の入手
- AWSのマニュアル から入手
5. 接続準備
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.Connecting.AWSCLI.PostgreSQL.html - 上記がマニュアルですが、サンプルに誤りがあります。後述の手順では修正していますが、
export PGPASSWORD="$(aws rds generated-db-auth-token --hostname $RDSHOST --port 3306 --region us-west-2 --username jane_doe )"
とあるところの、 generated-db-auth-token
は、 generate-db-auth-token
が正しいです。ご注意ください。
5.1 まずは token 生成ができるかを確認
- 以下は適宜読み替えてください
$ export RDSHOST=YOUR_INSTANCE_HOSTNAME $ aws rds generate-db-auth-token --hostname ${RDSHOST} --port 5432 --region ap-northeast-1 --username testdb1003 --profile test
すると、こんな感じの文字列が表示されます。されずに aws cli のエラーなどが出たら適宜見直してください
YOUR_INSTANCE_HOSTNAME:5432/?Action=connect&DBUser=testdb1003....(中略) $
5.2 実際に接続してみる
- 以下は適宜読み替えてください
$ export PGPASSWORD="$(aws rds generate-db-auth-token --hostname ${RDSHOST} --port 5432 --region ap-northeast-1 --username testdb1003 --profile test)" $ psql "host=${RDSHOST} port=5432 sslmode=verify-full sslrootcert=/path/to/rds-combined-ca-bundle.pem dbname=testdb user=testdb1003" psql (10.5 (Ubuntu 10.5-1.pgdg16.04+1)、サーバー 10.4) SSL 接続 (プロトコル: TLSv1.2、暗号化方式: ECDHE-RSA-AES256-GCM-SHA384、ビット長: 256、圧縮: オフ) "help" でヘルプを表示します。 testdb=>
- 注意としては、PostgreSQL のパスワードを打たない方法として、
$PGPASSWORD
にパスワードを格納する か、.pgpass
ファイルに諸々記載する があると思いますが、後者はうまくいかなそうです。- 理由としては、(変更できるのかな)デフォルトの
.pgpass
ファイルのセパレータが:
ですが、aws rds generate-db-auth-token
が生成する token に:
が利用されているからです。
- 理由としては、(変更できるのかな)デフォルトの
おまけ:ログインできないときに RDS コンソールから見れるログから推察したこと
- ログイン成功時
< HTTP/1.1 200 OK
- ログイン失敗時(パスワード誤り/IAMポリシー誤りっぽい?)
< HTTP/1.1 403 Forbidden
- ログイン失敗時(前述の ユーザ名が長すぎた か、
.pgpass
に登録してしまってセミコロンが暴発した 時
< HTTP/1.1 503 Service Unavailable
以上、速報レベルですが、うまくできましたというログです。