↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

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 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1
历史版本PostgreSQL 7.4 已于 2010 年 10 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

19.2. 认证方法 #

下面详细描述这些认证方法。

19.2.1. trust 认证 #

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

trust 认证对单用户工作站上的本地连接来说是 合适且非常方便的。在多用户机器上,通常单用它并 不合适。不过,如果用文件系统权限限制对 服务器 Unix 域套接字文件的访问,即使在多用户机器上也可以使用 trust。为此,可按 第 16.4.1 节 中的说明设置 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.2.2. 密码认证 #

基于密码的认证方法有 md5、 crypt 和 password。除了密码通过连接发送的方式之外,这些方法的操作是相似的。如果你对密码“嗅探”攻击有任何顾虑,应首选 md5;如果必须支持 pre-7.2 客户端,则次选 crypt。对通过开放 Internet 的连接(除非你在连接周围使用 SSL、SSH 或其他通信安全封装),尤其应避免使用明文 password。

PostgreSQL 数据库密码与操作系统用户密码是分开的。每个数据库用户的密码存储在 pg_shadow 系统目录表中。密码可以用 SQL 命令 CREATE USER 和 ALTER USER 管理,例如 CREATE USER foo WITH PASSWORD 'secret';。默认情况下,即如果没有设置密码,存储的密码为空,该用户的密码认证将总是失败。

要限制允许连接到某些数据库的用户集合,可在 pg_hba.conf 的 user 列中列出这些用户,如前一节所解释的那样。

19.2.3. Kerberos 认证 #

Kerberos 是一种行业标准的、适合在公共网络上进行分布式计算的安全认证系统。对 Kerberos 系统的描述远超出本文档的范围;就一般性而言,它可能相当复杂(然而强大)。Kerberos FAQ 或 MIT Project Athena 可以作为入门的起点。存在若干 Kerberos 发行版来源。

虽然 PostgreSQL 同时支持 Kerberos 4 和 Kerberos 5,但只推荐 Kerberos 5。Kerberos 4 被认为不安全,不再推荐一般使用。

要使用 Kerberos,必须在构建时启用对它的支持。更多信息见 第 14 章。Kerberos 4 和 5 都受支持,但任何一个构建中只能支持一个版本。

PostgreSQL 像一个正常的 Kerberos 服务那样运作。服务主体的名称是 servicename/hostname@realm,其中 servicename 是 postgres(除非在 configure 时用 ./configure --with-krb-srvnam=whatever 选择了不同的服务名)。hostname 是服务器机器的完全限定主机名。服务主体的 realm 是服务器机器的首选 realm。

客户端主体必须以它们的 PostgreSQL 用户名作为第一个组成部分,例如 pgusername/otherstuff@realm。目前 PostgreSQL 不检查客户端的 realm;因此,如果你启用了跨 realm 认证,那么任何能与你的 realm 通信的任何 realm 中的任何主体都会被接受。

确保你的服务器密钥文件可被 PostgreSQL 服务器账号读取(而且最好只被它读取)。(另见 第 16.1 节。)密钥文件的位置由运行时配置参数 krb_server_keyfile 指定。(另见 第 16.4 节。)默认值:使用 Kerberos 4 时为 /etc/srvtab,使用 Kerberos 5 时为 FILE:/usr/local/pgsql/etc/krb5.keytab(或构建时指定为 sysconfdir 的那个目录)。

要生成 keytab 文件,例如可以(用版本 5)使用

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

细节请阅读 Kerberos 文档。

连接到数据库时,确保你持有与所请求的数据库用户名匹配的主体的票据。一个例子:对于数据库用户名 fred,主体 fred@EXAMPLE.COM 和 fred/users.example.com@EXAMPLE.COM 都可以用来向数据库服务器认证。

如果你在 Apache Web 服务器上使用来自 http://modauthkerb.sf.net 的 mod_auth_kerb 和 mod_perl,你可以在 mod_perl 脚本中使用 AuthType KerberosV5SaveCredentials。这能通过 Web 安全地访问数据库,无需额外的密码。

