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

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 跟我来学如何保护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选项提示输入密码。
  1. 修改用户密码时
  • 使用 pg_md5 工具生成密码,并在 psql 中用 ALTER ROLE 填入生成的 md5 值。
  1. 使用域认证或第三方认证
    密码策略交由第三方管理,避免在数据库中直接管理密码。

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 的使用权限。

应用账号最容易暴露,也是最危险的。其权限越大,应用程序被攻击后的破坏性越大。

授予应用账号 SELECTINSERTUPDATEDELETE 以及函数的 EXECUTE 权限,严控 DROPTRUNCATEREPLACE 等权限。

通过列权限或视图限制应用账号权限。

  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、异地容灾,如流复制

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
10天前
|
关系型数据库 分布式数据库 数据库
开源云原生数据库PolarDB PostgreSQL 15兼容版本正式发布
PolarDB进行了深度的内核优化,从而实现以更低的成本提供商业数据库的性能。
|
1月前
|
存储 Ubuntu 关系型数据库
如何创建数据库 PostgreSQL
【8月更文挑战第12天】
38 4
如何创建数据库 PostgreSQL
|
22天前
|
关系型数据库 MySQL Linux
在Linux中,如何配置数据库服务器(如MySQL或PostgreSQL)?
在Linux中,如何配置数据库服务器(如MySQL或PostgreSQL)?
|
6天前
|
关系型数据库 数据库 网络虚拟化
Docker环境下重启PostgreSQL数据库服务的全面指南与代码示例
由于时间和空间限制,我将在后续的回答中分别涉及到“Python中采用lasso、SCAD、LARS技术分析棒球运动员薪资的案例集锦”以及“Docker环境下重启PostgreSQL数据库服务的全面指南与代码示例”。如果你有任何一个问题的优先顺序或需要立即回答的,请告知。
16 0
|
30天前
|
存储 Ubuntu 关系型数据库
如何在 Ubuntu VPS 上备份 PostgreSQL 数据库
如何在 Ubuntu VPS 上备份 PostgreSQL 数据库
16 1
|
1月前
|
关系型数据库 数据库 PostgreSQL
Linux 环境手动备份postgresql数据库
【8月更文挑战第12天】在Docker环境中使用命令行工具对PostgreSQL数据库进行备份和恢复。首先,通过dockerexec进入容器,使用pg_dump进行数据库模式的备份,然后使用dockercp将备份文件导出。接着,若需导入数据到另一数据库,先将备份文件复制到目标容器,再利用psql命令进行数据恢复。整个过程需确保目标数据库无同名模式,以防止导入失败
24 3
|
2月前
|
JavaScript 关系型数据库 API
Nest.js 实战 (二):如何使用 Prisma 和连接 PostgreSQL 数据库
这篇文章介绍了什么是Prisma以及如何在Node.js和TypeScript后端应用中使用它。Prisma是一个开源的下一代ORM,包含PrismaClient、PrismaMigrate、PrismaStudio等部分。文章详细叙述了安装PrismaCLI和依赖包、初始化Prisma、连接数据库、定义Prisma模型、创建Prisma模块的过程,并对比了Prisma和Sequelize在Nest.js中的使用体验,认为Prisma更加便捷高效,没有繁琐的配置。
Nest.js 实战 (二):如何使用 Prisma 和连接 PostgreSQL 数据库
|
14天前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
81 0
|
22天前
|
SQL 关系型数据库 数据库
手把手教你管理PostgreSQL数据库及其对象
手把手教你管理PostgreSQL数据库及其对象
21 0
|
29天前
|
关系型数据库 MySQL 数据库
探究数据库开源协议:PostgreSQL vs MySQL
探究数据库开源协议:PostgreSQL vs MySQL