选择 打开 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0
历史版本PostgreSQL 9.2 已于 2017 年 11 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本

第 19 章 客户端认证

当客户端应用连接到数据库服务器时,它会指定要以哪个 PostgreSQL 数据库用户名连接,这很像以某个特定用户身份登录 Unix 计算机一样。在 SQL 环境中,当前活动的数据库用户名决定了对数据库对象的访问权限 — 详见 第 20 章。因此,必须限制哪些数据库用户能够连接。

注意

第 20 章 中所述,PostgreSQL 实际上是以 角色 为单位进行权限管理的。在本章中,我们统一使用 数据库用户 来表示 拥有 LOGIN 权限的角色

认证是数据库服务器确认客户端身份的过程,并据此决定是否允许该客户端应用(或者运行该客户端应用的用户)以请求的数据库用户名进行连接。

PostgreSQL 提供了多种不同的客户端认证方法。用于认证特定客户端连接的方法可以根据(客户端)主机地址、数据库和用户来选择。

PostgreSQL 数据库用户名在逻辑上独立于服务器所在操作系统中的用户名。如果某台服务器的所有用户在该机器上也都有账号,那么为他们分配与操作系统用户名一致的数据库用户名是有意义的。不过,接受远程连接的服务器可能有许多数据库用户并没有本地操作系统账号,在这种情况下,数据库用户名与操作系统用户名之间就不必存在任何对应关系。

19.1. pg_hba.conf 文件 #

客户端认证由一个配置文件控制,该文件按惯例命名为 pg_hba.conf,并存放在数据库集簇的数据目录中。 (HBA 代表 host-based authentication,即基于主机的认证。) 当数据目录由 initdb 初始化时,会安装一个默认的 pg_hba.conf 文件。不过,也可以把认证配置文件放在别处; 请参见配置参数 hba_file

pg_hba.conf 文件的一般格式是一组记录,每行一条。空行被忽略,# 注释字符之后的任何文本也被忽略。记录不能跨行。一条记录由若干字段组成,字段之间用空格和/或制表符分隔。如果字段值被引号括起,字段中可以包含空白。把数据库、用户或地址字段中的某个关键字(例如 allreplication)用引号括起会使该词失去特殊含义,只是匹配同名的数据库、用户或主机。

每条认证记录都指定一种连接类型、一个客户端 IP 地址范围(如果该连接类型需要)、一个数据库名、一个用户名,以及对匹配这些参数的连接要使用的认证方法。第一条同时匹配连接类型、客户端地址、请求数据库和用户名的记录会被用来执行认证。这里不存在 继续向后匹配后备 机制:如果选中某条记录而认证失败,就不会再考虑后续记录。如果没有任何记录匹配,则拒绝访问。

记录可以采用以下七种格式之一

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 连接。

注意

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

hostssl

该记录匹配使用 TCP/IP 发起的连接尝试,但仅当连接使用 SSL 加密时才匹配。

要使用此选项,服务器必须在构建时启用 SSL 支持。 此外,还必须在服务器启动时通过设置 ssl 配置参数来启用 SSL (有关更多信息,请参见第 17.9 节)。

hostnossl

该记录类型与 hostssl 的行为相反;它只匹配通过 TCP/IP 发起且不使用 SSL 的连接尝试。

database

指定这条记录匹配哪些数据库名。all 表示匹配所有数据库。sameuser 表示如果请求的数据库名和请求的用户名相同,则匹配。samerole 表示请求的用户必须是与会话请求的数据库名相同的角色的成员。(samegroupsamerole 的一个已经废弃但仍然被接受的拼写。)对于 samerole,只有显式地直接或间接属于该角色,超级用户才被视为其成员,仅凭超级用户身份并不算。 The value replication specifies that the record matches if a replication connection is requested (note that replication connections do not specify any particular database). Otherwise, this is the name of a specific PostgreSQL database. Multiple database names can be supplied by separating them with commas. A separate file containing database names can be specified by preceding the file name with @.

user

