IAMデータベース認証でRDS PostgreSQLに接続してみた

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

本機能のリリース当初はIAMロールベースのIAM認証には対応していませんでした。2019/06/01時点では対応しています。

Amazon RDS の PostgreSQL 系サービス

  • Amazon RDS for PostgreSQL
  • Amazon Aurora PostgreSQL

は IAM データベース認証を使用して、DB インスタンスを認証できます。

アプリケーションから DB にアクセスする際、クレデンシャルは

  • アプリケーション内にべた書き
  • メタデータ(タグ、環境変数)で管理
  • AWS Systems Manager パラメータストア で管理
  • AWS Secrets Manager で管理
  • Hashicorp Vault のようなミドルウェア

などで管理します。これらはすべて永続的な認証情報を利用します。

一方で、IAM データベース認証は一時的な認証情報を利用します。さらに、この認証情報を取得する API をインスタンスプロファイルが有効な EC2 から呼び出すと、その API 呼び出し時も一時的な認証情報を利用するため、認証情報の管理がよりセキュアになります。

また、複数の DB インスタンスに対して、同じ IAM ユーザー/ロールで認証できるため、DB アクセスを一元管理しやすくなります。

それでは、この認証方式を試してみます。

作業の流れ

以下の流れで作業します。

  1. IAM データベース認証を有効にした DB インスタンスの作成
  2. IAM データベース認証用 PostgreSQL ユーザーを作成
  3. IAM データベース認証用ポリシーを作成
  4. RDS が発行する認証トークンを取得して DB 接続

手順は Aurora と 非 Aurora で実質的に同じです。 今回は Amazon Aurora PostgreSQL 9.6.9 を利用します。

1. IAM データベース認証を有効にした DB インスタンスの作成

Amazon Aurora PostgreSQL 9.6.9 のインスタンスを作成します。

"Step 3:Configure advanced settings" で IAM データベース認証を有効にします("Enable IAM DB authentication")。

Amazon Aurora PostgreSQL 9.6.8 のように、データベース認証に対応していないバージョンでは、この選択肢は表示されません。

2. IAM データベース認証用 PostgreSQL ユーザーを作成

PostgreSQL に接続し、IAM データベース認証用ユーザー(jane_doe) を作成し、rds_iam ロールを GRANT します。

まずは PostgreSQL に接続します。

$ psql --host=$RDSHOST --username=postgres --password --dbname=dbname
dbname=>

次に ユーザーを作成します。

dbname=> CREATE USER jane_doe WITH LOGIN;
CREATE ROLE
dbname=> GRANT rds_iam to jane_doe;
GRANT ROLE

3. IAM データベース認証用ポリシーを作成

IAM データベース認証を利用する ポリシーを作成し、IAM ユーザー/ロールにアタッチします。

ポリシーテンプレート

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
             "rds-db:connect"
         ],
         "Resource": [
             "arn:aws:rds-db:region:account-id:dbuser:dbi-resource-id/database-user-name"
         ]
      }
   ]
}

環境に合わせて以下の値を変更してください。

  • region
  • account-id
  • dbi-resource-id(DB インスタンス ID または DB クラスター ID)
  • database-user-name(IAMデータベース認証に利用するユーザー名)

例)DBインスタンスをまるっと指定

まるっと許可したいときは「*」 を利用します。

次の例では、任意の DB インスタンスの jane_doe ユーザーに対して IAM データベース認証を許可します。

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
             "rds-db:connect"
         ],
         "Resource": [
             "arn:aws:rds-db:us-west-2:123456789012:dbuser:*/jane_doe"
         ]
      }
   ]
}

例)DBインスタンとユーザー名を明示的に指定

次の例では、DB インスタンス db-12ABC34DEFG5HIJ6KLMNOP78QRのユーザー(jane_doeまたはmary_roe)に対して IAM データベース認証を許可します。

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
             "rds-db:connect"
         ],
         "Resource": [
             "arn:aws:rds-db:us-west-2:123456789012:dbuser:db-12ABC34DEFG5HIJ6KLMNOP78QR/jane_doe",
             "arn:aws:rds-db:us-west-2:123456789012:dbuser:db-12ABC34DEFG5HIJ6KLMNOP78QR/mary_roe"
         ]
      }
   ]
}

dbi-resource-id に設定する値

dbi-resource-id

  • DB インスタンスリソース ID
  • (Aurora の場合)DB クラスターリソース ID

のどちらかを指定できます。

管理コンソールから確認

管理コンソールでは

  • DB インスタンス
  • クラスター

それぞれの詳細ページから確認可能です。

DB インスタンスリソースIDを確認

DB クラスターリソースIDを確認

AWS CLI から確認

DB インスタンスリソースIDを取得

$ aws rds describe-db-instances \
 --query "DBInstances[*].[DBInstanceIdentifier,DbiResourceId]"
[
    [
        "test",
        "db-XXX"
    ]
]

DB クラスターリソースIDを取得

$ aws rds describe-db-clusters --query "DBClusters[*].[DBClusterIdentifier,DbClusterResourceId]"
[
    [
        "test-cluster-id",
        "cluster-XXX"
    ]
]

4. RDS が発行する認証トークンを取得して DB 接続

aws rds generate-db-auth-token API で一時認証トークンを取得します。 この値をパスワードとして環境変数 PGPASSWORD に渡し、PostgreSQL と認証します。

認証トークンの有効期間は15分です。

$ RDSHOST=CLUSTER-ID.XXX.eu-central-1.rds.amazonaws.com
$ export PGPASSWORD="$( aws rds generate-db-auth-token --hostname $RDSHOST --port 5432 --username jane_doe )"
$ psql "host=$RDSHOST dbname=dbname user=jane_doe"
psql (9.5.0, server 9.6.9)
WARNING: psql major version 9.5, server major version 9.6.
        Some psql features might not work.
SSL connection (protocol: TLSv1, cipher: DHE-RSA-AES256-SHA, bits: 256, compression: off)
Type "help" for help.

dbname=> select version();
                                  version
------------------------------------------------------------------------------
PostgreSQL 9.6.9 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.9.3, 64-bit
(1 row)

無事接続できました。

なお、psql コマンドはデフォルトで SSL 通信します。

Amazon RDS PostgreSQLにpsqlからSSL接続する

IAM データベース認証を利用可能な PostgreSQL のバージョン

  • Amazon RDS for PostgreSQL
    • 9.5.13 以上
    • 9.6.9 以上
    • 10.4 以上
  • Amazon Aurora PostgreSQL
    • 9.6.9 以上

※ Aurora PostgreSQL 9.6.8 は対応していません。

MySQL 系の IAM データベース認証方法

MySQL 向け IAM データベース認証方法は以下を参照ください。

最後に

AWS 公式ドキュメントにあるIAM データベース認証の利点を列挙します。

  • データベースに出入りするネットワークトラフィックは、Secure Sockets Layer (SSL) を使用して暗号化されます。
  • IAM を使用して各 DB インスタンスで個別に管理するのではなく、データベースリソースへのアクセスを一元的に管理できます。
  • Amazon EC2 で実行するアプリケーションの場合、セキュリティを高めるため、EC2 インスタンスプロファイルの認証情報を使用して、パスワードの代わりにデータベースにアクセスできます。

特に、後ろ2つは IAM データベース認証の大きな利点です。 これらのメリットに大きな魅力を感じる場合は、IAM データベース認証の利用を一度検討してみてはいかがでしょうか。

参考