19.1. pg_hba.conf 文件

客户端认证是由一个配置文件 通常名为 pg_hba.conf 控制的,它存放在数据库集群的数据目录里。 (HBA的意思是host-based authentication,也就是基于主机的认证)。 在initdb初始化数据目录的时候,它会安装一个缺省的pg_hba.conf文件。不过我们也可以把认证配置文件放在其它地方; 参阅hba_file 配置参数。

pg_hba.conf文件的常用格式是一组记录,每行一条。空白行将被忽略, # 开头的注释也被忽略。 一条记录是由若干用空格和/或制表符分隔的字段组成。如果字段用引号包围,那么它可以包含空白。 在数据库或用户名称字段中引用关键字之一(例如, all或者replication)使字失去其特殊的 字符,只是匹配数据库或使用该名称的用户。

每条记录声明一种连接类型、一个客户端IP地址范围(如果和连接类型相关的话)、一个数据库名、一个用户名字、对匹配这些参数的连接使用的认证方法。第一条匹配连接类型、客户端地址、连接请求的数据库名和用户名的记录将用于执行认证。这个处理过程没有"fall-through"或者"backup"的说法:如果选择了一条记录而且认证失败,那么将不再考虑后面的记录。如果没有匹配的记录,那么访问将被拒绝。

每条记录可以是下面七种格式之一:

local      database  user  auth-method  [auth-options]
host       database  user  CIDR-address  auth-method  [auth-options]
hostssl    database  user  CIDR-address  auth-method  [auth-options]
hostnossl  database  user  CIDR-address  auth-method  [auth-options]
host       database  user  IP-address  IP-mask  auth-method  [auth-options]
hostssl    database  user  IP-address  IP-mask  auth-method  [auth-options]
hostnossl  database  user  IP-address  IP-mask  auth-method  [auth-options]

各个字段的含义如下:

local

这条记录匹配企图通过Unix域套接字进行的连接。没有这种类型的记录,就不允许Unix域套接字的连接。

host

这条记录匹配企图通过TCP/IP进行的连接。host记录匹配SSL和非SSL的连接尝试。

Note: 除非服务器带着合适的 listen_addresses配置参数, 配置参数值启动,否则将不可能进行远程的TCP/IP连接,因为缺省的行为是只监听本地自环地址localhost的连接。

hostssl

这条记录匹配企图使用TCP/IP的SSL连接。但必须是使用SSL加密的连接。

要使用这个选项,编译服务器的时候必须打开SSL支持。而且在服务器启动的时候必须打开SSL配置选项 参阅Section 17.8.

hostnossl

这条记录与hostssl相反;它只匹配那些在TCP/IP上不使用SSL的连接请求。

database

声明记录所匹配的数据库名称。 值all表明该记录匹配所有数据库,值 sameuser表示如果被请求的数据库和请求的用户同名,则匹配。值samerole 表示请求的用户必须是一个与数据库同名的角色中的成员 (samegroup是一个已经废弃了,但目前仍然被接受的samerole同义词。) replication值指定记录匹配,如果复制连接请求(注意:复制连接不指定任何特定的数据库)。 在其它情况里,这就是一个特定的PostgreSQL数据库名字。可以通过用逗号分隔的方法声明多个数据库,也可以通过前缀@来声明一个包含数据库名的文件。

user

为这条记录声明所匹配的数据库用户。 值all 表明它匹配于所有用户。 否则,它就是特定数据库用户的名字或者是一个前缀+的组名称。 请注意,在PostgreSQL里,用户和组没有真正的区别, +实际上只是意味着"匹配任何直接或者间接属于这个角色的成员", 而没有+记号的名字只匹配指定的角色。 多个用户名可以通过用逗号分隔的方法声明。 一个包含用户名的文件可以通过在文件名前面前缀@ 来声明。

CIDR-address

声明这条记录匹配的客户端机器的IP地址范围。 它包含一个标准的点分十进制的IP地址 (只能用数值而不能用域或主机名)和一个CIDR掩码长度。 掩码长度表示客户端IP地址必须匹配的高位二进制位数。 在给出的IP地址里,这个长度的右边的二进制位必须为零。 在IP地址、/、CIDR掩码长度之间不能有空白。

