喵星之旅-屯粮的松鼠-Docker PostgreSQL13 改密码异常记录

问题描述

单PG13容器、数据卷不清空、保留业务数据、本地免密+远程强制密码、改密码不生效、旧密码仍可登录、新密码远程报错全套问题根因与标准解决流程

环境基线:Docker PostgreSQL 13、持久化数据卷、Python3.6+Airflow(老旧psycopg2不支持SCRAM)、离线极简容器(无ip/ifconfig命令)

开始情况为docker内的pg用户密码强度不够,需要修改密码。正好遇到端口号问题。直接重建容器,保留数据卷。指定新端口和高强度密码。

后续发现密码没有生效,进入容器修改密码,全程无报错,但是经测试验证失败。

核心问题总览(本次所有故障现象)

现象1:执行 ALTER USER 改密码看似成功,远程旧密码依然能登录、新密码报错
现象2:仅单独执行改密码语句不生效,不彻底
现象3:Docker 启动环境变量 POSTGRES_PASSWORD 修改无效
现象4:容器内裸psql可以免密登录,远程连接需要密码(业务所需配置)
现象5:Airflow 连接PG认证失败,SCRAM加密不兼容老旧驱动

最关键底层原理

Docker PG 环境变量只生效一次

POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_DB
仅在数据卷为空、首次初始化生效。

一旦挂载目录已有PG数据文件:无论重启/重建容器、怎么改环境变量,密码完全不变。

已有数据只能用 SQL 改密码,环境变量永久失效。

PG13 默认加密坑(新旧密码共存元凶)

PG13 默认加密:scram-sha-256

Airflow Python3.6 自带 psycopg2 不支持 SCRAM,只支持 MD5。

单独执行 ALTER USER 密码 的致命问题:
只改当前会话加密,未全局持久化
数据库仍然保留旧密码 SCRAM 哈希
新密码存为 SCRAM,老旧驱动不识别 → 新密码报错
旧哈希未覆盖 → 旧密码依然能登录

pg_hba.conf 认证规则优先级高于密码

如果外网规则为 trust:无视密码、新旧密码全部放行,改密码等于白改。

业务标准需求:本地socket免密、远程TCP强制密码

标准化正确改密码流程

适用:PG13、已有数据、不删库、保留业务、兼容Airflow

步骤1:进入容器本地免密登录

无需密码,直接本地socket登录:

1
docker exec -it 你的pg容器名 psql

步骤2:成套执行(必须全部执行,缺一不可)

1
2
3
4
5
6
7
8
9
10
11
12
-- 1. 全局永久修改加密方式为 md5(写入配置文件,重启不失效)
ALTER SYSTEM SET password_encryption = md5;

-- 2. 在线热重载,无需重启PG
SELECT pg_reload_conf();

-- 3. 覆盖更新密码,生成md5哈希,彻底清除旧scram哈希
ALTER USER postgres WITH PASSWORD '高强度新密码';

-- 4. 校验当前加密模式
SHOW password_encryption;
正确返回:md5

步骤3:验证密码哈希是否真正更新(核心校验)

1
2
3
4
SELECT rolname, rolpassword FROM pg_authid WHERE rolname='postgres';
✅ 正常:以 md5 开头
❌ 异常:以 SCRAM-SHA-256 开头(未修复完成)

严格验证方法(区分真假生效)

重点:裸psql本地登录不算验证!必须走TCP网络连接

  1. 本地免密验证(符合业务需求)

直接 psql 可登录 ✅

  1. 远程TCP验证(模拟Airflow/所有外部业务)
1
2
3
4
5
6
psql -U postgres -h 10.X.X.1 -p 5432 -W airflow
✅ 新密码登录成功
✅ 旧密码提示认证失败(彻底修复)
# ip需要查询机器具体ip,一般127也识别为本地,直接放行。必须验证错误密码登陆失败。
# 容器内万能查看IP
cat /etc/hosts

所有错误操作汇总

错误1:只执行单条改密码

1
ALTER USER postgres WITH PASSWORD 'xxx';

后果:加密模式未切换、旧哈希残留、新旧密码共存、远程报错

❌ 错误2:修改docker run 环境变量密码

已有数据卷完全无效

❌ 错误3:pg_hba 保留 trust 规则

后果:所有密码校验失效,任何人免密登录

❌ 错误4:仅会话级设置加密

1
SET password_encryption = md5;

仅当前窗口生效,全局不变,重启复原

最终根治总结

PG13改密码旧密码还能登、新密码报错,100%是未全局切换MD5加密导致新旧哈希共存;必须 ALTER SYSTEM 全局改加密 + 重载 + 重设密码,配合pg_hba远程md5校验,才能彻底修复。

文章目录
  1. 问题描述
  2. 核心问题总览(本次所有故障现象)
  3. 最关键底层原理
    1. Docker PG 环境变量只生效一次
    2. PG13 默认加密坑(新旧密码共存元凶)
    3. pg_hba.conf 认证规则优先级高于密码
  4. 标准化正确改密码流程
  5. 严格验证方法(区分真假生效)
  6. 所有错误操作汇总
  7. 最终根治总结
|