pg_hba.conf
文件
客户端身份验证由一个配置文件控制,传统上被命名为
pg_hba.conf
,并存储在集簇的数据目录中。
(HBA代表基于主机的身份验证。)当数据
目录被 initdb 初始化时,会安装一个默认的
pg_hba.conf
文件。
但是也可以将身份验证配置文件放在其他地方;
请参见 hba_file 配置参数。
pg_hba.conf
文件的常用格式是一组记录,每行一条。
空白行将被忽略, #
注释字符后面的任何文本也被忽略。
记录可以延续到下一行并以反斜线结束该行。(反斜线不是特定的的,除了在行尾。)
一条记录由若干用空格和/或制表符分隔的域组成。
如果域值用双引号包围,那么它可以包含空白。
在数据库、用户或地址域中引用一个关键字(例如,all
或replication
)将使该词失去其特殊含义,并且只是匹配一个有该名字的数据库、用户或主机。
反斜线行的延续在引用文本或注释中也可以使用。
每条记录指定一种连接类型、一个客户端 IP 地址范围(如果和连接类型相关)、一个数据库名、一个用户名以及对匹配这些参数的连接使用的认证方法。第一条匹配连接类型、客户端地址、连接请求的数据库和用户名的记录将被用于执行认证。这个过程没有“落空”或者“后备”的说法:如果选择了一条记录而且认证失败,那么将不再考虑后面的记录。如果没有匹配的记录,那么访问将被拒绝。
一条记录可以有多种格式:
localdatabase
user
auth-method
[auth-options
] hostdatabase
user
address
auth-method
[auth-options
] hostssldatabase
user
address
auth-method
[auth-options
] hostnossldatabase
user
address
auth-method
[auth-options
] hostgssencdatabase
user
address
auth-method
[auth-options
] hostnogssencdatabase
user
address
auth-method
[auth-options
] hostdatabase
user
IP-address
IP-mask
auth-method
[auth-options
] hostssldatabase
user
IP-address
IP-mask
auth-method
[auth-options
] hostnossldatabase
user
IP-address
IP-mask
auth-method
[auth-options
] hostgssencdatabase
user
IP-address
IP-mask
auth-method
[auth-options
] hostnogssencdatabase
user
IP-address
IP-mask
auth-method
[auth-options
]
字段的含义如下:
local
这个记录匹配使用Unix域套接字的连接尝试。没有这种类型的记录,Unix域套接字连接是不允许的。
host
这个记录匹配使用TCP/IP进行的连接尝试。
host
记录匹配
SSL或非SSL连接
尝试,以及GSSAPI加密或
非GSSAPI加密连接尝试。
远程TCP/IP连接将无法实现,除非服务器以适当的值启动
listen_addresses配置参数,
因为默认行为是仅在本地回环地址localhost
上监听TCP/IP连接。
hostssl
这条记录匹配使用TCP/IP进行的连接尝试,但仅当连接使用SSL加密时。
要使用此选项,服务器必须构建支持SSL。
此外,必须通过设置ssl配置参数来启用SSL
(有关更多信息,请参见第 19.9 节)。
否则,hostssl
记录将被忽略,除了记录一个警告,说明它无法匹配任何连接。
hostnossl
这个记录类型与hostssl
的行为相反;它只匹配通过TCP/IP进行的不使用SSL的连接尝试。
hostgssenc
这条记录匹配使用TCP/IP进行的连接尝试,但仅当连接使用GSSAPI加密时。
要使用此选项,服务器必须构建具有GSSAPI支持。
否则,hostgssenc
记录将被忽略,除了记录一个警告,说明它无法匹配任何连接。
hostnogssenc
这个记录类型与hostgssenc
的行为相反;
它只匹配通过TCP/IP进行的不使用GSSAPI加密的连接尝试。
database
指定此记录匹配的数据库名称。值all
指定匹配所有数据库。
值sameuser
指定如果请求的数据库与请求的用户具有相同的名称,则记录匹配。
值samerole
指定请求的用户必须是与请求的数据库具有相同名称的角色的成员。
(samegroup
是samerole
的一个过时但仍然被接受的拼写。)
超级用户不被视为samerole
的角色成员,除非他们明确是该角色的成员,直接或间接地,而不仅仅是因为是超级用户。
值replication
指定如果请求了物理复制连接,则记录匹配,但不匹配逻辑复制连接。请注意,物理复制连接不指定任何特定的数据库,而逻辑复制连接则指定。
否则,这是一个特定的PostgreSQL数据库的名称。
可以通过用逗号分隔它们来提供多个数据库名称。可以通过在文件名前加上@
来指定包含数据库名称的单独文件。
user
指定此记录匹配哪些数据库用户名。值all
指定匹配所有用户。
否则,这可以是特定数据库用户的名称,或者是以+
开头的组名。
(请记住,在PostgreSQL中,用户和组之间没有真正的区别;
+
标记实际上意味着“匹配直接或间接是此角色成员的任何角色”,
而没有+
标记的名称仅匹配该特定角色。)对于此目的,只有超级用户
被认为是角色的成员,如果他们明确是该角色的成员,直接或间接地,而不仅仅是因为
是超级用户。
可以通过用逗号分隔它们来提供多个用户名。可以通过在文件名前加上@
来指定包含用户名的单独文件。
address
指定此记录匹配的客户端机器地址。此字段可以包含主机名、IP地址范围或下面提到的特殊关键字之一。
IP地址范围使用标准的数字表示法来指定起始地址,然后是斜杠(/
)和一个CIDR掩码长度。
掩码长度表示客户端IP地址必须匹配的高位比特数。给定IP地址中右侧的比特应为零。
IP地址、/
和CIDR掩码长度之间不得有任何空格。
以这种方式指定的IPv4地址范围的典型示例包括172.20.143.89/32
用于单个主机,
或172.20.143.0/24
用于小型网络,或10.6.0.0/16
用于较大的网络。
IPv6地址范围可能看起来像::1/128
用于单个主机(在这种情况下是IPv6环回地址)或
fe80::7a31:c1ff:0000:0000/96
用于小型网络。
0.0.0.0/0
代表所有IPv4地址,::0/0
代表所有IPv6地址。
要指定单个主机,请对IPv4使用32的掩码长度,对IPv6使用128。在网络地址中,不要省略尾部的零。
以IPv4格式给出的条目将仅匹配IPv4连接,以IPv6格式给出的条目将仅匹配IPv6连接, 即使所代表的地址在IPv4-in-IPv6范围内。请注意,如果系统的C库不支持IPv6地址, 以IPv6格式给出的条目将被拒绝。
你也可以写all
来匹配任何IP地址,
samehost
来匹配服务器自己的任何IP地址,
或samenet
来匹配服务器直接连接到的任何子网中的任何地址。
如果指定了主机名(任何不是IP地址范围或特殊关键字的内容都被视为主机名),
则将该名称与客户端IP地址的反向名称解析结果进行比较(例如,如果使用DNS,则进行反向DNS查找)。
主机名比较不区分大小写。如果匹配成功,则对主机名执行正向名称解析(例如,进行正向DNS查找),
以检查其解析为的任何地址是否等于客户端IP地址。如果两个方向都匹配,则将条目视为匹配。
(在pg_hba.conf
中使用的主机名应该是客户端IP地址的地址到名称解析返回的名称,
否则该行将不会匹配。一些主机名数据库允许将IP地址与多个主机名关联,
但操作系统在要求解析IP地址时只会返回一个主机名。)
以点(.
)开头的主机名规范匹配实际主机名的后缀。
因此,.example.com
将匹配foo.example.com
(但不仅仅是example.com
)。
当在pg_hba.conf
中指定主机名时,您应确保名称解析相对快速。
最好设置一个本地名称解析缓存,如nscd
。
此外,您可能希望启用配置参数log_hostname
,以在日志中看到客户端的主机名而不是IP地址。
这些字段不适用于local
记录。
用户有时会想知道为什么主机名以这种看似复杂的方式处理,包括两次名称解析,其中包括对客户端IP地址的反向查找。
如果客户端的反向DNS条目未设置或生成了一些不良的主机名,则使用该功能会变得复杂。
这主要是为了效率:这样,连接尝试最多需要两次解析器查找,一次反向查找和一次正向查找。
如果某个地址存在解析器问题,那就只会成为该客户端的问题。
一个假设的替代实现只进行正向查找的情况下,在每次连接尝试期间都必须解析pg_hba.conf
中提到的每个主机名。
如果列出了许多名称,这可能会非常慢。
如果其中一个主机名存在解析器问题,那么这将成为所有人的问题。
此外,实现后缀匹配功能需要进行反向查找,因为需要知道实际客户端主机名 以便将其与模式进行匹配。
请注意,这种行为与其他流行的基于主机名的访问控制实现一致,例如 Apache HTTP服务器和TCP包装器。
IP-address
IP-mask
这两个字段可以用作IP地址
/
掩码长度
表示法的替代方案。而不是指定掩码长度,实际掩码在一个单独的列中指定。
例如,255.0.0.0
表示IPv4的CIDR掩码长度为8,
而255.255.255.255
表示CIDR掩码长度为32。
这些字段不适用于local
记录。
auth-method
指定连接匹配此记录时要使用的身份验证方法。可能的选择在这里总结; 详细信息在第 21.3 节中。所有选项都是小写的,并且区分大小写,因此即使是像ldap
这样的首字母缩写也必须指定为小写。
trust
允许无条件连接。这种方法允许任何可以连接到PostgreSQL数据库服务器的人以任何他们希望的PostgreSQL用户登录,无需密码或任何其他身份验证。有关详细信息,请参见第 21.4 节。
reject
无条件拒绝连接。这对于“过滤掉”某些主机很有用,例如一个reject
行可以阻止特定主机连接,
而后面的行允许特定网络中的其余主机连接。
scram-sha-256
执行SCRAM-SHA-256身份验证以验证用户的密码。详细信息请参见第 21.5 节。
md5
执行SCRAM-SHA-256或MD5身份验证以验证用户的密码。详细信息请参见第 21.5 节。
password
要求客户端提供未加密的密码进行身份验证。 由于密码以明文形式通过网络发送,因此不应在不受信任的网络上使用。 详细信息请参见第 21.5 节。
gss
使用GSSAPI对用户进行身份验证。这仅适用于TCP/IP连接。有关详细信息,请参见第 21.6 节。它可以与GSSAPI加密一起使用。
sspi
使用SSPI对用户进行身份验证。这仅适用于Windows。有关详细信息,请参见第 21.7 节。
ident
通过联系客户端上的ident服务器获取操作系统用户名称, 并检查是否与请求的数据库用户名称匹配。 Ident身份验证只能用于TCP/IP连接。 当为本地连接指定时,将改为使用对等身份验证。 详细信息请参见第 21.8 节。
peer
从操作系统获取客户端的操作系统用户名,并检查是否与请求的数据库用户名匹配。 这仅适用于本地连接。 有关详细信息,请参见第 21.9 节。
ldap
使用LDAP服务器进行身份验证。有关详细信息,请参见第 21.10 节。
radius
使用RADIUS服务器进行身份验证。详细信息请参见第 21.11 节。
cert
使用SSL客户端证书进行身份验证。详情请参见第 21.12 节。
pam
使用操作系统提供的可插拔认证模块(PAM)服务进行身份验证。详细信息请参见第 21.13 节。
bsd
使用操作系统提供的BSD认证服务进行身份验证。有关详细信息,请参见第 21.14 节。
auth-options
在auth-method
字段之后,可以是形如name
=
value
的字段,
用于指定认证方法的选项。关于哪些选项适用于哪些认证方法的详细信息见下文。
除了下面列出的特定于方法的选项外,还有一个方法无关的身份验证选项clientcert
,
可以在任何hostssl
记录中指定。
此选项可以设置为verify-ca
或verify-full
。
这两个选项都要求客户端提供有效(受信任的)SSL证书,
而verify-full
还要求证书中的cn
(通用名称)与用户名或适用映射匹配。
这种行为类似于cert
身份验证方法(请参阅第 21.12 节),
但允许将客户端证书的验证与支持hostssl
条目的任何身份验证方法配对。
在使用客户端证书认证的任何记录上(即使用cert
认证方法或使用clientcert
选项的记录),您可以使用clientname
选项指定要匹配的客户端证书凭据的哪个部分。此选项可以有两个值之一。如果您指定clientname=CN
,这是默认值,则用户名将与证书的Common Name (CN)
进行匹配。如果您改为指定clientname=DN
,则用户名将与证书的整个Distinguished Name (DN)
进行匹配。此选项最好与用户名映射一起使用。比较是使用DN
以RFC 2253格式进行的。要查看以此格式显示的客户端证书的DN
,请执行
openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject=//"
在使用此选项时需要小心,特别是在使用正则表达式匹配DN
时。
用@
结构包括的文件被读作一个名字列表,它们可以用空白或者逗号分隔。注释用#
引入,就像在pg_hba.conf
中那样,并且允许嵌套@
结构。除非跟在@
后面的文件名是一个绝对路径, 文件名都被认为是相对于包含引用文件的目录。
因为每一次连接尝试都会顺序地检查pg_hba.conf
记录,所以这些记录的顺序是非常关键的。通常,靠前的记录有比较严的连接匹配参数和比较弱的认证方法,而靠后的记录有比较松的匹配参数和比较强的认证方法。 例如,我们希望对本地 TCP/IP 连接使用trust
认证,而对远程 TCP/IP 连接要求口令。在这种情况下为来自于 127.0.0.1 的连接指定trust
认证的记录将出现在为一个更宽范围的客户端 IP 地址指定口令认证的记录前面。
在启动以及主服务器进程收到SIGHUP信号时,pg_hba.conf
文件会被读取。
如果你在活动的系统上编辑了该文件,你将需要通知 postmaster(使用pg_ctl reload
,调用SQL函数pg_reload_conf()
,或使用kill -HUP
)使其重新读取该文件。
前面的说明在Microsoft Windows上不为真:在Windows上,pg_hba.conf
文件中的任何更改会立即被应用到后续的新连接上。
系统视图pg_hba_file_rules
有助于预先测试对pg_hba.conf
文件的更改,该视图也可以在该文件的装载没有产生预期效果时用于诊断问题。该视图中带有非空error
域的行就表示该文件对应行中存在问题。
要连接到一个特定数据库,一个用户必须不仅要通过pg_hba.conf
检查,还必须要有该数据库上的CONNECT
权限。如果你希望限制哪些用户能够连接到哪些数据库,授予/撤销CONNECT
权限通常比在pg_hba.conf
项中设置规则简单。
例 21.1中展示了pg_hba.conf
项的一些例子。不同认证方法的详情请见下一节。
例 21.1. 示例 pg_hba.conf
项
# 允许本地系统上的任何用户 # 通过 Unix 域套接字以任意 # 数据库用户名连接到任意数据库(本地连接的默认值)。 # # TYPE DATABASE USER ADDRESS METHOD local all all trust # 相同的规则,但是使用本地环回 TCP/IP 连接。 # # TYPE DATABASE USER 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 # IPv6 上相同的规则 # # TYPE DATABASE USER ADDRESS METHOD host all all ::1/128 trust # 使用主机名的相同规则(通常同时覆盖 IPv4 和 IPv6)。 # # TYPE DATABASE USER ADDRESS METHOD host all all localhost trust # 允许来自任意具有 IP 地址192.168.93.x 的主机上任意 # 用户以 ident 为该连接所报告的相同用户名连接到 # 数据库 "postgres"(通常是操作系统用户名)。 # # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.93.0/24 ident # 如果用户的口令被正确提供,允许来自主机 192.168.12.10 # 的任意用户连接到数据库 "postgres"。 # # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.12.10/32 scram-sha-256 # 如果用户的口令被正确提供,允许 example.com 中主机上 # 的任意用户连接到任意数据库。 # # 为大部分用户要求SCRAM认证,但是用户'mike'是个例外, # 他使用的是不支持SCRAM认证的旧客户端。 # # TYPE DATABASE USER ADDRESS METHOD host all mike .example.com md5 host all all .example.com scram-sha-256 # 如果没有前面的 "host" 行,这三行 # 将拒绝所有来自 192.168.54.1的连接(因为那些项将首先被匹配), # 但是允许来自互联网其他任何地方的 # GSSAPI-encrypted连接。零掩码导致主机IP 地址中的所有位都不会被考虑, # 因此它匹配任意主机。未加密GSSAPI连接 # (which "跳转"到第三行是因为"hostgssenc" 仅匹配加密的 GSSAPI 连接) 是被允许的,但只能来自192.168.12.10. # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.54.1/32 reject hostgssenc all all 0.0.0.0/0 gss host all all 192.168.12.10/32 gss # 允许来自 192.168.x.x 主机的用户连接到任意数据库,如果它们能够 # 通过 ident 检查。例如,假设 ident说用户是 "bryanh" 并且他要求以 # PostgreSQL 用户 "guest1" 连接,如果在 pg_ident.conf 有一个映射 # "omicron" 的选项说 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.0.0/16 ident map=omicron # 如果这些是本地连接的唯一三行,它们将允许本地用户只连接到它们 # 自己的数据库(与其数据库用户名同名的数据库),不过管理员和角 # 色 "support" 的成员除外(它们可以连接到所有数据库)。文件 # $PGDATA/admins 包含一个管理员名字的列表。在所有情况下都要求口令。 # # TYPE DATABASE USER 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