31.9. 安全性#
用于复制连接的角色必须具有REPLICATION
属性(或为超级用户)。如果角色不具有SUPERUSER
和BYPASSRLS
,则发布者行安全策略可以执行。如果角色不信任所有表所有者,请在连接字符串中包含options=-crow_security=off
;如果表所有者随后添加行安全策略,该设置将导致复制停止,而不是执行策略。必须在pg_hba.conf
中配置角色的访问权限,并且它必须具有LOGIN
属性。
为了能够复制初始表数据,用于复制连接的角色必须对已发布表具有SELECT
权限(或为超级用户)。
要创建发布,用户必须在数据库中具有CREATE
权限。
要向发布中添加表,用户必须对该表具有所有权。要向发布中添加架构中的所有表,用户必须是超级用户。要创建发布以自动发布所有表或架构中的所有表,用户必须是超级用户。
目前没有对发布的权限。任何订阅(能够连接)都可以访问任何发布。因此,如果您打算通过使用行过滤器或列列表或不将整个表添加到发布中来对特定订阅者隐藏某些信息,请注意同一数据库中的其他发布可能会公开相同的信息。将来可能会向PostgreSQL中添加发布权限,以允许更细粒度的访问控制。
要创建订阅,用户必须具有pg_create_subscription
角色的特权以及数据库上的CREATE
特权。
订阅应用进程将在会话级别使用订阅所有者的特权运行。但是,在对特定表执行插入、更新、删除或截断操作时,它会切换到表所有者的角色并使用表所有者的特权执行操作。这意味着订阅所有者需要能够对拥有复制表的所有角色SET ROLE
。
如果订阅已配置为run_as_owner = true
,则不会发生用户切换。相反,所有操作都将使用订阅所有者的权限执行。在这种情况下,订阅所有者只需要对目标表具有SELECT
、INSERT
、UPDATE
和DELETE
特权,而不需要对表所有者SET ROLE
的特权。但是,这也意味着任何拥有正在进行复制的表的用户都可以使用订阅所有者的特权执行任意代码。例如,他们可以通过简单地将触发器附加到他们拥有的其中一个表来执行此操作。由于通常不希望允许一个角色自由承担另一个角色的特权,因此除非数据库中的用户安全性无关紧要,否则应避免此选项。
在发布者上,仅在复制连接开始时检查一次特权,并且在读取每个更改记录时不会重新检查。
在订阅者上,在应用时会重新检查订阅所有者的特权以进行每次事务。如果在并发事务更改订阅所有权时工作进程正在应用事务,则当前事务的应用将在旧所有者的特权下继续进行。