Amazon RDS for PostgreSQL に Kerberos 認証で接続してみる - サーバーワークスエンジニアブログ

Amazon RDS for PostgreSQL に Kerberos 認証で接続してみる

記事タイトルとURLをコピーする

こんにちは、カスタマーサクセス課の本田です。

Amazon RDS for PostgreSQL に Kerberos 認証で接続する方法についてのご紹介です。

はじめに

Kerberos認証とは、ネットワーク認証方式のひとつです。
はじめにIDとパスワードでログイン認証し、次回からその認証情報をもとにアクセス先へ接続します。
Amazon RDS for PostgreSQLにおいても、パスワード認証の他に、Active Directoryを使用したKerberos認証がサポートされています。
今回はこのAmazon RDS for PostgreSQL(以降PostgreSQL)におけるKerberos認証を試してみたいと思います。

構成図

構成図は次の通りです。
接続元クライアントはAmazon WorkSpacesのWindows 10とし、認証に使用するActive DirectoryはAWS Managed Microsoft AD(以降MSAD)を使用します。 f:id:swx-mikan-honda:20220217170800p:plain

設定手順

MSAD ディレクトリを作成

AWS Directory Serviceから、MSAD ディレクトリを作成します。
作成方法は下記手順をご参考ください。
docs.aws.amazon.com f:id:swx-mikan-honda:20220217144147p:plain

接続クライアント用のWorkSpacesを用意

PostgreSQLに接続用のクライアントとしてWorkSpacesを起動します。
ディレクトリは上記で作成したものを指定します。
f:id:swx-mikan-honda:20220217145809p:plain

ユーザーも作成し、指定します。
f:id:swx-mikan-honda:20220217150005p:plain

PostgreSQLインスタンスを作成

RDSのコンソールからPostgreSQLインスタンスを作成します。
データベースの認証セクションは [パスワードと Kerberos 認証] を選択し、ディレクトリは先ほど作成したMSADを指定します。 f:id:swx-mikan-honda:20220217150430j:plain f:id:swx-mikan-honda:20220217151935p:plain

PostgreSQLからMSAD ディレクトリへのアクセス用のIAMロールを作成

PostgreSQLインスタンス作成をコンソールから実行し、かつ、実行するコンソールユーザーが iam:CreateRole のアクセス許可を持っている場合はこの手順は必要ありません。
この場合は、 インスタンス作成時に rds-directoryservice-kerberos-access-role ロールを自動的に作成して付与してくれます。

それ以外の場合は、IAMロールを手動で作成し、PostgreSQLインスタンスのKerberos認証設定に付与する必要があります。
必要なポリシーは下記手順の「ステップ 3: Amazon RDS が AWS Directory Service にアクセスするための IAM ロールを作成する」をご確認ください。
docs.aws.amazon.com


今回は、前述の通り、マネジメントコンソール上からPostgreSQLインスタンスを作成し、自動的にIAMロールを作成し付与する手順としています。
そのため、PostgreSQLインスタンスのKerberos認証設定に必要なIAMロールが付与されているかどうかの確認のみ実施します。

マネジメントコンソール上ではKerberos認証に付与されているIAMロールを確認することはできませんでしたが、AWS CLIからは rds-directoryservice-kerberos-access-role ロールが付与されていることを確認することができました。

