暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

跟我来学如何保护PostgreSQL数据库


一、认证安全

1、用户密码安全存储

如果 password_encryption=md5
,但创建用户时未使用 ENCRYPTED
,密码将以明文存储。
格式:

  1. CREATE ROLE name [WITH option [...]] [ENCRYPTED | UNENCRYPTED] PASSWORD 'password';

2、用户密码更换周期

使用合理的密码更换周期:

  • 示例:ALTER ROLE rep VALID UNTIL ‘2028-04-18 00:09:07’;

  • 配合 crontab 或监控工具进行密码到期提醒。

3、用户密码复杂度策略

确保已编译 passwordcheck,如未编译,请在源码的 contrib
 目录中编译。
创建或修改用户密码时,强制密码复杂度和唯一性:

  • 示例:限制密码长度、包含数字、字母、大小写、特殊字符,排除常见弱密码。

4、防止密码被记录到日志中

  1. 创建用户时

    • 使用createuser命令行工具中的-W选项提示输入密码。

  2. 修改用户密码时

    • 使用 pg_md5 工具生成密码,并在 psql 中用 ALTER ROLE 填入生成的 md5 值。

  3. 使用域认证或第三方认证
    密码策略交由第三方管理,避免在数据库中直接管理密码。

5、处理 pg_stat_statements 模块记录SQL或用户密码信息

创建用户和修改用户密码后,调用 pg_stat_statements_reset()清除记录的SQL;
或者配置 pg_stat_statements.track_utility=off,避免记录 DDL 语句。

6、客户端认证控制

pg_hba.conf 配置项(详见用户手册)
安全建议:

  • 禁用 trust 认证方法

  • 超级用户 postgres仅允许本地连接

  • 将 dbname、username、IP 限制到最小,授权用户只能从授权IP连接授权数据库

  • 使用最小权限范围,避免 all、0.0.0.0/0 等大范围授权

  • 密码更换周期

  • 使用 md5 认证,确保网络传输密码是 md5+随机字符 的加密密文

7、密码方式method认证过程的安全事项

未使用 SSL 时,避免使用 password 认证以防密码明文传输。
建议在 PG 13 以上版本中使用 SCRAM
 认证(推荐),否则使用 md5

延迟反馈密码错误消息,防止暴力破解和 DDoS 攻击。

二、数据加密

1、数据传输加密

使用加密传输,例如OPENSSL
示例:设置数据传输安全ssl
端口安全性 :
修改默认端口,防火墙策略 ,ssh隧道技术

2、字段存储加密

将敏感数据加密后存储在数据库中,即使数据泄露,只要加解密方法未泄露,也相对安全。
建议加解密方法放在应用端,或加密在数据库端,解密在应用端。pgcrypto 模块提供密码函数。
示例:使用 pgcrypto
 加密敏感数据。

  1. create extension pgcrypto;

  2. 计算hash值的函数。

  3. digest(data text, type text) returns bytea

  4. digest(data bytea, type text) returns bytea

  5. type为算法.支持 md5, sha1, sha224, sha256, sha384, sha512

  6. 如果编译postgresql时有了with-openssl选项, 则可以支持更多的算法。

三、权限控制

1、用户权限最小化

使用超级用户创建数据库、所需 schema、表、索引、函数。
创建应用账号,并赋予其数据库和 schema 的使用权限。
应用账号最容易暴露,也是最危险的。其权限越大,应用程序被攻击后的破坏性越大。
授予应用账号 SELECT
INSERT
UPDATE
DELETE
 以及函数的 EXECUTE
 权限,严控 DROP
TRUNCATE
REPLACE
 等权限。
通过列权限或视图限制应用账号权限。

  1. grant connect on database dbname to approle;

  2. grant usage on schema sch_name to approle;

2、回收数据库,schema,language,应用对象的public权限。

  1. revoke all on database dbname from public;

  2. revoke all on schema sch_name from public;

  3. revoke all on language plpgsql from public;

  4. revoke all on table ... from public;

  5. revoke all on function ... from public;

3、函数语言安全

回收函数语言的public权限,以及普通用户的权限,普通用户不能创建函数

  1. revoke all on language plpgsql from public;

  2. revoke all on language plpgsql from app_role;

4、行级安全RLS (Row Level Security)

限制普通用户只能操作符合特定条件的记录。
行级安全策略(9.5版本后新增),不同用户可以看到表中不同的数据,控制级别为行级。

  1. CREATE POLICY name ON table_name

  2. [ AS { PERMISSIVE | RESTRICTIVE } ]

  3. [ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ]

  4. [ TO { role_name | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] ]

  5. [ USING ( using_expression ) ]

  6. [ WITH CHECK ( check_expression ) ];

5、触发器控制

通过事件触发器禁止应用账号执行 DDL,防止被攻击后 DROP 或 TRUNCATE 删除对象或清空数据。
防止无条件的 DELETE、UPDATE,在需保护的表中新增一条 dummy 记录,并创建行触发器,当此记录被更新或删除时抛出异常。

四、防恶意攻击

