认证方法

下面的小节更详细地描述认证方法。

信任认证

如果声明了trust认证模式,OushuDB 就假设任何可以连接到服务器的人都可以以任何他声明的数据库用户名(甚至超级用户名)连接。 当然,在database和user字段里面的限制仍然适用。 这个方法应该用于那些在连接到服务器已经有足够操作系统层次保护的环境里。

trust认证对于单用户工作站的本地连接是非常合适和方便的。 通常它本身并不适用于多用户环境的机器。不过,即使在多用户的机器上, 你也可以使用trust,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问。 要做这些限制,你可以设置unix_socket_permissions参数(以及可能还有 unix_socket_group),就像 连接和认证 里描述的那样。 或者你可以设置unix_socket_directories,把 Unix 域套接字文件放在一个经过恰当限制的目录里。

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

trust认证模式只适合 TCP/IP 连接,只有在你信任那些trust 行上所有机器中的所有用户的时候才是合适的。 很少有理由使用trust作为任何除来自localhost (127.0.0.1) 以外的 TCP/IP 连接的认证方式。

口令认证

以口令为基础的认证方法包括md5,crypt和password。这些方法操作上非常类似, 只不过口令通过连接传送的方法不同:分别是MD5 哈希、crypt加密、明文。有一个限制是crypt方法不适用于pg_authid已经加密的口令。

如果你担心口令被”窃听”,那么md5比较合适。 在开放网络中应该尽可能避免使用password(除非你使用SSL,SSH,或者另一种通信安全包装器连接)。

OushuDB 数据库口令与任何操作系统用户口令无关。 各个数据库用户的口令是存储在pg_authid系统表里面。 口令可以用 SQL 语言命令CREATE USER和ALTER ROLE 等管理(比如CREATE USER foo WITH PASSWORD ‘secret’)。如果没有明确设置口令,那么存储的口令是空并且该用户的口令认证总会失败。

Kerberos 认证

Kerberos是一种适用于在公共网络上进行分布计算的工业标准的安全认证系统。 对Kerberos系统的叙述超出了本文档的范围; 总的说来它是相当复杂(同样也相当强大)的系统。 Kerberos FAQ或MIT Kerberos page 是个开始学习的好地方。现存在好几种Kerberos发布的源代码。Kerberos 只提供安全认证,但并不加密在网络上传输的查询和数据,SSL可以用于这个目的。

OushuDB 支持 Kerberos 5 ,Kerberos 支持必须在编译的时候打开。

OushuDB 运行时像一个普通的 Kerberos 服务。服务主的名字是 servicename/hostname@realm

servicename可以用krb_srvname配置参数在服务器端设置, 或者在客户端使用krbsrvname连接参数设置。 编译的时候,可以把安装时的缺省postgres修改掉,方法是使用 ./configure –with-krb-srvnam=whatever。在大多数情况下, 我们不需要修改这个参数。但是,如果需要在同一台主机上同时安装多套OushuDB, 那么这个就是必须的了。有些 Kerberos 实现还可能要求其它的服务名, 比如 Microsoft Active Directory 就要求服务名必须是大写的(POSTGRES)。

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

客户主自己必须用它们自己的OushuDB 用户名作为第一个部件, 比如pgusername/otherstuff@realm。现在,OushuDB 没有检查客户的域;因此如果你打开了跨域的认证,那么任何区域的任何客户主与你的交流都会被接受。

确认服务器的密钥表文件是可以被OushuDB 服务器帐户读取 (最好就是只读的)。密钥文件(keytab)的位置是用配置参数 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将能够连接。

如果你在Apache服务器上使用了 mod_auth_kerb 和mod_perl模块,你可以用一个mod_perl 脚本进行AuthType KerberosV5SaveCredentials。 这样就有了一个通过 web 的安全数据库访问,不需要额外的口令。

基于Ident的认证

ident 认证方法是通过从一个ident服务器获取客户端的操作系统用户名,然后列出允许的相对应名称的映射文件确定允许的数据库用户名。客户端用户名的确定是安全关键点,取决于连接类型,它的工作方式不同。

通过TCP/IP进行Ident认证

