Postgresql 中文操作指南

21.1. The pg_hba.conf File #

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

pg_hba.conf 文件的一般格式是一组记录,每行一个。空白行将被忽略, # 注释字符后面的任何文本也将被忽略。可以通过在行的结尾加反斜杠将记录续写到下一行。(反斜杠不是每行的结尾除外都是特殊的。) 记录由多个字段组成,字段用空格和/或制表符分隔。字段可以包含空白,如果字段值用双引号引用。在数据库、用户或地址字段中引用某个关键字(例如 allreplication),将使得该单词失去其特殊含义,并仅仅匹配具有该名称的数据库、用户或主机。即使在引用的文本或注释中也会应用反斜杠行续写。

每条身份验证记录都特定连接类型、客户端 IP 地址范围(如果与连接类型相关)、数据库名称、用户名和用于匹配这些参数的连接的身份验证方法。第一个具有匹配的连接类型、客户端地址、请求的数据库和用户名记录用于执行身份验证。没有“故障转移”或“还原”:如果选择一条记录并身份验证失败,系统不会考虑后续记录。如果没有记录匹配,则会被拒绝访问权限。

每条记录可以是 include 指令或身份验证记录。Include 指令特定可以包含的其他记录的文件。这些记录将被插入 include 指令的位置。Include 指令只包含两个字段:includeinclude_if_existsinclude_dir 指令和要包含的文件或目录。该文件或目录可以是相对路径或绝对路径,也可以采用双引号。对于 include_dir 形式,将包括所有不以 . 开头和 .conf 结尾的文件。include 目录中的多个文件将按文件名顺序进行处理(根据 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-domain 套接字的连接尝试。如果没有此类型的记录,将不允许 Unix-domain 套接字连接。

  • host

    • 此记录匹配使用 TCP/IP 建立的连接尝试。host 记录匹配 SSL 或非 SSL 连接尝试,也匹配 GSSAPI 加密或非 GSSAPI 加密连接尝试。

  • hostssl

    • 此记录匹配通过 TCP/IP 建立的连接尝试,但仅当连接是使用 SSL 加密建立时。

    • 为了使用这个选项,服务器必须使用 SSL 支持进行构建。此外,必须通过设置 ssl配置参数来启用 SSL(有关更多信息,请参阅 Section 19.9)。否则,将忽略 _hostssl_记录,只是会记录一条警告,指出它无法匹配任何连接。

  • hostnossl

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

  • hostgssenc

    • 此记录匹配使用 TCP/IP 建立的连接尝试,但仅当连接是使用 GSSAPI 加密建立时。

    • 为了使用此选项,服务器必须使用 GSSAPI 支持进行构建。否则,将会忽略 hostgssenc 记录,只会记录警告,表明无法匹配任何连接。

  • hostnogssenc

    • 此记录类型具有与 hostgssenc 相反的行为;它仅匹配通过不使用 GSSAPI 加密建立的 TCP/IP 连接尝试。

  • database

    • 指定此记录匹配的数据库名称。值 all 指定它匹配所有数据库。值 sameuser 指定如果请求的数据库与请求的用户具有相同名称,则记录匹配。值 samerole 指定请求的用户必须是与请求的数据库同名的角色的成员。( samegroupsamerole 的过时但仍然被接受的拼写。)对于 samerole 的目的,超级用户不被视为角色成员,除非它们直接或间接地明确是角色成员,而不仅是因为它们是超级用户。值 replication 指定如果请求的是物理复制连接,则记录匹配,但是它与逻辑复制连接不匹配。请注意,物理复制连接不会指定任何特定数据库,而逻辑复制连接会指定特定数据库。否则,这是特定 PostgreSQL 数据库或正则表达式的名称。可以通过逗号分隔多个数据库名称和/或正则表达式来提供它们。

    • 如果数据库名称以斜杠 ( / ) 开头,则名称的其余部分将被视为正则表达式。(有关 PostgreSQL 正则表达式语法详细信息,请参见 Section 9.7.3.1 。)

    • 可以通过在文件名前加上 @ 来指定包含数据库名称和/或正则表达式的单独文件。

  • user

    • 指定此记录匹配哪个数据库用户名。值 all 指定它与所有用户匹配。否则,这是特定数据库用户的名称、正则表达式(以斜杠开头(/))或以 + 开头的组名称。(回想一下,PostgreSQL 中用户和组之间没有真正的区别;+ 标记实际上意味着“匹配直接或间接是此角色的成员的任何角色”,而没有 + 标记的名称只匹配该特定角色。)出于此目的,只有当超级用户明确是角色的成员、直接或间接是角色的成员(而不仅仅是因为是超级用户),才会被视为角色的成员。可以通过用逗号分隔来提供多个用户名和/或正则表达式。

    • 如果用户名以斜杠 ( / ) 开头,则名称的其余部分将被视为正则表达式。(有关 PostgreSQL 正则表达式语法详细信息,请参见 Section 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 和 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-address__IP-mask

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

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

  • auth-method

    • 指定与此记录匹配的连接时要使用的认证方法。这里总结了可能的选择;详细信息在 Section 21.3中。所有选项都是小写且区分大小写的,所以即使像 _ldap_这样的首字母缩略词也必须指定为小写。

  • auth-options

    • auth-method 字段之后,可以有 name=value 表单的字段,这些字段指定身份验证方法的选项。以下是有关哪种身份验证方法提供了哪些选项的详细信息。

    • 除下面列出的特定方法选项外,还有一个与方法无关的认证选项 clientcert,可在任何 hostssl 记录中指定。此选项可设置为 verify-caverify-full。这两个选项都要求客户端提交有效的(受信任的)SSL 证书,而 verify-full 此外还强制证书中的 cn(通用名称)与用户名或适用的映射匹配。此行为类似于 cert 认证方法(参见 Section 21.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 区域设置规则,即数字在字母之前,大写字母在大写字母之前)进行处理。小写字母)。

Note

除非使用服务器启动与 listen_addresses配置参数的适当值,否则远程 TCP/IP 连接将不可用,因为默认行为是在本地环回地址_localhost_上只侦听 TCP/IP 连接。

Note

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

此外,实现后缀匹配功能需要反向查找,因为需要知道实际客户端主机名才能将其与模式进行匹配。

请注意,这种行为与其他流行的主机名访问控制实现一致,例如 Apache HTTP 服务器和 TCP 包装器。

  • trust

    • 无条件允许连接。此方法允许任何可以连接到 PostgreSQL 数据库服务器的人登录为他们想要的任何 PostgreSQL 用户,而无需密码或任何其他认证。有关详细信息,请参阅 Section 21.4

  • reject

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

  • scram-sha-256

    • 执行 SCRAM-SHA-256 身份验证以验证用户密码。有关详细信息,请参阅 Section 21.5

  • md5

    • 执行 SCRAM-SHA-256 或 MD5 身份验证来验证用户的密码。有关详细信息,请参阅 Section 21.5

  • password

    • 要求客户端提供一个未加密的密码进行认证。由于密码以纯文本通过网络发送,因此不应在不可信网络上使用。有关详细信息,请参阅 Section 21.5

  • gss

    • 使用 GSSAPI 对用户进行认证。这仅适用于 TCP/IP 连接。有关详细信息,请参阅 Section 21.6。它可以与 GSSAPI 加密结合使用。

  • sspi

    • 使用 SSPI 对用户进行认证。这仅适用于 Windows。有关详细信息,请参阅 Section 21.7

  • ident

    • 通过联系客户端上的 ident 服务器获取客户端的操作系统用户名,并检查它是否与请求的数据库用户名匹配。Ident 认证仅能用于 TCP/IP 连接。在为本地连接指定时,将使用对等认证。有关详细信息,请参阅 Section 21.8

  • peer

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

  • ldap

    • 使用一个 LDAP 服务器进行认证。有关详细信息,请参阅 Section 21.10

  • radius

    • 使用一个 RADIUS 服务器进行认证。有关详细信息,请参阅 Section 21.11

  • cert

    • 使用 SSL 客户端证书进行认证。详情请参见 Section 21.12

  • pam

    • 使用操作系统提供的可插拔认证模块 (PAM) 服务进行认证。详情请参见 Section 21.13

  • bsd

    • 使用操作系统提供的 BSD 认证服务进行认证。详情请参见 Section 21.14

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

由于 pg_hba.conf 记录会针对每个连接尝试按顺序检查,因此记录的顺序很重要。通常,较早的记录会有严格的连接匹配参数和较弱的身份验证方法,而较晚的记录会有较宽松的匹配参数和较强身份验证方法。例如,你可能希望对本地 TCP/IP 连接使用 trust 认证,但要求对远程 TCP/IP 连接提供密码。在这种情况下,为来自 127.0.0.1 的连接指定 trust 认证的记录将出现在为更宽范围的允许客户端 IP 地址指定密码认证的记录之前。

pg_hba.conf 文件在启动时和主服务器进程接收 SIGHUP 信号时读取。如果你在活动系统上编辑了文件,你将需要向 postmaster(使用 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 输入中更轻松。

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

Example 21.1. Example pg_hba.conf Entries

# 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