可以用samehost代替CIDR-address来匹配任何服务器自己的IP地址,或samenet匹配任何直接连接到服务器子网的地址。

典型的CIDR-address举例:172.20.143.89/32表示一个主机,172.20.143.0/24表示一个小子网,10.6.0.0/16表示一个大子网,0.0.0.0/0 ("all balls")表示所有地址。要声明单个主机,给IPv4地址声明CIDR掩码32,给IPv6地址声明128。不要在地址中省略结尾的0 。

以IPv4格式给出的IP地址会匹配那些拥有对应地址的IPv6连接,比如127.0.0.1将匹配IPv6地址::ffff:127.0.0.1。一个以IPv6格式给出的记录将只匹配IPv6连接,即使对应的地址在IPv4-in-IPv6范围内。请注意如果系统的C库不支持IPv6地址,那么IPv6的格式将被拒绝。

这个字段只适用于hosthostsslhostnossl记录。

IP-address
IP-mask

这些方法可以用于作为 CIDR-address表示法的替补。 它不是声明掩码的长度,而是在另外一个字段里声明实际的掩码。 比如,255.0.0.0表示IPv4 CIDR掩码长度8,而255.255.255.255表示CIDR掩码长度32。

这些字段只适用于host, hostsslhostnossl记录。

auth-method

声明通过这条记录连接的时候使用的认证方法。可能的选择在下面简介,详细情况在Section 19.3中介绍。

trust

无条件地允许连接。这个方法允许任何可以与PostgreSQL数据库服务器连接的用户以他们期望的任意PostgreSQL数据库用户身份进行连接,而不需要口令或者其他任何认证。 参阅Section 19.3.1 获取详细信息。

reject

无条件地拒绝连接。筛选出若干主机是有用的,例如 reject行可以阻止一个特定的主机连接, 而稍后线允许在一个特定的其余主机进行 网络连接。

md5

要求客户端提供一个MD5加密的口令进行认证。 参阅Section 19.3.2 获得详细信息.

password

要求客户端提供一个未加密的口令进行认证。因为口令是以明文形式在网络上传递的,所以我们不应该在不安全的网络上使用这个方式。并且它通常还不能和线程化的客户端应用一起使用。 参阅Section 19.3.2 获得信息信息。

gss

用GSSAPI认证用户。只有在进行TCP/IP连接的时候才可能用。参阅Section 19.3.3获得详细信息。

sspi

用SSPI来认证用户。这仅仅是 在Windows上使用。参阅Section 19.3.4获得详细信息。

krb5

用Kerberos V5 认证用户。只有在进行TCP/IP连接的时候才能用。 参阅 Section 19.3.5获得详细信息.

ident

获取客户的操作系统名然后检查该用户是否允许以要求的数据库用户名进行连接, 对于TCP/IP连接,通过连接在客户端上的ident服务器进行判断的,对于本地连接,它是从操作系统获取的。 参见Section 19.3.6获得详细信息.

ldap

使用LDAP服务器认证。参阅Section 19.3.7获得详细信息。

radius

用RADIUS服务器认证,参阅Section 19.3.8获得详细信息。

cert

使用SSL客户端证书认证。参阅Section 19.3.9获得详细信息。

pam

使用操作系统提供的可插入认证模块服务(PAM)来认证。 参阅Section 19.3.10 获得详细信息.

auth-options

auth-method字段之后,形式name=value的字段集 是认证方法的指定选择。关于选项可用的详情,认证方法在下面。

@构造包含的文件是当作一列名字读取的, 这些名字可以用空白或者逗号分隔。 注释用#引入,就像在pg_hba.conf里那样, 允许嵌套@构造。除非跟在@后面的文件名是一个绝对路径, 否则被当作与该文件所在目录相对的路径。

