Amazon Web Services ブログ

IAM 認証を使用した Amazon RDS および Aurora PostgreSQL データベースアクセスの保護

AWS は 2 つのマネージド型 PostgreSQL オプションを提供しています。Amazon RDS for PostgreSQLAmazon Aurora PostgreSQL です。どちらも、データベースへのアクセスを管理するための IAM 認証をサポートしています。データベースユーザーを IAM ユーザーとロールに関連付けて、1 つの場所からすべてのデータベースへのユーザーアクセスを管理できます。これにより、異なる RDS/Aurora インスタンスで権限が同期されないことによる問題を回避できます。

この記事では、IAM 認証を使用できる 2 つの一般的なシナリオについてご説明します。同じ AWS アカウントの Amazon EC2 でホストされているアプリケーションから RDS/Aurora データベースにアクセスする方法と、別のアカウントからアクセスする方法があります。また、これらのシナリオに関連するベストプラクティスについてもご説明します。

この記事では Aurora PostgreSQL 環境を使用していますが、このソリューションは RDS PostgreSQL でも機能します。クラスタープロビジョニングの一部として IAM 認証を有効にしたり、クラスター作成後に CLI またはコンソールを使用してクラスターを変更したりできます。IAM データベース認証は、PostgreSQL バージョン 9.6.9 および 10.4 以降で使用できます。

前提条件

開始する前に、以下の前提条件を満たしてください。

  • 2 つの AWS アカウント (この記事では DB アカウントと管理アカウント) が必要です。
  • Aurora PostgreSQL DB クラスターを起動するか、PostgreSQL 10.7 で DB アカウントの既存の Aurora クラスターを使用します。
  • 各 AWS アカウントに 1 つずつ、2 つの EC2 インスタンスを起動します。
  • EC2 に psql クライアントをインストールし、Aurora クラスターへの接続を設定します。
  • 認証情報を使用して AWS CLI を設定します。両方の AWS アカウントに対する管理者 IAM 権限が必要です。AWS 管理ポリシーの管理者を使用することもできます。

この記事は、お客様が RDS/Aurora PostgreSQL および EC2 環境での作業に精通していることを前提としています。

環境の設定

