Docker部署Flask应用中PostgreSQL数据库遭意外删除及权限异常求助
排查步骤与解决方案
1. 立即阻断外部恶意访问
- 检查Docker Compose中PostgreSQL的端口映射:若配置为
ports: - "5432:5432",等于把数据库直接暴露到公网,是恶意扫描攻击的核心入口。 - 修正方式:将端口映射改为仅本地访问,如
ports: - "127.0.0.1:5432:5432";或直接删除ports字段,让PostgreSQL仅在Docker内部网络可见(Flask容器通过服务名db:5432访问)。 - 配置DigitalOcean防火墙:在Droplet防火墙规则中,严禁将5432端口开放给
0.0.0.0/0,仅允许本地或Docker内部网段访问。
2. 验证PostgreSQL权限与认证配置
- 进入PostgreSQL容器:
docker exec -it <postgres-container-name> psql -U postgres - 确认postgres用户超级权限:执行
SELECT rolname, rolsuper FROM pg_roles WHERE rolname='postgres';,若rolsuper值为t则权限正常。若仍提示权限不足,需排查是否攻击者篡改了权限配置,或应用连接用的不是postgres用户。 - 检查
pg_hba.conf:在容器内查看/var/lib/postgresql/data/pg_hba.conf,删除允许0.0.0.0/0的规则,仅保留Docker内部网段或本地连接的认证规则。示例配置:local all postgres trust local all all peer host all all 127.0.0.1/32 scram-sha-256 host all all 172.17.0.0/16 scram-sha-256 host all all ::1/128 scram-sha-256 - 挂载自定义
pg_hba.conf:在docker-compose.yml中添加卷映射,避免容器重建时使用被篡改的配置:volumes: - ./pg_hba.conf:/var/lib/postgresql/data/pg_hba.conf - db_data:/var/lib/postgresql/data
3. 排查Flask应用安全漏洞
- Web容器的恶意扫描日志说明应用可能存在漏洞(如SQL注入、未授权访问、后台弱口令等),攻击者可能通过Web端获取数据库权限后删除数据。
- 检查数据库连接配置:避免将postgres密码硬编码在代码中,或暴露在Web可访问路径下;改用.env文件存储敏感信息,通过Docker Compose读取。
- 创建最小权限数据库用户:禁止用postgres超级用户连接应用,创建仅拥有
expenses数据库读写权限的用户:CREATE USER expenses_user WITH PASSWORD 'your-strong-random-password'; GRANT ALL PRIVILEGES ON DATABASE expenses TO expenses_user; - 启用应用SQL审计:记录所有数据库操作语句,排查是否有来自Web端的恶意删除命令。
4. 彻底重置环境流程
- 清理所有关联资源:
docker-compose down -v(-v参数会删除所有挂载卷) - 检查并删除可疑Docker网络:
docker network ls列出所有网络,用docker network rm <network-name>删除无关网络。 - 生成强随机密码:用
openssl rand -hex 16生成postgres及应用数据库用户的密码,存入.env文件。 - 重启容器:
docker-compose up -d,启动后立即查看PostgreSQL日志,确认无异常认证尝试。
5. 长期防护措施
- 开启PostgreSQL审计日志:在
postgresql.conf中配置log_connections = on、log_disconnections = on、log_statement = 'all',便于追踪恶意操作。 - 使用Docker自定义内部网络:在docker-compose.yml中创建专属网络,让Flask与PostgreSQL仅在该网络内通信:
networks: app-internal: driver: bridge services: web: ... networks: - app-internal db: ... networks: - app-internal - 定期备份数据库:用定时任务(如cron)执行备份命令:
docker exec <postgres-container> pg_dump -U expenses_user expenses > backup-$(date +%Y%m%d).sql
内容的提问来源于stack exchange,提问作者John Cena
相关产品推荐
相关产品推荐

