解决 PostgreSQL 报错 FATAL: password authentication failed for user

详细排查并彻底解决 PostgreSQL 报错 FATAL: password authentication failed for user,剖析 pg_hba.conf 认证规则、密码加密算法与连接排错实战。

发布于

在安装配置 PostgreSQL,或使用 psql、Navicat、DBeaver、pgAdmin 及代码连接数据库时,最常见的连接报错就是:

psql: error: connection to server at "localhost" (127.0.0.1), port 5432 failed: FATAL: password authentication failed for user "postgres"

即使反复核对了密码,确认没有输入错误,系统仍然顽固地拒绝连接。

这是因为 PostgreSQL 拥有业界最严格的主机与身份认证控制文件——pg_hba.conf。认证失败往往不是密码输错这么简单,而是触发了认证方式不匹配、监听地址限制或用户权限问题。

本文将带您由浅入深,一步步定位并彻底解决该报错。


一、 快速自检:确认是否单纯输错密码

首先排除最简单的低级失误:

  1. 密码是否包含特殊字符:例如包含 $、! 等符号,在 Linux Bash 命令行下容易被 Shell 自动解析转义。
  2. 用户名大小写:PostgreSQL 默认将用户名视为小写,检查用户名拼写是否匹配。

如果不确定密码是否正确,可以通过本地免密方式直接重置。

重置 postgres 密码(以 Linux 为例):

在服务器本地通过系统用户 postgres 免密登录:

sudo -u postgres psql

成功进入 psql 后,执行修改密码语句:

ALTER USER postgres WITH PASSWORD 'YourNewStrongPass123!';
\q

如果即使重置了密码仍然提示认证失败,那么问题必然出在 pg_hba.conf 配置文件。


二、 核心关键:看懂 pg_hba.conf 的认证策略

PostgreSQL 的客户端认证完全由数据目录下的 pg_hba.conf(Host-Based Authentication)控制。

1. 找到 pg_hba.conf 的物理文件路径

登录 psql(或使用管理员连接)执行:

SHOW hba_file;

常见路径:

  • Linux (Ubuntu/Debian): /etc/postgresql/15/main/pg_hba.conf
  • Linux (CentOS/RHEL): /var/lib/pgsql/15/data/pg_hba.conf
  • macOS (Homebrew): /opt/homebrew/var/postgresql@15/pg_hba.conf
  • Docker 容器: /var/lib/postgresql/data/pg_hba.conf

2. pg_hba.conf 行规则格式:

# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             127.0.0.1/32            scram-sha-256
  • TYPE:连接类型。local 表示 Unix 域套接字(本地命令行);host 表示通过 TCP/IP 网络连接。
  • DATABASE:允许访问的数据库(all 代表全部)。
  • USER:适用的用户名(all 代表全部)。
  • ADDRESS:允许的客户端 IP 范围(127.0.0.1/32 表示本机,0.0.0.0/0 表示任意 IP)。
  • METHOD:认证方法(最常踩坑点)!

三、 常见认证方法不匹配与修复

场景 1:密码加密算法冲突(scram-sha-256 vs md5)

从 PostgreSQL 14 开始,默认的密码加密算法由旧版的 md5 切换为更加安全的 scram-sha-256。

  • 问题:如果某些旧版驱动(如老版本 JDBC 驱动、旧版 Python psycopg2 或老版本图形化客户端)不支持 SCRAM 协议,发起连接时就会报 password authentication failed。
  • 解决方案: 在 pg_hba.conf 中,将对应的认证方法从 scram-sha-256 改为 md5(若客户端驱动极老):
    # 将 scram-sha-256 临时切换为 md5
    host    all             all             127.0.0.1/32            md5
    

    [!TIP] 如果修改为 md5,需要重新为用户设置一次密码,让其以 MD5 散列存储: SET password_encryption = 'md5'; ALTER USER postgres WITH PASSWORD 'YourPass';

场景 2:规则匹配顺序优先匹配了旧规则

pg_hba.conf 是从上往下按顺序匹配第一条符合条件的规则。 如果在文件前面有一条:

host    all             all             127.0.0.1/32            reject

那么即使你在最下方配置了 host all all 0.0.0.0/0 scram-sha-256,也会因为前一条规则优先命中而被直接拒绝!

排查建议:将你自定义的白名单和特定用户的规则,放在 pg_hba.conf 文件的最前面。


四、 允许远程客户端连接的完整配置步骤

如果您是在本机以外的局域网或云端远程连接 PostgreSQL,必须同时完成两项配置:

步骤 1:开启网络监听(修改 postgresql.conf)

找到 postgresql.conf 文件(可通过 SHOW config_file; 查看):

# 默认是 listen_addresses = 'localhost',修改为 '*' 允许监听所有网卡
listen_addresses = '*'
port = 5432

步骤 2:开放客户端 IP 访问授权(修改 pg_hba.conf)

在 pg_hba.conf 的最底部添加一行:

# 允许任何 IP 使用密码通过 scram-sha-256 连接所有数据库
host    all             all             0.0.0.0/0               scram-sha-256

步骤 3:重新加载配置(无需重启数据库)

在 Linux 终端执行:

sudo systemctl reload postgresql
# 或在 psql 内部执行:
SELECT pg_reload_conf();

五、 临时救急:通过 trust 认证无条件修复

如果生产或本地环境密码彻底错乱,导致谁也登不进去:

  1. 打开 pg_hba.conf,将本地连接临时改为 trust(信任所有连接,无需密码):
    local   all             all                                     trust
    host    all             all             127.0.0.1/32            trust
    
  2. 重载配置后,直接执行 psql -U postgres 免密登录;
  3. 执行 ALTER USER postgres WITH PASSWORD 'NewPassword123!';;
  4. 务必改回 scram-sha-256 并重新加载配置,严禁在生产长期保留 trust!

六、 总结

FATAL: password authentication failed for user 的排查三板斧:

  1. 查密码:用 sudo -u postgres psql 本地登录,用 ALTER USER ... WITH PASSWORD 重置;
  2. 查 pg_hba.conf:核对连接 IP 是否在允许范围内,认证方式是否与客户端驱动兼容;
  3. 查监听:远程连接必须在 postgresql.conf 开启 listen_addresses = '*'。