Chapter 4. 用户认证

Table of Contents
4.1. pg_hba.conf 文件
4.2. 认证方法
4.2.1. 口令认证
4.2.2. Kerberos 认证
4.2.3. 基于 Ident 的认证
4.3. 认证问题

当一个客户端应用与数据库服务器进行联接时,它声明 它将以哪个 Postgres 用户的名称进行联接, 就象我们登录一台 Unix 计算机 一样.在 SQL 环境里,活跃的数据库用户名决定数据库对象的各种访问 权限--参阅Chapter 7获取相关的更多信息.因此, 很显然我们要对某个客户端可以使用的数据库用户名加以限制.

认证 是数据库服务器建立客户端应用的标识, 然后通过一些手段判断是否允许此客户端应用(或者运行这个客户端应用的 用户)与它所要求的用户名进行联接的过程.

Postgres 提供基于(客户端)主机和基于数据库的客户 端认证方式,其中包括许多不同的认证手段.

Postgres 数据库用户名在逻辑上是和 服务器运行的操作系统用户名相互独立的. 如果某个服务器的所有用户在那台服务器机器上也有帐号, 那么给数据库用户赋与 Unix 用户名是有意义的.不过, 一个接收远程访问的服务器很有可能有许多没有本地帐号的用户, 因而在这种情况下数据库用户和 Unix 用户名之间不必有任何联系.

4.1. pg_hba.conf 文件

客户端认证是由 $PGDATA 目录里的文件pg_hba.conf 控制的,也就是说, /usr/local/pgsql/data/pg_hba.conf. (HBA 的意思是 host-based authentication:基于主机的认证.) 在initdb初始化数据区的时候,它会 安装一个缺省的文件.

