IAMデータベース認証で、ポリシーにワイルドカードを使用して複数のDBユーザーを効率的に管理できるかを検証します。
IAMデータベース認証はセキュリティを強化しつつ、管理負荷を軽減する方法として有用なため、これまでいくつか記事を書いてきました。ワイルドカードが利用できれば、運用効率が上がること間違いなしですよね。
今回の記事では、この疑問を実際に検証した結果を共有します。
IAMデータベース認証検証
以前に、IAMデータベース認証を用いてAmazon Aurora for Postgresqlに接続できる記事を書きました。その際に、「DBユーザーが増えるたびにポリシーを増やすのか?」という疑問が湧いたので、検証してみました。
■前提
今回の手順の前提は以下の通りです。
-
EC2インスタンスが起動していること
Red Hat Enterprise Linux version 9 (HVM), EBS General Purpose (SSD) Volume Type
-
RDSデータベースが起動していること
Aurora PostgreSQL (Compatible with PostgreSQL 16.4)
-
上記のEC2インスタンスとRDSデータベースが疎通可能であること
-
IAMデータベース認証を有効化済みであること
こちらの記事を参考に、環境作成してみていただければと思います。
■手順の流れ
今回の検証手順は以下の通りです。
-
IAMポリシーを作成
IAMデータベース認証で利用するポリシーを作成します。Resouceセクションで定義する"db-user-name"部分に"app*"というワイルドカードを利用したDBユーザーネームを定義します。 -
DBにパスワード認証で接続
対象のDBユーザーがパスワード認証で正常に接続できることを確認します。 -
DBユーザーを作成
DBユーザーとして、"appuser1"と"appuser2"、ワイルドカードが適切に機能しているか検証用に一文字足りない"apuser1"を作成します。 -
対象のDBユーザーに
rds_iam
を付与
IAMデータベース認証を有効にするため、rds_iam
ロールを付与します。 -
rds_iam
を付与したDBユーザーでトークンを利用し接続確認
IAMデータベース認証用のトークンを使用して、各DBユーザーへの接続を確認します。 -
IAMポリシーを修正
"apuser1"への接続は失敗する想定ですので、IAMデータベース認証で接続できるようにIAMポリシーを修正します。
■IAMポリシー作成
DBクラスターへの接続を許可するためのIAM ポリシーを作成します。
次のポリシー例では、IAM データベース認証を使用して、DBクラスターに接続できます。
自身の環境に合わせ修正し、IAMポリシーを作成してください。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds-db:connect"
],
"Resource": "arn:aws:rds-db:<REGION>:<ACCOUNT_ID>:dbuser:<CLUSTER_ID>/app*"
}
]
}
作成が完了しましたら、接続元となるEC2で利用しているIAMロールにアタッチしてください。
IAMポリシー作成は以上です。
■データベースに接続
検証用のDBユーザを作成するために、データベースへ接続します。
マスタユーザとして作成したpostgres
ユーザーを利用し、パスワード認証でログインしてみましょう。
【実行コマンド】自身の環境に合わせ修正してください。
USERNAME=postgres
PASSWORD=<パスワード>
HOST=saitou-test-aurora.<CLUSTER_ID>.<REGION>.rds.amazonaws.com
PORT=5432
export PGPASSWORD=$PASSWORD
psql -h $HOST -p $PORT -U $USERNAME
【実行結果】
[ec2-user@ip-10-0-1-37 ~]$ USERNAME=postgres
PASSWORD=<パスワード>
HOST=saitou-test-aurora.<CLUSTER_ID>.<REGION>.rds.amazonaws.com
PORT=5432
export PGPASSWORD=$PASSWORD
[ec2-user@ip-10-0-1-130 ~]$ psql -h $HOST -p $PORT -U $DB_USER
psql (16.4)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.
postgres=>
postgres
ユーザでログインできることを確認しました。
■DBユーザを作成
次に、検証用のDBユーザを3つ作成します。
appuser1
appuser2
apuser1
【実行コマンド】
CREATE USER appuser1 WITH LOGIN;
CREATE USER appuser2 WITH LOGIN;
CREATE USER apuser1 WITH LOGIN;
【実行結果】
postgres=> CREATE USER appuser1 WITH LOGIN;
CREATE USER appuser2 WITH LOGIN;
CREATE USER apuser1 WITH LOGIN;
CREATE ROLE
CREATE ROLE
CREATE ROLE
DBユーザの作成が完了しました。
■DBユーザーにrds_iam
を付与
次に、作成したDBユーザに、IAMデータベース認証を有効化していきます。
rds_iam
というロールを付与することで、有効化されます。
【実行コマンド】
GRANT rds_iam to appuser1;
GRANT rds_iam to appuser2;
GRANT rds_iam to apuser1;
【実行結果】
postgres=> GRANT rds_iam to appuser1;
GRANT rds_iam to appuser2;
GRANT rds_iam to apuser1;
GRANT ROLE
GRANT ROLE
GRANT ROLE
各ユーザにロールが付与されたか確認します。
【実行コマンド】
SELECT
pg_has_role('appuser1', 'rds_iam', 'member') AS appuser1_has_rds_iam,
pg_has_role('appuser2', 'rds_iam', 'member') AS appuser2_has_rds_iam,
pg_has_role('apuser1', 'rds_iam', 'member') AS apuser1_has_rds_iam;
【実行結果】
postgres=> SELECT
pg_has_role('appuser1', 'rds_iam', 'member') AS appuser1_has_rds_iam,
pg_has_role('appuser2', 'rds_iam', 'member') AS appuser2_has_rds_iam,
pg_has_role('apuser1', 'rds_iam', 'member') AS apuser1_has_rds_iam;
appuser1_has_rds_iam | appuser2_has_rds_iam | apuser1_has_rds_iam
----------------------+----------------------+---------------------
t | t | t
(1 row)
postgres=>
trueを示すt
が出力されましたので、ロールが付与されていることを確認しました。
■接続確認
接続元のEC2インスタンスから作成したDBユーザに対し、トークンを取得して接続してみます。
IAMポリシーのDBユーザ指定の部分で、app*
としたので、各ユーザーの接続結果は以下の想定です。
【接続DBユーザ】
appuser1
: 接続できる想定appuser2
: 接続できる想定apuser1
: 接続失敗する想定
それでは、ひとつずつ接続してみましょう。
●appuser1
接続元サーバから、以下のコマンドを実行します。
【実行コマンド】自身の環境に合わせ修正してください。
HOST=saitou-test-aurora.<CLUSTER_ID>.<REGION>.rds.amazonaws.com
REGION=ap-southeast-1
PORT=5432
DB_USER=appuser1
DBNAME=testdb
TOKEN=$(aws rds generate-db-auth-token --hostname $HOST --port $PORT --region $REGION --username $DB_USER)
psql "host=$HOST port=$PORT dbname=$DBNAME user=$DB_USER password=$TOKEN sslmode=verify-full sslrootcert=/home/ec2-user/.postgresql/root.crt"
【実行結果】
[ec2-user@ip-10-0-1-130 ~]$ HOST=saitou-test-aurora.cluster-cxxxxxxxxxxxx.ap-southeast-1.rds.amazonaws.com
REGION=ap-southeast-1
PORT=5432
DB_USER=appuser1
DBNAME=testdb
[ec2-user@ip-10-0-1-130 ~]$ TOKEN=$(aws rds generate-db-auth-token --hostname $HOST --port $PORT --region $REGION --username $DB_USER)
[ec2-user@ip-10-0-1-130 ~]$ psql "host=$HOST port=$PORT dbname=$DBNAME user=$DB_USER password=$TOKEN sslmode=verify-full sslrootcert=/home/ec2-user/.postgresql/root.crt"
psql (16.4)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.
testdb=> SELECT current_database(), current_user;
current_database | current_user
------------------+--------------
testdb | appuser1
(1 row)
testdb=>
appuser1
で接続できることが確認できました。
この時点でワイルドカードが機能していることも確認できましたね。
●appuser2
続いて、appuser2
を試します。
接続元サーバから、以下のコマンドを実行します。
【実行コマンド】自身の環境に合わせ修正してください。
HOST=saitou-test-aurora.<CLUSTER_ID>.<REGION>.rds.amazonaws.com
REGION=ap-southeast-1
PORT=5432
DB_USER=appuser2
DBNAME=testdb
TOKEN=$(aws rds generate-db-auth-token --hostname $HOST --port $PORT --region $REGION --username $DB_USER)
psql "host=$HOST port=$PORT dbname=$DBNAME user=$DB_USER password=$TOKEN sslmode=verify-full sslrootcert=/home/ec2-user/.postgresql/root.crt"
【実行結果】
[ec2-user@ip-10-0-1-130 ~]$ HOST=saitou-test-aurora.cluster-cxxxxxxxxxxxx.ap-southeast-1.rds.amazonaws.com
REGION=ap-southeast-1
PORT=5432
DB_USER=appuser2
DBNAME=testdb
[ec2-user@ip-10-0-1-130 ~]$ TOKEN=$(aws rds generate-db-auth-token --hostname $HOST --port $PORT --region $REGION --username $DB_USER)
[ec2-user@ip-10-0-1-130 ~]$ psql "host=$HOST port=$PORT dbname=$DBNAME user=$DB_USER password=$TOKEN sslmode=verify-full sslrootcert=/home/ec2-user/.postgresql/root.crt"
psql (16.4)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.
testdb=> SELECT current_database(), current_user;
current_database | current_user
------------------+--------------
testdb | appuser2
(1 row)
testdb=>
appuser2
で接続できることが確認できました。
●apuser1
続いて、はじめに接続確認したappuser1
と一文字違いのapuser1
を試します。
接続元サーバから、以下のコマンドを実行します。
【実行コマンド】自身の環境に合わせ修正してください。
HOST=saitou-test-aurora.<CLUSTER_ID>.<REGION>.rds.amazonaws.com
REGION=ap-southeast-1
PORT=5432
DB_USER=apuser1
DBNAME=testdb
TOKEN=$(aws rds generate-db-auth-token --hostname $HOST --port $PORT --region $REGION --username $DB_USER)
psql "host=$HOST port=$PORT dbname=$DBNAME user=$DB_USER password=$TOKEN sslmode=verify-full sslrootcert=/home/ec2-user/.postgresql/root.crt"
【実行結果】
[ec2-user@ip-10-0-1-130 ~]$ HOST=saitou-test-aurora.cluster-cxxxxxxxxxxxx.ap-southeast-1.rds.amazonaws.com
REGION=ap-southeast-1
PORT=5432
DB_USER=apuser1
DBNAME=testdb
[ec2-user@ip-10-0-1-130 ~]$ TOKEN=$(aws rds generate-db-auth-token --hostname $HOST --port $PORT --region $REGION --username $DB_USER)
[ec2-user@ip-10-0-1-130 ~]$ psql "host=$HOST port=$PORT dbname=$DBNAME user=$DB_USER password=$TOKEN sslmode=verify-full sslrootcert=/home/ec2-user/.postgresql/root.crt"
psql: error: connection to server at "saitou-test-aurora.cluster-clqy3wpgthbm.ap-southeast-1.rds.amazonaws.com" (10.0.2.185), port 5432 failed: FATAL: PAM authentication failed for user "apuser1"
エラーが出力されました。文字列が一致していないためですね。
psql: error: connection to server at "saitou-test-aurora.cluster-clqy3wpgthbm.ap-southeast-1.rds.amazonaws.com" (10.0.2.185), port 5432 failed: FATAL: PAM authentication failed for user "apuser1"
psql: エラー: 「saitou-test-aurora.cluster-clqy3wpgthbm.ap-southeast-1.rds.amazonaws.com」(10.0.2.185) のサーバーへの接続、ポート 5432 に失敗しました: 致命的: ユーザー「apuser1」の PAM 認証に失敗しました
IAMポリシーで定義したDBユーザのワイルドカードが機能していることがわかりました。
■IAMポリシー修正
現在のIAMポリシーでは、さいごに接続確認したapuser1
がapp*
に一致しないため、接続できませんでした。
apuser1
も接続できるように、IAMポリシーの記述を修正してみましょう。
具体的には、app*
からap*
に修正します。
【変更前】
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds-db:connect"
],
"Resource": [
"arn:aws:rds-db:<REGION>:<ACCOUNT_ID>:dbuser:<CLUSTER_ID>/app*"
]
}
]
}
【変更後】自身の環境に合わせ修正してください。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds-db:connect"
],
"Resource": [
"arn:aws:rds-db:<REGION>:<ACCOUNT_ID>:dbuser:<CLUSTER_ID>/ap*"
]
}
]
}
修正が完了しましたら、再度接続確認してみましょう。
【実行コマンド】自身の環境に合わせ修正してください。
TOKEN=$(aws rds generate-db-auth-token --hostname $HOST --port $PORT --region $REGION --username $DB_USER)
psql "host=$HOST port=$PORT dbname=$DBNAME user=$DB_USER password=$TOKEN sslmode=verify-full sslrootcert=/home/ec2-user/.postgresql/root.crt"
【実行結果】
[ec2-user@ip-10-0-1-130 ~]$ TOKEN=$(aws rds generate-db-auth-token --hostname $HOST --port $PORT --region $REGION --username $DB_USER)
[ec2-user@ip-10-0-1-130 ~]$ psql "host=$HOST port=$PORT dbname=$DBNAME user=$DB_USER password=$TOKEN sslmode=verify-full sslrootcert=/home/ec2-user/.postgresql/root.crt"
psql (16.4)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.
testdb=> SELECT current_database(), current_user;
current_database | current_user
------------------+--------------
testdb | apuser1
(1 row)
testdb=>
無事に接続することができました。
今回のAmazon AuroraでのIAMデータベース認証におけるワイルドカード利用の検証は以上です。
まとめ
ワイルドカードを使用することでIAMデータベース認証の管理が効率化されるがわかりましたね。
しかし、最後に修正して接続できるようにしたように、適用範囲に注意が必要です。
本検証の手順を参考に、セキュリティ要件を満たした運用を構築してください。
参考リンク:IAM database authentication – AWS公式ドキュメント
↓ほかの協栄情報メンバーもAmazon RDSについての記事を公開しています。ぜひ参考にしてみてください。
■IAMデータベース認証を利用し、Aurora PostgreSQLに接続する手順(齊藤弘樹)
■EC2インスタンス(RHEL)からSecrets Managerを利用してAurora for PostgreSQL 16に接続する手順(齊藤弘樹)
■Amazon EC2(RHEL9)からAmazon Aurora for PostgreSQL16.4への接続手順(齊藤弘樹)
■“Amazon RDS for SQL Server”のクロスリージョンリードレプリカを作成・昇格してみた(齊藤弘樹)
■RDSのMySQL5.7標準サポート終了に伴う8.0へのアップグレードについて(ito.d)
■AWS RDS for Oracleメモリー不足際の解決案(dapeng)