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@realmservicename 是 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.orgkadmin%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-nameident-usernamedatabase-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 页面。