ご使用の環境を設定するには、次の手順を実行します。

  1. DB アカウントで EC2 インスタンスにログインします。psql クライアントを使用して Aurora PostgreSQL クラスターに接続し、サンプルスキーマ pgdemo をインストールします。次のコマンドを参照してください。
    create database demo; 
    create schema pgdemo;
    set search_path='pgdemo';
    
    CREATE TABLE products (
        product_no integer PRIMARY KEY,
        name text,
        price numeric
    );
    
    CREATE TABLE orders (
        order_id integer PRIMARY KEY,
        product_no integer references products,
        quantity integer,
        order_date timestamp(0) without time zone
    );
    
    
    insert into products values( 1, 'Apple', 1000);
    insert into products values( 2, 'Samsung', 800);
    insert into products values( 3, 'Lenovo', 500);
    insert into products values( 4, 'Oneplus', 800);
    insert into products values( 5, 'Xiaomi', 300);
    
    insert into orders
     SELECT s, floor(random() * 5 + 1)::int ,
     floor(random() * 10 + 1)::int ,
      (timestamp '2019-09-20 10:00:00' + 
      random() * (timestamp '2019-09-22 20:00:00' - timestamp '2019-09-20 10:00:00'))::timestamp(0) without time zone
     from generate_series(1,20) as s ;
    commit; 
  2. アクセスコントロール用のデータベースロールを設定します。
    PostgreSQL では、データベースユーザーに直接権限を付与することができます。ただし、アプリケーション要件に基づいて特定の権限セットを持つロールを作成することにより、最小権限モデルでロールベースのアクセスコントロールを実行するのが、ベストプラクティスです。詳細については、PostgreSQL ユーザーとロールの管理を参照して、PostgreSQL データベースでユーザー、ロール、およびグループを構成する方法を学びます。この記事では、次のロールを作成します。
    oltp_ro_role – テーブルに対する選択権限などの読み取り専用権限がある
    oltp_rw_role – テーブルに対する選択、削除、挿入、更新特権がある
    両方のロールを作成するには、次のコマンドを入力します。

    -- Create oltp_ro_role
    
    create role oltp_ro_role;
    grant usage on schema pgdemo to oltp_ro_role;
    grant select on all tables in schema pgdemo to oltp_ro_role;
    
    -- Create oltp_rw_role 
    create role oltp_rw_role;
    grant usage on schema pgdemo to oltp_rw_role;
    grant select,update,delete,insert on all tables in schema pgdemo to oltp_rw_role;
    
  3. IAM 認証がまだ有効になっていない場合、次の CLI コマンドを使用して有効にします。
    aws rds modify-db-cluster \
    --db-cluster-identifier <cluster-identifier> \
    --apply-immediately \
    --enable-iam-database-authentication
    

    <cluster-identifier> を実際のクラスター識別子に置き換えます。

  4. 次の CLI コマンドを入力して、RDS IAM 認証が有効になっていることを確認します。
    aws rds describe-db-clusters --db-cluster-identifier <cluster-identifier>  --query 'DBClusters[].[IAMDatabaseAuthenticationEnabled]' --output table

    true の出力が返されます。

  1. データベースユーザーを作成し、ロール rds_iam および IAM ポリシーを使用して IAM 認証のアクセスを提供します。次のコマンドを入力します。
    -- Create Read-only (RO) user and grant read-only role
    create user oltp_ro_user with login;
    grant rds_iam to oltp_ro_user;
    grant oltp_ro_role to oltp_ro_user;
    -- Create Read-write(RW) user and grant read-write role
    create user oltp_rw_user with login;
    grant rds_iam TO oltp_rw_user;
    grant oltp_rw_role to oltp_rw_user;
  1. データベースユーザーを作成したら、IAM ポリシーを作成して、手順 5 で作成したデータベースユーザーに接続アクセスを許可します。次のコードでファイル oltp_rw_user.json を作成します。
    {
       "Version": "2012-10-17",
       "Statement": [
          {
             "Effect": "Allow",
             "Action": [
                 "rds-db:connect"
             ],
             "Resource": [
    "arn:aws:rds-db:<AWS Region>:<AWS Account ID>:dbuser:<DbClusterResourceId>/oltp_rw_user"
             ]
          }
       ]
    }

    リソースパラメータの形式は次のとおりです。
    arn:aws:rds-db:region:account-id:dbuser: DbClusterResourceId/db-user-name
    リージョン:account-idDbClusterResourceId/db-user-name を適切な値に置き換えます。コンソールまたは次の CLI コマンドを使用して、リソース識別子を見つけることができます。

    aws rds describe-db-clusters --db-cluster-identifier <cluster-identifier> --query "DBClusters[0].[DbClusterResourceId]"	
  1. ポリシードキュメントの準備ができたら、次のコードを使用して IAM ポリシーを作成します。
    aws iam create-policy --policy-name pgdemo-oltp-rw-user-policy --policy-document file://oltp_rw_user.json  
  1. 以前のコードをテンプレートとして使用して、oltp_ro_user のポリシードキュメントを作成します。

環境をセットアップし、IAM 認証機能をテストする準備が整いました。

同じアカウントの EC2 でホストされているアプリケーションからデータベースにアクセスする

典型的な実稼働環境には、OLTP、バッチジョブ、レポートなどのユースケースのために、単一の Aurora データベースクラスターに接続する複数のアプリケーションが含まれます。これらのアプリケーションには、明確なセキュリティ、運用、およびパフォーマンスの要件があります。したがって、それらの要件は通常、独自の EC2 インスタンスでホストされます。この例では、IAM ロールを介してデータベースアクセスを管理できます。この概念を使用して、特定のデータベース環境へのアクセスをロックダウンすることもできます。たとえば、EC2 インスタンス (App1) でホストされるアプリケーションは、特定のデータベースインスタンス prod-db1 にのみ接続できます。

