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

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.1 已于 2016 年 10 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本

19.3. 认证方法 #

下面几节会更详细地介绍这些认证方法。

19.3.1. 信任认证 #

trust认证被指定时,PostgreSQL假设任何可以连接到服务器的人都被授权使用他们指定的任何数据库用户名(即使是超级用户)访问数据库。当然,在databaseuser列中设置的限制仍然适用。只有当在操作系统层对进入服务器的连接有足够保护时,才应该使用这种方法。

trust 认证对单用户工作站上的本地连接来说是 合适且非常方便的。在多用户机器上,通常单用它并 合适。不过,如果用文件系统权限限制对 服务器 Unix 域套接字文件的访问,即使在多用户机器上也可以使用 trust。为此,可按 第 18.3 节 中的说明设置 unix_socket_permissions(可能还有 unix_socket_group)配置参数。或者,也可以 设置 unix_socket_directory 配置参数,把套接字文件放在一个经过适当限制的目录中。

设置文件系统权限只能有助于 Unix 套接字连接。本地 TCP/IP 连接不会被文件系统权限限制。因此,如果你想利用文件系统权限来控制本地安全,那么从pg_hba.conf中移除host ... 127.0.0.1 ...行,或者把它改为一个非trust认证方法。

只有当你信任由 pg_hba.conf 中指定 trust 的行所允许连接的每台机器上的每个用户时,trust 认证才适合用于 TCP/IP 连接。对来自 localhost(127.0.0.1)以外的任何 TCP/IP 连接使用 trust,通常都不合理。

19.3.2. 密码认证 #

基于密码的认证方法有 md5password。除了密码通过连接发送的方式——前者以 MD5 哈希发送、后者以明文发送——之外,这两种方法的操作是相似的。

如果你担心密码嗅探攻击,那么应优先使用 md5。 如果可能,应始终避免使用明文 password。 不过,md5 不能与db_user_namespace功能一起使用。如果连接被 SSL 加密保护着,那么可以安全地使用 password(不过如果依靠 SSL,SSL 证书认证可能是更好的选择)。

PostgreSQL 数据库密码独立于操作系统用户密码。每个数据库用户的密码存储在 pg_authid 系统目录中。可以使用 SQL 命令 CREATE USERALTER ROLE 管理密码,例如 CREATE USER foo WITH PASSWORD 'secret',如果未为某个用户设置密码,存储的密码就是空值,该用户的密码认证始终会失败。

19.3.3. GSSAPI 认证 #

GSSAPI 是 RFC 2743 定义的安全认证行业标准协议。PostgreSQL 按照 RFC 1964 支持使用 Kerberos 认证的 GSSAPIGSSAPI 为支持它的系统提供自动认证(单点登录)。认证过程本身是安全的,但除非使用 SSL,否则数据库连接上传输的数据不会加密。

GSSAPI 使用 Kerberos 时,它使用标准格式 servicename/hostname@realm 的 principal。有关 principal 的组成部分以及如何设置所需密钥的信息,见 第 19.3.5 节

当编译PostgreSQL时,GSSAPI 支持必须被启用,详见第 15 章

以下配置选项适用于 GSSAPI

include_realm

如果设为 1,已认证用户主体中的 realm 名称将包含在传递给用户名映射(第 19.2 节)的系统用户名中。这是推荐的配置,因为否则将无法区分来自不同 realm 的同名用户。该参数的默认值为 0(即系统用户名中不包含 realm),但在未来版本的 PostgreSQL 中可能会改为 1。用户可以显式设置它,以避免升级时出现任何问题。

map

允许在系统用户名与数据库用户名之间建立映射。详见 第 19.2 节。对于 username@EXAMPLE.COM(或较少见的 username/hostbased@EXAMPLE.COM)这样的 GSSAPI/Kerberos 主体,映射默认使用的用户名是 username(或相应的 username/hostbased);但如果按上文建议将 include_realm 设为了 1,那么映射时视为系统用户名的就是 username@EXAMPLE.COM(或 username/hostbased@EXAMPLE.COM)。

krb_realm

设置用于匹配用户主体名的 realm。如果设置了该参数,则只接受来自该 realm 的用户;如果未设置,则允许来自任意 realm 的用户连接,但仍受已执行的用户名映射约束。

19.3.4. SSPI 认证 #