[cloudshell-user@ip-10-0-3-89 ~]$ aws rds describe-db-instances --db-instance-identifier postgres13-kerberos
{
    "DBInstances": [
        {
            "DBInstanceIdentifier": "postgres13-kerberos",
~~ 略 ~~
            "Engine": "postgres", 
           "DomainMemberships": [
                {
                    "Domain": "d-95670bd1c8",
                    "Status": "kerberos-enabled",
                    "FQDN": "mikan.local",
                    "IAMRoleName": "rds-directoryservice-kerberos-access-role"
                }
            ],
~~ 略 ~~

また、IAMロール rds-directoryservice-kerberos-access-role が自動的に作成され、必要なポリシー AmazonRDSDirectoryServiceAccess が付与されていることも確認できました。
f:id:swx-mikan-honda:20220217152305p:plain

PostgreSQLのユーザー作成

PostgreSQLのマスターユーザーの認証情報を使用して、作成したPostgreSQLインスタンスに接続します。
今回はEC2 Amazon Linux 2から接続します。

[ec2-user@linux ~]$ psql -h postgres13-kerberos.cw3nyjrsx6xz.ap-northeast-1.rds.amazonaws.com -p 5432 -U postgres
Password for user postgres:
psql (9.2.24, server 13.4)
WARNING: psql version 9.2, server version 13.0.
         Some psql features might not work.
SSL connection (cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256)
Type "help" for help.
postgres=>

ユーザーを作成します。

postgres=> CREATE USER "HondaMikan@MIKAN.LOCAL" WITH LOGIN;
CREATE ROLE

作成したユーザーにロールを付与します。

postgres=> GRANT rds_ad TO "HondaMikan@MIKAN.LOCAL";
GRANT ROLE

ユーザー一覧で、指定したユーザーが作成されていることを確認します。

postgres=> select usename from pg_user;
        usename
------------------------
 postgres
 rdstopmgr
 rdsadmin
 HondaMikan@MIKAN.LOCAL
(4 rows)

ここでの注意点は、 MSADに存在するユーザーのログイン名と一致する名前でPostgreSQLのユーザーを作成する必要があることです。
また、PostgreSQLのユーザー名のドメイン名は大文字で作成する必要があることも注意です。 f:id:swx-mikan-honda:20220217161305p:plain f:id:swx-mikan-honda:20220217162631p:plain

クライアントからPostgreSQLにKerberos認証で接続

今回はpgAdminで接続してみます。
接続元クライアントであるWorkSpacesにログインし、pgAdminをインストールし、起動します。
ログイン情報を確認します。
f:id:swx-mikan-honda:20220218163854p:plain


[Servers]-[Create]-[Server]-[Connection]にて下記情報を入力し、Kerberos認証で接続します。

項目
Host name/address 対象のPostgreSQLのエンドポイント
Port 5432
Maintenance datebase postgres
Username HondaMikan@MIKAN.LOCAL
Kerberos authentication? オン

f:id:swx-mikan-honda:20220217163801p:plain


接続できました! f:id:swx-mikan-honda:20220217163904p:plain


試しに、対象のPostgreSQLインスタンスに接続可能な別のWindows環境にて、他のドメインユーザーでログインし接続してみます。
ログイン情報を確認します。 先ほどと同じドメイン環境のAdminユーザーです。
f:id:swx-mikan-honda:20220218164351p:plain


[Servers]-[Create]-[Server]-[Connection]にて、先ほどと同じ情報を入力し、Kerberos認証で接続すると、エラーになりました。
ログインしているユーザーと異なるユーザー情報では、Kerberos認証で接続できないことが確認できました。
f:id:swx-mikan-honda:20220218165901p:plain

オンプレミス環境からの利用について

オンプレミスのActive Directoryを使用してオンプレミスのクライアントからRDS for PostgreSQLにKerberos認証で接続したい場合、構成図は次の図のようになります。
f:id:swx-mikan-honda:20220217165555p:plain


オンプレミス環境からの利用の場合、MSADディレクトリとオンプレミスのActive Directoryの信頼関係を作成する必要があります。
信頼関係の作成方法は下記手順の「ステップ2:(オプション)オンプレミスのActive Directoryの信頼を作成する」をご確認ください。 docs.aws.amazon.com

また、上記の図のようにオンプレミスのクライアントにてオンプレミスのActive Directoryの認証を使って、PostgreSQLにKerberos認証で接続する場合は、接続時のエンドポイント指定が少し異なってきます。
エンドポイント最後のドメイン名をrds.amazonaws.comではなく、Active Directoryのドメイン名に変更し、接続する必要があります。
例えば、Active Directory のドメイン名が corp.example.com である場合は、接続時のエンドポイントはPostgreSQL-endpoint.AWS-Region.rds.amazonaws.comではなく、PostgreSQL-endpoint.AWS-Region.corp.example.comとなります。

さいごに

今回は下記の手順を参考に試してみました。 docs.aws.amazon.com docs.aws.amazon.com

さいごに、つまづきポイントをまとめて終わりにしたいと思います!

  • MSADとPostgreSQLの通信は問題ないかどうか

    • MSADとPostgreSQLインスタンスが異なるVPCに存在する場合は、VPC ピア接続または AWS Transit Gateway を使用して相互間通信が可能になっていること
    • MSADディレクトリのセキュリティグループが、PostgreSQLインスタンスのセキュリティグループへのアウトバウンドトラフィックを許可していること
    • PostgreSQLインスタンスのセキュリティグループが、MSADディレクトリのセキュリティグループからのインバウンドトラフィックを許可していること
    • PostgreSQLのKerberos認証設定にて適切なIAMロールが付与されていること
  • PostgreSQLのユーザー名は問題ないかどうか

    • MSADに存在するユーザーのログイン名とPostgreSQLのユーザー名が一致していること
    • ドメイン名が大文字になっていること

【その他】Active Directoryのドメイン名について

※2022/2/25 追記

今回、検証用にプライベートネットワーク用のActive Directoryのドメイン名を XXX.local の形式で作成しましたが、 XXX.local の形式はインタネット標準でサポートされていないため、Microsoftでは推奨していませんでした。

プライベートネットワーク用のActive Directoryのドメイン名としては下記ドメイン名の利用を推奨されておりましたのでご注意ください。
.test
.example
.invalid
.localhost

以下MSサイトからの引用文となります。

Dummy DNS name vs official DNS name
In the past, lots of people chose to use a dummy, unofficial TLD (top-level-domain) for their internal network, like domain.lan, domain.local of domain.internal (and also domain.internalhost)

But this can get you in serious trouble. Because these names are not supported by internet standards, the most important RFC on this is: RFC 2606 Jump (http://tools.ietf.org/html/rfc2606 Jump ) This RFC standard is very explicit on choosing domain names for private testing and documentation
.test
.example
.invalid
.localhost

But also for documentation some 2nd level domains are reserved
example.com
example.net
example.org

social.technet.microsoft.com