指定这条记录匹配哪些数据库用户名。all 表示匹配所有用户。否则,它要么是一个具体数据库用户的名字,要么是一个前面带有 + 的组名。(回想一下,PostgreSQL 中用户和组之间没有真正的区别;+ 标记的实际含义是匹配直接或间接属于该角色成员的任何角色,而不带 + 标记的名字只匹配那个具体的角色。)为此,只有显式地直接或间接属于该角色,超级用户才被视为其成员,仅凭超级用户身份并不算。可以用逗号分隔多个用户名。也可以在文件名前加 @,指定一个单独存放用户名的文件。

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范围内。请注意,如果系统的C库不支持IPv6地址, 以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 地址。

这个字段只适用于 hosthostsslhostnossl 记录。

IP-address
IP-mask

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

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

auth-method

指定连接匹配此记录时要使用的认证方法。可选值在此处做了概述;详细说明见 第 19.3 节

trust

无条件允许连接。这种方法允许任何能够连接到PostgreSQL数据库服务器的人以任意他们希望的PostgreSQL用户身份登录,无需密码或任何其他认证。详见第 19.3.1 节

reject

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

md5

要求客户端提供一个经过双重 MD5 哈希的密码以完成认证。 详见第 19.3.2 节

password

要求客户端提供未加密的密码以完成认证。 由于密码会以明文形式通过网络发送,因此不应在不受信任的网络上使用。 详见第 19.3.2 节

gss

使用 GSSAPI 认证用户。这仅适用于 TCP/IP 连接。详情参见 第 19.3.3 节

sspi

使用 SSPI 对用户进行认证。这仅适用于 Windows。详见第 19.3.4 节

krb5

使用 Kerberos V5 对用户进行认证。这只适用于 TCP/IP 连接。详见 第 19.3.5 节

ident

通过联系客户端上的 ident 服务器获取客户端的操作系统用户名, 并检查它是否与请求的数据库用户名匹配。 Ident 认证只能用于 TCP/IP 连接。 当为本地连接指定时,将改为使用 peer 认证。 详见第 19.3.6 节

peer

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

ldap

使用LDAP服务器进行认证。详见第 19.3.8 节

radius

使用 RADIUS 服务器进行认证。详见第 19.3.9 节

cert

使用 SSL 客户端证书进行认证。详见第 19.3.10 节

pam

使用操作系统提供的可插拔认证模块(PAM)服务进行认证。详见第 19.3.11 节

auth-options

auth-method 字段之后,可以有一个或多个形如 name=value 的字段,用于指定认证方法的选项。下文会详细说明各认证方法有哪些可用选项。

@ 构造引用的文件会被读取为名称列表,其中的名称可以用空白或逗号分隔。注释仍然用 # 引入,与 pg_hba.conf 中相同,并且允许嵌套的 @ 构造。除非 @ 后面的文件名是绝对路径,否则它会被视为相对于引用它的文件所在目录。

由于每次连接尝试都会按顺序检查 pg_hba.conf 记录,因此记录的顺序很重要。通常,靠前的记录使用较严格的连接匹配条件和较弱的认证方法,靠后的记录使用较宽松的匹配条件和较强的认证方法。例如,可能希望对本地 TCP/IP 连接使用 trust 认证,而要求远程 TCP/IP 连接提供密码。此时,为来自 127.0.0.1 的连接指定 trust 认证的记录,应放在为更大范围的允许客户端 IP 地址指定密码认证的记录之前。

在启动时以及主服务器进程收到 SIGHUP 信号时,pg_hba.conf 文件会被读取。 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reloadkill -HUP)重新读取该文件。

提示

要连接到一个特定数据库,一个用户必须不仅要通过pg_hba.conf检查,还必须要有该数据库上的CONNECT权限。如果你希望限制哪些用户能够连接到哪些数据库,授予/撤销CONNECT权限通常比在pg_hba.conf项中设置规则简单。

例 19.1 展示了一些 pg_hba.conf 条目示例。有关不同认证方法的详细信息,参见下一节。

例 19.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        md5

# Allow any user from hosts in the example.com domain to connect to
# any database if the user's password is correctly supplied.
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             .example.com            md5

# 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 Kerberos 5 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               krb5

# 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

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。