SSPI 是一种提供安全认证和单点登录的 Windows 技术。PostgreSQL 会以 negotiate 模式使用 SSPI,尽可能使用 Kerberos,否则自动回退到 NTLM。只有服务器和客户端都运行 Windows,或者在非 Windows 平台上可用 GSSAPI 时,SSPI 认证才能工作。

当使用Kerberos认证时,SSPIGSSAPI的工作方式相同,详见第 19.3.3 节

SSPI 支持下列配置选项:

include_realm

如果设为 1,已认证用户主体中的 realm 名称将包含在传递给用户名映射(第 19.2 节)的系统用户名中。这是推荐的配置,因为否则将无法区分来自不同 realm 的同名用户。该参数的默认值为 0(即系统用户名中不包含 realm),但在未来版本的 PostgreSQL 中可能会改为 1。用户可以显式设置它,以避免升级时出现任何问题。

map

允许在系统用户名与数据库用户名之间建立映射。详见 第 19.2 节。对于 SSPI/Kerberos 主体,例如 username@EXAMPLE.COM(或者较少见的 username/hostbased@EXAMPLE.COM),映射默认使用的用户名是 username(或相应的 username/hostbased);但如果按上文建议将 include_realm 设为了 1,那么映射时视为系统用户名的就是 username@EXAMPLE.COM(或 username/hostbased@EXAMPLE.COM)。

krb_realm

设置用于匹配用户主体名的 realm。如果设置了该参数,则只接受来自该 realm 的用户;如果未设置,则允许来自任意 realm 的用户连接,但仍受已执行的用户名映射约束。

19.3.5. Kerberos 认证 #

注意

原生 Kerberos 认证已被弃用,只应用于向后兼容。鼓励新建和升级的安装改用行业标准 GSSAPI 认证方法(见第 19.3.3 节)。

Kerberos 是一种适合在公共网络上进行分布式计算的行业标准安全认证系统。对 Kerberos 系统的描述超出了本文档的范围;在最一般的意义上它可能相当复杂(但也很强大)。 Kerberos FAQMIT Kerberos 页面 可以作为很好的探索起点。存在若干 Kerberos 发行版来源。 Kerberos 提供安全认证,但不对网络上传递的查询或数据加密;如需加密请使用 SSL

PostgreSQL 支持 Kerberos 版本 5。构建 PostgreSQL 时必须启用 Kerberos 支持;更多信息见第 15 章

PostgreSQL 像一个普通的 Kerberos 服务那样运作。服务主体的名称为 servicename/hostname@realm

servicename can be set on the server side using the krb_srvname configuration parameter, and on the client side using the krbsrvname connection parameter. (See also 第 31.1 节.) 安装时的默认值可以在构建时用 ./configure --with-krb-srvnam=whatever 从默认的 postgres 改变。在大多数环境中,这个参数永远不需要更改。但是,在同一台主机上支持多个 PostgreSQL 安装时需要更改它。 Some Kerberos implementations might also require a different service name, such as Microsoft Active Directory which requires the service name to be in upper case (POSTGRES).

hostname 是服务器机器的完全限定主机名。服务主体的 realm 是服务器机器的首选 realm。

客户端主体的第一个组成部分必须是 PostgreSQL 数据库用户名,例如 pgusername@realm。或者,也可以使用用户名映射,将主体名的第一个组成部分映射为数据库用户名。默认情况下,PostgreSQL 不检查客户端的 realm。如果启用了跨 realm 认证并且需要验证 realm,请使用 krb_realm 参数,或者启用 include_realm 并使用用户名映射来检查 realm。

确保你的服务器密钥表文件可被 PostgreSQL 服务器账户读取(最好只有该账户可读)。 (另见第 17.1 节。)密钥文件的位置由 krb_server_keyfile 配置参数指定。默认为 /usr/local/pgsql/etc/krb5.keytab(或构建时指定为 sysconfdir 的目录)。

keytab 文件由 Kerberos 软件生成;详情参见 Kerberos 文档。以下示例适用于兼容 MIT 的 Kerberos 5 实现:

kadmin% ank -randkey postgres/server.my.domain.org
kadmin% ktadd -k krb5.keytab postgres/server.my.domain.org

连接数据库时,请确保持有与请求的数据库用户名相匹配的主体票据。例如,数据库用户名为 fred 时,主体 fred@EXAMPLE.COM 可以连接。如果还要允许主体 fred/users.example.com@EXAMPLE.COM,请按 第 19.2 节 所述使用用户名映射。