EC2 に IAM ロールを使用すると、手動またはプログラムでの管理が必要な長期 AWS アクセスキーを使用する必要がなくなります。詳細については、Amazon EC2 の IAM ロールを参照してください。

この記事では EC2 インスタンスプロファイルを使用して、この機能を実現します。詳細については、インスタンスプロファイルの使用を参照してください。

次の図は、このソリューションの高レベルアーキテクチャを示しています。このアーキテクチャには、Aurora クラスターのデモデータベースへの読み取り/書き込みアクセスが必要な OLTP アプリケーションがあります。OLTP アプリケーションは、IAM ロール pgdemo_oltp_rw_role にマップされたインスタンスロールを持つ EC2 Auto Scaling グループでホストされます。レポートアプリケーションは、インスタンスロール pgdemo_oltp_ro_role を持つ別の EC2 Auto Scaling グループで実行されます。

このアーキテクチャを説明するために、psql などのクライアントアプリケーションが EC2 インスタンスにインストールされていて、データベースへの読み取りおよび書き込みアクセスが必要だと想定します。このアプリケーションにアクセスを付与するには、DB アカウントで次の手順を実行します。

  1. 次の信頼ポリシーを作成し、ec2-role-trust-policy.json という名前のテキストファイルに保存します。
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": { "Service": "ec2.amazonaws.com"},
          "Action": "sts:AssumeRole"
        }
      ]
    } 
  1. IAM ロール pgdemo-oltp-rw-role を作成し、ポリシー pgdemo-oltp-rw-user-policy をロールに添付します。次のコマンドを参照してください。
    # IAM ロールを作成します
    aws iam create-role --role-name pgdemo-oltp-rw-role --assume-role-policy-document file://ec2-role-trust-policy.json
    # IAM ポリシーを AWS EC2 インスタンスロールに添付
    aws iam attach-role-policy --role-name pgdemo-oltp-rw-role --policy-arn arn:aws:iam::<AWS Account id>:policy/pgdemo-oltp-rw-user-policy
  1. 次のコマンドを使用して、この IAM ロールを EC2 インスタンスに添付します。
    # インスタンスプロファイルを作成します
    aws iam create-instance-profile --instance-profile-name pgdemo-db-access-profile
    # IAM ロールをこのインスタンスプロファイルに添付します
    aws iam add-role-to-instance-profile --instance-profile-name pgdemo-db-access-profile --role-name pgdemo-oltp-rw-role
    # インスタンスプロファイルを EC2 インスタンスに添付します
    aws ec2 associate-iam-instance-profile --instance-id <EC2 Instance id> --iam-instance-profile Name="pgdemo-db-access-profile"
  1. EC2 インスタンスにログインし、aws rds generate-db-auth-tokenAPI を使用して一時的な認証情報を生成します。次のコマンドを参照してください。
    export RDSHOST="<Aurora Cluster Endpoint>"
    export PGPASSWORD="$(aws rds generate-db-auth-token --hostname $RDSHOST --port 5432 --region <AWS Region><--username oltp_rw_user )"
    

    注: echo $PGPASSWORD コマンドを使用して、生成された認証情報トークンを表示できます。詳細については、IAMDBAuth.Connecting.AWSCLI.PostgreSQL を参照してください。

  1. psql ユーティリティを使用して、生成された認証情報を使用して Aurora クラスターに接続します。
    psql -h $RDSHOST -p 5432 -d demo -U oltp_rw_user
    -- データベースユーザーを確認します
    select current_user;
     current_user
    --------------
     oltp_rw_user
    -- 製品テーブルに行を挿入します
    demo=> insert into pgdemo.products values(6,'Nokia',600);
    INSERT 0 1

IAM 認証を使用すると、psql などのアプリケーションはデータベースにログインし、データベースレベルのロールマッピングに基づいて DML アクションを実行できます。同じ手順を拡張して、レポートアプリケーションへの読み取り専用アクセスを提供できます。

別のアカウントの EC2 でホストされているアプリケーションからデータベースにアクセスする

