这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

访问控制

Pigsty 提供的默认角色系统与权限模型

    Pigsty 提供了一套开箱即用的,基于角色系统权限系统的访问控制模型。

    权限控制很重要,但很多用户做不好。因此 Pigsty 提供了一套开箱即用的精简访问控制模型,为您的集群安全性提供一个兜底。


    角色系统

    Pigsty 默认的角色系统包含四个默认角色和四个默认用户

    角色名称属性所属描述
    dbrole_readonlyNOLOGIN角色:全局只读访问
    dbrole_readwriteNOLOGINdbrole_readonly角色:全局读写访问
    dbrole_adminNOLOGINpg_monitor,dbrole_readwrite角色:管理员/对象创建
    dbrole_offlineNOLOGIN角色:受限的只读访问
    postgresSUPERUSER系统超级用户
    replicatorREPLICATIONpg_monitor,dbrole_readonly系统复制用户
    dbuser_dbaSUPERUSERdbrole_adminpgsql 管理用户
    dbuser_monitorpg_monitorpgsql 监控用户

    这些角色与用户的详细定义如下所示:

    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: 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。 该命令会在 template1postgres 数据库中执行,新创建的数据库会通过模板 template1 继承这些默认权限配置。

    也就是说,为了维持正确的对象权限,您必须用管理员用户来执行 DDL,它们可以是:

    1. {{ pg_dbsu }},默认为 postgres
    2. {{ pg_admin_username }},默认为 dbuser_dba
    3. 授予了 dbrole_admin 角色的业务管理员用户(通过 SET ROLE 切换为 dbrole_admin 身份)。

    使用 postgres 作为全局对象所有者是明智的。如果您希望以业务管理员用户身份创建对象,创建之前必须使用 SET ROLE dbrole_admin 来维护正确的权限。

    当然,您也可以在数据库中通过 ALTER DEFAULT PRIVILEGE FOR ROLE <some_biz_admin> XXX 来显式对业务管理员授予默认权限。


    数据库权限

    在 Pigsty 中,数据库(Database)层面的权限在数据库定义中被涵盖。

    数据库有三个级别的权限:CONNECTCREATETEMP,以及一个特殊的’权限’:OWNERSHIP

    - name: meta         # 必选,`name` 是数据库定义中唯一的必选字段
      owner: postgres    # 可选,数据库所有者,默认为 postgres
      allowconn: true    # 可选,是否允许连接,默认为 true。显式设置 false 将完全禁止连接到此数据库
      revokeconn: false  # 可选,撤销公共连接权限。默认为 false,设置为 true 时,属主和管理员之外用户的 CONNECT 权限会被回收
    
    • 如果 owner 参数存在,它作为数据库属主,替代默认的 {{ pg_dbsu }}(通常也就是postgres
    • 如果 revokeconnfalse,所有用户都有数据库的 CONNECT 权限,这是默认的行为。
    • 如果显式设置了 revokeconntrue
      • 数据库的 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 权限。