pg_hba.conf
文件 #客户端认证由一个配置文件控制,传统上命名为 pg_hba.conf
,并存储在数据库集群的数据目录中。(HBA 代表基于主机的认证。)当数据目录由 initdb 初始化时,将安装一个默认的 pg_hba.conf
文件。但是,可以将认证配置文件放在其他位置;请参阅 hba_file 配置参数。
pg_hba.conf
文件的一般格式是一组记录,每行一个记录。空白行将被忽略,#
注释字符之后的任何文本也将被忽略。可以通过在行尾加上反斜杠来将记录续到下一行。(反斜杠只有在行尾时才特殊。)记录由若干个字段组成,这些字段由空格和/或制表符分隔。如果字段值用双引号引起来,则字段可以包含空格。在数据库、用户或地址字段中引用其中一个关键字(例如,all
或 replication
),会使该词失去其特殊含义,并且仅匹配具有该名称的数据库、用户或主机。反斜杠行续行甚至适用于引号引起来的文本或注释。
每个认证记录指定一个连接类型、一个客户端 IP 地址范围(如果与连接类型相关)、一个数据库名称、一个用户名以及用于匹配这些参数的连接的认证方法。具有匹配连接类型、客户端地址、请求的数据库和用户名的第一个记录用于执行认证。没有 “后备” 或 “备份”:如果选择了一个记录并且认证失败,则不会考虑后续记录。如果没有匹配的记录,则拒绝访问。
每个记录可以是包含指令或认证记录。包含指令指定可以包含的其他记录的文件。这些记录将插入包含指令的位置。包含指令只包含两个字段:include
、include_if_exists
或 include_dir
指令和要包含的文件或目录。该文件或目录可以是相对路径或绝对路径,并且可以加上双引号。对于 include_dir
形式,将包含所有不以 .
开头且以 .conf
结尾的文件。包含目录中的多个文件将按文件名顺序处理(根据 C 语言环境规则,即数字在字母之前,大写字母在小写字母之前)。
记录可以有多种格式
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
] includefile
include_if_existsfile
include_dirdirectory
字段的含义如下
local
此记录匹配使用 Unix 域套接字的连接尝试。如果没有此类型的记录,则不允许 Unix 域套接字连接。
host
此记录匹配使用 TCP/IP 进行的连接尝试。host
记录匹配 SSL 或非 SSL 连接尝试以及 GSSAPI 加密或非 GSSAPI 加密连接尝试。
除非服务器使用 listen_addresses 配置参数的适当值启动,否则远程 TCP/IP 连接将不可用,因为默认行为仅在本地环回地址 localhost
上侦听 TCP/IP 连接。
hostssl
此记录匹配使用 TCP/IP 进行的连接尝试,但仅当连接使用 SSL 加密时。
要使用此选项,服务器必须使用 SSL 支持构建。此外,必须通过设置 ssl 配置参数启用 SSL(有关更多信息,请参见 第 19.9 节)。否则,hostssl
记录将被忽略,但会记录一条警告,指出它无法匹配任何连接。
hostnossl
此记录类型的行为与 hostssl
相反;它仅匹配未使用 SSL 通过 TCP/IP 进行的连接尝试。
hostgssenc
此记录匹配使用 TCP/IP 进行的连接尝试,但仅当连接使用 GSSAPI 加密时。
要使用此选项,服务器必须使用 GSSAPI 支持构建。否则,hostgssenc
记录将被忽略,但会记录一条警告,指出它无法匹配任何连接。
hostnogssenc
此记录类型的行为与 hostgssenc
相反;它仅匹配未使用 GSSAPI 加密通过 TCP/IP 进行的连接尝试。
database
指定此记录匹配的数据库名称。值 all
指定它匹配所有数据库。值 sameuser
指定如果请求的数据库与请求的用户同名,则记录匹配。值 samerole
指定请求的用户必须是与请求的数据库同名的角色的成员。(samegroup
是 samerole
的过时拼写,但仍被接受。)对于 samerole
的目的,超级用户不被视为角色的成员,除非它们直接或间接地显式成为角色的成员,而不仅仅是因为它们是超级用户。值 replication
指定如果请求物理复制连接,则记录匹配,但是它与逻辑复制连接不匹配。请注意,物理复制连接不指定任何特定数据库,而逻辑复制连接则指定。否则,这是特定 PostgreSQL 数据库或正则表达式的名称。可以通过用逗号分隔多个数据库名称和/或正则表达式来提供它们。
如果数据库名称以斜杠 (/
) 开头,则名称的其余部分将被视为正则表达式。(有关 PostgreSQL 的正则表达式语法的详细信息,请参见 第 9.7.3.1 节。)
可以通过在文件名前面加上 @
来指定包含数据库名称和/或正则表达式的单独文件。
user
指定此记录匹配的数据库用户名。值 all
指定它匹配所有用户。否则,这可能是特定数据库用户的名称、正则表达式(以斜杠 (/
) 开头)或以 +
为前缀的组名。(请记住,在 PostgreSQL 中,用户和组之间没有真正的区别;+
标记实际上表示 “匹配直接或间接属于此角色的任何角色”,而没有 +
标记的名称仅匹配该特定角色。)为此目的,只有当超级用户直接或间接显式成为角色的成员时,才将其视为角色的成员,而不仅仅是由于其是超级用户。可以通过用逗号分隔多个用户名和/或正则表达式来提供它们。
如果用户名以斜杠 (/
) 开头,则名称的其余部分将被视为正则表达式。(有关 PostgreSQL 的正则表达式语法的详细信息,请参见 第 9.7.3.1 节。)
可以通过在文件名前面加上 @
来指定包含用户名和/或正则表达式的单独文件。
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 范围内也是如此。
您还可以编写 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 Wrappers)一致。
IP 地址
IP 掩码
这两个字段可以用作 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
(这是默认值),则用户名将与证书的 通用名称 (CN)
匹配。如果您指定 clientname=DN
,则用户名将与证书的整个 专有名称 (DN)
匹配。此选项最适合与用户名映射结合使用。比较使用 RFC 2253 格式中的 DN
进行。要查看此格式中客户端证书的 DN
,请执行
openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject=//"
使用此选项时需要小心,尤其是在对 DN
使用正则表达式匹配时。
include
此行将替换为给定文件的内容。
include_if_exists
如果文件存在,此行将替换为给定文件的内容。否则,将记录一条消息以指示已跳过该文件。
include_dir
如果文件名称不以 .
开头且以 .conf
结尾,此行将替换为目录中找到的所有文件的内容,按文件名顺序处理(根据 C 区域设置规则,即数字在字母之前,大写字母在小写字母之前)。
由 @
构造包含的文件被读作名称列表,这些名称可以用空格或逗号分隔。注释以 #
引入,就像在 pg_hba.conf
中一样,并且允许嵌套 @
构造。除非 @
后面的文件名是绝对路径,否则它将被视为相对于包含引用文件的目录。
由于 pg_hba.conf
记录会针对每次连接尝试按顺序检查,因此记录的顺序至关重要。通常,较早的记录将具有严格的连接匹配参数和较弱的身份验证方法,而较晚的记录将具有较宽松的匹配参数和较强身份验证方法。例如,你可能希望对本地 TCP/IP 连接使用 trust
身份验证,但要求远程 TCP/IP 连接提供密码。在这种情况下,指定来自 127.0.0.1 的连接的 trust
身份验证的记录将出现在指定对更广泛的允许客户端 IP 地址范围进行密码身份验证的记录之前。
在启动时和主服务器进程收到 SIGHUP 信号时,将读取 pg_hba.conf
文件。如果你在活动系统上编辑该文件,则需要向后端程序发送信号(使用 pg_ctl reload
、调用 SQL 函数 pg_reload_conf()
或使用 kill -HUP
)以使其重新读取该文件。
上述语句在 Microsoft Windows 上不成立:在该系统上,pg_hba.conf
文件中的任何更改都将立即应用于后续新连接。
系统视图 pg_hba_file_rules
有助于预先测试对 pg_hba.conf
文件的更改,或在加载文件未产生预期效果时诊断问题。视图中具有非空 error
字段的行指示文件中相应行的存在问题。
要连接到特定数据库,用户不仅必须通过 pg_hba.conf
检查,还必须具有该数据库的 CONNECT
权限。如果你希望限制哪些用户可以连接到哪些数据库,通常通过授予/撤销 CONNECT
权限比在 pg_hba.conf
条目中设置规则更容易控制。
一些 pg_hba.conf
条目的示例显示在 示例 21.1 中。有关不同身份验证方法的详细信息,请参见下一节。
示例 21.1. 示例 pg_hba.conf
条目
# Allow any user on the local system to connect to any database with # any database user name using Unix-domain sockets (the default for local # connections). # # TYPE DATABASE USER ADDRESS METHOD local all all trust # The same using local loopback TCP/IP connections. # # TYPE DATABASE USER ADDRESS METHOD host all all 127.0.0.1/32 trust # The same as the previous line, but using a separate netmask column # # TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD host all all 127.0.0.1 255.255.255.255 trust # The same over IPv6. # # TYPE DATABASE USER ADDRESS METHOD host all all ::1/128 trust # The same using a host name (would typically cover both IPv4 and IPv6). # # TYPE DATABASE USER ADDRESS METHOD host all all localhost trust # The same using a regular expression for DATABASE, that allows connection # to the database db1, db2 and any databases with a name beginning with "db" # and finishing with a number using two to four digits (like "db1234" or # "db12"). # # TYPE DATABASE USER ADDRESS METHOD local db1,"/^db\d{2,4}$",db2 all localhost trust # Allow any user from any host with IP address 192.168.93.x to connect # to database "postgres" as the same user name that ident reports for # the connection (typically the operating system user name). # # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.93.0/24 ident # Allow any user from host 192.168.12.10 to connect to database # "postgres" if the user's password is correctly supplied. # # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.12.10/32 scram-sha-256 # Allow any user from hosts in the example.com domain to connect to # any database if the user's password is correctly supplied. # # Require SCRAM authentication for most users, but make an exception # for user 'mike', who uses an older client that doesn't support SCRAM # authentication. # # TYPE DATABASE USER ADDRESS METHOD host all mike .example.com md5 host all all .example.com scram-sha-256 # In the absence of preceding "host" lines, these three lines will # reject all connections from 192.168.54.1 (since that entry will be # matched first), but allow GSSAPI-encrypted connections from anywhere else # on the Internet. The zero mask causes no bits of the host IP address to # be considered, so it matches any host. Unencrypted GSSAPI connections # (which "fall through" to the third line since "hostgssenc" only matches # encrypted GSSAPI connections) are allowed, but only from 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 # Allow users from 192.168.x.x hosts to connect to any database, if # they pass the ident check. If, for example, ident says the user is # "bryanh" and he requests to connect as PostgreSQL user "guest1", the # connection is allowed if there is an entry in pg_ident.conf for map # "omicron" that says "bryanh" is allowed to connect as "guest1". # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.0.0/16 ident map=omicron # If these are the only four lines for local connections, they will # allow local users to connect only to their own databases (databases # with the same name as their database user name) except for users whose # name end with "helpdesk", administrators and members of role "support", # who can connect to all databases. The file $PGDATA/admins contains a # list of names of administrators. Passwords are required in all cases. # # TYPE DATABASE USER ADDRESS METHOD local sameuser all md5 local all /^.*helpdesk$ md5 local all @admins md5 local all +support md5 # The last two lines above can be combined into a single line: local all @admins,+support md5 # The database column can also use lists and file names: local db1,db2,@demodbs all md5