

# 为 PostgreSQL 数据库实例设置 Kerberos 身份验证
<a name="postgresql-kerberos-setting-up"></a>

您可以使用 AWS Directory Service for Microsoft Active Directory (AWS Managed Microsoft AD) 为 PostgreSQL 数据库实例设置 Kerberos 身份验证。要设置 Kerberos 身份验证，请执行以下步骤。

**Topics**
+ [步骤 1：使用 AWS Managed Microsoft AD 创建目录](#postgresql-kerberos-setting-up.create-directory)
+ [步骤 2：（可选）在本地 Active Directory 和 Directory Service 之间创建信任关系](#postgresql-kerberos-setting-up.create-trust)
+ [步骤 3：为 Amazon RDS 创建 IAM 角色以访问 Directory Service](#postgresql-kerberos-setting-up.CreateIAMRole)
+ [步骤 4：创建和配置用户](#postgresql-kerberos-setting-up.create-users)
+ [步骤 5：在目录和数据库实例之间启用跨 VPC 流量](#postgresql-kerberos-setting-up.vpc-peering)
+ [步骤 6：创建或修改 PostgreSQL 数据库实例](#postgresql-kerberos-setting-up.create-modify)
+ [步骤 7：为您的 Kerberos 主体创建 PostgreSQL 用户](#postgresql-kerberos-setting-up.create-logins)
+ [步骤 8：配置 PostgreSQL 客户端](#postgresql-kerberos-setting-up.configure-client)

## 步骤 1：使用 AWS Managed Microsoft AD 创建目录
<a name="postgresql-kerberos-setting-up.create-directory"></a>

Directory Service 将在 AWS 云中创建一个完全托管的 Active Directory。在创建 AWS Managed Microsoft AD 目录时，Directory Service 将创建两个域控制器和 DNS 服务器。目录服务器在 VPC 中的不同子网中创建。这种冗余有助于确保始终可以访问目录，即使发生了故障。

 创建 AWS Managed Microsoft AD 目录时，AWS Directory Service 将代表您执行下列任务：
+ 在您的 VPC 中设置 Active Directory。
+ 创建具有用户名 `Admin` 和指定密码的目录管理员账户。您可以使用此账户管理您的目录。
**重要**  
请务必保存此密码。Directory Service 不会存储此密码并且它无法取回或重置。
+ 为目录控制器创建安全组。安全组必须允许与 PostgreSQL 数据库实例进行通信。

在启动 AWS Directory Service for Microsoft Active Directory 时，AWS 创建一个组织单位 (OU)，其中包含目录的所有对象。此 OU（具有您在创建目录时输入的 NetBIOS 名称）位于域根目录中。此域根目录由 AWS 拥有和管理。

 使用 `Admin` 目录创建的 AWS Managed Microsoft AD 账户有权为您的 OU 执行最常见的管理活动：
+ 创建、更新或删除用户
+ 将资源添加到域（如文件或打印服务器），然后为 OU 中的用户分配这些资源的权限 
+ 创建额外的 OU 和容器 
+ 委托授权 
+ 从 Active Directory 回收站还原删除的对象 
+ 在 Active Directory Web 服务上为 Windows PowerShell 运行 Active Directory 和域名服务 (DNS) 模块 

`Admin` 账户还有权执行以下域范围的活动：
+ 管理 DNS 配置（添加、删除或更新记录、区域和转发器） 
+ 查看 DNS 事件日志 
+ 查看安全事件日志 

**使用 AWS Managed Microsoft AD 创建目录**

1.  在 [Directory Service 控制台](https://console.aws.amazon.com/directoryservicev2/)导航窗格中，选择 **Directories (目录)**，然后选择 **Set up directory (设置目录)**。

1. 选择 **AWS Managed Microsoft AD**。AWS Managed Microsoft AD 是当前唯一支持用于 Amazon RDS 的选项。

1. 选择 **Next (下一步)**。

1. 在**输入目录信息**页面上，提供以下信息：  
**版本**  
 选择符合您要求的版本。  
**目录 DNS 名称**  
 目录的完全限定名称，例如 **corp.example.com**。  
**目录 NetBIOS 名称**  
 可选的目录短名称，如 `CORP`。  
**目录描述**  
 目录的可选描述。  
**管理员密码**  
 目录管理员的密码。目录创建过程将创建一个具有 `Admin` 用户名和此密码的管理员账户。  
 目录管理员密码不能包含单词“admin”。此密码区分大小写，且长度必须介于 8 – 64 个字符之间。至少，它还必须包含下列四种类别中三种类别的一个字符：  
   +  小写字母 (a–z) 
   +  大写字母 (A–Z) 
   +  数字 (0–9) 
   +  非字母数字字符 (\$1\$1@\$1\$1%^&\$1\$1-\$1=`\$1\$1()\$1\$1[]:;"'<>,.?/)   
**确认密码**  
 重新键入管理员密码。  
确保您保存该密码。Directory Service 不会存储该密码，也无法检索或重置该密码。

1. 选择 **Next (下一步)**。

1. 在**选择 VPC 和子网**页面上，提供以下信息：  
**VPC**  
为目录选择 VPC。您可以在该相同 VPC 或不同的 VPC 中创建 PostgreSQL 数据库实例。  
**子网**  
 为目录服务器选择子网。两个子网必须位于不同的可用区。

1. 选择 **Next (下一步)**。

1.  检查目录信息。如果需要进行更改，请选择 **Previous (上一步)** 并作出更改。如果信息正确，请选择 **Create directory (创建目录)**。  
![\[“目录详细信息”页面\]](http://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/UserGuide/images/WinAuth2.png)

 目录创建需要几分钟时间。创建成功后，**Status (状态)** 值将更改为 **Active (活动)**。

 要查看有关您的目录的信息，请在目录列表中选择目录。记下**目录 ID** 值。在创建或修改 PostgreSQL 数据库实例时，您需要使用该值。

![\[详细信息页面的图像\]](http://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/UserGuide/images/WinAuth3.png)


## 步骤 2：（可选）在本地 Active Directory 和 Directory Service 之间创建信任关系
<a name="postgresql-kerberos-setting-up.create-trust"></a>

如果您不打算使用自己的本地 Microsoft Active Directory，请跳转至 [步骤 3：为 Amazon RDS 创建 IAM 角色以访问 Directory Service](#postgresql-kerberos-setting-up.CreateIAMRole)。

要使用本地 Active Directory 获取 Kerberos 身份验证，您需要使用林信任在本地 Microsoft Active Directory 和 AWS Managed Microsoft AD 目录（在 [步骤 1：使用 AWS Managed Microsoft AD 创建目录](#postgresql-kerberos-setting-up.create-directory) 中创建）之间创建信任域关系。信任可以是单向的，此时 AWS Managed Microsoft AD 目录信任本地 Microsoft Active Directory。信任也可以是双向的，此时两个 Active Directory 相互信任。有关使用 Directory Service 设置信任的更多信息，请参阅 *AWS Directory Service 管理指南*中的[何时创建信任关系](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_setup_trust.html)。

**注意**  
如果您使用本地 Microsoft Active Directory，则 Windows 客户端使用端点中 Directory Service 的域名而不是 rds.amazonaws.com 进行连接。要了解更多信息，请参阅[使用 Kerberos 身份验证连接到 PostgreSQL](postgresql-kerberos-connecting.md)。

请确保您的本地 Microsoft Active Directory 域名包含与新创建的信任关系对应的 DNS 后缀路由。以下屏幕截图显示一个示例。

![\[DNS 路由对应于创建的信任\]](http://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/UserGuide/images/kerberos-auth-trust.png)


## 步骤 3：为 Amazon RDS 创建 IAM 角色以访问 Directory Service
<a name="postgresql-kerberos-setting-up.CreateIAMRole"></a>

要使 Amazon RDS 为您调用 Directory Service，您的 AWS 账户需要一个使用托管式 IAM 策略 `AmazonRDSDirectoryServiceAccess` 的 IAM 角色。该角色允许 Amazon RDS 对 Directory Service 进行调用。

当您使用 AWS 管理控制台 创建数据库实例并且控制台用户账户具有 `iam:CreateRole` 权限时，控制台将自动创建所需的 IAM 角色。在这种情况下，角色名为 `rds-directoryservice-kerberos-access-role`。否则，您必须手动创建 IAM 角色。在创建该 IAM 角色时，请选择 `Directory Service`，然后将 AWS 托管策略 `AmazonRDSDirectoryServiceAccess` 附加到该角色。

有关为服务创建 IAM 角色的更多信息，请参阅 *IAM 用户指南*中的[创建向AWS服务委托权限的角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html)。

**注意**  
用于 RDS for Microsoft SQL Server 的 Windows 身份验证的 IAM 角色不能用于 Amazon RDS for PostgreSQL。

作为使用 `AmazonRDSDirectoryServiceAccess` 托管式策略的替代方法，您可以创建具有所需权限的策略。在这种情况下，IAM 角色必须具有以下 IAM 信任策略。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "directoryservice.rds.amazonaws.com",
          "rds.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

------

角色还必须具有以下 IAM 角色策略。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Action": [
        "ds:DescribeDirectories",
        "ds:AuthorizeApplication",
        "ds:UnauthorizeApplication",
        "ds:GetAuthorizedApplicationDetails"
      ],
    "Effect": "Allow",
    "Resource": "*"
    }
  ]
}
```

------

对于选择加入的 AWS 区域，请在 IAM 角色信任策略中使用区域特定的服务主体。在为这些区域中的服务创建信任策略时，请在服务主体中指定区域代码。

以下示例显示了包括区域特定的服务主体的信任策略：

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "directoryservice.rds.REGION-CODE.amazonaws.com",
          "rds.REGION-CODE.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

------

将 REGION-CODE 替换为特定区域的代码。例如，对亚太地区（墨尔本）区域使用以下服务主体：

```
"Service": [
  "directoryservice.rds.ap-southeast-4.amazonaws.com",
  "rds.ap-southeast-4.amazonaws.com"
]
```

## 步骤 4：创建和配置用户
<a name="postgresql-kerberos-setting-up.create-users"></a>

 您可以使用“Active Directory 用户和计算机”工具创建用户。该工具是 Active Directory Domain Services 和 Active Directory Lightweight Directory Services 工具之一。有关更多信息，请参阅 Microsoft 文档中的[将用户和计算机添加到 Active Directory 域](https://learn.microsoft.com/en-us/troubleshoot/windows-server/identity/create-an-active-directory-server#add-users-and-computers-to-the-active-directory-domain)。在这种情况下，用户是个人或其他实体，例如属于域的计算机，其身份在目录中维护。

要在 Directory Service 目录中创建用户，您必须连接到属于 Directory Service 目录成员的基于 Windows 的 Amazon EC2 实例。同时，您必须以具有创建用户权限的用户身份登录。有关更多信息，请参阅 *AWS Directory Service 管理指南*中的[创建用户](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_manage_users_groups_create_user.html)。

## 步骤 5：在目录和数据库实例之间启用跨 VPC 流量
<a name="postgresql-kerberos-setting-up.vpc-peering"></a>

如果您打算将目录和数据库实例放在同一 VPC 中，请跳过该步骤，然后转到[步骤 6：创建或修改 PostgreSQL 数据库实例](#postgresql-kerberos-setting-up.create-modify)。

如果您计划在不同 VPC 中查找目录和数据库实例，请使用 VPC 对等连接或 [AWS Transit Gateway](https://docs.aws.amazon.com/vpc/latest/tgw/what-is-transit-gateway.html) 配置跨 VPC 流量。

以下过程使用 VPC 对等连接启用 VPC 之间的流量。请按照 *Amazon Virtual Private Cloud 对等连接指南*中的[什么是 VPC 对等连接？](https://docs.aws.amazon.com/vpc/latest/peering/Welcome.html)操作。

**使用 VPC 对等连接启用跨 VPC 流量**

1. 设置适合的 VPC 路由规则，以便确保网络流量可以双向流动。

1. 确保数据库实例安全组可以从目录安全组接收入站流量。

1. 确保没有任何网络访问控制列表 (ACL) 规则会阻止流量。

如果该目录由不同的 AWS 账户拥有，则您必须共享该目录。

**在 AWS 账户之间共享目录**

1. 按照 *AWS 管理指南*中的[教程：共享 AWS 托管 Microsoft AD 目录以实现无缝 EC2 域加入](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_tutorial_directory_sharing.html)中的说明，开始与将要在其中创建数据库实例的 Directory Service 账户共享目录。

1. 使用数据库实例的账户登录到 Directory Service 控制台，并确保在处理之前域具有 `SHARED` 状态。

1. 使用数据库实例的账户登录 Directory Service 控制台时，请记录**目录 ID** 值。您可以使用此目录 ID 将数据库实例加入域。

## 步骤 6：创建或修改 PostgreSQL 数据库实例
<a name="postgresql-kerberos-setting-up.create-modify"></a>

创建或修改 PostgreSQL 数据库实例以用于您的目录。您可以使用控制台、CLI 或 RDS API 将数据库实例与目录关联。您可以通过下列方式之一来执行该操作：
+  使用控制台、[create-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/create-db-instance.html) CLI 命令或 [CreateDBInstance](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBInstance.html) RDS API 操作创建新的 PostgreSQL 数据库实例。有关说明，请参阅 [创建 Amazon RDS 数据库实例](USER_CreateDBInstance.md)。
+  使用控制台、[modify-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-instance.html) CLI 命令或 [ModifyDBInstance](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_ModifyDBInstance.html) RDS API 操作修改现有的 PostgreSQL 数据库实例。有关说明，请参阅 [修改 Amazon RDS 数据库实例](Overview.DBInstance.Modifying.md)。
+  使用控制台、[restore-db-instance-from-db-snapshot](https://docs.aws.amazon.com/cli/latest/reference/rds/restore-db-instance-from-db-snapshot.html) CLI 命令或 [RestoreDBInstanceFromDBSnapshot](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_RestoreDBInstanceFromDBSnapshot.html) RDS API 操作，从数据库快照还原 PostgreSQL 数据库实例。有关说明，请参阅 [还原到数据库实例](USER_RestoreFromSnapshot.md)。
+  使用控制台、[restore-db-instance-to-point-in-time](https://docs.aws.amazon.com/cli/latest/reference/rds/restore-db-instance-to-point-in-time.html) CLI 命令或 [RestoreDBInstanceToPointInTime](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_RestoreDBInstanceToPointInTime.html) RDS API 操作，将 PostgreSQL 数据库实例还原到某个时间点。有关说明，请参阅 [将 Amazon RDS 的数据库实例还原到指定时间](USER_PIT.md)。

仅 VPC 中的 PostgreSQL 数据库实例支持 Kerberos 身份验证。数据库实例可以与目录在同一 VPC 中或在不同 VPC 中。数据库实例必须使用允许在目录的 VPC 中传入和传出的安全组，以便数据库实例与目录通信。

### 控制台
<a name="postgresql-kerberos-setting-up.create-modify.Console"></a>

在使用控制台创建、修改或还原数据库实例时，请选择**数据库身份验证**部分中的**密码和 Kerberos 身份验证**。然后选择**浏览目录**。选择目录或选择**创建一个新目录**以使用 Directory Service。

![\[选择 Kerberos 进行身份验证并确定要使用的目录。\]](http://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/UserGuide/images/rpg-authentication-use-kerberos.png)


### AWS CLI
<a name="postgresql-kerberos-setting-up.create-modify.CLI"></a>

使用 AWS CLI 时，数据库实例需要以下参数才能使用您创建的目录：
+ 对于 `--domain` 参数，请使用创建目录时生成的域标识符（“d-\$1”标识符）。
+ 对于 `--domain-iam-role-name` 参数，请使用您使用托管 IAM 策略 `AmazonRDSDirectoryServiceAccess` 创建的角色。

例如，以下 CLI 命令会修改数据库实例以使用目录。

```
aws rds modify-db-instance --db-instance-identifier mydbinstance --domain d-Directory-ID --domain-iam-role-name role-name 
```

**重要**  
如果修改数据库实例以启用 Kerberos 身份验证，请在做出更改之后重新启动数据库实例。

## 步骤 7：为您的 Kerberos 主体创建 PostgreSQL 用户
<a name="postgresql-kerberos-setting-up.create-logins"></a>

此时，您的 RDS for PostgreSQL 数据库实例已加入 AWS Managed Microsoft AD 域。您需要将您在[步骤 4：创建和配置用户](#postgresql-kerberos-setting-up.create-users)的目录中创建的用户设置为 PostgreSQL 数据库用户，并授予登录数据库的权限。为此，请以具有 `rds_superuser` 权限的数据库用户身份登录。例如，如果在创建 RDS for PostgreSQL 数据库实例时接受了缺省设置值，请使用 `postgres`，如以下步骤所示。

**为 Kerberos 主体创建 PostgreSQL 数据库用户**

1. 使用 `psql` 通过 `psql` 连接到 RDS for PostgreSQL 数据库实例端点。以下示例对于 `rds_superuser` 角色使用原定设置 `postgres` 账户。

   ```
   psql --host=cluster-instance-1.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

1. 为要访问数据库的每个 Kerberos 主体（Active Directory 用户名）创建一个数据库用户名。使用 Active Directory 实例中定义的规范用户名（身份），即该用户名的小写 `alias`（Active Directory 中的用户名）和大写 Active Directory 域名。Active Directory 用户名是经过外部身份验证的用户，因此请在名称前后使用引号，如下所示。

   ```
   postgres=> CREATE USER "username@CORP.EXAMPLE.COM" WITH LOGIN;
   CREATE ROLE
   ```

1. 将 `rds_ad` 角色授予数据库用户。

   ```
   postgres=> GRANT rds_ad TO "username@CORP.EXAMPLE.COM";
   GRANT ROLE
   ```

为 Active Directory 用户身份创建完所有 PostgreSQL 用户后，用户可以使用他们的 Kerberos 凭证访问 RDS for PostgreSQL 数据库实例。

使用 Kerberos 进行身份验证的数据库用户需要从属于 Active Directory 域成员的客户端计算机进行身份验证。

被授予 `rds_ad` 角色的数据库用户不能同时拥有 `rds_iam` 角色。这也适用于嵌套成员资格。有关更多信息，请参阅 [适用于 MariaDB、MySQL 和 PostgreSQL 的IAM 数据库身份验证](UsingWithRDS.IAMDBAuth.md)。

## 步骤 8：配置 PostgreSQL 客户端
<a name="postgresql-kerberos-setting-up.configure-client"></a>

要配置 PostgreSQL 客户端，请采取以下步骤：
+ 创建一个 krb5.conf 文件（或等效的文件）以指向域。
+ 验证流量是否可以在客户端主机和 Directory Service 之间流动。使用网络实用程序（如 Netcat）执行以下操作：
  + 验证端口 53 上通过 DNS 的流量。
  + 验证端口 53 上通过 TCP/UDP 的流量以及 Kerberos 的流量，包括用于 Directory Service 的端口 88 和 464。
+ 验证流量是否可以通过数据库端口在客户端主机和数据库实例之间流动。例如，使用 psql 连接和访问数据库。

以下是 AWS Managed Microsoft AD 的示例 Krb5.conf 内容。

```
[libdefaults]
 default_realm = EXAMPLE.COM
[realms]
 EXAMPLE.COM = {
  kdc = example.com
  admin_server = example.com
 }
[domain_realm]
 .example.com = EXAMPLE.COM
 example.com = EXAMPLE.COM
```

以下是本地 Microsoft Active Directory 的示例 krb5.conf 内容。

```
[libdefaults]
 default_realm = EXAMPLE.COM
[realms]
 EXAMPLE.COM = {
  kdc = example.com
  admin_server = example.com
 }
 ONPREM.COM = {
  kdc = onprem.com
  admin_server = onprem.com
 }
[domain_realm]
 .example.com = EXAMPLE.COM
 example.com = EXAMPLE.COM
 .onprem.com = ONPREM.COM
 onprem.com = ONPREM.COM  
 .rds.amazonaws.com = EXAMPLE.COM
 .amazonaws.com.rproxy.goskope.com.cn = EXAMPLE.COM
 .amazon.com = EXAMPLE.COM
```