访问控制
Module:
Categories:
权限控制很重要,但很多用户做不好。因此 Pigsty 提供了一套开箱即用的精简访问控制模型,为您的集群安全性提供一个兜底。
角色系统
Pigsty 默认的角色系统包含四个默认角色和四个默认用户:
角色名称 | 属性 | 所属 | 描述 |
---|---|---|---|
dbrole_readonly |
NOLOGIN |
角色:全局只读访问 | |
dbrole_readwrite |
NOLOGIN |
dbrole_readonly | 角色:全局读写访问 |
dbrole_admin |
NOLOGIN |
pg_monitor,dbrole_readwrite | 角色:管理员/对象创建 |
dbrole_offline |
NOLOGIN |
角色:受限的只读访问 | |
postgres |
SUPERUSER |
系统超级用户 | |
replicator |
REPLICATION |
pg_monitor,dbrole_readonly | 系统复制用户 |
dbuser_dba |
SUPERUSER |
dbrole_admin | pgsql 管理用户 |
dbuser_monitor |
pg_monitor | pgsql 监控用户 |
这些角色与用户的详细定义如下所示:
pg_default_roles: # 全局默认的角色与系统用户
- { name: dbrole_readonly ,login: false ,comment: role for global read-only access }
- { name: dbrole_offline ,login: false ,comment: role for restricted read-only access }
- { name: dbrole_readwrite ,login: false ,roles: [dbrole_readonly] ,comment: role for global read-write access }
- { name: dbrole_admin ,login: false ,roles: [pg_monitor, dbrole_readwrite] ,comment: role for object creation }
- { name: postgres ,superuser: true ,comment: system superuser }
- { name: replicator ,replication: true ,roles: [pg_monitor, dbrole_readonly] ,comment: system replicator }
- { name: dbuser_dba ,superuser: true ,roles: [dbrole_admin] ,pgbouncer: true ,pool_mode: session, pool_connlimit: 16 ,comment: pgsql admin user }
- { name: dbuser_monitor ,roles: [pg_monitor] ,pgbouncer: true ,parameters: {log_min_duration_statement: 1000 } ,pool_mode: session ,pool_connlimit: 8 ,comment: pgsql monitor user }
默认角色
Pigsty 中有四个默认角色:
- 业务只读 (
dbrole_readonly
): 用于全局只读访问的角色。如果别的业务想要此库只读访问权限,可以使用此角色。 - 业务读写 (
dbrole_readwrite
): 用于全局读写访问的角色,主属业务使用的生产账号应当具有数据库读写权限 - 业务管理员 (
dbrole_admin
): 拥有DDL权限的角色,通常用于业务管理员,或者需要在应用中建表的场景(比如各种业务软件) - 离线只读访问 (
dbrole_offline
): 受限的只读访问角色(只能访问 offline 实例,通常是个人用户,ETL工具账号)
默认角色在 pg_default_roles
中定义,除非您确实知道自己在干什么,建议不要更改默认角色的名称。
- { name: dbrole_readonly , login: false , comment: role for global read-only access } # 生产环境的只读角色
- { name: dbrole_offline , login: false , comment: role for restricted read-only access (offline instance) } # 受限的只读角色
- { name: dbrole_readwrite , login: false , roles: [dbrole_readonly], comment: role for global read-write access } # 生产环境的读写角色
- { name: dbrole_admin , login: false , roles: [pg_monitor, dbrole_readwrite] , comment: role for object creation } # 生产环境的 DDL 更改角色
默认用户
Pigsty 也有四个默认用户(系统用户):
- 超级用户 (
postgres
),集群的所有者和创建者,与操作系统 dbsu 名称相同。 - 复制用户 (
replicator
),用于主-从复制的系统用户。 - 监控用户 (
dbuser_monitor
),用于监控数据库和连接池指标的用户。 - 管理用户 (
dbuser_dba
),执行日常操作和数据库更改的管理员用户。
这4个默认用户的用户名/密码通过4对专用参数进行定义,并在很多地方引用:
pg_dbsu
:操作系统 dbsu 名称,默认为 postgres,最好不要更改它pg_dbsu_password
:dbsu 密码,默认为空字符串意味着不设置 dbsu 密码,最好不要设置。pg_replication_username
:postgres 复制用户名,默认为replicator
pg_replication_password
:postgres 复制密码,默认为DBUser.Replicator
pg_admin_username
:postgres 管理员用户名,默认为dbuser_dba
pg_admin_password
:postgres 管理员密码的明文,默认为DBUser.DBA
pg_monitor_username
:postgres 监控用户名,默认为dbuser_monitor
pg_monitor_password
:postgres 监控密码,默认为DBUser.Monitor
在生产部署中记得更改这些密码,不要使用默认值!
pg_dbsu: postgres # 数据库超级用户名,这个用户名建议不要修改。
pg_dbsu_password: '' # 数据库超级用户密码,这个密码建议留空!禁止dbsu密码登陆。
pg_replication_username: replicator # 系统复制用户名
pg_replication_password: DBUser.Replicator # 系统复制密码,请务必修改此密码!
pg_monitor_username: dbuser_monitor # 系统监控用户名
pg_monitor_password: DBUser.Monitor # 系统监控密码,请务必修改此密码!
pg_admin_username: dbuser_dba # 系统管理用户名
pg_admin_password: DBUser.DBA # 系统管理密码,请务必修改此密码!
如果您修改默认用户的参数,在 pg_default_roles
中修改相应的角色定义即可:
- { name: postgres ,superuser: true ,comment: system superuser }
- { name: replicator ,replication: true ,roles: [pg_monitor, dbrole_readonly] ,comment: system replicator }
- { name: dbuser_dba ,superuser: true ,roles: [dbrole_admin] ,pgbouncer: true ,pool_mode: session, pool_connlimit: 16 , comment: pgsql admin user }
- { name: dbuser_monitor ,roles: [pg_monitor, dbrole_readonly] ,pgbouncer: true ,parameters: {log_min_duration_statement: 1000 } ,pool_mode: session ,pool_connlimit: 8 ,comment: pgsql monitor user }
权限系统
Pigsty 拥有一套开箱即用的权限模型,该模型与默认角色一起配合工作。
- 所有用户都可以访问所有模式。
- 只读用户(
dbrole_readonly
)可以从所有表中读取数据。(SELECT,EXECUTE) - 读写用户(
dbrole_readwrite
)可以向所有表中写入数据并运行 DML。(INSERT,UPDATE,DELETE)。 - 管理员用户(
dbrole_admin
)可以创建对象并运行 DDL(CREATE,USAGE,TRUNCATE,REFERENCES,TRIGGER)。 - 离线用户(
dbrole_offline
)类似只读用户,但访问受到限制,只允许访问离线实例(pg_role = 'offline'
或pg_offline_query = true
) - 由管理员用户创建的对象将具有正确的权限。
- 所有数据库上都配置了默认权限,包括模板数据库。
- 数据库连接权限由数据库定义管理。
- 默认撤销
PUBLIC
在数据库和public
模式下的CREATE
权限。
对象权限
数据库中新建对象的默认权限由参数 pg_default_privileges
所控制:
- GRANT USAGE ON SCHEMAS TO dbrole_readonly
- GRANT SELECT ON TABLES TO dbrole_readonly
- GRANT SELECT ON SEQUENCES TO dbrole_readonly
- GRANT EXECUTE ON FUNCTIONS TO dbrole_readonly
- GRANT USAGE ON SCHEMAS TO dbrole_offline
- GRANT SELECT ON TABLES TO dbrole_offline
- GRANT SELECT ON SEQUENCES TO dbrole_offline
- GRANT EXECUTE ON FUNCTIONS TO dbrole_offline
- GRANT INSERT ON TABLES TO dbrole_readwrite
- GRANT UPDATE ON TABLES TO dbrole_readwrite
- GRANT DELETE ON TABLES TO dbrole_readwrite
- GRANT USAGE ON SEQUENCES TO dbrole_readwrite
- GRANT UPDATE ON SEQUENCES TO dbrole_readwrite
- GRANT TRUNCATE ON TABLES TO dbrole_admin
- GRANT REFERENCES ON TABLES TO dbrole_admin
- GRANT TRIGGER ON TABLES TO dbrole_admin
- GRANT CREATE ON SCHEMAS TO dbrole_admin
由管理员新创建的对象,默认将会上述权限。使用 \ddp+
可以查看这些默认权限:
类型 | 访问权限 |
---|---|
函数 | =X |
dbrole_readonly=X | |
dbrole_offline=X | |
dbrole_admin=X | |
模式 | dbrole_readonly=U |
dbrole_offline=U | |
dbrole_admin=UC | |
序列号 | dbrole_readonly=r |
dbrole_offline=r | |
dbrole_readwrite=wU | |
dbrole_admin=rwU | |
表 | dbrole_readonly=r |
dbrole_offline=r | |
dbrole_readwrite=awd | |
dbrole_admin=arwdDxt |
默认权限
ALTER DEFAULT PRIVILEGES
允许您设置将来创建的对象的权限。 它不会影响已经存在对象的权限,也不会影响非管理员用户创建的对象。
在 Pigsty 中,默认权限针对三个角色进行定义:
{% for priv in pg_default_privileges %}
ALTER DEFAULT PRIVILEGES FOR ROLE {{ pg_dbsu }} {{ priv }};
{% endfor %}
{% for priv in pg_default_privileges %}
ALTER DEFAULT PRIVILEGES FOR ROLE {{ pg_admin_username }} {{ priv }};
{% endfor %}
-- 对于其他业务管理员而言,它们应当在执行 DDL 前执行 SET ROLE dbrole_admin,从而使用对应的默认权限配置。
{% for priv in pg_default_privileges %}
ALTER DEFAULT PRIVILEGES FOR ROLE "dbrole_admin" {{ priv }};
{% endfor %}
这些内容将会被 PG集群初始化模板 pg-init-template.sql
所使用,在集群初始化的过程中渲染并输出至 /pg/tmp/pg-init-template.sql
。
该命令会在 template1
与 postgres
数据库中执行,新创建的数据库会通过模板 template1
继承这些默认权限配置。
也就是说,为了维持正确的对象权限,您必须用管理员用户来执行 DDL,它们可以是:
{{ pg_dbsu }}
,默认为postgres
{{ pg_admin_username }}
,默认为dbuser_dba
- 授予了
dbrole_admin
角色的业务管理员用户(通过SET ROLE
切换为dbrole_admin
身份)。
使用 postgres
作为全局对象所有者是明智的。如果您希望以业务管理员用户身份创建对象,创建之前必须使用 SET ROLE dbrole_admin
来维护正确的权限。
当然,您也可以在数据库中通过 ALTER DEFAULT PRIVILEGE FOR ROLE <some_biz_admin> XXX
来显式对业务管理员授予默认权限。
数据库权限
在 Pigsty 中,数据库(Database)层面的权限在数据库定义中被涵盖。
数据库有三个级别的权限:CONNECT
、CREATE
、TEMP
,以及一个特殊的’权限’:OWNERSHIP
。
- name: meta # 必选,`name` 是数据库定义中唯一的必选字段
owner: postgres # 可选,数据库所有者,默认为 postgres
allowconn: true # 可选,是否允许连接,默认为 true。显式设置 false 将完全禁止连接到此数据库
revokeconn: false # 可选,撤销公共连接权限。默认为 false,设置为 true 时,属主和管理员之外用户的 CONNECT 权限会被回收
- 如果
owner
参数存在,它作为数据库属主,替代默认的{{ pg_dbsu }}
(通常也就是postgres
) - 如果
revokeconn
为false
,所有用户都有数据库的CONNECT
权限,这是默认的行为。 - 如果显式设置了
revokeconn
为true
:- 数据库的
CONNECT
权限将从PUBLIC
中撤销:普通用户无法连接上此数据库 CONNECT
权限将被显式授予{{ pg_replication_username }}
、{{ pg_monitor_username }}
和{{ pg_admin_username }}
CONNECT
权限将GRANT OPTION
被授予数据库属主,数据库属主用户可以自行授权其他用户连接权限。
- 数据库的
revokeconn
选项可用于在同一个集群间隔离跨数据库访问,您可以为每个数据库创建不同的业务用户作为属主,并为它们设置revokeconn
选项。
示例:数据库隔离
pg-infra:
hosts:
10.10.10.40: { pg_seq: 1, pg_role: primary }
10.10.10.41: { pg_seq: 2, pg_role: replica , pg_offline_query: true }
vars:
pg_cluster: pg-infra
pg_users:
- { name: dbuser_confluence, password: mc2iohos , pgbouncer: true, roles: [ dbrole_admin ] }
- { name: dbuser_gitlab, password: sdf23g22sfdd , pgbouncer: true, roles: [ dbrole_readwrite ] }
- { name: dbuser_jira, password: sdpijfsfdsfdfs , pgbouncer: true, roles: [ dbrole_admin ] }
pg_databases:
- { name: confluence , revokeconn: true, owner: dbuser_confluence , connlimit: 100 }
- { name: gitlab , revokeconn: true, owner: dbuser_gitlab, connlimit: 100 }
- { name: jira , revokeconn: true, owner: dbuser_jira , connlimit: 100 }
CREATE权限
出于安全考虑,Pigsty 默认从 PUBLIC
撤销数据库上的 CREATE
权限,从 PostgreSQL 15 开始这也是默认行为。
数据库属主总是可以根据实际需要,来自行调整 CREATE 权限。
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.