9.3 9.4 9.5 9.6 10 11 12 13 14 15 Current(16) 17
问题报告 纠错本页面

21.1. pg_hba.conf文件 #

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

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加密连接尝试。

注意

远程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表示请求的用户必须是与请求的数据库 同名的角色的成员。(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服务器和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-caverify-full。 这两个选项都要求客户端提供有效(受信任的)SSL证书, 而verify-full还要求证书中的cn(通用名称)与用户名或适用映射匹配。 这种行为类似于cert身份验证方法(请参阅第 21.12 节), 但允许将客户端证书的验证与支持hostssl条目的任何身份验证方法配对。

在使用客户端证书认证的任何记录上(即使用cert认证方法或使用clientcert选项的记录),您可以使用clientname选项指定要匹配的客户端证书凭据的哪个部分。此选项可以有两个值之一。如果您指定clientname=CN,这是默认值,则用户名将与证书的Common Name (CN)进行匹配。如果您改为指定clientname=DN,则用户名将与证书的整个Distinguished Name (DN)进行匹配。此选项最好与用户名映射一起使用。比较是使用DNRFC 2253格式进行的。要查看以此格式显示的客户端证书的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文件会被读取。 如果你在活动的系统上编辑了该文件,你将需要通知 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

# 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