2024 年 9 月 26 日: PostgreSQL 17 发布!
支持版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不支持的版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2

20.1. pg_hba.conf 文件 #

客户端认证由一个配置文件控制,该文件通常名为 pg_hba.conf,并存储在数据库集群的数据目录中。(HBA代表基于主机的身份验证。)当 initdb 初始化数据目录时,会安装一个默认的 pg_hba.conf 文件。但是,可以将身份验证配置文件放在其他位置;请参阅 hba_file 配置参数。

pg_hba.conf 文件在启动时和主服务器进程收到 SIGHUP 信号时读取。如果在活动系统上编辑该文件,则需要向 postmaster 发送信号(使用 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 文件的一般格式是一组记录,每行一条。空行和 # 注释字符后面的任何文本都会被忽略。可以使用反斜杠将记录续写到下一行。(除了在行尾,反斜杠没有特殊含义。)记录由若干个字段组成,这些字段用空格和/或制表符分隔。如果字段值用双引号括起来,则字段可以包含空格。引用数据库、用户或地址字段中的某个关键字(例如,allreplication)会使该词失去其特殊含义,只匹配名称与之匹配的数据库、用户或主机。即使在引用的文本或注释中,反斜杠行延续也适用。

每个身份验证记录都指定连接类型、客户端 IP 地址范围(如果与连接类型相关)、数据库名称、用户名以及用于匹配这些参数的连接的身份验证方法。使用第一个与连接类型、客户端地址、请求的数据库和用户名匹配的记录来执行身份验证。没有 贯穿备份:如果选择了一条记录,而身份验证失败,则不会考虑后续的记录。如果没有任何记录匹配,则拒绝访问。

每个记录可以是一个包含指令或一个身份验证记录。包含指令指定可以包含的文件,这些文件包含其他记录。这些记录将被插入到包含指令的位置。包含指令只包含两个字段:includeinclude_if_existsinclude_dir 指令以及要包含的文件或目录。该文件或目录可以是相对路径或绝对路径,也可以用双引号括起来。对于 include_dir 形式,将包含所有不以 . 开头且以 .conf 结尾的文件。包含目录中的多个文件按照文件名顺序处理(根据 C 地区设置规则,即数字在字母之前,大写字母在小写字母之前)。

记录可以有几种格式

local               database  user  auth-method [auth-options]
host                database  user  address     auth-method  [auth-options]
hostssl             database  user  address     auth-method  [auth-options]
hostnossl           database  user  address     auth-method  [auth-options]
hostgssenc          database  user  address     auth-method  [auth-options]
hostnogssenc        database  user  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]
hostgssenc          database  user  IP-address  IP-mask      auth-method  [auth-options]
hostnogssenc        database  user  IP-address  IP-mask      auth-method  [auth-options]
include             file
include_if_exists   file
include_dir         directory

这些字段的含义如下

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 配置参数来启用(有关更多信息,请参阅 第 18.9 节)。否则,将忽略 hostssl 记录,除非记录一条警告,指出它无法匹配任何连接。

hostnossl

此记录类型的行为与 hostssl 相反;它只匹配通过 TCP/IP 进行的连接尝试,这些尝试不使用SSL.

hostgssenc

此记录匹配使用 TCP/IP 进行的连接尝试,但仅当连接使用GSSAPI加密。

要使用此选项,服务器必须使用GSSAPI支持。否则,将忽略 hostgssenc 记录,除非记录一条警告,指出它无法匹配任何连接。

hostnogssenc

此记录类型的行为与 hostgssenc 相反;它只匹配通过 TCP/IP 进行的连接尝试,这些尝试不使用GSSAPI加密。

database

指定此记录匹配的数据库名称。值 all 指定它匹配所有数据库。值 sameuser 指定如果请求的数据库名称与请求的用户相同,则该记录匹配。值 samerole 指定请求的用户必须是与请求的数据库同名的角色的成员。(samegroupsamerole 的过时但仍然可接受的拼写。)除非超级用户是该角色的显式成员(直接或间接,不仅仅是由于是超级用户),否则它们不会被视为该角色的成员,以便于 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 Server 和 TCP Wrappers。

IP-address
IP-mask

这两个字段可以用作 IP-address/mask-length 表示法的替代方法。不是指定掩码长度,而是将实际掩码指定在单独的列中。例如,255.0.0.0 代表 IPv4 CIDR 掩码长度为 8,而 255.255.255.255 代表 CIDR 掩码长度为 32。

这些字段不适用于 local 记录。

auth-method

