认证方法
本页目录
认证方法#
下面的小节更详细地描述认证方法。
信任认证#
如果声明了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。
OushudbDB支持多kerberos服务。servicename可以用krb_server_list配置参数中的项在服务器端设置,在客户端则可以复制服务端的kerb5.conf文件并使用,通常kerb5.conf文件的路径是/etc/krb5.conf。有些 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文件。 如果您在活动系统上编辑文件,则需要向服务器发送信号(oushudb 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 进行认证之前,用户必须已经存在于数据库中。
LDAP 认证可以在两种模式下操作。在第一种模式中(我们将称之为简单绑定模式),服务器将绑定到构造成 prefix username suffix 的可区分名称。通常,prefix 参数被用于指定 cn= 或者一个活动目录环境中的 DOMAIN 。suffix 被用来指定非活动目录环境中的 DN 的剩余部分。
在第二种模式中(我们将称之为搜索与绑定模式),服务器首先用一个固定的用户名和密码(用 ldapbinddn 和 ldapbindpasswd 指定)绑定到 LDAP 目录 ,并为试图登入该数据库的用户执行一次搜索。如果没有配置用户名和密码, 将尝试一次匿名绑定到目录。搜索将在位于 ldapbasedn 的子树上被执行,并将尝试做一次 ldapsearchattribute 中指定属性的精确匹配。一旦在这次搜索中找到用户,服务器断开并且作为这个用户重新绑定到目录,使用由客户端指定的口令来验证登录是正确的。这种模式与在其他软件中的 LDAP 认证所使用的相同,例如 Apache mod_authnz_ldap 和 pam_ldap 。这种方法允许位于目录中用户对象的更大灵活性,但是会导致建立两个到 LDAP 服务器的独立连接。
下列配置选项被用于两种模式:
ldapserver
要连接的 LDAP 服务器的名称或 IP 地址。可以指定多个服务器,用空格分隔。
ldapport
要连接的 LDAP 服务器的端口号。如果没有指定端口, LDAP 库的默认端口设置将被使用。
ldapscheme
设置为 ldaps 可以使用LDAPS。这是一种非标准的在 SSL 之上使用 LDAP 的方法,在有一些 LDAP 服务器实现上可以支持。其他选择还可以参考 ldaptls 选项。
ldaptls
设置为1以使 PostgreSQL 和 LDAP 服务器之间的连接使用 TLS 加密。这会按照 RFC 4513 使用 StartTLS 操作。其他选择还可以参考 ldapscheme 选项。
注意使用 ldapscheme 或 ldaptls 仅会加密 PostgreSQL 服务器和 LDAP 服务器之间的通信。PostgreSQL 服务器和 PostgreSQL 客户端之间的连接仍是未加密的,除非也在其上使用 SSL。
下列选项只被用于简单绑定模式:
ldapprefix
当做简单绑定认证时,前置到用户名形成要用于绑定的 DN 的字符串。
ldapsuffix
当做简单绑定认证时,前置到用户名形成要用于绑定的 DN 的字符串。
下列选项只被用于搜索与绑定模式:
ldapbasedn
当做搜索与绑定认证时,开始搜索用户的根 DN。
ldapbinddn
当做搜索与绑定认证时,用户要绑定到目录开始执行搜索的 DN。
ldapbindpasswd
当做搜索与绑定认证时,用户用于绑定到目录开始执行搜索的口令。
ldapsearchattribute
当做搜索与绑定认证时,在搜索中用来与用户名匹配的属性。如果没有指定属性,将会使用 uid 属性。
ldapsearchfilter
在做 search+bind 认证时使用的搜索过滤器。$username 的出现将被替换为用户名。这允许比 ldapsearchattribute 更加灵活的搜索过滤器。
ldapurl
一个 RFC 4516 LDAP URL。这是一种用更紧凑和标准的形式书写某些其他 LDAP 选项的可选方法。格式是
ldap[s]://host[:port]/basedn[?[attribute][?[scope][?[filter]]]]
scope 必须是 base、one、sub 之一,通常是最后一个(默认是 base,但它在这个应用中通常没啥用)。attribute 可以指定一个属性,在这种情况中它被用作 ldapsearchattribute 的一个值。如果 attribute 为空,那么 filter 可以被用作 ldapsearchfilter 的一个值。
URL 模式 ldaps 选择 LDAPS 方法来在 SSL 上建立 LDAP 连接,等效于使用 ldapscheme=ldaps。要使用 StartTLS 操作加密 LDAP 连接,可以用普通的 URL 模式 ldap 并且在 ldapurl 之外指定 ldaptls 选项。
对于非匿名绑定,ldapbinddn 和 ldapbindpasswd 必须被指定为独立选项。
LDAP URL 当前只支持 OpenLDAP,而不支持 Windows。
将简单绑定的选项中混合用于搜索与绑定的选项是一种错误。
在使用 search+bind 模式时,可以用 ldapsearchattribute 指定的单个属性执行搜索,或者使用 ldapsearchfilter 指定的自定义搜索过滤器执行搜索。指定 ldapsearchattribute=foo 等效于指定 ldapsearchfilter=”(foo=$username)”。如果两个选项都没有被指定,则默认为 ldapsearchattribute=uid。
如果 PostgreSQL 与 OpenLDAP 一起编译为 LDAP 客户端库,ldapserver 设置可能被省略。 在这种情况下,主机名和端口列表通过 RFC 2782 DNS SRV 记录来进行查询。 查询名称 _ldap._tcp.DOMAIN , DOMAIN 是从 ldapbasedn 中摘取的。
这里是一个简单绑定 LDAP 配置的例子:
host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net"
当请求一个作为数据库用户 someuser 到数据库服务器的连接时,PostgreSQL 将尝试使用 cn=someuser, dc=example, dc=net 和客户端提供的口令来绑定到 LDAP 服务器。如果那个连接成功,将被授予数据库访问。
这里是一个搜索与绑定配置的例子:
host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid
当请求一个作为数据库用户 someuser 到数据库服务器的连接时,PostgreSQL 将尝试匿名绑定(因为没有指定 ldapbinddn )到 LDAP 服务器,在指定的基础 DN 下执行一次对于( uid=someuser )的搜索。如果找到一个项,则它将尝试使用找到的信息和客户端提供的口令进行绑定。如果第二个连接成功,将被授予数据库访问。
这里是被写成一个 URL 的相同搜索与绑定配置:
host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub"
一些支持根据 LDAP 认证的其他软件使用相同的 URL 格式,因此很容易共享该配置。
这里是一个 search+bind 配置的例子,它使用 ldapsearchfilter 而不是 ldapsearchattribute 来允许用用户 ID 或电子邮件地址进行认证:
host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchfilter="(|(uid=$username)(mail=$username))"
这是一个 search+bind 配置的例子,它使用 DNS SRV discovery 来查找域名 example.net 的 LDAP 服务的主机名和端口。
host ... ldap ldapbasedn="dc=example,dc=net"
PAM 认证#
除了使用PAM(可插入认证模块)作为认证机制之外,此认证方法与密码类似。 默认的PAM服务名称是postgresql。 您可以选择在pg_hba.conf文件中的pam关键字之后提供您自己的服务名称。 PAM仅用于验证用户名/密码对。 因此,在PAM可以用于认证之前,用户必须已经存在于数据库中。 有关PAM的更多信息,请阅读Linux-PAM页面和Solaris PAM页面。