20.1. pg_hba.conf 文件

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

pg_hba.conf文件的一般格式是一组记录,每行一条。空行以及#Comments 字符后的任何文本都将被忽略。记录不能跨行 continue。记录由许多由空格和/或制表符分隔的字段组成。如果字段值用双引号引起来,则字段可以包含空格。引用数据库,用户或地址字段中的关键字之一(例如allreplication)会使该单词失去其特殊含义,仅与该名称的数据库,用户或主机匹配。

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

记录可以具有以下七个格式之一

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]
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上侦听 TCP/IP 连接。

  • hostssl

    • 该记录与使用 TCP/IP 进行的连接尝试匹配,但仅在使用 SSL 加密进行连接时才匹配。

要使用此选项,必须使用 SSL 支持来构建服务器。此外,必须通过设置ssl配置参数来启用 SSL(有关更多信息,请参见Section 18.9)。否则,hostssl记录将被忽略,但会记录一条警告,指出该记录无法匹配任何连接。

  • hostnossl

    • 此记录类型具有与hostssl相反的行为;它仅与不使用 SSL 的通过 TCP/IP 进行的连接尝试匹配。
  • database

    • 指定此记录匹配的数据库名称。值all指定它与所有数据库匹配。值sameuser指定如果请求的数据库与请求的用户具有相同的名称,则记录匹配。值samerole指定所请求的用户必须是与所请求的数据库同名的角色成员。 (samegroupsamerole的过时但仍被接受的拼写.)出于samerole的目的,超级用户不被视为角色的成员,除非他们直接或间接地(而不只是通过成为超级用户)明确地是角色的成员。 。值replication指定如果请求物理复制连接,则记录匹配(请注意,复制连接未指定任何特定的数据库)。否则,这是特定 PostgreSQL 数据库的名称。可以使用逗号分隔多个数据库名称。可以通过在文件名前面加上@来指定包含数据库名称的单独文件。
  • user

    • 指定此记录匹配的数据库用户名。值all指定它与所有用户匹配。否则,它要么是特定数据库用户的名称,要么是带有+的组名。 (回想一下,PostgreSQL 中的用户和组之间没有 true 的区别; +标记实际上表示“匹配直接或间接属于此角色的任何角色”,而没有+标记的名称仅与该特定角色匹配.)为此,只有超级用户直接或间接明确地是角色的成员,而不仅仅是凭借超级用户,才将其视为角色的成员。可以使用逗号分隔多个用户名。可以在文件名前面加上@来指定包含用户名的单独文件。
  • address

    • 指定此记录匹配的 Client 端计算机地址。该字段可以包含主机名,IP 地址范围或下面提到的特殊关键字之一。

IP 地址范围是使用标准数字符号指定范围的起始地址,然后是斜杠(/)和 CIDR 掩码长度。掩码长度表示必须匹配的 Client 端 IP 地址的高位位数。在给定的 IP 地址中,其右边的位应为零。 IP 地址,/和 CIDR 掩码长度之间不得有任何空格。

以这种方式指定的 IPv4 地址范围的典型示例是对于单个主机为172.20.143.89/32,对于小型网络为172.20.143.0/24,对于较大网络为10.6.0.0/16。对于单个主机(在本例中为 IPv6 回送地址),IPv6 地址范围可能看起来像::1/128,对于小型网络来说可能看起来像fe80::7a31:c1ff:0000:0000/960.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 地址范围或特殊关键字的任何主机名),则将该名称与 Client 端 IP 地址的反向名称解析结果(例如反向 DNS)进行比较查找(如果使用 DNS)。主机名比较不区分大小写。如果存在匹配,则对主机名执行前向名称解析(例如,前向 DNS 查找),以检查其解析为的地址中的任何一个是否等于 Client 端的 IP 地址。如果两个方向都匹配,则认为该条目匹配。 (pg_hba.conf中使用的主机名应该是 Client 端 IP 地址的地址到名称解析返回的主机名,否则该行将不匹配.某些主机名数据库允许将 IP 地址与多个主机名相关联,但是当系统要求您解析 IP 地址时,os 只会返回一个主机名.)

以点(.)开头的主机名规范与实际主机名的后缀匹配。因此.example.com将匹配foo.example.com(但不仅是example.com)。

pg_hba.conf中指定主机名后,应确保名称解析相当快。设置本地名称解析缓存(例如nscd)可能是有利的。另外,您可能希望启用配置参数log_hostname以查看 Client 端的主机名,而不是日志中的 IP 地址。

该字段仅适用于hosthostsslhostnossl记录。

Note

用户有时会想知道为什么以这种看似复杂的方式来处理主机名,并具有两个名称解析,其中包括对 Client 端 IP 地址的反向查找。如果未设置 Client 端的反向 DNS 条目或产生某些不良的主机名,则会使该功能的使用复杂化。这样做主要是为了提高效率:通过这种方式,连接尝试最多需要两次解析器查找,一次反向查找和一次正向查找。如果某个地址存在解析器问题,则仅成为该 Client 的问题。假设只执行前向查找的替代实现,必须在每次连接尝试期间解析pg_hba.conf中提到的每个主机名。如果列出了许多名称,那可能会很慢。而且,如果其中一个主机名存在解析器问题,那么它将成为每个人的问题。