指定当连接匹配此记录时要使用的身份验证方法。可能的选项总结如下;详细信息请参见 第 20.3 节。所有选项均为小写,并区分大小写,因此即使像 ldap 这样的缩写词也必须指定为小写。

trust

无条件地允许连接。此方法允许任何能够连接到 PostgreSQL 数据库服务器的人以他们想要的任何 PostgreSQL 用户登录,无需密码或任何其他身份验证。有关详细信息,请参见 第 20.4 节

reject

无条件地拒绝连接。这对于过滤掉某些主机很有用,例如 reject 行可以阻止特定主机连接,而随后的行允许特定网络中的其余主机连接。

scram-sha-256

执行 SCRAM-SHA-256 身份验证以验证用户的密码。有关详细信息,请参见 第 20.5 节

md5

执行 SCRAM-SHA-256 或 MD5 身份验证以验证用户的密码。有关详细信息,请参见 第 20.5 节

password

要求客户端提供未加密的密码以进行身份验证。由于密码以明文形式通过网络发送,因此不应在不受信任的网络上使用它。有关详细信息,请参见 第 20.5 节

gss

使用 GSSAPI 对用户进行身份验证。这仅适用于 TCP/IP 连接。有关详细信息,请参见 第 20.6 节。它可以与 GSSAPI 加密一起使用。

sspi

使用 SSPI 对用户进行身份验证。这仅适用于 Windows。有关详细信息,请参见 第 20.7 节

ident

通过联系客户端上的 ident 服务器来获取客户端的操作系统用户名,并检查它是否与请求的数据库用户名匹配。Ident 身份验证只能用于 TCP/IP 连接。当指定用于本地连接时,将改为使用对等身份验证。有关详细信息,请参见 第 20.8 节

peer

从操作系统获取客户端的操作系统用户名,并检查它是否与请求的数据库用户名匹配。这仅适用于本地连接。有关详细信息,请参见 第 20.9 节

ldap

使用LDAP服务器进行身份验证。有关详细信息,请参见 第 20.10 节

radius

使用 RADIUS 服务器进行身份验证。有关详细信息,请参见 第 20.11 节

cert

使用 SSL 客户端证书进行身份验证。有关详细信息,请参见 第 20.12 节

pam

使用操作系统提供的可插拔身份验证模块 (PAM) 服务进行身份验证。有关详细信息,请参见 第 20.13 节

bsd

使用操作系统提供的 BSD 身份验证服务进行身份验证。有关详细信息,请参见 第 20.14 节

auth-options

auth-method 字段之后,可以存在形式为 name=value 的字段,这些字段指定身份验证方法的选项。有关哪些选项可用于哪些身份验证方法的详细信息,请参见下文。

除了下面列出的方法特定选项之外,还存在一个与方法无关的身份验证选项 clientcert,它可以在任何 hostssl 记录中指定。此选项可以设置为 verify-caverify-full。这两个选项都要求客户端提供有效的(受信任的)SSL 证书,而 verify-full 还会强制执行证书中的 cn(通用名)与用户名或适用的映射匹配。此行为类似于 cert 身份验证方法(参见 第 20.12 节),但允许将客户端证书的验证与支持 hostssl 条目的任何身份验证方法配对。

在使用客户端证书身份验证的任何记录(即使用 cert 身份验证方法或使用 clientcert 选项的记录)上,您可以使用 clientname 选项指定客户端证书凭据的哪个部分要匹配。此选项可以具有两个值之一。如果您指定 clientname=CN(默认值),则用户名将与证书的 Common Name (CN) 进行匹配。如果您改为指定 clientname=DN,则用户名将与证书的整个 Distinguished Name (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 连接要求密码。在这种情况下,指定了 trust 身份验证以用于来自 127.0.0.1 的连接的记录将出现在指定了密码身份验证以用于更广泛的允许客户端 IP 地址范围的记录之前。

提示

要连接到特定数据库,用户不仅要通过 pg_hba.conf 检查,还必须对该数据库拥有 CONNECT 权限。如果您希望限制哪些用户可以连接到哪些数据库,通常通过授予/撤销 CONNECT 权限来控制比在 pg_hba.conf 条目中设置规则更容易。

一些 pg_hba.conf 条目的示例在 示例 20.1 中显示。有关不同身份验证方法的详细信息,请参见下一节。

示例 20.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 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
host    "/^db\d{2,4}$"  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

提交更正

如果您在文档中看到任何不正确的内容,与您对特定功能的体验不符,或者需要进一步澄清,请使用 此表单 报告文档问题。