如果你在 Apache Web 服务器上使用 mod_auth_kerbmod_perl,可以在 mod_perl 脚本中使用 AuthType KerberosV5SaveCredentials。这可提供经过 Web 的安全数据库访问,而无需额外的口令。

Kerberos 支持以下配置选项:

map

允许在系统用户名和数据库用户名之间进行映射。详见 第 19.2 节

include_realm

如果设置为 1,已认证用户主体中的领域名将包含在传递给用户名映射 (第 19.2 节)的系统用户名中。这有助于处理来自多个领域的用户。

krb_realm

设置用于匹配用户主体名的 realm。如果设置了该参数,则只接受来自该 realm 的用户;如果未设置,则允许来自任意 realm 的用户连接,但仍受已执行的用户名映射约束。

krb_server_hostname

设置服务主体的主机名部分。它与 krb_srvname 组合生成完整的服务主体,即 krb_srvname/krb_server_hostname@REALM。 如果未设置,默认为服务器主机名。

19.3.6. Ident 认证 #

ident 认证方法通过从一个 ident 服务器获得客户端的操作系统用户名并且用它作为被允许的数据库用户名(和可选的用户名映射)来工作。它只在 TCP/IP 连接上支持。

注意

当为一个本地(非 TCP/IP)连接指定 ident 时,将实际使用 peer 认证(见第 19.3.7 节)。

以下配置选项适用于 ident

map

允许在系统用户名和数据库用户名之间进行映射。详见 第 19.2 节

标识协议在 RFC 1413 中定义。几乎所有类 Unix 操作系统都自带 ident 服务器,默认监听 TCP 端口 113。ident 服务器的基本功能是回答这样的问题:从你的端口 X 连到我的端口 Y 的连接,是哪个用户发起的?由于建立物理连接时,PostgreSQL 已知 XY,因此可以询问连接客户端所在主机上的 ident 服务器,理论上能够确定任意给定连接的操作系统用户。

这个过程的缺点在于它依赖客户端本身的可信性:如果客户端机器不可信或者已被攻破,攻击者几乎可以在 113 端口上运行任何程序,并返回任意他选择的用户名。因此,这种认证方法只适用于封闭网络,在这类网络中每台客户端机器都受到严格控制,而且数据库管理员与系统管理员之间保持密切协作。换句话说,你必须信任运行 ident 服务器的那台机器。请注意下面的警告:

 

标识协议的本意不是作为一种授权或访问控制协议。

 
  --RFC 1413

有些 ident 服务器提供了一个非标准选项,会让返回的用户名被加密,而解密所需密钥只有发起连接机器的管理员才知道。将 ident 服务器与 PostgreSQL 配合使用时,绝不能启用这个选项,因为 PostgreSQL 无法解密返回的字符串,也就无法确定实际用户名。

19.3.7. Peer 认证 #

Peer 认证通过从内核获取客户端的操作系统用户名,并把它用作被允许的数据库用户名(可结合可选的用户名映射)来工作。这种方法只支持本地连接。

以下配置选项适用于 peer

map

允许在系统用户名和数据库用户名之间进行映射。详见 第 19.2 节

Peer 认证只在提供 getpeereid() 函数、SO_PEERCRED 套接字参数或类似机制的操作系统上可用。目前这包括 Linux、大多数 BSD 变种(包括 OS X)以及 Solaris

19.3.8. LDAP 认证 #

这种认证方法的工作方式与 password 类似,只不过它使用 LDAP 作为密码验证方法。LDAP 只用于验证用户名/密码对。因此,在使用 LDAP 进行认证之前,用户必须已经存在于数据库中。

LDAP 认证可以以两种模式运作。在第一种模式中,服务器将绑定到由 prefix username suffix 构造的可分辨名称上。通常,prefix 参数用于指定 cn=,或者在 Active Directory 环境中指定 DOMAIN\suffix 用于在非 Active Directory 环境中指定 DN 的剩余部分。

在第二种模式中,服务器首先用一个固定的用户名和密码绑定到 LDAP 目录(由 ldapbinddnldapbindpasswd 指定),然后为尝试登录数据库的用户执行搜索。如果没有配置用户和密码,将尝试对目录做匿名绑定。搜索将在 ldapbasedn 的子树上进行,并尝试对 ldapsearchattribute 中指定的属性做精确匹配。如果没有指定属性,将使用 uid 属性。 Once the user has been found in this search, the server disconnects and re-binds to the directory as this user, using the password specified by the client, to verify that the login is correct. This method allows for significantly more flexibility in where the user objects are located in the directory, but will cause two separate connections to the LDAP server to be made.

