PostgreSQL 报 no pg_hba.conf entry?认证配置 pg_hba.conf 一次讲透

PostgreSQL 报 no pg_hba.conf entry?认证配置 pg_hba.conf 一次讲透

环境:PostgreSQL 16--18 通用 · 机制各版本一致 · 附生产模板

perl 复制代码
FATAL:  no pg_hba.conf entry for host "192.168.1.23", user "app", database "postgres"

先说结论:这个报错和密码对不对没有关系------PostgreSQL 根本没打算让你进门。守门的那个文件,就是 pg_hba.conf

它是数据库的第一道门,管三件事:谁能连、从哪连、怎么证明是自己。这篇把它的字段格式、匹配顺序、认证方法、生效机制一次讲透,最后给一份可以直接抄的生产模板。以 PostgreSQL 16--18 为例,机制各版本一致。

一、它在哪,管什么

文件在数据目录里,initdb 初始化时自动生成:

ini 复制代码
SHOW hba_file;

想放到别的位置,改 hba_file 参数(改它要重启)。

先划清管辖边界,很多人连不上时在这三个机制里来回打转:

  • 网络层listen_addresses(进程听哪个网卡)+ 防火墙/安全组------决定「包能不能到门口」;
  • 认证层pg_hba.conf------决定「到了门口放不放行、怎么核验身份」;
  • 权限层:角色与 GRANT------决定「进门之后能干什么」。

pg_hba.conf 只管中间那层。三层各有各的报错长相,第六节给对照表。

二、一条规则,五段式

sql 复制代码
# TYPE  DATABASE  USER      ADDRESS         METHOD
host    all       all       192.168.1.0/24  scram-sha-256

TYPE :连接类型。local 匹配 Unix 域套接字(本机 psql 默认走它),host 匹配 TCP/IP(含 SSL 与非 SSL);要按是否加密再细分,用 hostssl / hostnossl

DATABASEall(全部)、具体库名(逗号分隔可写多个)、sameuser(库名=用户名)、samerole(角色成员)、replication(物理复制专用,见坑 7)、/ 开头的正则、@文件(从文件读列表)。

USERall、具体用户、+组名(匹配该角色的直接和间接成员)、正则、@文件

ADDRESS :客户端来源,两种等价写法------CIDR 一段式(192.168.1.0/24),或 IP+掩码两列式(192.168.1.0 255.255.255.0)。单主机是 /320.0.0.0/0 匹配全部 IPv4;还有 all / samehost / samenet 三个关键字。local 行没有这一段。

METHOD:认证方法,下一节单独讲。

顺带@文件、正则、逗号列表这些写法,在规则多的库上比手写十几行 all 好维护得多------规则是给人读的,不是给机器读的。

三、第一匹配原则:顺序比规则本身更重要

整个文件最容易被低估的一条性质,官方文档写得干脆:每条连接尝试自上而下 扫描,第一条 TYPE、库、用户、地址都匹配的规则生效;没有「回落」------选中一条之后认证失败,后面的规则不会再被考虑;一条都不匹配,直接拒绝。

两个直接推论:

  1. 具体规则在前,宽泛规则在后。 官方示例就是「127.0.0.1/32 用 trust、大网段用密码」的排法------窄的先匹配,宽的兜后面。
  2. reject 是合法的卡口。 先用一行 reject 拒掉某个具体 IP,再放行它所在的网段,就能实现「网段放行、但排除一台」。

经典翻车现场:

错误顺序

css 复制代码
host    all    all    0.0.0.0/0           md5
host    all    all    192.168.1.0/24      scram-sha-256   ← 永远轮不到

第一行匹配一切来源,第二行永远不会被执行------它不是备胎,门禁没有备胎。

python 复制代码
# 正确顺序:窄在前,宽在后
host    all    all    192.168.1.0/24      scram-sha-256
host    all    all    0.0.0.0/0           md5

反过来同理:把 trust 的宽规则写在前面的任何位置,都等于把那之后的全部规则变成注释。

四、认证方法怎么选

方法 行为 适用
trust 无条件放行,不问密码 仅本机调试;生产禁用
reject 无条件拒绝 显式卡口、收尾兜底
scram-sha-256 SCRAM 挑战应答校验密码 首选;PG 14 起密码默认加密格式
md5 按密码存储格式自动走 SCRAM 或 MD5 只为兼容老客户端保留
password 明文传输密码 不可信网络禁用
peer 核对操作系统用户名(仅 local) 本机运维常用
cert / ldap / gss / sspi 外部认证体系 有对应基础设施时

md5 别再选了:官方已明确 MD5 密码支持会在未来版本移除,PG 19 起对 MD5 密码登录直接告警。还在用 md5 行的库,趁早把密码重存成 SCRAM(见坑 6,直接改方法会把老用户锁在门外)。

五、改完怎么生效:reload 三式 + 一个 Windows 特例

文件的读取时机:启动时 ,以及主进程收到 SIGHUP 信号时。所以改完文件要触发一次重读,三种方式任选:

csharp 复制代码
pg_ctl reload                          # 命令行
SELECT pg_reload_conf();               -- psql 里一行 SQL
kill -HUP <postmaster主进程PID>        # 信号直接给

reload 不中断现有连接,只有后续新连接按新规则走------这就是 pg_hba.conf 改动不需要 restart 的原因(对比:listen_addresses 是 postmaster 级参数,必须 restart)。

Windows 特例 :官方文档明说,Windows 上 pg_hba.conf 的改动会立即作用于后续新连接,不需要手动 reload。Windows 装机用户常以为「改配置必须重启服务」,其实是平台差异。