次の例では、DB アカウントの RDS/Aurora データベースと、管理アカウントなどの別のアカウントのツールをホストするセキュリティチームを一元管理する DBA と IT オペレーターのマルチアカウントシナリオを想定しています。セキュリティチームは、監査および監視を行うために、すべてのデータベースにアクセスする必要があります。DB アカウントのすべてのデータベースでデータベースユーザー/ロールをプロビジョニングする代わりに、IAM 認証を使用できます。

DBA は、IAM クロスアカウントロール機能を介して DB アカウントからのアクセスを提供するために、最小特権モデルをデプロイできます。

次の図は、このソリューションの高レベルアーキテクチャを示しています。このアーキテクチャは、インスタンスプロファイルオプションを介して EC2 インスタンスに関連付けられた管理アカウント内の pg-mgmt-role という名前の標準ロールで構成されます。監視が必要な DB アカウントのすべてのデータベースには、必須権限で構成されたデータベースユーザー pgmonitor があります。 IAM データベース認証を使用して Aurora クラスターに接続するために、DB アカウントに pg-monitor-role を設定します。

このソリューションを実行するには、次の手順を実行します。

管理 AWS アカウントで実行する手順

  1. 次の信頼ポリシーを作成し、ec2-role-trust-policy.json という名前のテキストファイルに保存します。
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": { "Service": "ec2.amazonaws.com"},
          "Action": "sts:AssumeRole"
        }
      ]
    } 
  1. EC2 信頼ポリシーを使用して IAM ロール pg-mgmt-role を作成します。これは、ツールとアプリケーションによって、DB アカウントでホストされているさまざまなデータベースに接続するために使用されます。次のコードを参照してください。
    aws iam create-role --role-name pg-mgmt-role --assume-role-policy-document file://ec2-role-trust-policy.json
  1. ポリシードキュメント pg-mgmt-policy.json を作成します。これにより、権限が監視対象のデータベースアカウントで pg-monitor-role のロールを引き受けるように設定できます。次のコードを参照してください。
    {
      "Version": "2012-10-17",
      "Statement": {
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": "arn:aws:iam::<DB AWS Account ID>:role/pg-monitor-role"
      }
    }
  1. ポリシーを作成し、管理アカウントの pg-mgmt-role に添付します。次のコードを参照してください。
    # IAM ポリシーを作成します 
    aws iam create-policy --policy-name pg-mgmt-policy --policy-document file://pg-mgmt-policy.json  
    # IAM ポリシーを pg-mgmt-role に添付します
    aws iam attach-role-policy --role-name pg-mgmt-role --policy-arn arn:aws:iam::<Management AWS Account id>:policy/pg-mgmt-policy
  1. pg-mgmt-role IAM ロールが EC2 インスタンスプロファイルを介して EC2 インスタンスに添付されていることを確認してください。
    aws iam create-instance-profile --instance-profile-name pgmonitor-access-profile
    aws iam add-role-to-instance-profile --instance-profile-name pgmonitor-access-profile --role-name pg-mgmt-role
    aws ec2 associate-iam-instance-profile --instance-id <EC2 instance id> --iam-instance-profile Name="pgmonitor-access-profile"