The following configuration options are supported for LDAP:

ldapserver

要连接的 LDAP 服务器的名字或 IP 地址。可以指定多个服务器,用空格分隔。

ldapport

要连接的LDAP服务器的端口号。如果未指定端口,则将使用LDAP库的默认端口设置。

ldaptls

设为 1 时,PostgreSQL 与 LDAP 服务器之间的连接会使用 TLS 加密。注意,这只加密与 LDAP 服务器之间的流量 — 除非使用 SSL,否则与客户端之间的连接仍不加密。

ldapprefix

在进行简单绑定认证时,附加到用户名前面以形成绑定 DN 的字符串。

ldapsuffix

在进行简单绑定认证时,附加到用户名后面以形成绑定 DN 的字符串。

ldapbasedn

在进行搜索+绑定认证时,用作用户搜索起点的根 DN。

ldapbinddn

在进行搜索+绑定认证时,用于绑定到目录并执行搜索的用户 DN。

ldapbindpasswd

在进行搜索+绑定认证时,用于绑定到目录并执行搜索的用户密码。

ldapsearchattribute

做 search+bind 认证时,在搜索中与用户名匹配的属性。

注意

由于 LDAP 通常使用逗号和空格来分隔 DN 的不同部分,配置 LDAP 选项时常常需要使用双引号括起的参数值,例如:

ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net"

19.3.9. RADIUS 认证 #

这种认证方法的工作方式与 password 类似,只不过它使用 RADIUS 作为密码验证方式。RADIUS 只用于验证用户名/密码对。因此,在使用 RADIUS 进行认证之前,用户必须已经存在于数据库中。

使用 RADIUS 认证时,会向配置好的 RADIUS 服务器发送一条 Access Request 消息。 该请求的类型为 Authenticate Only,并包含 user namepassword(加密的)以及 NAS Identifier 参数。 该请求会使用与服务器共享的密钥进行加密。 这台服务器会返回 Access AcceptAccess Reject 作为响应。PostgreSQL 不支持 RADIUS 记账。

RADIUS 支持下列配置选项:

radiusserver

要连接的 RADIUS 服务器的名称或 IP 地址。此参数为必需项。

radiussecret

与 RADIUS 服务器进行安全通信时使用的共享密钥。它在 PostgreSQL 服务器和 RADIUS 服务器上必须完全相同。建议它至少是一个 16 个字符长的字符串。此参数为必需项。

注意

只有当 PostgreSQL 在构建时启用了 OpenSSL 支持,所使用的加密向量才具有足够的密码学强度。在其他情况下,到 RADIUS 服务器的传输只能被视为经过混淆,而非受到安全保护;如有必要,应额外采取外部安全措施。

radiusport

要连接的 RADIUS 服务器端口号。如果未指定端口,则会使用默认端口 1812

radiusidentifier

在 RADIUS 请求中用作 NAS Identifier 的字符串。这个参数可用作第二个参数,例如标识用户正尝试以哪个数据库用户进行认证,从而便于在 RADIUS 服务器上进行策略匹配。如果未指定标识符,则默认使用 postgresql

19.3.10. 证书认证 #

这种认证方法使用 SSL 客户端证书进行认证,因此仅适用于 SSL 连接。使用此方法时,服务器要求客户端提供有效的证书,不会向客户端发送密码提示。服务器会将证书的 cn(通用名称)属性与请求的数据库用户名比较,匹配时才允许登录。可以使用用户名映射,允许 cn 与数据库用户名不同。

SSL 证书认证支持下列配置选项:

map

允许在系统用户名和数据库用户名之间进行映射。详见 第 19.2 节

19.3.11. PAM 认证 #

这种认证方法的工作方式与 password 类似,只是它使用 PAM(可插拔认证模块)作为认证机制。默认的 PAM 服务名是 postgresql。PAM 只用于验证用户名/密码对。因此,在能够使用 PAM 认证之前,用户必须已经存在于数据库中。 For more information about PAM, please read the Linux-PAM Page and the Solaris PAM Page.

PAM 支持下列配置选项:

pamservice

PAM 服务名称。

注意

如果 PAM 被设置为读取 /etc/shadow,认证将会失败,因为 PostgreSQL 服务器是由非 root 用户启动的。不过,当 PAM 被配置为使用 LDAP 或其他认证方法时,这就不是问题。

提交更正

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