Skip to content

PostgreSQL Ident 认证详解

概述

Ident 认证是 PostgreSQL 提供的一种身份验证方法,它通过从 ident 服务器获取客户端的操作系统用户名,并将其用作允许的数据库用户名。这种认证方式基于 RFC 1413 定义的"标识协议"。

WARNING

Ident 认证仅在 TCP/IP 连接上受支持。当为本地(非 TCP/IP)连接指定 ident 时,PostgreSQL 将自动改为使用对等身份验证(peer authentication)。

工作原理

Ident 协议机制

Ident 认证的工作流程如下:

基本概念

组件描述端口
Ident 服务器运行在客户端机器上的服务TCP 113
PostgreSQL 服务器数据库服务器通常 5432
客户端应用连接数据库的应用程序随机端口

配置选项

pg_hba.conf 配置

pg_hba.conf 文件中配置 Ident 认证:

bash
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    mydatabase      dbuser          192.168.1.0/24          ident
host    all             all             10.0.0.0/8              ident map=mymap

支持的配置参数

map 参数

map 参数允许在系统用户名和数据库用户名之间进行映射。

bash
# 不使用映射,系统用户名必须与数据库用户名完全匹配
host    mydb    john    192.168.1.100/32    ident
bash
# 使用名为 "mymap" 的用户名映射
host    mydb    dbuser  192.168.1.0/24      ident map=mymap

实际应用示例

示例 1:基本 Ident 认证配置

问题陈述:在企业内部网络中,需要让系统用户直接使用其操作系统账户连接 PostgreSQL 数据库。

解决方案

  1. 配置 pg_hba.conf
bash
# 允许内网用户使用 ident 认证
host    company_db    all    192.168.1.0/24    ident
  1. 确保客户端运行 ident 服务
bash
# 在 Linux 系统上检查 ident 服务状态
sudo systemctl status identd

# 启动 ident 服务(如果未运行)
sudo systemctl start identd
  1. 创建对应的数据库用户
sql
-- 为系统用户 'john' 创建数据库用户
CREATE USER john;
GRANT CONNECT ON DATABASE company_db TO john;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO john;

分析过程

  • PostgreSQL 接收来自 IP 192.168.1.100 的连接请求
  • 查询该 IP 的 ident 服务器,获取发起连接的系统用户名(如 'john')
  • 检查数据库中是否存在名为 'john' 的用户
  • 如果存在且有相应权限,则允许连接

输入和输出

bash
# 客户端连接命令
psql -h database.company.com -d company_db -U john

# 成功连接输出
psql (15.3)
Type "help" for help.

company_db=>

示例 2:使用用户名映射的 Ident 认证

问题陈述:系统用户名与期望的数据库用户名不匹配,需要建立映射关系。

解决方案

  1. 配置用户名映射文件pg_ident.conf):
bash
# MAPNAME       SYSTEM-USERNAME    PG-USERNAME
mymap           john               db_john
mymap           mary               db_mary
mymap           admin              dba
  1. 配置 pg_hba.conf
bash
host    mycompany    db_john,db_mary    192.168.1.0/24    ident map=mymap
host    postgres     dba                192.168.1.10/32   ident map=mymap
  1. 创建映射的数据库用户
sql
-- 创建映射后的数据库用户
CREATE USER db_john;
CREATE USER db_mary;
CREATE USER dba SUPERUSER;

-- 分配权限
GRANT CONNECT ON DATABASE mycompany TO db_john, db_mary;
GRANT ALL PRIVILEGES ON DATABASE postgres TO dba;

分析过程

  • 系统用户 'john' 连接数据库时,PostgreSQL 查询 ident 服务器获取 'john'
  • 根据 'mymap' 映射规则,将 'john' 映射为 'db_john'
  • 检查 'db_john' 用户的权限并允许连接

测试示例

bash
# 系统用户 john 连接(会被映射为 db_john)
psql -h localhost -d mycompany -U db_john

# 系统管理员连接(会被映射为 dba)
psql -h localhost -d postgres -U dba
sql
-- 连接后检查当前用户
SELECT current_user;
-- 输出: db_john

-- 检查可访问的数据库
\l

-- 检查当前数据库权限
\dp

安全考虑

安全风险分析

安全最佳实践

DANGER

重要安全警告 RFC 1413 明确声明:"标识协议不打算作为授权或访问控制协议。" 因此,Ident 认证存在固有的安全风险。

1. 适用场景限制

bash
# 仅在以下情况下使用 Ident 认证:
# - 完全受控的内部网络
# - 客户端机器可信
# - 数据库和系统管理员紧密合作

2. 网络安全配置

bash
# 限制连接来源
host    mydb    all    127.0.0.1/32      ident  # 仅本机
host    mydb    all    192.168.1.0/24    ident  # 仅内网

3. 避免加密选项

WARNING

一些 ident 服务器提供加密选项,会返回加密的用户名。PostgreSQL 无法解密这些字符串,因此绝不能使用此选项。

故障排除

常见问题诊断

问题可能原因解决方案
连接被拒绝Ident 服务未运行启动客户端 ident 服务
用户名不匹配缺少用户映射配置 pg_ident.conf
超时错误网络问题或防火墙检查端口 113 连通性

调试步骤

  1. 检查 ident 服务状态
bash
# Linux 系统
netstat -tlnp | grep :113
systemctl status identd

# 测试 ident 响应
telnet client_ip 113
  1. 查看 PostgreSQL 日志
bash
# 启用详细日志
log_connections = on
log_disconnections = on
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '
  1. 手动测试 ident 查询
bash
# 使用 ident 客户端工具测试
echo "LOCAL_PORT, REMOTE_PORT" | nc client_ip 113

性能考量

性能影响分析

优化建议

  1. 设置合理的超时时间
bash
# postgresql.conf
ident_timeout = 5s  # 默认 10s,可适当缩短
  1. 使用连接池
bash
# 减少频繁的认证开销
# 使用 pgbouncer 或应用层连接池

与其他认证方法的比较

认证方法安全性性能复杂度适用场景
Ident中等受控内网
Peer本地连接
Password通用场景
Certificate很高高安全要求

TIP

选择建议在现代环境中,建议优先考虑更安全的认证方法,如证书认证或 SCRAM-SHA-256 密码认证,而不是 Ident 认证。

总结

Ident 认证虽然配置简单,但存在显著的安全风险。它适用于完全受控的内部网络环境,其中所有客户端机器都是可信的。在实际部署中,需要仔细评估安全需求,并考虑使用更安全的认证替代方案。

INFO

关键要点

  • Ident 认证依赖客户端 ident 服务器的诚实性
  • 仅适用于 TCP/IP 连接
  • 支持用户名映射功能
  • 在安全敏感环境中应避免使用
  • 需要客户端运行 ident 服务(端口 113)