1、视图攻击

用户利用PostgreSQL的优化器原理,创建成本极低的函数,在函数中获取视图限制外的隐藏内容。
如果用户没有创建函数的权限,用户就无法利用这个原理,或者使用安全栅栏来弥补。

2、密码暴力破解

目前可以通过密码错误延迟认证(auth_delay)来增加暴力破解需要的时间

3、防止普通用户通过陷阱进行攻击

参考文档《PostgreSQL 安全陷阱 - 利用触发器或规则,结合security invoker函数制造反噬陷阱》

4、防止SQL注入

应用层应该有SQL注入预防手段,例如使用简单的过滤器,使用绑定变量等手段。
以下攻击示例只要检查变量类型, 拒绝请求就不会有问题
statement := “SELECT FROM userinfo WHERE id = “ + a_variable + “;”
如果a_variable 不做任何判断, 传入 1;DROP TABLE users
那么SQL变成 :SELECT 
FROM userinfo WHERE id=1;DROP TABLE users;

五、安全审计

1、审计功能,一般是用于排查问题,也是一种举证的手段。

2、审计的主要通过记录日志来实现

3、审计功能建议考虑以下内容

跟踪 postgresql.conf
 配置变更:

  • 使用标准日志工具 log_statement = all

    跟踪表中记录被哪个用户修改或插入:

  • 使用 hstore
     插件和触发器。
    跟踪表的创建时间和定义修改时间:

  • 使用 pgAudit
     插件获取详细的会话和对象审计日志记录。

4、SQL审计

记录某DBA用户的所有SQL,并审计业务用户的DDL以减少日志输出。
配置 postgresql.conf
 参数 log_statement
 实现。
示例:记录某用户的所有SQL。

5、表对象的审计

PostgreSQL 可通过 log_statement=all
 实现日志审计,但不够详细。pgAudit
 扩展提供更详细的会话和对象审计日志。
注意:若删除并需重建 pgAudit
 扩展,必须先取消设置 pgaudit.log
,否则会报错。

6、会话或对象审计日志记录

对象触发器:权限限制,数据审计
在数据库应用中,需跟踪某些表的记录更改,如删除、增加、更新。跟踪信息包括:旧记录值、新记录值、变更时间、操作用户等。可用触发器实现跟踪。
使用 hstore
 类型存储变更前后的行信息,并利用 each
 函数方便提取原始值。

六、对象安全控制

1、约束:一般用于控制数据的安全,如 check (balance >=0)

2、视图和物化视图:一般被用于控制列或者值的被查询安全

3、查询列

4、条件筛选行

5、加密列

6、防范视图攻击

七、版本升级

PostgreSQL 社区更新频繁,几乎每天都有修复补丁、功能增强或性能提升。大家可以根据漏扫结果进行版本升级和加固。

  • 小版本升级:通常仅需跟随小版本升级。如有重大安全漏洞,补丁发布后会快速跟进小版本。若无发布小版本,说明无重大漏洞。

  • 大版本升级:包含大量新功能,需注意与应用相关的修改和模块更新。
    数据库升级分为两种:

  1. 小版本迭代

  2. 大版本(主版本)升级
    例如:PostgreSQL 14.12 中,14 是主要版本,12 是次要版本。

八、外界环境安全

当然这些一般不需要我们去操心,是云网管理员、应用管理员和主机管理员负责的。

1、应用程序是否安全?

2、中间件是否安全?

3、数据库所在操作系统是否安全?

4、数据库所在服务器是否安全?

5、存储安全,存储是否在安全的地方,有没有硬盘被拔掉的风险?

6、网络安全,如机架交换机,未插网线的端口是否禁用了,是否做了MAC地址过滤或绑定?

7、机房安全?

九、资源控制

1、 资源控制举例

  1. 控制连接数和活动连接数

  2. 限制 SQL 执行时间

  3. 限制锁等待时间

  4. 控制事务空闲时间

2、并发用户连接的限制

pg_hba.conf可严格限制地址,确保用户来源可信。

  • 配置用户最大并发连接数。

  • PostgreSQL 默认具有连接超时策略。

  • 配置参数 connect_timeout(秒计,十进制整数字符串)。

  • 0 或未指定表示无限等待。不建议使用低于 2 秒的超时时间。

十、可靠性参数优化建议

1、事务返回成功前,事务日志写入磁盘,synchronous_commit = on
能够保证数据的一致性,但是不能保证数据完全不丢失
2、fsync = on ,full_page_writes = on
3、存储Cache写机制write-through,write-back
关闭磁盘的write cache
只允许有断电保护的write cache
4、开启归档,并且有良好的备份策略
5、异地容灾,如流复制


文中的概念来源于网络,如有侵权,请联系我删除。

欢迎关注公众号:小周的数据库进阶之路,一起交流数据库、中间件和云计算等技术。欢迎觉得读完本文有收获,可以转发给其他朋友,大家一起学习进步!感兴趣的朋友可以加我微信,拉您进群与业界的大佬们一起交流学习。


文章转载自小周的数据库进阶之路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论