花拾录
← 返回知识库

PostgreSQL 用错密码也能连上:官方镜像对回环地址默认是 trust

数据库导入2026/09/220 阅读0 评论

你在测试环境验证数据库认证是否正常,故意输了个错密码——结果连上了。不是记错了密码,而是认证压根没生效。

现象

用错误的密码执行 PostgreSQL 连接,居然成功了:

psql -h 127.0.0.1 -U postgres -d mydb
# 提示 Password: 随便输一个错的
# 进去了

进去执行 select 1 也正常返回。看起来密码认证形同虚设,安全配置完全没有起作用。

这种问题特别容易被"顺手忽略"——因为你本来就是奔着"能连上"去的,输对密码进去是预期结果,根本不会怀疑"其实我输错也能进"。

反过来也值得警惕:如果你从另一台机器用错密码连,可能会被拒绝。这说明"本机能连、外网连不上"并不代表安全——很可能是两套规则分别起了作用,本机那条恰恰是最宽松的。

根因

问题在官方镜像的默认认证配置(pg_hba.conf)。

pg_hba.conf 是 PostgreSQL 的主机认证配置,它按行定义"什么来源、什么用户、什么数据库、用什么认证方式"。官方 Docker 镜像的默认配置里有这么几行:

# TYPE  DATABASE  USER  ADDRESS       METHOD
host    all       all   127.0.0.1/32  trust
host    all       all   ::1/128       trust

trust 的含义是"无条件信任"——只要连接来自这个地址,就直接放行,根本不校验密码。

所以当你从本机(127.0.0.1)用 TCP 连接时,命中的是 trust 规则,密码字段填什么都会被忽略。这就是"用错密码也能连上"的原因。

注意 trust 只按来源地址判断,跟用户名、库名无关——也就是说,本机上任何知道库名的人都能免密进库。这一点在共享主机或多容器共用网络的环境里尤其危险。

官方镜像这么配是为了"开箱即用"——开箱就能连、不阻塞你,代价是默认不设防。而且这个默认值很隐蔽:你去看配置文件就看到了,但很少有人会想到去看。

还有一点要留意:pg_hba.conf 是按顺序逐行匹配、命中即停的。如果前面有一行 trust 覆盖了你的来源地址,后面即使写了 scram-sha-256 也不会生效。所以排查"密码为什么不管用"时,关键是找到实际命中的那一行,而不是看有没有加密配置。

解决

第一步,编辑 pg_hba.conf,把本机回环的两行从 trust 改成 scram-sha-256:

# TYPE  DATABASE  USER  ADDRESS       METHOD
host    all       all   127.0.0.1/32  scram-sha-256
host    all       all   ::1/128       scram-sha-256

第二步,重新加载配置(不需要重启数据库):

select pg_reload_conf();

这一步一定要做,否则改了文件不生效——很多"改了没用"的问题就出在这。

第三步,做双向验证。

# 正确密码应成功
PGPASSWORD='<密码>' psql -h 127.0.0.1 -U postgres -d mydb -c 'select 1'

# 错误密码必须失败(这一步才是真正验证了认证生效)
PGPASSWORD='wrong' psql -h 127.0.0.1 -U postgres -d mydb -c 'select 1'

关于 Unix socket: 可以保留 local 那行的 trust,方便本机维护(比如容器内免密进库做运维)。只锁 TCP 连接就够了——因为外部攻击者走的是 TCP,不是 socket。

延伸与预防

官方镜像的"开箱即用"往往意味着"默认不设防"——这是一条通用规律,不只适用于 PostgreSQL。Redis 默认无密码、MongoDB 默认无认证、Elasticsearch 早期默认无认证,都是同一个模式。

拿到任何官方镜像,先花两分钟看一遍它的默认认证 / 授权配置。

还有一个更重要的方法论:安全配置改完后一定要做一次"负向验证"。

  • 正向验证:用正确凭据能连上 → 证明"能用";
  • 负向验证:用错误凭据连不上 → 才证明"设防了"。

只做正向验证是发现不了"没设防"的——因为没设防的时候,正向验证同样通过。这个区别值得记住。

顺带一条自查手段:想快速确认当前连接是被哪条规则放行的,可以看连接方式(socket 还是 TCP)。把这个动作加进"上线前检查清单",就不会再出现"以为设了密码其实没有"的情况。

再补一条部署习惯:把 pg_hba.conf 纳入版本管理(或至少写进部署文档),并在流水线里加一个"用错密码连不上"的断言。这样每次重建环境,都能自动验证认证没有被默认配置悄悄放过。

评论(0)

  • 还没有评论,来抢沙发~

相关文章