另外,必须执行反向查找以实现后缀匹配功能,因为需要知道实际的 Client 端主机名,以便将其与模式进行匹配。

请注意,此行为与基于主机名的访问控制的其他流行实现方式一致,例如 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.

这些字段仅适用于hosthostsslhostnossl记录。

  • auth-method

    • 指定连接与该记录匹配时要使用的身份验证方法。这里总结了可能的选择。详细信息在Section 20.3中。
  • trust

    • 无条件允许连接。此方法允许可以连接到 PostgreSQL 数据库服务器的任何人以他们希望的任何 PostgreSQL 用户身份登录,而无需密码或任何其他身份验证。有关详情,请参见Section 20.3.1

    • reject

      • 无条件拒绝连接。这对于“过滤”组中的某些主机很有用,例如reject线可能会阻止特定主机进行连接,而后面的行则允许特定网络中的其余主机进行连接。
    • scram-sha-256

      • 执行 SCRAM-SHA-256 身份验证以验证用户密码。有关详情,请参见Section 20.3.2
    • md5

      • 执行 SCRAM-SHA-256 或 MD5 身份验证以验证用户密码。有关详情,请参见Section 20.3.2
    • password

      • 要求 Client 端提供未加密的密码进行身份验证。由于密码是通过网络以明文形式发送的,因此不应在不受信任的网络上使用该密码。有关详情,请参见Section 20.3.2
    • gss

      • 使用 GSSAPI 对用户进行身份验证。这仅适用于 TCP/IP 连接。有关详情,请参见Section 20.3.3
    • sspi

      • 使用 SSPI 对用户进行身份验证。仅在 Windows 上可用。有关详情,请参见Section 20.3.4
    • ident

      • 通过联系 Client 端上的 ident 服务器获取 Client 端的 os 用户名,并检查其是否与请求的数据库用户名匹配。身份验证只能在 TCP/IP 连接上使用。当为本地连接指定时,将使用对等身份验证。有关详情,请参见Section 20.3.5
    • peer

      • 从 os 获取 Client 端的 os 用户名,并检查其是否与请求的数据库用户名匹配。这仅适用于本地连接。有关详情,请参见Section 20.3.6
    • ldap

      • 使用 LDAP 服务器进行身份验证。有关详情,请参见Section 20.3.7
    • radius

      • 使用 RADIUS 服务器进行身份验证。有关详情,请参见Section 20.3.8
    • cert

      • 使用 SSLClient 端证书进行身份验证。有关详情,请参见Section 20.3.9
    • pam

      • 使用 os 提供的可插拔身份验证模块(PAM)服务进行身份验证。有关详情,请参见Section 20.3.10
    • bsd

      • 使用 os 提供的 BSD 身份验证服务进行身份验证。有关详情,请参见Section 20.3.11
  • auth-options

      • auth-method 字段之后,可以存在 name * = * value *形式的字段,用于指定身份验证方法的选项。下面显示有关哪些身份验证方法可用的选项的详细信息。

除了下面列出的特定于方法的选项之外,还有一个与方法无关的身份验证选项clientcert,可以在任何hostsslLogging 指定。当设置为1时,除了身份验证方法的其他要求之外,此选项还要求 Client 端提供有效(可信)的 SSL 证书。

@构造包含的文件被读取为名称列表,可以用空格或逗号分隔。Comments 由#引入,就像pg_hba.conf一样,并且允许嵌套@构造。除非@后面的文件名是绝对路径,否则它将被视为相对于包含引用文件的目录的相对路径。

由于pg_hba.conf记录是针对每次连接尝试 Sequences 检查的,因此记录的 Sequences 很重要。通常,较早的记录将具有紧密的连接匹配参数和较弱的身份验证方法,而较新的记录将具有较宽松的匹配参数和较强的身份验证方法。例如,可能希望对本地 TCP/IP 连接使用trust身份验证,但对于远程 TCP/IP 连接则需要密码。在这种情况下,一条记录将为来自 127.0.0.1 的连接指定trust身份验证的记录将出现在为更广泛的允许的 Client 端 IP 地址范围指定密码身份验证的记录之前。

在启动时以及主服务器进程收到 SIGHUP signal 时,将读取pg_hba.conf文件。如果在活动系统上编辑文件,则需要向邮局局长发 signal(使用pg_ctl reload,调用 SQL 函数pg_reload_conf()或使用kill -HUP)以使其重新读取文件。

Note

前面的声明在 Microsoft Windows 上是不正确的:pg_hba.conf文件中的任何更改都将由后续的新连接立即应用。

系统视图pg_hba_file_rules有助于预先测试对pg_hba.conf文件的更改,或者在文件加载未达到预期效果时诊断问题。视图中带有非空error字段的行表示文件相应行中的问题。

Tip

要连接到特定的数据库,用户不仅必须通过pg_hba.conf检查,而且必须对数据库具有CONNECT特权。如果您希望限制哪些用户可以连接到哪些数据库,通常通过授予/撤消CONNECT特权来控制它比将规则放入pg_hba.conf条目要容易。

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

例 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

# 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 two lines will
# reject all connections from 192.168.54.1 (since that entry will be
# matched first), but allow GSSAPI 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.
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             192.168.54.1/32         reject
host    all             all             0.0.0.0/0               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 three 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 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             @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