19.2.4. 基于 ident 的认证 #

ident 认证方法的工作方式是获取客户端的操作系统用户名,并用一个列出允许的对应用户名对的映射文件来确定允许的数据库用户名。确定客户端用户名是安全上的关键点,其工作方式因连接类型而异。

19.2.4.1. TCP/IP 上的 Ident 认证

“Identification Protocol”(识别协议)在 RFC 1413 中描述。几乎每个类 Unix 操作系统都附带一个 ident 服务器,默认监听 TCP 端口 113。ident 服务器的基本功能是回答诸如“哪个用户发起了从你的端口 X 出来并连接到我的端口 Y 的连接?”这样的问题。由于在建立物理连接时 PostgreSQL 同时知道 X 和 Y,它可以查询连接客户端主机上的 ident 服务器,并由此在理论上确定任何给定连接的操作系统用户。

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

 

标识协议(Identification Protocol)并不打算用作授权或访问控制协议。

 
  --RFC 1413

19.2.4.2. 本地套接字上的 Ident 认证

在支持对 Unix 域套接字的 SO_PEERCRED 请求的系统上(目前有 Linux、FreeBSD、 NetBSD、OpenBSD 和 BSD/OS),ident 认证也可以应用于本地连接。这种情况下,使用 ident 认证不会增加安全风险;实际上,在这样的系统上它是本地连接的更可取选择。

在不支持 SO_PEERCRED 请求的系统上,ident 认证只适用于 TCP/IP 连接。作为一种变通办法,可以指定 localhost 地址 127.0.0.1 并连接到该地址。

19.2.4.3. Ident 映射

使用基于 ident 的认证时,在确定了发起连接的操作系统用户的名称之后,PostgreSQL会检查该用户是否被允许以他请求连接的数据库用户身份连接。这由 pg_hba.conf 文件中跟在 ident 关键字之后的 ident 映射参数控制。有一个预定义的 ident 映射 sameuser,它允许任何操作系统用户以同名的数据库用户身份连接(如果后者存在)。其他映射必须手工创建。

sameuser 之外的 ident 映射定义在数据目录的文件 pg_ident.conf 中,该文件包含如下一般形式的行:

map-name ident-username database-username

注释和空白的处理与通常一样。map-name 是一个任意名称,将用于在 pg_hba.conf 中引用这个映射。另外两个字段指定哪个操作系统用户被允许以哪个数据库用户身份连接。同一个 map-name 可以重复使用,以在单个映射中指定更多的用户映射。一个给定的操作系统用户可以对应多少个数据库用户、反之一个数据库用户可以对应多少个操作系统用户,都没有限制。

pg_ident.conf 文件在启动时以及主服务器进程(postmaster)收到 SIGHUP 信号时读取。如果在运行的系统上编辑了该文件,你需要(使用 pg_ctl reload 或 kill -HUP)向 postmaster 发信号,让它重新读取该文件。

一个可与 例 19.1 中的 pg_hba.conf 文件配合使用的 pg_ident.conf 文件见 例 19.2。在这个示例设置中,任何登录到 192.168 网络某台机器上、但 Unix 用户名不是 bryanh、ann 或 robert 的人都不会被授予访问权限。Unix 用户 robert 只有在他尝试以 PostgreSQL 用户 bob 而不是 robert 或任何其他人身份连接时才被允许访问。ann 只被允许以 ann 身份连接。用户 bryanh 被允许以 bryanh 本人或 guest1 身份连接。

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

19.2.5. PAM 认证 #

这种认证方法的工作方式与 password 类似,只不过它使用 PAM(可插拔认证模块)作为认证机制。默认的 PAM 服务名为 postgresql。你可以在文件 pg_hba.conf 中 pam 关键字之后可选地提供你自己的服务名。关于 PAM 的更多信息,请阅读 Linux-PAM 页面 和 Solaris PAM 页面。

提交更正

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