PostgreSQL 默认仅监听localhost,Navicat远程连接失败多因未配置listen_addresses和pg_hba.conf,需检查端口监听、修改配置并reload,同时确认防火墙与连接参数正确。
检查 PostgreSQL 是否监听正确端口和地址
navicat 连不上,第一反应常是密码或用户名错了,但实际大概率是 postgresql 根本没在监听你连的那个地址+端口。默认安装下,postgresql 往往只监听 localhost(即 127.0.0.1),不接受远程连接;而 navicat 如果填的是服务器 ip(比如 192.168.1.100),就会卡在 tcp 握手阶段,最终报超时。
- 查监听状态:登录服务器后运行
sudo netstat -tuln | grep :5432,确认输出里有127.0.0.1:5432或*:5432;若只有127.0.0.1:5432,说明不响应外部 IP - 改配置:编辑
postgresql.conf,找到listen_addresses,改成listen_addresses = 'localhost,192.168.1.100'(填你的服务器实际 IP)或更宽泛的'*'(仅测试环境) - 别忘了 reload:改完执行
sudo systemctl reload postgresql或pg_ctl reload,不是 restart
确认 pg_hba.conf 允许该 IP 的连接方式
即使端口通了,PostgreSQL 还有一道门禁——pg_hba.conf。它按顺序匹配规则,一旦某条规则拒绝,后续就不看了。常见错误是加了一条允许规则,但前面已有 reject 或更严格的 host all all 127.0.0.1/32 reject 挡住了。
- 检查规则顺序:用
sudo grep -v '^#' /etc/postgresql/*/main/pg_hba.conf | grep host快速看有效行 - 加一条明确放行:例如从内网连,追加
host all all 192.168.1.0/24 md5;从 Navicat 所在机器直连,用具体 IP:host all all 192.168.1.50/32 md5 - 认证方式选
md5,别用trust(除非本地调试);peer只对 Unix socket 有效,对 TCP 无效 - 改完必须 reload:
sudo systemctl reload postgresql,否则不生效
排查中间网络设备是否拦截 5432 端口
服务器上 netstat 显示监听了,telnet server_ip 5432 却不通?问题大概率出在网络层:防火墙、云平台安全组、路由器 NAT 规则,甚至公司出口代理都可能拦掉非标准端口。
- 本地测试:在服务器本机跑
telnet 127.0.0.1 5432,通 → 服务正常;不通 → PostgreSQL 没启或配置错 - 同局域网另一台机器试:
telnet 192.168.1.100 5432,不通 → 查服务器防火墙:sudo ufw status或sudo iptables -L -n,确认放行5432 - 如果是阿里云/腾讯云:进控制台查「安全组」,确保入方向规则包含
5432/TCP,来源 IP 设置合理(不要留0.0.0.0/0开放生产库) - Navicat 跟服务器不在同一内网时,还要确认路由、NAT 映射是否把外部请求正确转到 PostgreSQL 所在机器
Navicat 连接参数中 host 和 port 的实际含义
很多人填 Host 时写 localhost,以为是连本地数据库,结果 Navicat 是装在自己笔记本上的——这个 localhost 指的是笔记本自身,不是服务器。这是最隐蔽也最高频的配置错误。
-
Host填的是 Navicat 所在机器能直接路由到的目标地址:服务器真实 IP(如192.168.1.100)、域名(需 DNS 可解析)、或 Docker 容器名(仅限同 network) -
Port默认5432,但如果你改过postgresql.conf中的port参数,这里必须同步改,不能依赖“默认” - 避免用
localhost或127.0.0.1作为 Host 连远端服务器;如果真想走本地回环测试,先用ssh -L 5433:127.0.0.1:5432 user@server_ip建隧道,再让 Navicat 连127.0.0.1:5433 - 连接前点「Test Connection」只是发个 TCP SYN 包,不验证账号密码;超时失败说明连不上端口,跟认证无关
端口通、配置开、防火墙放、Navicat 地址填对——这四步缺一不可。最容易被忽略的是 pg_hba.conf 规则顺序和 reload 操作,改完不 reload 等于没改。


















