亚马逊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