文章目录
- 问题描述
- 使用场景
- 排查解决
- 修改已有的文件卷
- 使用SQL初始化
问题描述
- PostgreSQL使用docker虚拟化部署,使用docker-compose管理,配置了密码
- 部署在客户现场时,客户的安全扫描,反馈测到PostgreSQL数据库弱密码漏洞
- 查看docker-compose配置文件已经配置了密码,怀疑是扫描有问题,于是将暴露的ports5432屏蔽掉了,问题解决
- 因为一直在配置文件里给服务配置的是设置的数据库用户名密码,连接一直没问题,就没怀疑密码设置有问题
- 后来测试人员进行集成测试时,发现确实存在弱密码问题,用数据库连接工具连接,不需要输入密码
- PostgreSQL的密码设置没生效,不科学啊,我开始排查分析原因
使用场景
- 我们使用PostgreSQL作为业务数据库,存储我们的业务数据
- 有一部分比较小的客户,业务量较少,只提供一台机器部署项目。为了维护方便,我们将平台服务都放在docker里部署,使用docker-compose管理,PostgreSQL也放在docker里部署
- PostgreSQL的docker-compose配置如下:
postgresql:image: postgres:14.2container_name: postgresports:- 5432:5432volumes:- ./volumes/postgresql/:/var/lib/postgresql/data/- /etc/localtime:/etc/localtimeenvironment:- POSTGRES_USER=postgres- POSTGRES_PASSWORD=xxxxxxx- POSTGRES_HOST_AUTH_METHOD=md5- TZ=Asia/Shanghainetworks:- signal-networkrestart: always
- 原则上,是不建议使用docker部署数据库的,会限制数据库利用机器性能。使用动车客人部署,肯定需要将PostgreSQL的数据目录(
/var/lib/postgresql/data/
)映射到物理机上,保证容器关闭删除异常损坏等情况时数据不丢失,但这样会造成一些性能损耗 - 对于生产数据的备份问题,我们将映射出的数据目录每天凌晨(凌晨没有业务,几乎没有数据读写)定时压缩备份,全量备份,这些备份压缩文件,循环删除,只保留最近七天的
- 原则上至少应该备份到其他机器上,在没有多余机器时,才能备份在本机。如果客户需要迁移部署到不同机器,就可以直接拿最新一天的备份,在其他机器还原即可。
- 我们平台有一部分初始化数据,需要在部署时初始化库里面。为了减少部署复杂度,我们直接将一个初始化的数据目录一起部署
排查解决
-
知道存在弱密码漏洞时,我首先想到的是PostgreSQL的配置问题,因为默认就是不进行密码校验的
-
查看了配置文件
pg_hba.conf
,果然是默认配置,不做密码校验
-
如果按照正常情况下,PostgreSQL容器初始化时,会创建数据目录,按照配置创建用户名和密码
-
由于我们的数据目录文件夹非空,已经存在数据库,就会跳过初始化过程,就不会重新创建数据目录,也就没有设置密码
-
回忆起这份数据目录的来源,应该是在项目初期,还没有设置数据库密码时生成的
-
问题很明确了,一开始PostgreSQL的docker配置没设置密码,默认生成的文件目录也就没有密码。后面设置了密码,因为数据目录非空没有执行创建过程,导致密码设置没生效
-
此时有两种解决方式,一是修改已有的文件卷,增加密码校验;二是保持文件目录空,使用sql初始化库表和数据
修改已有的文件卷
- 在现有的初始化数据库基础上,启动容器
- 修改配置文件
pg_hba.conf
,增加密码校验 - 使用命令,设置用户密码(设置的密码要是docker-compose配置文件里设置的那个)
- 将此时的文件卷导出,作为初始数据库
- 问题:此时密码校验是生效的,但是如果想修改初始数据库的密码,在配置文件里修改是没用的,要重新把设置用户密码和导出的流程走一遍
使用SQL初始化
- 将原有的数据目录置空,在数据库的docker容器创建启动时,进行初始化,会自动生成文件
- 然后在容器启动后,执行初始化脚本,创建数据库,创建表,初始化数据
- 要想执行脚本,脚本必须能由docker访问到才可以,可以将这些sql文件和sh文件,放到映射出来的文件目录里
- 需要注意的是,这些脚本,要等容器创建完成后再移动到数据目录下,不然无法完成初始化