do_su_0805's blog

dairyquestions は typo です。

Amazon RDS for PostgreSQL が IAM 認証に対応したので試してみた

はじめに

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 認証ができるようになったみたいです。 早速試してみました。

やってみた

前提: 検証した環境

接続対象

手元

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. 手元の準備

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 生成ができるかを確認

  • 以下は適宜読み替えてください
    • YOUR_INSTANCE_HOSTNAME : エンドポイント
    • masteruser : ユーザ名
    • testdb : DB 名
    • testdb1003 : 予め作成しておいた IAM ユーザと同じユーザ名
    • 5432 : ポート
    • --profile test : (aws cli でたくさん credentials を切り替えている人は、この方法が使えますという備忘録。)
$ 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 実際に接続してみる

  • 以下は適宜読み替えてください
    • YOUR_INSTANCE_HOSTNAME : エンドポイント
    • masteruser : ユーザ名
    • testdb : DB 名
    • testdb1003 : 予め作成しておいた IAM ユーザと同じユーザ名
    • 5432 : ポート
    • --profile test : (aws cli でたくさん credentials を切り替えている人は、この方法が使えますという備忘録。)
$ 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

以上、速報レベルですが、うまくできましたというログです。