“Identification Protocol”(标识协议)在 RFC 1413 里面描述。 实际上每个类 Unix 的操作系统都带着一个缺省时侦听 113 端口的身份服务器。 身份服务器的基本功能是回答类似这样的问题:”是什么用户从你的端口 X初始化出来连接到我的端口Y上来了?”。 因为在建立起物理连接后,OushuDB 既知道X也知道Y, 因此它可以询问运行尝试连接的客户端的主机,并且理论上可以判断发起连接的操作系统用户。

这样做的缺点是它取决于客户端的完整性:如果客户端不可信或者被盗用, 那么攻击者可以在 113 端口上运行任何程序并且返回他们选择的任何用户。 这个认证方法只适用于封闭的网络, 这样的网络里的每台客户机都处于严密的控制下并且数据库和操作系统管理员可以比较方便地联系上。 换句话说,你必须信任运行身份(ident)服务的机器。下面是警告:

身份标识协议并不适用于认证或者访问控制协议。

–RFC 1413

有些身份服务器有一个非标准的选项,导致返回的用户名是加密的, 使用的是只有原机器的管理员知道的一个密钥。在与OushuDB 配合使用身份认证的时候, 你一定 不能 使用这个选项,因为OushuDB 没有任何方法对返回的字符串进行解密以获取实际的用户名。

通过本地套接字进行Ident认证

在支持Unix域套接字(当前为Linux,FreeBSD,NetBSD,OpenBSD和BSD / OS)的SO_PEERCRED请求的系统上,ident身份验证也可以应用于本地连接。 在这种情况下,使用身份验证不会增加安全风险; 它确实是这种系统上本地连接的首选。

在没有SO_PEERCRED请求的系统上,身份验证仅适用于TCP / IP连接。 作为解决方法,可以指定本地主机地址127.0.0.1并建立到该地址的连接。 在您信任本地身份服务器的情况下,此方法值得信赖。

Ident映射

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

身份映射文件中定义了除sameuser之外的身份映射,默认情况下该身份映射文件名为pg_ident.conf并存储在群集的数据目录中。 (然而,可以将映射文件放置在其他地方;请参阅ident_file配置参数。)ident映射文件包含一般形式的行:

map-name ident-username database-username

注释和空白的处理方式与pg_hba.conf中的相同。 map-name是一个任意名称,将用于在pg_hba.conf中引用此映射。 其他两个字段指定允许哪个操作系统用户连接作为哪个数据库用户。 相同的映射名称可以重复使用,以在单个映射内指定更多的用户映射。 对于给定的操作系统用户可以对应多少个数据库用户没有限制,反之亦然。

在启动时以及主服务器进程收到SIGHUP信号时读取pg_ident.conf文件。 如果您在活动系统上编辑文件,则需要向服务器发送信号(使用hawq reload或kill -HUP)以使其重新读取文件。

下面例子中显示了可以与之前示例中的pg_hba.conf文件结合使用的pg_ident.conf文件。 在此示例设置中,任何登录到192.168网络上没有Unix用户名bryanh,ann或robert的计算机的用户都不会被授予访问权限。 Unix用户robert只有在他试图以OushuDB 用户bob而不是robert或其他人的身份连接时才被允许访问。 ann只能被允许连接作为ann。 用户bryanh将被允许连接为无论是bryanh本人还是guest1。

# 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

LDAP 认证

这个认证方法操作起来类似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加密。 请注意,这将仅加密OushuDB服务器和LDAP服务器之间的连接。 客户端和OushuDB服务器之间的连接不受此设置的影响。 要使用TLS加密,您可能需要在配置OushuDB之前配置LDAP库。 请注意,加密的LDAP仅在平台的LDAP库支持时才可用。

如果未指定端口,则将使用在LDAP库中配置的默认端口。

服务器将使用客户端提供的用户名绑定到作为基本dn指定的专有名称。 如果指定了前缀和后缀,则会在绑定之前将其前缀和后缀添加到用户名中。 通常,前缀参数用于在Active Directory环境中指定cn =或DOMAIN 。

PAM 认证

除了使用PAM(可插入认证模块)作为认证机制之外,此认证方法与密码类似。 默认的PAM服务名称是postgresql。 您可以选择在pg_hba.conf文件中的pam关键字之后提供您自己的服务名称。 PAM仅用于验证用户名/密码对。 因此,在PAM可以用于认证之前,用户必须已经存在于数据库中。 有关PAM的更多信息,请阅读Linux-PAM页面和Solaris PAM页面。