Ongoing service disruptions
For the most recent update on ongoing service disruptions affecting the AWS Middle East (UAE) Region (ME-CENTRAL-1), refer to the AWS Health Dashboard. For information on AWS Service migration, see How do I migrate my services to another region?
如何在 Amazon RDS for PostgreSQL 中创建密码策略?
我想在 Amazon Relational Database Service (Amazon RDS) for PostgreSQL 中创建密码策略。
简短描述
默认情况下,Amazon RDS for PostgreSQL 不具有强制执行密码策略的功能。但是,您可以使用 PostgreSQL 钩子和可信语言扩展 (TLE) 扩展来扩展核心功能。要在创建或更改用户或角色的密码时自定义 PostgreSQL 处理密码的方式,请使用 passcheck 钩子。
**注意:**TLE 支持 Amazon RDS for PostgreSQL 版本 16.1 及更高版本、15.2 及更高版本、14.5 及更新版本以及 13.12 及更高版本的 Amazon RDS。有关详细信息,请参阅使用 PostgreSQL 的可信语言扩展的要求。
解决方法
**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI。
创建客户参数组并设置 TLE 扩展
完成以下步骤:
-
创建自定义参数组,然后将其关联到您的 Amazon RDS for PostgreSQL 实例。
**注意:**参数组更改将导致停机。使用维护时段来避免立即停机。 -
登录您的实例,运行以下查询,然后确认 shared_preload_libraries 参数已更新:
postgres=> SHOW shared_preload_libraries;shared_preload_libraries rdsutils,pg_tle,pg_stat_statements (1 row) postgres=> -
运行以下查询来创建 TLE 扩展:
CREATE EXTENSION pg_tle;**注意:**要设置和配置 pg_tle 扩展,您的数据库用户角色必须具有 rds_superuser 角色权限。
-
向您的 Amazon RDS for PostgreSQL 实例主用户授予 pgtle_admin 角色。如果您使用了默认用户,则这是 postgres 主用户:
GRANT pgtle_admin TO example-user;**注意:**将 example-user 替换为 Amazon RDS for PostgreSQL 实例主用户。
设置 passcheck 钩子
PostgreSQL passcheck 钩子检查 SQL 操作的密码,不允许用户设置 password_check.bad_passwords 表中列出的密码。passcheck 钩子还会检查密码长度并确认密码包含大写和小写字母、数字和特殊字符。
**注意:**您可以根据自己的特定需求修改 PostgreSQL 钩子的函数。您可以将更多密码添加到 bad_passwords 表中,更改所需的密码长度,或者修改该函数以检查密码复杂性。
完成以下步骤:
-
运行以下 pgtle.install_extension SQL 命令。根据您的特定需求修改 SQL 代码:
SELECT pgtle.install_extension ( 'example-password-check-rules', '1.0', 'Do not let users use the 10 most commonly used passwords', $_pgtle_$ CREATE SCHEMA password_check; REVOKE ALL ON SCHEMA password_check FROM PUBLIC; GRANT USAGE ON SCHEMA password_check TO PUBLIC; CREATE TABLE password_check.bad_passwords (plaintext) AS VALUES ('123456'), ('password'), ('12345678'), ('qwerty'), ('123456789'), ('12345'), ('1234'), ('111111'), ('1234567'), ('dragon'); CREATE UNIQUE INDEX ON password_check.bad_passwords (plaintext); CREATE FUNCTION password_check.passcheck_hook(username text, password text, password_type pgtle.password_types, valid_until timestamptz, valid_null boolean) RETURNS void AS $$ DECLARE invalid bool := false; BEGIN -- Check password length IF length(password) < 8 THEN RAISE EXCEPTION 'Password must be at least 8 characters long.'; END IF; -- Check common passwords from password from bad_passwords table IF password_type = 'PASSWORD_TYPE_MD5' THEN SELECT EXISTS( SELECT 1 FROM password_check.bad_passwords bp WHERE ('md5' || md5(bp.plaintext || username)) = password ) INTO invalid; IF invalid THEN RAISE EXCEPTION 'Cannot use passwords from the common password dictionary'; END IF; ELSIF password_type = 'PASSWORD_TYPE_PLAINTEXT' THEN SELECT EXISTS( SELECT 1 FROM password_check.bad_passwords bp WHERE bp.plaintext = password ) INTO invalid; IF invalid THEN RAISE EXCEPTION 'Cannot use passwords from the common password dictionary'; END IF; END IF; -- Check password contains uppercase lowercase number and special character IF NOT (password ~ '[A-Z]' AND password ~ '[a-z]' AND password ~ '[0-9]' AND password ~ '[^a-zA-Z0-9]') THEN RAISE EXCEPTION 'Password must contain uppercase letters, lowercase letters, numbers, and special characters'; END IF; END $$ LANGUAGE plpgsql SECURITY DEFINER; GRANT EXECUTE ON FUNCTION password_check.passcheck_hook TO PUBLIC; SELECT pgtle.register_feature('password_check.passcheck_hook', 'passcheck'); $_pgtle_$);**注意:**在前面的命令中,将 example-password-check-rules 替换为密码检查规则的名称。
-
运行以下查询来创建扩展:
postgres=> CREATE EXTENSION "example-password-check-rules";**注意:**在前面的命令中,****将 example-password-check-rules 替换为密码检查规则的名称。
-
修改与您的实例关联的自定义参数组,然后启用 pgtle.enable_password_check 参数。
-
要测试您的密码检查规则,请使用以下示例。
示例:postgres=> CREATE ROLE t_role PASSWORD 'password';ERROR: Cannot use passwords from the common password dictionary CONTEXT: PL/pgSQL function password_check.passcheck_hook(text,text,pgtle.password_types,timestamp with time zone,boolean) line 25 at RAISE SQL statement "SELECT password_check.passcheck_hook($1::pg_catalog.text, $2::pg_catalog.text, $3::pgtle.password_types, $4::pg_catalog.timestamptz, $5::pg_catalog.bool)"**注意:**前面的示例表明存在错误,因为您无法使用通用密码词典中的密码。
示例:postgres=> CREATE ROLE t_role PASSWORD 'pass';ERROR: Password must be at least 8 characters long. CONTEXT: PL/pgSQL function password_check.passcheck_hook(text,text,pgtle.password_types,timestamp with time zone,boolean) line 7 at RAISE SQL statement "SELECT password_check.passcheck_hook($1::pg_catalog.text, $2::pg_catalog.text, $3::pgtle.password_types, $4::pg_catalog.timestamptz, $5::pg_catalog.bool)"**注意:**前面的示例表明存在错误,因为密码长度必须至少为 8 个字符。
示例:postgres=> CREATE ROLE t_role PASSWORD 'passwordd';ERROR: Password must contain uppercase letters, lowercase letters, numbers, and special characters CONTEXT: PL/pgSQL function password_check.passcheck_hook(text,text,pgtle.password_types,timestamp with time zone,boolean) line 31 at RAISE SQL statement "SELECT password_check.passcheck_hook($1::pg_catalog.text, $2::pg_catalog.text, $3::pgtle.password_types, $4::pg_catalog.timestamptz, $5::pg_catalog.bool)"**注意:**前面的示例表明存在错误,因为密码必须包含大写字母、小写字母、数字和特殊字符。
对于不支持 TLE 的 Amazon RDS for PostgreSQL 版本,使用 AWS Identity and Access Management (IAM) for Amazon RDS 或 Kerberos 身份验证。此外,要将密码创建限制为一组角色或特定角色,请参阅委托和控制用户密码管理。
