

# 了解 PostgreSQL 角色和权限
<a name="Appendix.PostgreSQL.CommonDBATasks.Roles"></a>

在使用 AWS 管理控制台 创建 RDS for PostgreSQL 数据库实例时，将同时创建管理员账户。默认情况下，其名称为 `postgres`，如以下屏幕截图所示：

![\[Create database（创建数据库）页面中凭据的默认登录身份是 postgres。\]](http://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/UserGuide/images/default-login-identity-apg-rpg.png)


您可以选择其他名称，而不是接受默认值（`postgres`)。如果这样做，您选择的名称必须以字母开头，并且必须介于 1 到 16 个字母数字字符之间。为简单起见，在整个指南中，我们将使用默认值 (`postgres`) 来指代此主用户账户。

如果您使用 `create-db-instance` AWS CLI 而不是 AWS 管理控制台，则可以通过将名称传递给命令中的 `master-username` 参数来创建名称。有关更多信息，请参阅 [创建 Amazon RDS 数据库实例](USER_CreateDBInstance.md)。

无论您是使用 AWS 管理控制台、AWS CLI 还是 Amazon RDS API，也无论您是使用默认 `postgres` 名称还是选择其他名称，这第一个数据库用户账户都是 `rds_superuser` 组的成员并具有 `rds_superuser` 权限。

**Topics**
+ [了解 rds\$1superuser 角色](Appendix.PostgreSQL.CommonDBATasks.Roles.rds_superuser.md)
+ [控制用户对 PostgreSQL 数据库的访问](Appendix.PostgreSQL.CommonDBATasks.Access.md)
+ [委托和控制用户密码管理](Appendix.PostgreSQL.CommonDBATasks.RestrictPasswordMgmt.md)
+ [使用 SCRAM 进行 PostgreSQL 密码加密](PostgreSQL_Password_Encryption_configuration.md)

# 了解 rds\$1superuser 角色
<a name="Appendix.PostgreSQL.CommonDBATasks.Roles.rds_superuser"></a>

在 PostgreSQL 中，*角色*可以针对数据库中的各种对象定义一个用户、一个组或一组授予组或用户的特定权限。PostgreSQL 命令 `CREATE USER` 和 `CREATE GROUP` 已替换为更通用的 `CREATE ROLE`，并使用特定属性来区分数据库用户。数据库用户可以被视为具有 LOGIN 权限的角色。