文件 pg_hba.conf 的常用格式是一套记录, 每行一条。空白行或者井号(“#”)开头的行被忽略。一条记录 是由若干用空格和/或 tab 分隔的字段组成。

每条记录可以下面三种格式之一

local   database authentication-method [ authentication-option ]
host    database IP-address IP-mask authentication-method [ authentication-option ]
hostssl database IP-address IP-mask authentication-method [ authentication-option ]
    
各个字段的含义如下:

local

这条记录适用于通过 Unix 域套接字的联接.

host

这条记录适用于通过 TCP/IP 网络的联接.请注意,除非服务器是 带着 -i 选项或者等效的配置参数集启动的,否则 TCP/IP 联接将完全被禁止掉.

hostssl

这条记录适用于试图建立在 TCP/IP 上的 SSL 之上的联接. 要使用这个选项,服务器必须带着 SSL 支持编译.而且在服务器启动的时候, 必须用 -l 选项 或等效的配置设置打开 SSL.

database

声明记录所适用的数据库。值 all 表明该记录应用于所有数据库, 值 sameuser 表示于正在联接的用户同名的数据库。 否则它就是某个具体的 Postgres 数据库名字.

IP address, IP mask

这两个字段以各主机的 IP 地址为基础, 控制一条 host 记录应用于哪个主机. (当然,IP 地址可能会被欺骗(spoofed),但是这个考虑 超过了 Postgres 的考虑范围.) 准确的逻辑是,对于匹配的记录

(actual-IP-address xor IP-address-field) and IP-mask-field
必需为零.

authentication method(认证方法)

声明一个用户在与该数据库联接的时候必须使用的认证方法. 可能的选择如下,详细情况在 Section 4.2

trust

无条件地允许联接.这个方法允许任何有登录客户机权限的用户以任意 Postgres 数据库用户身份进行联接.

reject

联接无条件拒绝.常用于从组中“过滤”某些主机.

password

要求客户端在尝试联接的时候提供一个口令, 这个口令与为该用户设置的口令必须匹配.

password 关键字后面可以声明一个可选的文件名. 这个文件包含一个用户列表,列表记录的是那些适用口令认证记录的用户, 以及可选的候选口令.

口令是以明文的方式在线路上传输的.如果要更好的保护,请使用 crypt 方法.

crypt

类似 password 方法,但是口令是用一种简单的 口令对应协议加密后在线路上传送的.这么做在密码学理论上是不安全的, 但可以防止偶然的线路侦听.在 crypt 关键字后面 可以有一个文件,文件里包含适用口令认证记录的用户列表.

krb4

用 Kerberos V4 认证用户.只有在进行 TCP/IP 联接的时候才能用. (译注:Kerberos,"克尔波洛斯",故希腊神话冥王哈得斯的多头看门狗. Kerberos 是 MIT 开发出来的基与对称加密算法的认证协议和/或密钥 交换方法.其特点是需要两个不同用途的服务器,一个用于认证身份, 一个用于通道两端用户的密钥交换.同时 Kerberos 对网络时间同步 要求比较高,以防止回放攻击,因此通常伴随 NTP 服务.)

krb5

用 Kerberos V5 认证用户.只有在进行 TCP/IP 联接的时候才能用. (译注:Kerberos V5 是上面 V4 的改良,主要是不再依赖 DES 算法, 同时增加了一些新特性.)

ident

服务器将询问客户机上的 ident 服务器以核实正在联接的用户身份. 然后 Postgres 核实该操作系统用户是否被允许以其请求的数据库用户身份与数据库联接. 只有在使用 TCP/IP 联接的时候才能用这个选项. 跟在 ident 关键字后面的 authentication option 声明一个 ident map(身份映射), 该文件声明那些操作系统用户等效于数据库用户.见下文获取详细信息.

authentication option(认证选项)

这个字段根据不同的认证方法(authentication method)有不同的 解释.

认证时使用与联接请求的客户端 IP 地址和所要求的 数据库名字匹配的第一条记录. 请注意这里没有 “fall-through(越过)” 或者 “backup(备份)”:如果选定了一条记录但认证失败, 那么将不会继续考虑下面的记录.如果没有匹配的记录,则拒绝访问.

在每次联接的请求时,文件 pg_hba.conf 都会被重新读取.因此很容易就能在服务器运行的时候修改访问权限.

Example 4-1 里是 pg_hba.conf 的一个例子. 阅读下文理解不同认证方法的细节.

Example 4-1. 一个 pg_hba.conf 文件的例子

# TYPE       DATABASE    IP_ADDRESS    MASK               AUTHTYPE  MAP

# 允许在本机上的任何用户以任何身份联接任何数据库
# 但必须是通过 IP 进行联接

host         all         127.0.0.1     255.255.255.255    trust     

# 同样,但用的是 Unix-套接字联接

local        all                                          trust

# 允许 IP 地址为 192.168.93.x 的任何主机与数据库
# "template1" 相连,用与他们在自己的主机上相同 ident 的用户名标识他自己
# (通常是他的 Unix 用户名)

host         template1   192.168.93.0  255.255.255.0      ident     sameuser

# 允许来自主机 192.168.12.10 的用户与 "template1" 数据库联接,
# 只要该用户提供了在 pg_shadow 里正确的口令.

host         template1   192.168.12.10 255.255.255.255    crypt

# 如果前面没有其它 "host" 行,那么下面两行将拒绝所有来自
# 192.168.54.1 的联接请求 (因为前面的记录先匹配
# 但是允许来自互联网上其它任何地方有效的 Kerberos V5 认证的联接
# 零掩码表示不考虑主机 IP 的任何位.因此它匹配任何主机:

host         all        192.168.54.1   255.255.255.255    reject
host         all        0.0.0.0        0.0.0.0            krb5

# 允许来自 192.168.x.x 的任何用户与任意数据库联接,只要他们通过 ident 检查
# 但如果 ident 说该用户是 "bryanh" 而他要求以 PostgreSQL 用户 "guest1" 联接,
# 那么只有在 `pg_ident.conf' 里有 "omicron" 的映射,说 "bryanh" 允许以
#  "guest1" 进行联接时才真正可以进行联接.

host         all        192.168.0.0    255.255.0.0        ident     omicron