乐于分享
好东西不私藏

PostgreSQL 免密登录:一篇文章讲清楚

PostgreSQL 免密登录:一篇文章讲清楚

REVIEW – 老柴实测
PostgreSQL 免密登录:一篇文章讲清楚
老柴杂货铺 – 运维工具箱系列
PART
01
一篇文章讲清楚
POSTGRESQL PASSWORDLESS LOGIN
你有没有过这种场景——
写了个脚本要连PostgreSQL,每次都要输密码,挺烦的。
或者你写了个 cron 定时任务,每天自动跑一段 SQL。
这时候密码怎么办?写在命令里不安全,交互输入又不现实。
PostgreSQL 提供了好几种免密登录的方案,从简单到复杂,从本地到远程,我一个个说清楚。
PART
02
方法一:.pgpass 文件
USE .PGPASS FILE
最常用、最简单的一种。
原理:在你的用户目录下放一个 .pgpass 文件,psql 和其他客户端会自动读取里面的密码。
文件格式
hostname:port:database:username:password
每行一条规则,可以用通配符 * 匹配任意值。
操作步骤
STEP 1
创建文件
:创建 ~/.pgpass 文件
STEP 2
写入规则
:写入连接规则,每行一条
STEP 3
设置权限
:chmod 600 ~/.pgpass,这一步 PostgreSQL 会强制检查
举个实际例子
# 本机 5432 端口 mydb 数据库 chai 用户 
localhost:5432:mydb:chai:mypassword123  
# 内网服务器 192.168.1.100 的所有数据库 postgres 用户 
192.168.1.100:5432:*:postgres:anotherpassword  
# 匹配所有情况(谨慎使用) 
*:*:*:*:superpassword
然后直接连
psql -h localhost -U chai -d mydb
⚠️ 这一步是必须的:必须 chmod 600 ~/.pgpass,权限错了 PostgreSQL 会直接忽略这个文件,不报错,但就是连不上。
老柴踩过的坑
1
Windows 上路径是 %APPDATA%\postgresql\pgpass.conf
2
文件内容不要有多余空格,特别是冒号前后
3
密码里如果有冒号或反斜杠,需要用 \: 和 \\ 转义
4
规则是从上到下匹配,匹配到第一条就停止,所以具体的规则写在前面,兜底的写在后面
PART
03
方法二:trust 认证
TRUST AUTHENTICATION
原理:告诉 PostgreSQL,某些连接来源不需要密码。
操作:编辑 pg_hba.conf(通常在数据目录下,或者 /etc/postgresql/版本号/main/):
# 本地 Unix socket 连接,所有用户都不用密码 
local   all    all    trust  
# 本机 IP 地址连接,不用密码 
host    all    all    127.0.0.1/32    trust 
host    all    all    ::1/128    trust  
# 只允许某个内网网段 
host    all    all    192.168.1.0/24    trust
修改后重载配置
pg_ctl reload # 或者 systemctl reload postgresql
优点:最简单,什么都不用改。
缺点:太宽松了,生产环境不要用。别人只要能登录到你的服务器,或者能从那个 IP 连过来,就能直接进数据库。
⚠️ 只建议在本地开发环境或绝对可信的内网中使用
PART
04
方法三:peer / ident 认证
PEER / IDENT AUTHENTICATION
原理:客户端是哪个 Linux 用户,就自动用同名字的 PostgreSQL 用户登录,不需要密码。
这是我认为最优雅的本地免密方案
pg_hba.conf 配置
local    all    postgres    peer 
local    all    all    peer
然后创建同名的数据库用户
# 假设当前 Linux 用户是 chai 
createuser -U postgres chai 
createdb -U postgres -O chai chaidb
之后,直接这样连
psql -d chaidb
就是这么简单。不需要密码,不需要配置文件。
为什么它安全
1
必须登录到同一台机器(走 Unix socket)
2
必须是那个 Linux 用户
3
没有明文密码存放在任何地方
缺点:只能用于本地连接,远程 TCP 连接用不了。
PART
05
方法四:环境变量 PGPASSWORD
USE ENVIRONMENT VARIABLE
最简单粗暴的方式。
export PGPASSWORD=yourpassword 
psql -h localhost -U chai -d mydb
或者一行搞定:
PGPASSWORD=yourpassword 
psql -h localhost -U chai -d mydb
优点:一行命令,不用改文件,适合临时用。
缺点
1
通过 ps aux 或 /proc/PID/environ 别人可能看到密码
2
某些系统会记录带密码的命令历史
适用场景:临时测试脚本、CI/CD pipeline,用完就 unset。
export PGPASSWORD=xxx ;psql -U chai -d mydb -c "SELECT 1;" ;unset PGPASSWORD
PART
06
方法五:SSL 证书认证
SSL CERTIFICATE AUTHENTICATION
这是最安全的方案,适合生产环境和远程连接。
原理:客户端用 SSL 证书登录,PostgreSQL 验证客户端证书,不需要密码。
大致流程
1. 服务端配置
ssl = on 
ssl_cert_file = 'server.crt' 
ssl_key_file = 'server.key' 
ssl_ca_file = 'root.crt'
2. 生成客户端证书
# 生成客户端私钥 
openssl genrsa -out ~/.postgresql/client.key 2048 
chmod 600 ~/.postgresql/client.key  
# 生成 CSR 
openssl req -new -key ~/.postgresql/client.key -out ~/.postgresql/client.csr -subj "/CN=chai"  
# 用 CA 证书签名 
openssl x509 -req -in ~/.postgresql/client.csr -CA root.crt -CAkey root.key -CAcreateserial -out ~/.postgresql/client.crt -days 3650
3. 配置 pg_hba.conf
hostssl   all    all    0.0.0.0/0    cert
4. 客户端连接
psql "host=myserver user=chai dbname=mydb sslmode=verify-full"
客户端会自动用 ~/.postgresql/client.crt 和 client.key 登录。
优点:传输加密 + 证书认证双重安全,不需要密码。
缺点:配置最麻烦,适合生产环境使用。
PART
07
方法六:service 服务文件
SERVICE FILE
如果你有多个 PostgreSQL 实例需要管理,可以用服务配置文件。
创建 ~/.pg_service.conf
[mydb] 
host=localhost 
port=5432 
dbname=mydb 
user=chai  
[production] 
host=prod-db.example.com 
port=5432 
dbname=appdb 
user=appuser 
sslmode=require
然后这样连:
psql service=mydb # 或者 psql "service=production"
配合 .pgpass 使用,效果最好。
PART
08
总结:怎么选
WHICH ONE TO USE
把这几种方法做个对比:
1
本地开发/个人机器 → .pgpass 文件 + peer 认证,安全方便不折腾
2
临时脚本/CI/CD → PGPASSWORD 环境变量
3
生产环境/远程连接 → SSL 证书认证
4
内网绝对可信环境 → trust 认证(慎用)
5
多个实例管理 → .pg_service.conf + .pgpass 组合拳
cron 定时任务的推荐做法
chai  0 2 * * * psql -d mydb -c "SELECT my_function();" >> /var/log/mydb.log 2>&1
在 postgres 用户或者对应用户下运行,配合 peer 认证或 .pgpass 文件即可。
PART
09
我踩过的坑
COMMON PITFALLS
坑一:.pgpass 权限问题
文件权限不是 600,PostgreSQL 会直接忽略。你得到 password authentication failed 的报错,但根本不知道是权限问题。
解决chmod 600 ~/.pgpass 永远是第一步检查。
坑二:pg_hba.conf 改了没 reload
改完必须 pg_ctl reload 或者 systemctl reload,否则老规则依然生效。很多人改完配置不重启,怀疑人生一小时。
坑三:peer 认证必须走 Unix socket
psql -h localhost 是 TCP 连接,走不了 peer。不带 -h 参数才是 Unix socket 连接。
坑四:pg_hba.conf 的规则顺序
pg_hba.conf 是从上到下匹配匹配到第一条就停
如果你写了:
host    all    all    0.0.0.0/0    md5 host    all    all    192.168.1.1/32    trust
第二条 trust 永远不会生效。
坑五:.pgpass 的规则顺序
和 pg_hba.conf 一样,从上到下匹配,匹配到第一条就停。所以具体的规则写在前面,兜底的写在后面。
坑六:PGPASSWORD 在新版本中的警告
PostgreSQL 11 开始使用 PGPASSWORD 会收到 warning,但仍然工作。官方推荐用 .pgpass
PART
010
最后一句
SUMMARY
PostgreSQL 的免密登录,本质上是一个认证链条
你告诉 PostgreSQL “我是谁”(user),PostgreSQL 决定”我信不信你”(auth_method)。
选哪个方法取决于你的环境:
1
个人开发 → 简单就好
2
团队共享 → 加一层密码保护
3
生产环境 → SSL 证书
一句话:选最简单够用的方案
别把简单事情复杂化。
— END —
本文首发于「老柴杂货铺」公众号
点个「在看」- 让更多人看到
点赞 – 在看 – 转发 – 三连支持THANK YOU FOR READING