上线前先查再放流量------系统视图 pg_hba_file_rules 就是给预检用的,error 列非空即有问题行:

vbnet 复制代码
SELECT line_number, type, database, user_name, error
FROM pg_hba_file_rules
WHERE error IS NOT NULL;

规则条数多的库,PG 16 起支持 include / include_dir 拆文件管理,按文件名顺序合并进主文件------按业务分文件,比一整个大文件好审得多。

六、远程连不上:先分层,再动手

「连不上」是三种完全不同的病,报错长相就是分诊台:

报错 卡在哪层 查什么
connection timed out / refused 网络层,包没到门口 listen_addresses(默认只听 localhost,改它必须 restart)→ 防火墙 → 云安全组
no pg_hba.conf entry 认证层,到了门没放行 规则是否匹配:顺序、地址段、库名、用户名 → 改完 reload
password authentication failed 认证层,放行了但核验没过 密码本身,或方法与密码存储格式不匹配(坑 6)

见过太多人拿着 no pg_hba.conf entry 的报错去反复改防火墙,也见过反过来拿着 timeout 去改 pg_hba------先看报错分层,再动手,一步都不浪费。

七、8 个生产坑

  1. 顺序坑:宽规则写在窄规则前面,第一匹配、无回落,窄规则永远不生效。
  2. 裸奔坑0.0.0.0/0 + trust 上生产等于整库开门------任何能路由到这台机器的人都能以任意用户身份进入。
  3. 生效坑:改完不 reload 等于没改(Windows 除外,改动立即生效)。
  4. 层级坑 :只盯 pg_hba,漏了 listen_addresses(要 restart 才生效)和防火墙/云安全组------三层各管一段,报错长相不同,先分层。
  5. IPv6 坑 :只写 127.0.0.1/32,本机走 ::1 的连接照样被拒。补一行 ::1/128,或地址列写主机名 localhost(可同时覆盖 v4/v6)。
  6. 存储格式坑 :把方法改成 scram-sha-256 后,密码仍以 MD5 旧格式存储的用户会立即登录失败------要给这些用户重设一次密码 ,让它以 SCRAM 格式重新存储。反方向兼容:存储已是 SCRAM、方法写 md5,会自动按 SCRAM 校验,不受影响。
  7. 复制坑replication 只匹配物理复制连接;逻辑复制按数据库名走普通规则。流复制起不来、却只写了普通库规则,先查这一行。
  8. DNS 坑:地址写主机名,每次连接要做反向+正向两次解析,DNS 慢或不规范会直接拖累连接建立------生产环境建议一律写 CIDR。

八、一份可以直接抄的生产模板

python 复制代码
# TYPE     DATABASE     USER          ADDRESS           METHOD
# 本机:套接字 + 回环
local      all          all                             peer
host       all          all          127.0.0.1/32      scram-sha-256
host       all          all          ::1/128           scram-sha-256
# 内网网段:按实际情况收窄
host       all          all          10.0.1.0/24       scram-sha-256
# 物理复制专用:单独用户 + 单主机
host       replication  replicator   10.0.1.15/32      scram-sha-256
# 收尾:显式拒绝其余全部(无匹配本就拒绝,写出来是给人看的)
host       all          all          0.0.0.0/0         reject

三个要点:窄前宽后;复制单独一行单独用户;结尾显式 reject 让拒绝意图可见。

最后一个容易忽略的配合关系:pg_hba 管「能不能进门」,进门后能连哪个库还要看 CONNECT 权限。按人限库,用 GRANT/REVOKE CONNECT 比往 pg_hba 里堆规则好维护------这也是官方的建议。

小结

pg_hba.conf 的心智模型一句话:一张自上而下、第一条匹配就定终身的门禁表。顺序即语义,reload 才生效(Windows 立即),连不上先分层。

后面会继续更 pg_dump 备份恢复、慢 SQL 优化、Patroni 高可用这些实战,有认证配置问题可以评论区聊。

参考:PostgreSQL 官方文档 20.1 The pg_hba.conf File --- postgresql.org/docs/current/auth-pg-hba-conf.html

关键词:pg_hba.conf、PostgreSQL认证、no pg_hba.conf entry、scram-sha-256、PostgreSQL远程连接

相关推荐
Harry Lei2 小时前
长期记忆系统的设计与实现
spring boot·postgresql·embedding
jonyleek9 小时前
低代码平台的数据架构设计:动态表单存储与查询优化
低代码·postgresql·开源·数据架构·动态表单·jvs低代码平台·jvs低代码
Logintern0916 小时前
PostgreSQL 的 ORDER BY 多列排序
数据库·postgresql
微软技术分享20 小时前
Ubuntu 本地部署Ollama+OpenWebUI教程
数据库·ubuntu·postgresql
大喵桑丶1 天前
AlmaLinux 9 上基于 PostgreSQL + Nginx 部署高可用轻量级 Gitea 服务
nginx·postgresql·gitea
xuefuhe1 天前
CLion2026本地阅读PostgreSQL源码实现跳转
postgresql
数智启示录2 天前
PostgreSQL 内存调优实战(第 12 篇):work_mem 只调大 64 倍,峰值为什么远不止 64 倍
运维·数据库·经验分享·postgresql·面试
自动化监测Learner2 天前
QGIS 把geojson数据导入 PostgreSQL/PostGIS 的完整流程
数据库·postgresql
jnrjian2 天前
Postgres 序列(sequence)的权限
数据库·postgresql