pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
下面几节会更详细地介绍这些认证方法。
当trust认证被指定时,PostgreSQL假设任何可以连接到服务器的人都被授权使用他们指定的任何数据库用户名(包括超级用户)访问数据库。当然,在database和 user列中设置的限制仍然适用。只有当在操作系统层对进入服务器的连接有足够保护时,才应该使用这种方法。
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,通常都不合理。
基于密码的认证方法有md5、crypt和password。除了密码通过连接发送的方式——分别以 MD5 哈希、crypt 加密和明文发送——之外,这些方法的操作是相似的。一个限制是crypt方法不能用于pg_authid中已被加密存储的密码。
如果你担心密码“嗅探”攻击,那么应优先使用md5,只有在必须支持 7.2 之前的客户端时才使用crypt。明文password应当尽量避免,尤其是通过开放 Internet 的连接(除非你为连接使用了SSL、SSH或其他通信安全包装)。
PostgreSQL 数据库密码与操作系统用户 密码是分开的。每个数据库用户的密码存储在 pg_authid 系统目录中。密码可以用 SQL 命令 CREATE USER 和 ALTER USER 管理,例如 CREATE USER foo WITH PASSWORD 'secret'。 如果用户没有设置密码,存储的密码为空,该用户的密码认证将 始终失败。
GSSAPI 是 RFC 2743 定义的安全认证行业标准协议。PostgreSQL 按照 RFC 1964 支持使用 Kerberos 认证的 GSSAPI。GSSAPI 为支持它的系统提供自动认证(单点登录)。认证过程本身是安全的,但除非使用 SSL,否则数据库连接上传输的数据不会加密。
当 GSSAPI 使用 Kerberos 时,它使用格式为 的标准主体。关于主体各部分的 说明以及如何设置所需的密钥,参见 第 21.2.5 节。编译 PostgreSQL 时必须启用 GSSAPI 支持,更多信息见 第 15 章。servicename/hostname@realm
SSPI 是一种用于单点登录安全认证的 Windows 技术。 PostgreSQL 将以 negotiate 模式使用 SSPI,该模式在可能时使用 Kerberos,在其他情况下自动回退到 NTLM。 SSPI 认证只在服务器和客户端都运行 Windows 时才起作用。
当使用Kerberos认证时,SSPI和GSSAPI的工作方式相同,详见第 21.2.3 节。
原生 Kerberos 认证已被弃用,只应用于向后兼容。鼓励新的和 升级的安装改用行业标准的 GSSAPI 认证方法(参见 第 21.2.3 节)。
Kerberos 是一种行业标准的、适合在公共 网络上进行分布式计算的安全认证系统。 Kerberos 系统的说明超出了本文档的 范围;在最一般的形式下它可能相当复杂(但功能强大)。 Kerberos FAQ 或 MIT Kerberos 页面 是不错的入门起点。Kerberos 发行版有 多个来源。Kerberos 提供安全认证, 但不加密在网络上传递的查询或数据;为此请使用 SSL。
PostgreSQL 支持 Kerberos 版本 5。构建 PostgreSQL 时必须启用 Kerberos 支持;更多信息 参见 第 15 章。
PostgreSQL 的运行方式与普通的 Kerberos 服务相同。 服务主体的名称为 。servicename/hostname@realm
servicename 可以在服务器端用 krb_srvname 配置参数设置,在客户端用 krbsrvname 连接参数设置。(另见 第 30.1 节。)安装默认值可以在构建时用 ./configure --with-krb-srvnam=whatever 从默认的 postgres 改为其他值。在大多数环境中, 此参数永远不需要更改。但是,在同一台主机上支持多个 PostgreSQL 安装时,就需要修改它。某些 Kerberos 实现可能还要求不同的服务名,例如 Microsoft Active Directory 要求服务名为大写 (POSTGRES)。
hostname 是服务器机器的完全限定主机名。服务主体的 realm 是服务器机器的首选 realm。
客户端主体的第一个组成部分必须是PostgreSQL数据库用户名,例如pgusername@realm。默认情况下,PostgreSQL不检查客户端的 realm。如果启用了跨 realm 认证并且需要验证 realm,请使用krb_realm参数。
确保你的服务器 keytab 文件可被 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.orgkadmin%ktadd -k krb5.keytab postgres/server.my.domain.org
连接数据库时,请确保持有与请求的数据库用户名相匹配的主体票据。例如,对于数据库用户名 fred,主体 fred@EXAMPLE.COM 和 fred/users.example.com@EXAMPLE.COM 都可以用来向数据库服务器认证。
如果在 Apache Web 服务器上使用 mod_auth_kerb 和 mod_perl,则可以在 mod_perl 脚本中使用 AuthType KerberosV5SaveCredentials。这样即可 通过 Web 安全地访问数据库,无需额外的密码。
ident 认证方法的工作方式是获取客户端的操作系统用户名,然后使用一个列出允许的对应名称对的映射文件,确定允许的数据库用户名。确定客户端用户名是安全上的关键点,其工作方式因连接类型而异,如下所述。
“标识协议”在 RFC 1413 中定义。几乎所有类 Unix 操作系统都自带 ident 服务器,默认监听 TCP 端口 113。ident 服务器的基本功能是回答这样的问题:“从你的端口 X 连到我的端口 Y 的连接,是哪个用户发起的?”由于建立物理连接时,PostgreSQL 已知 X 和 Y,因此可以询问连接客户端所在主机上的 ident 服务器,理论上能够确定任意给定连接的操作系统用户。
这个过程的缺点在于它依赖客户端本身的可信性:如果客户端机器不可信或者已被攻破,攻击者几乎可以在 113 端口上运行任何程序,并返回任意他选择的用户名。因此,这种认证方法只适用于封闭网络,在这类网络中每台客户端机器都受到严格控制,而且数据库管理员与系统管理员之间保持密切协作。换句话说,你必须信任运行 ident 服务器的那台机器。请注意下面的警告:
|
标识协议的本意不是作为一种授权或访问控制协议。 |
||
| --RFC 1413 | ||
有些 ident 服务器提供了一个非标准选项,会让返回的用户名被加密,而解密所需密钥只有发起连接机器的管理员才知道。将 ident 服务器与 PostgreSQL 配合使用时,绝不能启用这个选项,因为 PostgreSQL 无法解密返回的字符串,也就无法确定实际用户名。
在支持对 Unix 域套接字使用 SO_PEERCRED 请求的系统(目前包括 Linux、 FreeBSD、 NetBSD、 OpenBSD 和 BSD/OS)上,ident 认证也可以 应用于本地连接。在这种情况下,使用 ident 认证不会增加任何安全风险;事实上,在这类系统上,它是本地 连接的首选方案。
在不支持 SO_PEERCRED 请求的系统上,ident 认证只适用 于 TCP/IP 连接。作为一种变通办法,可以指定 localhost 地址 127.0.0.1 并连接 到该地址。此方法的可信程度取决于你对本地 ident 服务器的 信任程度。
使用基于 ident 的认证时,在确定了发起连接的操作系统用户的名称之后,PostgreSQL会检查该用户是否被允许以其请求的数据库用户身份连接。这由pg_hba.conf文件中跟在ident关键词后面的 ident 映射参数控制。有一个预定义的 ident 映射sameuser,它允许任何操作系统用户以同名的数据库用户身份连接(如果后者存在)。其他映射必须手工创建。
sameuser之外的 ident 映射定义在 ident 映射文件中,该文件默认名为pg_ident.conf,存储在集簇的数据目录中。(不过也可以把该映射文件放在其他地方,参见ident_file配置参数。)ident 映射文件包含如下一般形式的行:
map-nameident-usernamedatabase-username
注释和空白的处理方式与pg_hba.conf中相同。map-name是任意名称,将用在pg_hba.conf中引用该映射。另外两个字段指定哪个操作系统用户被允许以哪个数据库用户身份连接。同一个map-name可以重复使用,在一个映射中指定更多用户映射。对于一个操作系统用户可以对应多少个数据库用户,或者反过来,都没有限制。
pg_ident.conf文件在启动时以及主服务器进程收到SIGHUP信号时读取。如果你在一个运行中的系统上编辑了该文件,你需要通知服务器重新读取它(使用pg_ctl reload或kill -HUP)。
一个可以与例 21.1中的pg_hba.conf文件配合使用的pg_ident.conf文件如例 21.2所示。在这个示例配置中,任何登录到 192.168 网络上某台机器的用户,如果其 Unix 用户名不是bryanh、ann或robert,将不会被授予访问权限。Unix 用户robert只有在他试图以PostgreSQL用户bob而非robert或其他任何人身份连接时才被允许访问。ann只被允许以ann身份连接。用户bryanh被允许以bryanh本人或guest1身份连接。
例 21.2. 一个 pg_ident.conf 文件示例
# MAPNAME IDENT-USERNAME PG-USERNAME omicron bryanh bryanh omicron ann ann # bob has user name robert on these machines omicron robert bob # bryanh can also connect as guest1 omicron bryanh guest1
这种认证方法的工作方式与password类似,只不过它使用 LDAP 作为认证方法。LDAP 只用于验证用户名/密码对。因此,在使用 LDAP 进行认证之前,用户必须已经存在于数据库中。所使用的服务器和参数在pg_hba.conf文件中指定在ldap关键词之后。该参数的格式为:
ldap[s]://servername[:port]/base dn[;prefix[;suffix]]
在ldap组件中,逗号被用来指定多个项。但是,由于未加引号的逗号在pg_hba.conf中会被当作项分隔符,明智的做法是用双引号把ldap URL 括起来,以保留其中的逗号,例如:
"ldap://ldap.example.net/dc=example,dc=net;EXAMPLE\"
如果指定的是ldaps而不是ldap,将为连接启用 TLS 加密。注意,这只会加密 PostgreSQL 服务器与 LDAP 服务器之间的连接。客户端与 PostgreSQL 服务器之间的连接不受此设置影响。要使用 TLS 加密,你可能需要先配置 LDAP 库再配置 PostgreSQL。注意,只有当平台的 LDAP 库支持时,加密的 LDAP 才可用。
如果未指定端口,将使用 LDAP 库中配置的默认端口。
服务器将使用客户端提供的用户名绑定到由base dn指定的可分辨名称。如果指定了prefix和suffix,它们将在绑定前分别前置和追加到用户名上。通常,prefix 参数用于指定cn=,或在 Active Directory 环境中指定DOMAIN\。
这种认证方法的工作方式与 password 类似,只不过它使用 PAM(可插拔认证 模块)作为认证机制。默认的 PAM 服务名为 postgresql。你也可以在pg_hba.conf文件中pam关键词后面提供自己的服务名。PAM 只用于验证用户名/密码对。 因此,在使用 PAM 进行认证之前,用户必须已经存在于数据库中。 关于 PAM 的更多信息,请阅读 Linux-PAM 页面 和 Solaris PAM 页面。
如果 PAM 被设置为读取 /etc/shadow,认证将会失败,因为 PostgreSQL 服务器是由非 root 用户启动的。不过,当 PAM 被配置为使用 LDAP 或其他认证方法时,这就不是问题。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。