DB AWS アカウントで実行する手順

  1. すべての Aurora クラスターに、IAM 認証および監視のための適切な権限を持つ、pgmonitor という名前のデータベースユーザーを作成します。次のコマンドを参照してください。
    create user pgmonitor with login;
    grant rds_iam to pgmonitor;
    
    -- Below role is available starting PostgreSQL 10
    grant pg_monitor to pgmonitor;
  1. 次のコードでポリシードキュメント mgmt-account-trust-policy.json を作成します。
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam::<Management AWS Account ID>:role/pg-mgmt-role"
          },
          "Action": "sts:AssumeRole"
        }
      ]
    }
  1. ロール信頼ポリシードキュメント mgmt-account-trust-policy.json で IAM ロール pg-monitor-role を作成します。次のコマンドを参照してください。
    aws iam create-role --role-name pg-monitor-role --assume-role-policy-document file://mgmt-account-trust-policy.json
  1. 次に、IAM ポリシーを作成して、Aurora クラスターへのアクセスを提供する必要があります。次のコードを使用して、ポリシー pg-db-monitor-policy を作成します。
    {
       "Version": "2012-10-17",
       "Statement": [
          {
             "Effect": "Allow",
             "Action": [
                 "rds-db:connect"
             ],
             "Resource": [
                 "arn:aws:rds-db: <AWS Region>:<DB AWS Account ID>:dbuser:*/pgmonitor"
             ]
          }
       ]
    }

    この場合、DBA は特定の AWS アカウントと AWS リージョンのすべての Aurora クラスターへのアクセスを提供しています。ご注意ください。特定のデータベースクラスターに制限する場合は、リソース ARN で DBClusterResourceId を "arn:aws:rds-db:<AWS Region>:<AWS Account ID>:dbuser:<DbClusterResourceId>/pgmonitor" に指定します。

    aws iam create-policy --policy-name pg-db-monitor-policy --policy-document file://pg-db-monitor-policy.json
  1. このポリシーを IAM ロール pg-monitor-role に添付します。次のコマンドを参照してください。
    aws iam attach-role-policy --role-name pg-monitor-role --policy-arn arn:aws:iam::<AWS Account id>:policy/pg-db-monitor-policy
  1. ロールを作成した後、管理アカウントの EC2 インスタンスが送信先セキュリティグループの IP をホワイトリストに登録して Aurora クラスターに接続できることを確認します。詳細については、セキュリティグループによるアクセスのコントロールを参照してください。または、VPC ピアリングを設定している場合は、ルートとセキュリティグループを適切に設定してください。詳細については、異なる VPC の EC2 インスタンスによってアクセスされる VPC の DB インスタンスを参照してください。

これで、すべてのロールとネットワークアクセスが設定されました。ただし、データベースに接続するように管理アプリケーションを構成する必要があります。この記事では、このアプリケーションが EC2 インスタンスで実行されていると仮定します。ロールのセットアップ中に、pg-mgmt-role にデータベースアカウントの pg-monitor-role を引き継ぎ、信頼関係を設定する権限を与えました。SDK を使用している場合、通常、STS 呼び出しを行ってターゲットロールの認証情報を取得し、それらの認証情報を使用して作業を実行します。EC2 では、最初の例で説明したように、インスタンスプロファイルを使用してロールを引き受けることが容易になります。

管理 AWS アカウントで実行する手順

  1. 管理アカウントで EC2 インスタンスにログインし、.aws/config にロールの新しいプロファイルを作成します。次のコマンド例では、DB アカウントの pg-monitor-role ロールに切り替える instancecrossaccount プロファイルを作成します。
    $cat .aws/config
    [profile instancecrossaccount]
    role_arn = arn:aws:iam::<DB account>:role/pg-monitor-role
    credential_source = Ec2InstanceMetadata
  1. これで設定が完了しました。次に、EC2 アカウントから DB アカウントで実行されている Aurora クラスターに接続します。
    export RDSHOST="<Aurora Cluster Endpoint>"
    export PGPASSWORD="$(aws rds generate-db-auth-token --hostname $RDSHOST --port 5432 --region <AWS Region> --username pgmonitor --profile instancecrossaccount)"
    
    $psql -h $RDSHOST -p 5432 -d demo -U pgmonitor
    

    このプロファイルが呼び出されると、AWS CLI は EC2 インスタンスプロファイルメタデータの認証情報を使用して、pg-monitor-role の認証情報をリクエストします。
    .
    次のクエリを実行することにより、10 秒ごとに pg_stat_activity をクエリしてデータベース内の現在のアクティビティを特定できるようになりました。

    SELECT 
        pid
        ,datname
        ,usename
        ,application_name
        ,client_hostname
        ,client_port
        ,backend_start
        ,query_start
        ,query
        ,state
    FROM pg_stat_activity
    WHERE state = 'active'  \watch 10;

    この記事の例では、EC2 クライアントを利用しました。AWS Lambda などのサーバーレスアプリケーションを介して IAM 認証を使用することもできます。詳細については、サーバーレスアプリケーションから Amazon Aurora への IAM ロールベース認証を参照してください。