**注意**  
仍然可以使用 `CREATE USER` 和 `CREATE GROUP` 命令。有关更多信息，请参阅 PostgreSQL 文档中的[数据库角色](https://www.postgresql.org/docs/current/user-manag.html)。

`postgres` 用户是您的 RDS for PostgreSQL 数据库实例上权限最高的数据库用户。它具有以下 `CREATE ROLE` 语句所定义的特征。

```
CREATE ROLE postgres WITH LOGIN NOSUPERUSER INHERIT CREATEDB CREATEROLE NOREPLICATION VALID UNTIL 'infinity'
```

属性 `NOSUPERUSER`、`NOREPLICATION`、`INHERIT` 和 `VALID UNTIL 'infinity'` 是 CREATE ROLE 的默认选项，除非另有说明。

默认情况下，`postgres` 拥有授予 `rds_superuser` 角色的权限以及创建角色和数据库的权限。`rds_superuser` 角色允许 `postgres` 用户执行以下操作：
+ 添加可用于 Amazon RDS 的扩展。有关更多信息，请参阅 [使用 Amazon RDS for PostgreSQL 支持的 PostgreSQL 功能](PostgreSQL.Concepts.General.FeatureSupport.md) 
+ 为用户创建角色并向用户授予权限。有关更多信息，请参阅 PostgreSQL 文档中的 [CREATE ROLE](https://www.postgresql.org/docs/current/sql-createrole.html) 和 [GRANT](https://www.postgresql.org/docs/14/sql-grant.html)。
+ 创建数据库。有关更多信息，请参阅 PostgreSQL 文档中的 [CREATE DATABASE](https://www.postgresql.org/docs/14/sql-createdatabase.html)。
+ 将 `rds_superuser` 权限授予没有这些权限的用户角色，并根据需要撤销权限。建议您仅向执行超级用户任务的那些用户授予此角色。换句话说，您可以将此角色授予数据库管理员 (DBA) 或系统管理员。
+ 向没有 `rds_superuser` 角色的数据库用户授予（和撤销）`rds_replication` 角色。
+ 向没有 `rds_superuser` 角色的数据库用户授予（和撤销）`rds_password` 角色。
+ 通过使用 `pg_stat_activity` 视图获取有关所有数据库连接的状态信息。需要时，`rds_superuser` 可以通过使用 `pg_terminate_backend` 或 `pg_cancel_backend` 停止任何连接。

在 `CREATE ROLE postgres...` 语句中，您可以看到 `postgres` 用户角色明确禁止 PostgreSQL `superuser` 权限。RDS for PostgreSQL 是一项托管服务，因此您无法访问主机操作系统，也无法使用 PostgreSQL `superuser` 账户进行连接。许多需要独立 PostgreSQL 上的 `superuser` 访问权限的任务都由 Amazon RDS 自动管理。

有关授权权限的更多信息，请参阅 PostgreSQL 文档中的 [GRANT](http://www.postgresql.org/docs/current/sql-grant.html)。

`rds_superuser` 角色是 中的几个*预定义*角色之一。RDS for PostgreSQL 数据库实例。

**注意**  
在 PostgreSQL 13 和更早版本中，*预定义*角色称为*默认*角色。

在下面的列表中，您可以找到为新 自动创建的一些其他预定义角色。RDS for PostgreSQL 数据库实例。无法更改预定义角色及其权限。无法删除、重命名或修改这些预定义角色的权限。此类尝试会导致错误。
+ **rds\$1password** – 可以为数据库用户更改密码和设置密码限制的角色。默认情况下，`rds_superuser` 角色被授予此角色，并且可以将此角色授予数据库用户。有关更多信息，请参阅 [控制用户对 PostgreSQL 数据库的访问控制用户对 PostgreSQL 的访问](Appendix.PostgreSQL.CommonDBATasks.Access.md)。
  + 对于早于 14 的 RDS for PostgreSQL 版本，`rds_password` 角色可以为数据库用户和具有 `rds_superuser` 角色的用户更改密码和设置密码限制。在 RDS for PostgreSQL 14 及更高版本中，`rds_password` 角色只能为数据库用户更改密码和设置密码限制。只有具有 `rds_superuser` 角色的用户才能对具有 `rds_superuser` 角色的其他用户执行这些操作。
+ **rdsadmin** – 具有 `superuser` 权限的管理员将对独立的 PostgreSQL 数据库执行许多管理任务，此角色专为处理这些管理任务而创建。此角色由 RDS for PostgreSQL 在内部用于许多管理任务。
+ **rdstopmgr** – Amazon RDS 在内部用于支持多可用区部署的角色。
+ **rds\$1reserved** – Amazon RDS 在内部用于保留数据库连接的角色。

# 查看角色及其权限
<a name="Appendix.PostgreSQL.CommonDBATasks.Roles.View"></a>

根据您的 PostgreSQL 版本，您可以使用不同的命令在 RDS for PostgreSQL 数据库实例中查看预定义角色及其权限。要查看所有预定义角色，可以连接到 RDS for PostgreSQL 数据库实例，并使用 `psql` 运行以下命令。

**对于 `psql` 15 及更早版本**

连接到 RDS for PostgreSQL 数据库实例，并在 psql 中使用 `\du` 命令：

```
postgres=> \du
                                                               List of roles
    Role name    |                         Attributes                         |                          Member of
-----------------+------------------------------------------------------------+------------------------------------------------------
 postgres        | Create role, Create DB                                    +| {rds_superuser}
                 | Password valid until infinity                              |
 rds_ad          | Cannot login                                               | {}
 rds_iam         | Cannot login                                               | {}
 rds_password    | Cannot login                                               | {}
 rds_replication | Cannot login                                               | {}
 rds_superuser   | Cannot login                                               | {pg_monitor,pg_signal_backend,rds_password,rds_replication}
 rdsadmin        | Superuser, Create role, Create DB, Replication, Bypass RLS+| {}
                 | Password valid until infinity                              |
```

**对于 `psql` 16 及更高版本**

```
postgres=> \drg+
                             List of role grants
   Role name   |          Member of          |       Options       | Grantor
---------------+-----------------------------+---------------------+----------
 postgres      | rds_superuser               | INHERIT, SET        | rdsadmin
 rds_superuser | pg_checkpoint               | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | pg_monitor                  | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | pg_signal_backend           | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | pg_use_reserved_connections | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | rds_password                | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | rds_replication             | ADMIN, INHERIT, SET | rdsadmin
```

要检查没有版本依赖关系的角色成员资格，可以使用以下 SQL 查询：

```
SELECT m.rolname AS "Role name", r.rolname AS "Member of"
FROM pg_catalog.pg_roles m
JOIN pg_catalog.pg_auth_members pam ON (pam.member = m.oid)
LEFT JOIN pg_catalog.pg_roles r ON (pam.roleid = r.oid)
LEFT JOIN pg_catalog.pg_roles g ON (pam.grantor = g.oid)
WHERE m.rolname !~ '^pg_'
ORDER BY 1, 2;
```

在输出中，您可以看到 `rds_superuser` 不是数据库用户角色（无法登录），但它具有许多其他角色的权限。您还可以看到数据库用户 `postgres` 是 `rds_superuser` 角色的成员。如前所述，`postgres` 是 Amazon RDS 控制台的 **Create database**（创建数据库）页面中的默认值。如果您选择了另一个名称，则该名称将显示在角色列表中。

# 控制用户对 PostgreSQL 数据库的访问
<a name="Appendix.PostgreSQL.CommonDBATasks.Access"></a>

PostgreSQL 中的新数据库始终使用数据库 `public` 架构中的一组默认权限创建，允许所有数据库用户和角色创建对象。例如，这些权限使数据库用户能够连接数据库，并在连接后创建临时表格。

为了更好地控制用户对您在 RDS for PostgreSQL 数据库实例上创建的数据库实例的访问，我们建议您撤消这些默认 `public` 权限。撤消后，您可以更精确地为数据库用户授权，如以下过程中所示。

**为新数据库实例设置角色和权限**

假设您正在新创建的 RDS for PostgreSQL 数据库实例上设置数据库，以供几位研究人员使用，他们都需要对数据库的读写访问权限。

1. 使用 `psql`（或 pgAdmin）连接到 RDS for PostgreSQL 数据库实例：

   ```
   psql --host=your-db-instance.666666666666.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

   出现提示时请输入密码。`psql` 客户端会建立连接并显示默认的管理连接数据库 `postgres=>`，作为提示符。

1. 要阻止数据库用户在 `public` 架构中创建对象，执行以下操作：

   ```
   postgres=> REVOKE CREATE ON SCHEMA public FROM PUBLIC;
   REVOKE
   ```

1. 接下来，创建一个新数据库实例：

   ```
   postgres=> CREATE DATABASE lab_db;
   CREATE DATABASE
   ```

1. 在这个新数据库上，撤消 `PUBLIC` 架构的所有权限。

   ```
   postgres=> REVOKE ALL ON DATABASE lab_db FROM public;
   REVOKE
   ```

1. 为数据库用户创建角色。

   ```
   postgres=> CREATE ROLE lab_tech;
   CREATE ROLE
   ```

1. 为具有此角色的数据库用户提供连接到数据库的能力。

   ```
   postgres=> GRANT CONNECT ON DATABASE lab_db TO lab_tech;
   GRANT
   ```

1. 向具有 `lab_tech` 角色的所有用户授予对此数据库的所有权限。

   ```
   postgres=> GRANT ALL PRIVILEGES ON DATABASE lab_db TO lab_tech;
   GRANT
   ```

1. 创建数据库用户，如下所示：

   ```
   postgres=> CREATE ROLE lab_user1 LOGIN PASSWORD 'change_me';
   CREATE ROLE
   postgres=> CREATE ROLE lab_user2 LOGIN PASSWORD 'change_me';
   CREATE ROLE
   ```

1. 向这两个用户授予与 lab\$1tech 角色关联的权限：

   ```
   postgres=> GRANT lab_tech TO lab_user1;
   GRANT ROLE
   postgres=> GRANT lab_tech TO lab_user2;
   GRANT ROLE
   ```

此时，`lab_user1` 和 `lab_user2` 可以连接到 `lab_db` 数据库。此示例未遵循企业使用的最佳实践，其中可能包括创建多个数据库实例、不同的架构和授予有限权限。有关更多完整信息和其他方案，请参阅[管理 PostgreSQL 用户和角色](https://aws.amazon.com/blogs//database/managing-postgresql-users-and-roles/)。

有关 PostgreSQL 数据库中特权的更多信息，请参阅 PostgreSQL 文档中的 [GRANT](https://www.postgresql.org/docs/current/static/sql-grant.html) 命令。

# 委托和控制用户密码管理
<a name="Appendix.PostgreSQL.CommonDBATasks.RestrictPasswordMgmt"></a>

作为 DBA，您可能需要委托用户密码的管理。或者，您可能希望防止数据库用户更改其密码或重新配置密码限制，例如密码生命周期。要确保只有您选择的数据库用户才能更改密码设置，可以启用受限密码管理特征。激活此特征时，只有那些已被授予 `rds_password` 角色的数据库用户可以管理密码。

**注意**  
要使用受限密码管理，您的 RDS for PostgreSQL 数据库实例必须运行 PostgreSQL 10.6 或更高版本。

默认情况下，此特征为 `off`，如下所示：

```
postgres=> SHOW rds.restrict_password_commands;
  rds.restrict_password_commands
--------------------------------
 off
(1 row)
```

要启用此特征，请使用自定义参数组并将 `rds.restrict_password_commands` 的设置更改为 1。一定要重新启动 RDS for PostgreSQL 数据库实例，此设置才能生效。

激活此特征后，以下 SQL 命令需要 `rds_password` 权限：

```
CREATE ROLE myrole WITH PASSWORD 'mypassword';
CREATE ROLE myrole WITH PASSWORD 'mypassword' VALID UNTIL '2023-01-01';
ALTER ROLE myrole WITH PASSWORD 'mypassword' VALID UNTIL '2023-01-01';
ALTER ROLE myrole WITH PASSWORD 'mypassword';
ALTER ROLE myrole VALID UNTIL '2023-01-01';
ALTER ROLE myrole RENAME TO myrole2;
```

如果密码使用 MD5 哈希算法，重命名角色 (`ALTER ROLE myrole RENAME TO newname`) 也会受到限制。

激活此特征后，在没有 `rds_password` 角色权限的情况下尝试这些 SQL 命令中的任何一个都会生成以下错误：

```
ERROR: must be a member of rds_password to alter passwords
```

我们建议您仅将 `rds_password` 授予少数几个仅用于密码管理的角色。如果您将 `rds_password` 权限授予没有 `rds_superuser` 权限的数据库用户，则还需要授他们 `CREATEROLE` 属性。

请确保您验证了密码要求，例如客户端上的过期时间以及所需的复杂性。如果您使用自己的客户端实用程序进行与密码相关的更改，则该实用程序需要是 `rds_password` 的成员并具有 `CREATE ROLE` 权限。

# 使用 SCRAM 进行 PostgreSQL 密码加密
<a name="PostgreSQL_Password_Encryption_configuration"></a>

在对密码进行加密时，*加盐质询响应身份验证机制（SCRAM）*是 PostgreSQL 的默认消息摘要（MD5）算法的替代方案。―般认为 SCRAM 身份验证机制比 MD5 更安全。要了解有关这两种不同的密码保护方法的更多信息，请参阅 PostgreSQL 文档中的[密码身份验证](https://www.postgresql.org/docs/14/auth-password.html)。

我们建议您使用 SCRAM 而不是 MD5 作为您的 RDS for PostgreSQL 数据库实例的密码加密方案。这是一种加密质询-响应机制，它使用 scram-sha-256 算法进行密码身份验证和加密。

要支持 SCRAM，您可能需要更新客户端应用程序的库。例如，42.2.0 之前的 JDBC 版本不支持 SCRAM。有关更多信息，请参阅 PostgreSQL JDBC 驱动程序文档中的 [PostgreSQL JDBC 驱动程序](https://jdbc.postgresql.org/changelogs/2018-01-17-42.2.0-release/)。有关其他 PostgreSQL 驱动程序和 SCRAM 支持的列表，请参阅 PostgreSQL 文档中的[驱动程序列表](https://wiki.postgresql.org/wiki/List_of_drivers)。

RDS for PostgreSQL 版本 13.1 和更高版本支持 scram-sha-256。这些版本还可让您将数据库实例配置为需要 SCRAM，如以下过程所述。

## 设置 RDS for PostgreSQL 数据库实例以要求使用 SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.preliminary"></a>

您可以要求 RDS for PostgreSQL 数据库实例仅接受使用 scram-sha-256 算法的密码。

**重要**  
对于带有 PostgreSQL 数据库的现有 RDS 代理，如果您将数据库身份验证修改为仅使用 `SCRAM`，代理将在长达 60 秒的时间内不可用。要避免此问题，请执行以下操作之一：  
确保数据库同时允许 `SCRAM` 和 `MD5` 身份验证。
要仅使用 `SCRAM` 身份验证，请创建一个新代理，将应用程序流量迁移到新代理，然后删除先前与数据库关联的代理。

在对系统进行更改之前，请务必了解完整的过程，如下所示：
+ 获取有关所有数据库用户的所有角色和密码加密的信息。
+ 仔细检查 RDS for PostgreSQL 数据库实例的参数设置，以了解用于控制密码加密的参数。
+ 如果您的 RDS for PostgreSQL 数据库实例使用默认参数组，您需要创建自定义数据库参数组，然后将其应用到您的 RDS for PostgreSQL 数据库实例，以便您可以在需要时修改参数。如果您的 RDS for PostgreSQL 数据库实例使用自定义参数组，您可以稍后根据需要在此过程中修改必要的参数。
+ 将 `password_encryption` 参数更改为 `scram-sha-256`。
+ 通知所有数据库用户他们需要更新密码。对您的 `postgres` 账户执行相同的操作。使用 scram-sha-256 算法对新密码进行加密和存储。
+ 验证是否使用加密类型对所有密码加密。
+ 如果所有密码都使用 scram-sha-256，您可以将 `rds.accepted_password_auth_method` 参数从 `md5+scram` 更改为 `scram-sha-256`。

**警告**  
仅将 `rds.accepted_password_auth_method` 更改为 scram-sha-256 之后，使用 `md5` 加密的密码的任何用户（角色）都将无法连接。

### 做好准备，以要求 RDS for PostgreSQL 数据库实例使用 SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.getting-ready"></a>

在对 RDS for PostgreSQL 数据库实例进行任何更改之前，检查所有现有的数据库用户账户。另外，请检查用于密码的加密类型。您可以使用 `rds_tools` 扩展来执行这些任务。要了解哪些 PostgreSQL 版本支持 `rds_tools`，请参阅 [Extension versions for Amazon RDS for PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html)。

**获取数据库用户（角色）和密码加密方法的列表**

1. 使用 `psql` 连接到 RDS for PostgreSQL 数据库实例，如下所示。

   ```
   psql --host=db-name.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

1. 安装 `rds_tools` 扩展。

   ```
   postgres=> CREATE EXTENSION rds_tools;
   CREATE EXTENSION
   ```

1. 获取角色和加密的列表。

   ```
   postgres=> SELECT * FROM 
         rds_tools.role_password_encryption_type();
   ```

   您将看到类似以下内容的输出。

   ```
          rolname        | encryption_type
   ----------------------+-----------------
    pg_monitor           |
    pg_read_all_settings |
    pg_read_all_stats    |
    pg_stat_scan_tables  |
    pg_signal_backend    |
    lab_tester           | md5
    user_465             | md5
    postgres             | md5
   (8 rows)
   ```

### 创建自定义数据库参数组
<a name="PostgreSQL_Password_Encryption_configuration.custom-parameter-group"></a>

**注意**  
如果您的 RDS for PostgreSQL 数据库实例已使用自定义参数组，您不需要创建新参数组。

有关 Amazon RDS 的参数组的概述，请参阅[在 RDS for PostgreSQL 数据库实例上使用参数](Appendix.PostgreSQL.CommonDBATasks.Parameters.md)。

用于密码的密码加密类型在一个参数（即 `password_encryption`）中设置。 RDS for PostgreSQL 数据库实例允许的加密在另一个参数 `rds.accepted_password_auth_method` 中设置。更改其中任何一个的默认值都要求您创建自定义数据库参数组，然后将其应用到您的实例。

也可以使用 AWS 管理控制台 或 RDS API 创建自定义数据库参数组。有关更多信息，请参阅。

现在可以将自定义参数组与数据库实例关联。

**创建自定义数据库参数组**

1. 使用 CLI 命令 `[create-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/create-db-parameter-group.html) ` 创建自定义数据库参数组。此示例使用 `postgres13` 作为此自定义参数组的来源。

   对于 Linux、macOS 或 Unix：

   ```
   aws rds create-db-parameter-group --db-parameter-group-name 'docs-lab-scram-passwords' \
     --db-parameter-group-family postgres13  --description 'Custom parameter group for SCRAM'
   ```

   对于：Windows

   ```
   aws rds create-db-parameter-group --db-parameter-group-name "docs-lab-scram-passwords" ^
     --db-parameter-group-family postgres13  --description "Custom DB parameter group for SCRAM"
   ```

1. 使用 CLI 命令 `[modify-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-instance.html)` 将此自定义参数组应用于 RDS for PostgreSQL 数据库集群。

   对于 Linux、macOS 或 Unix：

   ```
   aws rds modify-db-instance --db-instance-identifier 'your-instance-name' \
           --db-parameter-group-name "docs-lab-scram-passwords
   ```

   对于：Windows

   ```
   aws rds modify-db-instance --db-instance-identifier "your-instance-name" ^
           --db-parameter-group-name "docs-lab-scram-passwords
   ```

   要将 RDS for PostgreSQL 数据库实例与您的自定义数据库参数组重新同步，您需要重启集群的主实例和所有其他实例。为了尽量减少对用户的影响，请安排在常规维护时段内执行此操作。

### 配置密码加密以使用 SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.configure-password-encryption"></a>

RDS for PostgreSQL 数据库实例使用的密码加密机制在数据库参数组的 `password_encryption` 参数中设置。允许的值为未设置、`md5` 或 `scram-sha-256`。默认值取决于 RDS for PostgreSQL 版本，如下所示：
+ RDS for PostgreSQL 14 和更高版本 – 默认为 `scram-sha-256`
+ RDS for PostgreSQL 13 – 默认为 `md5`

使用附加到 RDS for PostgreSQL 数据库实例的自定义数据库参数组，您可以修改密码加密参数的值。

![\[接下来，RDS 控制台显示 RDS for PostgreSQL 的 password_encryption 参数的默认值。\]](http://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/UserGuide/images/rpg-pwd-encryption-md5-scram-1.png)


**将密码加密设置更改为 scram-sha-256**
+ 将密码加密的值更改为 scram-sha-256，如下所示。可以立即应用更改，因为参数是动态的，这样，无需重新启动即可使更改生效。

  对于 Linux、macOS 或 Unix：

  ```
  aws rds modify-db-parameter-group --db-parameter-group-name \
    'docs-lab-scram-passwords' --parameters 'ParameterName=password_encryption,ParameterValue=scram-sha-256,ApplyMethod=immediate'
  ```

  对于：Windows

  ```
  aws rds modify-db-parameter-group --db-parameter-group-name ^
    "docs-lab-scram-passwords" --parameters "ParameterName=password_encryption,ParameterValue=scram-sha-256,ApplyMethod=immediate"
  ```

### 将用户角色的密码迁移到 SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.migrating-users"></a>

您可以将用户角色的密码迁移到 SCRAM，如下所述。

**将数据库用户（角色）密码从 MD5 迁移到 SCRAM**

1. 以管理员用户身份（默认用户名 `postgres`）登录，如下所示。

   ```
   psql --host=db-name.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

1. 通过使用以下命令，在 RDS for PostgreSQL 数据库实例上检查 `password_encryption` 参数的设置。

   ```
   postgres=> SHOW password_encryption;
    password_encryption
   ---------------------
    md5
    (1 row)
   ```

1. 将此参数的值更改为 scram-sha-256。有关更多信息，请参阅 [配置密码加密以使用 SCRAM](#PostgreSQL_Password_Encryption_configuration.configure-password-encryption)。

1.  再次检查该值，以确保它现在已设置为 `scram-sha-256`，如下所示。

   ```
   postgres=> SHOW password_encryption;
    password_encryption
   ---------------------
    scram-sha-256
    (1 row)
   ```

1. 通知所有数据库用户更改其密码。请确保还要更改您自己的用于 `postgres` 账户的密码（具有 `rds_superuser` 权限的数据库用户）。

   ```
   labdb=> ALTER ROLE postgres WITH LOGIN PASSWORD 'change_me';
   ALTER ROLE
   ```

1. 对于您的 RDS for PostgreSQL 数据库实例上的所有数据库重复此过程。

### 更改参数以要求使用 SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.require-scram"></a>

这是该过程的最后一步。在以下过程中进行更改后，任何仍对密码使用 `md5` 加密的用户账户（角色）都将无法登录到 RDS for PostgreSQL 数据库实例。

`rds.accepted_password_auth_method` 指定 RDS for PostgreSQL 数据库实例在登录过程中接受的用户密码加密方法。默认值为 `md5+scram`，这意味着可以接受任一种方法。在下面的图中，您可以找到此参数的默认设置。

![\[RDS 控制台显示 rds.accepted_password_auth_method 参数的默认值和允许的值。\]](http://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/UserGuide/images/pwd-encryption-md5-scram-2.png)


此参数允许的值仅为 `md5+scram` 或 `scram`。如果将此参数值更改为 `scram`，则必须使用这种方法。

**更改参数值以要求对密码进行 SCRAM 身份验证**

1. 验证 RDS for PostgreSQL 数据库实例上所有数据库的所有数据库用户密码是否使用 `scram-sha-256` 进行密码加密。为此，查询 `rds_tools` 以获得角色（用户）和加密类型，如下所示。

   ```
   postgres=> SELECT * FROM rds_tools.role_password_encryption_type();
     rolname        | encryption_type
     ----------------------+-----------------
     pg_monitor           |
     pg_read_all_settings |
     pg_read_all_stats    |
     pg_stat_scan_tables  |
     pg_signal_backend    |
     lab_tester           | scram-sha-256
     user_465             | scram-sha-256
     postgres             | scram-sha-256
     ( rows)
   ```

1. 在您的 RDS for PostgreSQL 数据库实例中的所有数据库实例中重复此查询。

   如果所有密码都使用 scram-sha-256，您可以继续操作。

1. 将接受的密码身份验证的值更改为 scram-sha-256，如下所示。

   对于 Linux、macOS 或 Unix：

   ```
   aws rds modify-db-parameter-group --db-parameter-group-name 'docs-lab-scram-passwords' \
     --parameters 'ParameterName=rds.accepted_password_auth_method,ParameterValue=scram,ApplyMethod=immediate'
   ```

   对于：Windows

   ```
   aws rds modify-db-parameter-group --db-parameter-group-name "docs-lab-scram-passwords" ^
     --parameters "ParameterName=rds.accepted_password_auth_method,ParameterValue=scram,ApplyMethod=immediate"
   ```