前言
PostgreSQL 中的权限设计略微复杂,属于层次结构,对于新手不太友好,老鸟也会经常云里雾里。举个栗子,假如你需要查询某一行数据的话,让我捋捋,你大概需要经过这么多层关卡:
- 先通过数据库防火墙
- 能够登录对应数据库 (LOGIN)
- 表所在数据库的连接权限 (CONNECT)
- 表所在模式的使用权限 (USAGE)
- 表本身的查看权限 (SELECT)
- 列级权限 (SELECT)
- 行级策略 (RLS)
实名劝退不少新手小白,还有角色 (ROLE)、用户 (USER)和组 (GROUP) 这些十分类似的概念,更不用说还可以角色嵌套 (套娃)了。关于权限我也写了不少文章:
今天向各位分享几个实用插件,简单易懂,快速上手,帮助各位轻松拿捏这个晕乎的权限体系。
权限查询
crunchy_check_access
第一个推荐的插件是 crunchy_check_access
Functions and views to facilitate PostgreSQL object access inspection
在 MySQL 中,如果要获取一个用户的所有权限,很方便,一条语句就可以搞定,但是在 PostgreSQL 中,很不幸,你需要拼接大量的表才能获取出可能并不完整的权限列表,crunchy_check_access 便可以解决这样的难题。
1 | postgres=# create extension check_access ; |
比如你想 postgres 用户对于表的相关权限
1 | postgres=# SELECT * FROM all_access() WHERE base_role = 'postgres' and objtype = 'table' limit 5;; |
对于库的相关权限
1 | postgres=# SELECT * FROM all_access() WHERE base_role = 'postgres' and objtype = 'database' limit 5; |
更多用法各位读者自行尝试吧,还是十分方便的!
pg_permissions
第二个插件是 pg_permissions
This extension allows you to review object permissions on a PostgreSQL database.
pg_permissions 支持权限对比,DBA 在管理权限时只需要在 permission_target 表中录入相应的权限,后期开发人员或 DBA 在开发阶段可能会随意的分配权限,比如权限超了,只需要查询结果还可以写入等,那么 DBA 只需要运行对比函数就能发现权限是否符合设计要求,防患于未然。
1 | postgres=# \dx+ pg_permissions |
权限对比参照它自己展示的例子即可:
1 | SELECT * FROM public.permission_diffs(); |
That means that
appuser
is missing theDELETE
privilege onappschema.apptable
which should be granted, while userlaurenz
has the additionalSELECT
privilege onappschema.appview
(missing
isFALSE
).
另外一个功能类似于 crunchy_check_access,可以查询某个用户的权限列表,对应于 *_permissions相对应的视图,比如
1 | postgres=# select * from table_permissions limit 2; |
灰常好用!
实用 SQL
如果各位觉得装插件麻烦的话,那有没有懒人专用的 SQL 呢?Sure!
1 | WITH server_permissions AS ( |
权限限制
set_user
原生 PostgreSQL 权限有很多”漏洞”,比如无法阻止 alter system,copy on program 搞破坏等等
This PostgreSQL extension allows switching users and optional privilege escalation with enhanced logging and control. It provides an additional layer of logging and control when unprivileged users must escalate themselves to superuser or object owner roles in order to perform needed maintenance tasks.
- The current effective user becomes
rolename
. - The role transition is logged, with a specific notation if
rolename
is a superuser. log_statement
setting is set to “all”, meaning every SQL statement executed while in this state will also get logged.- If
set_user.block_alter_system
is set to “on”,ALTER SYSTEM
commands will be blocked. - If
set_user.block_copy_program
is set to “on”,COPY PROGRAM
commands will be blocked. - If
set_user.block_log_statement
is set to “on”,SET log_statement
and variations will be blocked. - If
set_user.block_log_statement
is set to “on” androlename
is a database superuser, the currentlog_statement
setting is changed to “all”, meaning every SQL statement executed - If
set_user.superuser_audit_tag
is set, the string value will be appended tolog_line_prefix
upon superuser escalation. All logs after superuser escalation will be tagged with the value ofset_user.superuser_audit_tag
. This value defaults to'AUDIT'
. - If
set_user.exit_on_error
is set to “on”, the backend process will exit on ERROR during calls to set_session_auth(). - Post-execution hook for
set_user
is called if it is set.
这个插件就是提供了一些此类限制,还是十分简单的。
pg_restrict
pg_restrict 类似,多了个禁止删库这个操作,原生 PostgreSQL 是无法阻止删库的 (除非你设置为模板数据库)
pg_restrict.alter_system
(boolean): restrict ALTER SYSTEM command to master roles (pg_restrict.master_roles
parameter). Default is false.pg_restrict.copy_program
(boolean): restrict COPY … PROGRAM command to master roles (pg_restrict.master_roles
parameter). Default is false.pg_restrict.master_roles
(string): Roles that are allowed to execute the restricted commands. If there is more than one role, separate them with comma. Default is postgres.pg_restrict.nonremovable_databases
(string): restrict DROP databases listed here to a master role (even if the current role is the database owner or superuser). Default is postgres, template1, template0.pg_restrict.nonremovable_roles
(string): restrict DROP roles listed here to a master role (even if the current role has CREATEROLE privilege or is a superuser). Default is postgres.
pg_sulog
pg_sulog 主要针对的是超级用户,让超级用户也不能肆无忌惮的搞破坏了!但是很久不维护了,有点脱裤子放屁的味道,与其这样,还给超级用户的权限做什么。
- ‘BLOCK’, super user role’s all operation is blocked.
- ‘MAINTENANCE’, Other than the following commands, super user operation will be blocked.
- VACUUM, REINDEX, ANALYZE, CLUSTER
- ‘LOGGING’, super user role’s all operation is logged.
小结
权限还是需要多动手,多折腾几下,其实也就那么回事。