数据库Security

对象权限(Object Privileges)

在多用户数据库环境中,不同用户(或角色)对表、视图、函数等对象的访问权限不应相同。
PostgreSQL 通过对象权限机制来决定谁可以对哪些数据库对象执行哪些操作,包括防止未经授权的数据访问,控制数据修改,实现多层访问隔离。

不同对象类型拥有不同的权限类型:

  • PostgreSQL中常见的对象类型:表 (TABLE),视图 (VIEW),序列 (SEQUENCE),函数 (FUNCTION),数据库 (DATABASE),模式 (SCHEMA),外部服务器 (SERVER)。
  • 常见的权限类型CREATE,USAGE,EXECUTE,SELECT,UPDATE

权限的授予和回收

授予权限(GRANT)

语法:

1
GRANT 权限类型 ON 对象类型 对象名 TO 用户/角色 [WITH GRANT OPTION];

示例:

1
2
3
4
5
6
7
8
-- 允许用户 alice 查询 employees 表
GRANT SELECT ON employees TO alice;

-- 允许 bob 对 employees 表执行插入和更新
GRANT INSERT, UPDATE ON employees TO bob;

-- 允许 alice 将 SELECT 权限再授予别人,WITH GRANT OPTION 表示该用户可以把同样的权限再授予别人。
GRANT SELECT ON employees TO alice WITH GRANT OPTION;

回收权限(REVOKE)

语法:

1
REVOKE 权限列表 ON 对象类型 对象名 FROM 用户/角色 [CASCADE | RESTRICT];

示例:

1
2
3
4
5
-- 回收 bob 的 UPDATE 权限
REVOKE UPDATE ON employees FROM bob;

-- 回收 alice 的 SELECT 权限,并级联收回她授予他人的权限
REVOKE SELECT ON employees FROM alice CASCADE;

创建角色(ROLE)来管理权限

在 PostgreSQL 中,角色是管理数据库访问权限的实体,结合了用户和组的功能。角色可以拥有数据库对象并拥有权限,例如创建数据库或表的能力。角色可以配置登录功能(登录角色),也可以纯粹用于权限管理(组角色)。

PostgreSQl中,可以通过创建角色(Role)来统一管理 Linux用户 的权限。
可以减少操作量,不用一个个去授予权限。
失礼了:

1
2
3
4
5
6
7
8
-- 创建角色
CREATE ROLE readonly;

-- 给角色授予查询权限
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;

-- 将用户加入该角色
GRANT readonly TO alice, bob;

默认权限与所有权

对象所有者(Owner) 默认拥有该对象的所有权限,只有对象所有者或超级用户才能授予权限。

此外,还可以修改默认权限

1
2
3
4
-- 以后在 public 模式中新建的表都会自动授予 readonly 角色查询权限。
ALTER DEFAULT PRIVILEGES
IN SCHEMA public
GRANT SELECT ON TABLES TO readonly;

查看权限

psql中:

1
2
3
4
5
6
7
8
9
\z employees
-- 或
\dp employees
-- 输出示例
Access privileges
Schema | Name | Type | Access privileges
--------+------------+-------+-------------------------
public | employees | table | alice=arwdDxt/alice

其中的缩写对应的权限含义:a=INSERT, r=SELECT, w=UPDATE, d=DELETE, D=TRUNCATE, x=REFERENCES, t=TRIGGER。


身份验证模型

PostgreSQL 的 身份验证模型(Authentication Model) 控制“谁能连接数据库、从哪里连接、用什么方式验证身份”,是整个数据库安全体系的第一道防线。

身份验证流程

1
2
3
4
5
6
7
8
客户端 → 服务器:请求连接(指定数据库名、用户名、主机)

服务器检查 pg_hba.conf 文件(决定是否允许连接 & 使用哪种验证方法)

服务器执行相应的认证方式(例如密码验证、信任验证、证书验证等)

验证通过 → 建立连接
验证失败 → 拒绝访问

控制核心在于:pg_hba.conf 文件。Host-Based Authentication(基于主机的认证)。

pg_hda.conf文件:

1
2
# TYPE  DATABASE  USER  ADDRESS       METHOD
host mydb alice 192.168.1.0/24 md5

注意:当客户端连接时,PostgreSQL 按照 pg_hba.conf 中的行 从上到下 匹配,因此,规则顺序非常重要!常见做法:把具体规则(如内网、特定用户)放上面,把通用规则放下面。

主要身份验证方法(METHOD)

方式 说明 是否安全 典型场景
trust 无条件信任,不需要密码 ❌ 极不安全 本地测试环境
password 明文密码传输 ❌ 不推荐 已加密通道中(如 SSH 隧道)
md5 密码 MD5 散列传输 ✅ 较常用 一般生产环境
scram-sha-256 更安全的密码加密算法 ✅ 推荐 PostgreSQL 10+
peer 操作系统用户名匹配数据库用户名 ✅ 安全(本地连接) Linux 本地进程
ident 通过外部 ident 服务验证 ⚠️ 一般仅限受控环境 内网环境
cert 客户端提供 SSL 证书验证 ✅ 高安全性 企业级、银行、政府系统
ldap 使用 LDAP 目录服务验证 企业统一身份认证
radius 使用 RADIUS 服务器验证 大型组织集中认证
pam 使用 Linux PAM 模块认证 系统级安全环境

查看当前连接的认证信息

可以使用查询:

1
2
3
SELECT usename, client_addr, client_port, backend_type
FROM pg_stat_activity
WHERE pid = pg_backend_pid();

SSL(Secure Sockets Layer)

在 PostgreSQL 中,SSL(Secure Sockets Layer) 是一种用于加密数据库客户端与服务器之间通信的安全机制,服务器(甚至客户端)都可以使用证书验证对方身份,它确保了数据在网络传输过程中不会被窃听、篡改或伪造。

SSL工作过程:
客户端向服务器请求建立连接,服务器返回自己的 公钥证书(server.crt),客户端验证服务器证书是否可信,若验证通过,双方协商会话密钥,随后通信使用该密钥加密。

SSL 设置位于 postgresql.conf 文件中

行级安全性(Row-Level Security)

行级安全性(RLS) 是 PostgreSQL 提供的一种精细化访问控制机制,用于限制不同用户能访问表中哪些“行”。这相当于为表加上了“行过滤规则”,是对传统的表级、列级权限控制的进一步细化。

RLS能够实现同一个表中的不同行对不同用户显示不同的内容。

行级安全的使用

  1. 开启行级安全

    1
    ALTER TABLE employees ENABLE ROW LEVEL SECURITY;
  2. 定义访问策略(Policy)
    RLS 的核心是 策略(Policy),它定义了“允许谁访问哪些行”的规则。

语法:

1
2
3
4
5
6
CREATE POLICY policy_name
ON table_name
[ FOR { SELECT | INSERT | UPDATE | DELETE | ALL } ]
[ TO { role_name | PUBLIC } ]
USING (条件表达式) -- 控制 SELECT/UPDATE/DELETE 可见的行
[ WITH CHECK (条件表达式) ]; -- 控制 插入/更新 时,哪些行允许被写入
  1. 启用强制执行

创建策略后,还必须确保 PostgreSQL 启用了策略检查:

1
ALTER TABLE employees FORCE ROW LEVEL SECURITY;

这会让即使拥有 superuser 之外的用户也受策略约束(防止用户绕过策略)。

  • Copyrights © 2023-2025 Hexo

请我喝杯咖啡吧~

支付宝
微信