PostgreSQL跨主机Ident认证失败问题排查求助
我有两台部署在host1和host2上的数据库服务器。两台主机的pg_ident.conf均配置了映射规则:
# MAPNAME SYSTEM-USERNAME PG-USERNAME mymap system_username pg_username
host1的pg_hba.conf配置如下:
# TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only ... local dbname pg_username peer map=mymap .... host dbname pg_username all ident map=mymap
已执行select pg_reload_conf();重载配置。从host1本地连接数据库(ssh system_username@host1后执行psql -p 5432 -U pg_username -d dbname)可正常工作,但从host2远程连接host1的数据库(ssh system_username@host2后执行psql -h host1 -p 5432 -U pg_username -d dbname)时,出现错误:
FATAL: Ident authentication failed for user "pg_username" with pg_ident.conf settings
日志信息如下:
2023-12-07 11:01:47.062 +05 [26328-1] LOG: could not connect to Ident server at address "host1", port 113: Connection refused 2023-12-07 11:01:47.062 +05 [26328-1] FATAL: Ident authentication failed for user "pg_username" 2023-12-07 11:01:47.062 +05 [26328-1] DETAIL: Connection matched pg_hba.conf line 104: "host dbname pg_username all ident map=mymap"
核心原因
日志明确指出could not connect to Ident server at address "host1", port 113: Connection refused。Ident认证的逻辑是:当host2的客户端发起远程连接时,host1的PostgreSQL会尝试连接**客户端所在机器(host2)**的113端口(Ident服务端口),获取发起连接的系统用户名,再通过pg_ident.conf的映射匹配PG用户。出现该错误的本质是Ident服务不可达,可能是host2未部署Ident服务、防火墙拦截了113端口,或是客户端IP解析异常导致服务器错误连接自身端口。
解决方案
方案1:修复Ident服务连通性
- 在host2上部署Ident服务:
- Debian/Ubuntu系统:
sudo apt update && sudo apt install identd sudo systemctl start identd && sudo systemctl enable identd - RHEL/CentOS系统:
sudo yum install identd sudo systemctl start identd && sudo systemctl enable identd
- Debian/Ubuntu系统:
- 开放host2的113端口:
允许host1的IP访问host2的113端口,以firewalld为例:sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="host1的IP" port port="113" protocol="tcp" accept' --permanent sudo firewall-cmd --reload - 验证连通性:
在host1上执行nc -zv host2 113,若返回成功则说明服务和网络配置正常。
方案2:改用密码认证(推荐)
Ident认证可用性低且安全性弱,推荐替换为更可靠的密码认证:
- 修改host1的
pg_hba.conf:
将对应行的ident map=mymap替换为scram-sha-256(更安全)或md5:host dbname pg_username all scram-sha-256 - 设置PG用户密码:
连接到host1的数据库执行:ALTER USER pg_username WITH PASSWORD '你的安全密码'; - 重载配置:
SELECT pg_reload_conf(); - 重新连接:
在host2上执行psql -h host1 -p 5432 -U pg_username -d dbname,输入设置的密码即可连接。
方案3:使用SSH隧道实现本地peer认证
如果需要保留系统用户到PG用户的映射,可通过SSH隧道将远程连接转为本地连接,复用peer认证:
- 在host2上建立SSH隧道:
ssh -L 5433:host1:5432 system_username@host1 -N - 通过隧道连接数据库:
在host2上执行:
此时连接通过隧道走本地Unix套接字逻辑,复用已生效的peer映射规则。psql -p 5433 -U pg_username -d dbname
内容的提问来源于stack exchange,提问作者Anastasia