運用上のベストプラクティス

ベストプラクティスを使用して IAM ポリシーとロールを実装することを強くお勧めします。詳細については、IAM ベストプラクティスを参照してください。

DB インスタンスパラメータグループで log_connections (1 に設定) を有効にすることにより、IAM を介してデータベースのログイン接続を監視できます。次のコードは、ログからの出力例です。

2019-09-29 10:08:45 UTC:ec2-x.x.us-east-2.compute.amazonaws.com(35608):pgmonitor@pgbench:[24601]:LOG: connection authorized: user=pgmonitor database=pgbench SSL enabled (protocol=TLSv1.2, cipher=ECDHE-RSA-AES256-GCM-SHA384, bits=256, compression=off)

ログインに失敗すると、次のようなエラーが報告されます。

2019-09-29 10:13:24 UTC:ec2-x.x.us-east-2.compute.amazonaws.com(35620):pgmonitor@pgbench:[29443]:LOG: pam_authenticate failed: Permission denied
2019-09-29 10:13:24 UTC:ec2-x.x.us-east-2.compute.amazonaws.com(35620):pgmonitor@pgbench:[29443]:FATAL: PAM authentication failed for user "pgmonitor"

クロスアカウントアクセスモニタリングの場合、AWS CloudTrail ログを使用してデータベース接続のソースを特定することもできます。これは、管理アカウントが AWS STS AssumeRole API を使用しているため可能になります。DB アカウントで CloudTrail ログが有効になっていることを確認します。詳細については、AWS CloudTrail ログのクエリを参照してください。

Amazon Athena 経由でログをクエリすることもできます。たとえば、次のクエリを使用して詳細を特定できます。

SELECT a.useridentity.accountid as "source_account",a.eventtime,a.eventsource,a.eventname,a.awsregion,a.sourceipaddress, names.arn  FROM "default"."cloudtrail_logs" a cross join unnest(resources) as t(names) where names.arn='arn:aws:iam::<DBaccountID>:role/pg-monitor-role'  order by a.eventtime limit 10;

<DBaccountID> を監視対象のアカウントに置き換えます。

次のスクリーンショットは、4934 と 1026 で終わるアカウントから 2 つのリクエストを受信したことを示しています。また、ソースを識別できる sourceipaddress も提供しています。

DBA と IT オペレーターでは、IAM 認証アクセスポリシーとデータベースユーザーが各クラスターに対して適切に同期されていることを確認する必要があります。たとえば、データベースユーザーを削除または変更する場合は、対応する IAM ポリシーを更新してください。また、IAM アクセスアドバイザー API を使用して権限を定期的に確認してください。たとえば、特定の IAM ロールまたはユーザーからのアクティビティがない場合、rds-db:connect アクセスの取り消しを検討できます。詳細については、IAM アクセスアドバイザー API を使用した権限分析の自動化を参照してください。

まとめ

この記事では、IAM 認証を使用してデータベースアクセスを管理できるシナリオと、監視に関連するベストプラクティスについて説明しました。各 DB クラスターで個別にアクセスを管理する代わりに、IAM 認証を使用してデータベースリソースへのアクセスを一元管理できます。AWS は、常にご意見・ご感想をお待ちしております。コメントや質問を残してください。

 

 


著者について

 

Gowri Balasubramanian は、アマゾン ウェブ サービスのプリンシパルデータベースソリューションアーキテクトです。 彼は、AWS を使用している場合にソリューションの価値を向上させる手助けとなるために、AWS のお客様と協力してリレーショナルデータベースと NoSQL データベースサービスの両方の指導や技術支援を行っています。

 

 

 

Amit Bansal は、アマゾン ウェブ サービスでプロフェッショナルサービスチームのシニアコンサルタントを務めています。彼は、AWS へのデータベース移行に焦点を当て、AWS RDS、Aurora、Redshift のアーキテクチャを設計および実装するために顧客と協力しています。