因为认证时系统是为每个连接请求顺序检查 pg_hba.conf里的记录的, 所以这些记录的顺序是非常关键的。 通常,靠前的记录有比较严的连接匹配参数和比较弱的认证方法, 而靠后的记录有比较松的匹配参数和比较严的认证方法。 比如,我们一般都希望对本地TCP/IP连接使用trust认证, 而对远端的TCP/IP连接要求口令。 在这种情况下我们将trust认证方法用于来自127.0.0.1的连接, 这条记录将出现在允许更广泛的客户端IP地址的使用口令认证的记录前面。

在启动和主服务器进程收到SIGHUP信号的时候, 系统都会重新装载pg_hba.conf文件。 如果你在活跃的系统上编辑了该文件, 就必须通知服务器(使用pg_ctl reloadkill -HUP) 重新加载该文件。

Tip: 一个用户要想成功连接到特定的数据库, 不仅需要通过pg_hba.conf的检查, 还必须要有该数据库上的CONNECT权限。 如果希望限制哪些用户能够连接到哪些数据库, 赋予/撤销CONNECT权限通常比在pg_hba.conf 中设置规则简单。

Example 19-1里是 pg_hba.conf 记录的一些例子。阅读下文理解不同认证方法的细节。

Example 19-1. Example pg_hba.conf entries例20-1 pg_hba.conf 记录的例子

#允许在本机上的任何用户使用 Unix 域套接字(缺省为本地连接)以任何数据库用户身份连接任何数据库
#
# TYPE  DATABASE        USER            CIDR-ADDRESS            METHOD
local   all             all                                     trust

#和上面相同,但是使用的是回环的(loopback)TCP/IP 连接
#
# TYPE  DATABASE        USER            CIDR-ADDRESS            METHOD
host    all             all             127.0.0.1/32            trust

##和上面一行相同,但是用的是独立的掩码字段
# TYPE  DATABASE        USER            IP-ADDRESS      IP-MASK             METHOD
host    all             all             127.0.0.1       255.255.255.255     trust

# 允许 IP 地址为 192.168.93.x 的任何主机与 "postgres" 数据库相连,
#用与他们在自己的主机上相同 ident 的用户名标识他自己(通常是他的 Unix 用户名)
#
# TYPE  DATABASE        USER            CIDR-ADDRESS            METHOD
host    postgres        all             192.168.93.0/24         ident

# 允许来自主机 192.168.12.10 的用户提供了正确的口令之后与 "postgres" 数据库连接。
#
# TYPE  DATABASE        USER            CIDR-ADDRESS            METHOD
host    postgres        all             192.168.12.10/32        md5

# 如果前面没有其它 "host" 行,那么下面两行将拒绝所有来自 192.168.54.1 的连接请求(因为前面的记录先匹配)。
# 但是允许来自互联网上其它任何地方的有效的 Kerberos 5 认证的连接。
# 零掩码表示不考虑主机 IP 的任何位。因此它匹配任何主机。
#
# TYPE  DATABASE        USER            CIDR-ADDRESS            METHOD
host    all             all             192.168.54.1/32         reject
host    all             all             0.0.0.0/0               krb5

#允许来自 192.168.x.x 的任何用户与任意数据库连接,只要他们通过 ident 检查。
# 但如果 ident 说该用户是 "bryanh" 且他要求以 PostgreSQL 用户 "guest1" 连接,
# 那么只有在 pg_ident.conf 里有 "omicron" 的映射说 "bryanh" 允许以 "guest1" 进行连接时才真正可以进行连接。
#
# TYPE  DATABASE        USER            CIDR-ADDRESS            METHOD
host    all             all             192.168.0.0/16          ident map=omicron

#如果下面是用于本地连接的仅有的三行,那么它们将允许本地用户只和同名数据库连接。
# 只有管理员和 "support" 角色里的成员例外,他们可以连接到任何数据库。
#
# TYPE  DATABASE        USER            CIDR-ADDRESS            METHOD
local   sameuser        all                                     md5
local   all             @admins                                 md5
local   all             +support                                md5

#上面最后两行可以合起来写成一行:
local   all             @admins,+support                        md5

# 数据库字段也可以使用列表和文件名
local   db1,db2,@demodbs  all                                   md5