pg_hba.conf 认证配置
High Contrast
Dark Mode
Light Mode
Sepia
Forest
3 min read600 words

pg_hba.conf 认证配置

pg_hba.conf(Host-Based Authentication)控制谁能从哪里以什么方式连接 PostgreSQL。理解这个文件是避免"连接被拒绝"错误和正确设置数据库安全边界的关键。


pg_hba.conf 的格式

每行代表一条认证规则,格式为:

类型    数据库    用户      地址/掩码          认证方式
TYPE    DATABASE  USER      ADDRESS            METHOD

PostgreSQL 按从上到下的顺序匹配规则,命中第一条就停止。


认证类型(TYPE)

类型 含义
local 通过 Unix Domain Socket 连接(本机,不经过网络)
host 通过 TCP/IP 连接(明文或加密均可)
hostssl 只允许 SSL/TLS 加密的 TCP/IP 连接
hostnossl 只允许非 SSL 的 TCP/IP 连接(不推荐)

常用认证方法(METHOD)

方法 含义 推荐场景
trust 无需密码,直接允许 仅限本机 local 连接,开发环境
peer 使用操作系统用户名匹配 Unix Socket,postgres 用户管理
md5 MD5 加密密码 生产已广泛使用,但 scram-sha-256 更安全
scram-sha-256 SCRAM 加密密码(PostgreSQL 10+) 推荐的生产密码方式
password 明文密码(危险) 不要用
reject 拒绝连接 黑名单

典型的 pg_hba.conf 配置

默认配置(Ubuntu 安装后)

# TYPE  DATABASE        USER            ADDRESS                 METHOD
# "local" is for Unix domain socket connections only
local   all             postgres                                peer
local   all             all                                     peer
# IPv4 local connections:
host    all             all             127.0.0.1/32            scram-sha-256
# IPv6 local connections:
host    all             all             ::1/128                 scram-sha-256

推荐的生产配置

# TYPE  DATABASE        USER            ADDRESS                 METHOD
# 本地 socket:postgres 超级用户用 peer(操作系统用户认证,无需密码)
local   all             postgres                                peer
# 本地 socket:其他用户用密码
local   all             all                                     scram-sha-256
# 本地 TCP 连接(127.0.0.1):密码认证
host    all             all             127.0.0.1/32            scram-sha-256
host    all             all             ::1/128                 scram-sha-256
# 应用服务器连接(仅允许来自特定 IP 的特定用户连接特定数据库)
host    myapp           myapp_user      10.0.1.0/24             scram-sha-256
# 拒绝其他所有连接
host    all             all             0.0.0.0/0               reject

开发环境简化配置

# 开发环境:本地所有连接信任(不需要密码)
# 警告:不要在生产环境使用 trust
local   all             all                                     trust
host    all             all             127.0.0.1/32            trust
host    all             all             ::1/128                 trust

修改 pg_hba.conf 后重载

修改 pg_hba.conf 后不需要重启 PostgreSQL,只需重载:

# 方法一:系统命令
sudo systemctl reload postgresql
# 方法二:在 psql 中执行(需要超级用户权限)
SELECT pg_reload_conf();
# 方法三:发送 SIGHUP 信号
sudo kill -HUP $(head -1 /var/lib/postgresql/16/main/postmaster.pid)

注意postgresql.conf 中的一些参数变更需要重启(而非重载)才能生效。但 pg_hba.conf 的变更只需重载。


常见连接错误排查

错误 1:FATAL: Ident authentication failed for user "xxx"

原因:pg_hba.conf 中配置了 peer,但连接的操作系统用户和 PostgreSQL 用户不匹配。

解决

# 确认当前操作系统用户
whoami  # 如果是 ubuntu,但 pg_hba.conf 要求 peer 匹配
# 方法一:用 postgres 用户连接
sudo -u postgres psql
# 方法二:修改 pg_hba.conf,改用 scram-sha-256 密码认证
# 将 peer 改为 scram-sha-256,然后重载

错误 2:FATAL: no pg_hba.conf entry for host "X.X.X.X", user "xxx", database "yyy"

原因:连接来源的 IP 地址不在任何允许的规则中。

解决

# 在 pg_hba.conf 中添加对应的 host 规则
# 例如,允许 10.0.0.0/8 网段的 myapp_user 连接 myapp 数据库
host    myapp    myapp_user    10.0.0.0/8    scram-sha-256
# 重载
sudo systemctl reload postgresql

错误 3:FATAL: password authentication failed for user "xxx"

原因:密码错误,或者用户没有设置密码(peer 模式下用密码连接)。

解决

-- 修改用户密码
ALTER USER myapp_user WITH PASSWORD 'new_secure_password';

用户与角色管理基础

-- 创建只读用户
CREATE USER readonly_user WITH PASSWORD 'password';
GRANT CONNECT ON DATABASE myapp TO readonly_user;
GRANT USAGE ON SCHEMA public TO readonly_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly_user;
-- 让未来新建的表也自动赋予只读权限
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO readonly_user;
-- 创建应用用户(读写,但不能 DROP/TRUNCATE)
CREATE USER app_user WITH PASSWORD 'password';
GRANT CONNECT ON DATABASE myapp TO app_user;
GRANT USAGE, CREATE ON SCHEMA public TO app_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_user;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO app_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT USAGE ON SEQUENCES TO app_user;

本节记录清单


下一章数据类型与 Schema 设计——数据库搭起来了,现在学如何设计一个经得起时间考验的表结构。