亚马逊AWS官方博客
新功能 — Amazon Aurora 和 Amazon RDS 上适用于 PostgreSQL 的 Trusted Language Extensions
PostgreSQL 凭借其面向开发者的可扩展设计,已成为许多企业和初创企业首选的开源关系数据库。开发人员使用 PostgreSQL 的原因之一是,通过使用自己喜欢的编程语言,他们可以构建扩展来添加数据库功能。
您已经可以在 Amazon Aurora PostgreSQL 兼容版和适用于 PostgreSQL 的 Amazon Relational Database Service 中安装并使用 PostgreSQL 扩展。我们在 Amazon Aurora 和 Amazon RDS 中支持超过 85 个 PostgreSQL 扩展,例如用于记录数据库活动的 pgAudit
扩展。虽然许多工作负载都使用这些扩展,但客户要求灵活地为 PostgreSQL 数据库实例构建和运行他们选择的扩展。
今天,我们宣布正式推出适用于 PostgreSQL 的 Trusted Language Extensions (pg_tle
),这是一款用于构建 PostgreSQL 扩展的新开源开发工具包。借助适用于 PostgreSQL 的 Trusted Language Extensions,开发人员可以构建在 PostgreSQL 上安全运行的高性能扩展。
采用适用于 PostgreSQL 的 Trusted Language Extensions,数据库管理员可以控制谁可以安装扩展以及运行扩展的权限模型,让应用程序开发人员在确定扩展程序满足其需求后立即提供新功能。
要开始使用 Trusted Language Extensions 进行构建,您可以使用可信语言,例如 JavaScript、Perl 和 PL/pgSQL。这些可信语言具有安全属性,包括限制直接访问文件系统和防止不必要的权限升级。您可以轻松地在 Amazon Aurora PostgreSQL 兼容版 14.5 和 Amazon RDS for PostgreSQL 14.5 或更高版本上安装用可信语言编写的扩展。
适用于 PostgreSQL 的 Trusted Language Extensions 是一个在 GitHub 上 Apache License 2.0 下获得许可的开源项目。您可以在适用于 PostgreSQL 的 Trusted Language Extensions 路线图上评论或提出建议,帮助我们支持跨多种编程语言的项目等。作为一个社区来做这件事将帮助开发者更容易使用 PostgreSQL 的最佳部分来构建扩展。
让我们探讨一下如何使用适用于 PostgreSQL 的 Trusted Language Extensions 为 Amazon Aurora 和 Amazon RDS 构建新的 PostgreSQL 扩展。
设置适用于 PostgreSQL 的 Trusted Language Extensions
要将 pg_tle
与 Amazon Aurora 一起使用,或者使用 Amazon RDS for PostgreSQL,您需要设置一个参数组,在 PostgreSQL shared_preload_libraries
设置中加载 pg_tle
。在 Amazon RDS 控制台的左侧导航窗格中选择参数组,然后选择创建参数组以创建新的参数组。
在参数组系列中选择 postgres14
和 Amazon RDS for PostgreSQL,并在组名中选择 pg_tle 后,选择创建。您可以为 Amazon Aurora PostgreSQL 兼容版的集群选择 aurora-postgresql14
。
选择已创建的 pgtle
参数组,然后在参数组操作下拉菜单中选择编辑。您可以在搜索框中搜索 shared_preload_library
,然后选择编辑参数。您可以添加首选值,包括 pg_tle
,然后选择保存更改。
您也可以在 AWS 命令行界面 (AWS CLI) 中执行同样的任务。
$ aws rds create-db-parameter-group \
--region us-east-1 \
--db-parameter-group-name pgtle \
--db-parameter-group-family aurora-postgresql14 \
--description "pgtle group"
$ aws rds modify-db-parameter-group \
--region us-east-1 \
--db-parameter-group-name pgtle \
--parameters "ParameterName=shared_preload_libraries,ParameterValue=pg_tle,ApplyMethod=pending-reboot"
现在,您可以将 pgtle
参数组添加到 Amazon Aurora 或 Amazon RDS for PostgreSQL 数据库中。如果您有一个名为 testing-pgtle
的数据库实例,则可以使用以下命令将 pgtle
参数组添加到数据库实例中。请注意,这将导致活动实例重启。
$ aws rds modify-db-instance \
--region us-east-1 \
--db-instance-identifier testing-pgtle \
--db-parameter-group-name pgtle-pg \
--apply-immediately
验证 pg_tle
库在 Amazon Aurora 或 Amazon RDS for PostgreSQL 实例上是否可用。在您的 PostgreSQL 实例上运行以下命令:
SHOW shared_preload_libraries;
pg_tle
应该出现在输出中。
现在,我们需要在当前的数据库中创建 pg_tle
扩展来运行这个命令:
CREATE EXTENSION pg_tle;
现在,您可以在当前数据库中创建和安装适用于 PostgreSQL 的 Trusted Language Extensions。如果您创建了新的扩展,则应使用以下命令将 pgtle_admin
角色授予您的主要用户(例如 postgres
):
GRANT pgtle_admin TO postgres;
现在让我们看看如何创建我们的第一个 pg_tle
扩展!
构建适用于 PostgreSQL 的 Trusted Language Extension
在这个示例中,我们将构建一个 pg_tle 扩展来验证用户是否没有设置常见密码字典中的密码。许多团队都对密码的复杂性制定了规则,特别是对于数据库用户而言。PostgreSQL 允许开发人员使用 check_password_hook
帮助强制执行密码复杂性。
在此示例中,您将使用 PL/pgSQL 构建密码检查挂钩。在挂钩中,您可以查看用户提供的密码是否在包含 10 个最常用密码值的字典中:
SELECT pgtle.install_extension (
'my_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
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 'password must not be found on a 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 'password must not be found on a common password dictionary';
END IF;
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_$
);
您需要通过 pgtle.enable_password_check
配置参数启用挂钩。在 Amazon Aurora 和 Amazon RDS for PostgreSQL 上,您可以使用以下命令来实现:
$ aws rds modify-db-parameter-group \
--region us-east-1 \
--db-parameter-group-name pgtle \
--parameters "ParameterName=pgtle.enable_password_check,ParameterValue=on,ApplyMethod=immediate"
这些更改可能需要几分钟才能传送。您可以使用 SHOW 命令检查该值是否已设置:
SHOW pgtle.enable_password_check;
如果该值启用,您将看到以下输出:
pgtle.enable_password_check
-----------------------------
on
现在您可以在当前的数据库中创建扩展,尝试将密码设置为字典中的一个密码,然后观察挂钩是如何拒绝的:
CREATE EXTENSION my_password_check_rules;
CREATE ROLE test_role PASSWORD '123456';
ERROR: password must not be found on a common password dictionary
CREATE ROLE test_role;
SET SESSION AUTHORIZATION test_role;
SET password_encryption TO 'md5';
\password
-- set to "password"
ERROR: password must not be found on a common password dictionary
要禁用挂钩,请将 pgtle.enable_password_check
的值设置为 off
:
$ aws rds modify-db-parameter-group \
--region us-east-1 \
--db-parameter-group-name pgtle \
--parameters "ParameterName=pgtle.enable_password_check,ParameterValue=off,ApplyMethod=immediate"
您可以使用以下命令从数据库中卸载这个 pg_tle
扩展,防止其他人在 my_password_check_rules
上运行创建扩展
:
DROP EXTENSION my_password_check_rules;
SELECT pgtle.uninstall_extension('my_password_check_rules');
您可以找到更多扩展示例并尝试一下。要在本地 PostgreSQL 数据库中构建和测试 Trusted Language Extensions,可以在克隆存储库后使用我们的源代码进行构建。
加入我们的社区!
适用于 PostgreSQL 的 Trusted Language Extensions 社区向所有人开放。试一试,并向我们反馈您希望在未来版本中看到的内容。我们欢迎任何贡献,例如新功能、扩展示例、附加文档或 GitHub 中的任何错误报告。
要了解有关在 AWS Cloud 中使用适用于 PostgreSQL 的 Trusted Language Extensions 的更多信息,请参阅 Amazon Aurora PostgreSQL 兼容版和 Amazon RDS for PostgreSQL 文档。
尝试一下,请将反馈发送给 AWS re:Post for PostgreSQL 或通过常见的 AWS Support 联系人发送。
– Channy