客户端认证
本页目录
客户端认证#
OushuDB 支持以不同方式认证客户端。
pg_hba.conf#
客户端认证是由一个配置文件(通常名为pg_hba.conf)控制的, 该文件位于数据库集群 main 节点的数据目录中。HBA的意思是”host-based authentication”, 即基于主机的认证。在initdb初始化数据目录时, 会自动生成一个默认的pg_hba.conf文件。不过我们也可以把认证配置文件放在其它地方。参考hba_file配置参数,修改之后需要同步到所有 main 节点。
pg_hba.conf文件由多条记录组成,每行一条。空白行和以 # 开头的注释也被忽略。每条记录是由若干用空格和/或制表符分隔的字段组成。字段可用引号括起来以包含空白。记录不能跨行。
每条记录声明一种连接类型、一个客户端 IP 地址范围(如果和连接类型相关的话)、一个数据库名、一个用户名字、以及用于匹配这些参数的连接而使用的认证方法。系统会按顺序查找,第一条匹配连接类型、 客户端地址、连接请求的数据库名和用户名的记录将用于执行认证。这个处理过程没有 “跨越”或者”回头”的说法:如果选择了一条记录而且认证失败, 那么将不再考虑后面的记录。如果没有匹配的记录,则拒绝访问。
每条记录可以是下面七种格式之一:
local <database> <user> <auth-method> [<auth-options>]
host <database> <user> <address> <auth-method> [<auth-options>]
hostssl <database> <user> <address> <auth-method> [<auth-options>]
hostnossl <database> <user> <address> <auth-method> [<auth-options>]
host <database> <user> <IP-address> <IP-mask> <auth-method> [<auth-options>]
hostssl <database> <user> <IP-address> <IP-mask> <auth-method> [<auth-options>]
hostnossl <database> <user> <IP-address> <IP-mask> <auth-method> [<auth-options>]
各个字段的含义如下:
local
这条记录匹配企图通过 Unix 域套接字进行的连接。没有此类型的记录,则不允许 Unix 域套接字的连接。
host
这条记录匹配企图通过 TCP/IP 进行的连接。host记录匹配 SSL和非SSL的连接请求。
注:除非服务器设置了合适的listen_addresses配置参数值启动, 否则不可能进行远程的 TCP/IP 连接,因为缺省的行为是只监听本地自环地址localhost的连接。 默认情况下 OushuDB 接收来自任意主机的连接。
hostssl
这条记录匹配企图使用 SSL 加密的 TCP/IP 连接。
要使用这个选项,编译服务器的时候必须打开SSL支持,并在服务器启动的时候打开ssl配置选项(参阅 用 SSL 进行安全的 TCP/IP 连接 )。
hostnossl
匹配不使用 SSL 加密的 TCP/IP 连接。
database
声明记录所匹配的数据库名称。值 all 表明该记录匹配所有数据库, 值 sameuser 表示数据库名和用户名相同。 值 samerole 表示请求的用户属于与数据库同名的角色。 ( samegroup 是一个已经废弃了,但目前仍然被接受的 samerole 同义词。) 在其它情况里,这就是一个特定的 OushuDB 数据库的名字。可以通过用逗号分隔的方法声明多个数据库, 或通过前缀@来声明一个包含数据库名的文件。
user
指定此记录匹配的数据库角色名称。值all指定它匹配所有角色。如果指定的角色是一个组,组名前加 + 包含所有成员。可用逗号分隔多个角色名,或通过在文件名前加上@来指定包含角色名称的单独文件。
address
声明这条记录匹配的客户端机器IP地址范围。该地址用标准点分十进制声明并带有CIDR掩码长度(IP地址只能被声明为数字,无法作为域名或主机名)。 掩码长度表示客户端 IP 地址必须匹配的高位二进制位数。在给出的 IP 地址里, 这个长度的右边的二进制位应该为零。在 IP 地址、斜杠(\)和 CIDR 掩码长度之间不能有空格。
例如:172.20.143.89/32表示单个主机, 172.20.143.0/24表示一个小子网,10.6.0.0/16 表示一个大子网。要声明单个主机,给 IPv4 地址声明 CIDR 掩码 32 ,给 IPv6 地址声明 128 。 不要在地址中省略结尾的 0 。
以 IPv4 格式给出的 IP 地址只会匹配 IPv4 连接,一个以 IPv6 格式给出的记录将只匹配 IPv6 连接, 即使对应的地址在 IPv4-in-IPv6 范围内。请注意如果系统的 C 库不支持 IPv6 地址, 那么 IPv6 的格式将被拒绝。
也可使用特殊关键字:
all
匹配任意 IP,samehost
匹配服务器自身 IP,samenet
匹配服务器所在子网。如果指定了主机名(非IP地址、IP范围或特殊关键字的地址被视为主机名),则会将该名称与客户端IP地址的反向名称解析结果进行比较(如果使用DNS,则进行反向DNS查找)。主机名比较不区分大小写。如果匹配成功,则会对主机名执行正向名称解析(正向DNS查找),确认主机名解析出的地址与客户端 IP 相同,如果两个方向都匹配,则该条目被视为匹配。
在pg_hba.conf中使用的主机名应该是客户端IP地址的地址通过名称解析返回的名称,否则不会匹配。部分主机名数据库允许一个IP地址与多个主机名相关联,但操作系统在请求解析IP地址时只会返回一个主机名。
以点(.)开头的主机名规范匹配实际主机名的后缀。因此,.example.com将匹配foo.example.com(而不只是example.com)。
当在pg_hba.conf中指定主机名时,建议确保主机名解析速度较快,设置本地名称解析缓存(如nscd)。此外,可以启用服务器配置参数log_hostname,以便在日志中查看客户端主机名而不是IP地址。
IP-address & IP-mask
这些方法可以用于作为 CIDR-address 表示法的替补。它不是声明掩码的长度, 而是在另外一个字段里声明实际的掩码。比如,255.0.0.0表示 IPv4 CIDR 掩码长度为 8 , 而255.255.255.255表示 CIDR 掩码长度为 32 。
auth-method
声明连接匹配这条记录的时候使用的认证方法。常见方法如下:
trust: 无条件允许连接。允许任何可以与OushuDB 数据库服务器连接的用户以任意OushuDB 数据库用户身份进行连接,无需口令或其他认证。参阅“信任认证”获取细节。
reject: 无条件拒绝连接。常用于从一个组中”过滤”某些主机。
md5: 要求客户端提供一个 MD5 加密的口令进行认证。参阅“口令认证”获取细节。
password: 要求客户端提供一个未加密的口令进行认证。因为口令是以明文形式在网络上传递的, 所以我们不建议在不安全的网络上使用这个方式,也不应该在有威胁的客户端应用中使用。参阅“口令认证”获取细节。
krb5: 用 Kerberos V5 认证用户。仅适用于 TCP/IP 连接。 参阅“Kerberos认证”获取细节。
ident 获取客户端操作系统名,并检查该用户是否匹配连接要求的数据库用户名。方法是用户的身份通过与通过与客户端上的 ident 服务器通信进行判断或通过从操作系统获取本地连接来获得TCP/IP连接。 参阅“基于Ident的认证”获取细节。
ldap: 使用LDAP中心服务器进行认证。参阅“LDAP认证“获取细节。
pam: 使用操作系统提供的可插入认证模块服务(PAM)来认证。参阅”PAM 认证“获取细节。
auth-options: 此可选字段的含义取决于所选的身份验证方法。 详情见”auth-method“项。
用@构造包含的文件是当作一列名字读取的,这些名字可以用空白或者逗号分隔。 注释用 # 引入,就像在pg_hba.conf里那样, 允许嵌套@构造。除非跟在@后面的文件名是一个绝对路径, 否则被当作与该文件所在目录相对的路径。
认证时,系统会为每个连接请求顺序检查 pg_hba.conf 里的记录, 所以这些记录的顺序是非常关键的。通常,靠前的记录有更严格的连接匹配参数和更宽松的认证方法, 而靠后的记录有比较松的匹配参数和比较严的认证方法。比如,我们通常希望对本地 TCP/IP 连接使用 trust认证,而对远端的 TCP/IP 连接要求口令。在这种情况下我们将trust 认证方法用于来自 127.0.0.1 的连接,这条记录将出现在允许更广泛的客户端 IP 地址的使用口令认证的记录前面。
在启动和主服务器进程收到 SIGHUP 信号的时候,系统都会重新装载pg_hba.conf文件。 如果你在运行中的系统上编辑了该文件,必须通过 oushudb reload 或 kill -HUP 通知主服务器重新加载配置,以使更改生效。
用户要想成功连接到特定的数据库,不仅需要通过pg_hba.conf的检查, 还必须要有该数据库上的 CONNECT 权限。如果希望限制哪些用户能够连接到哪些数据库, 赋予或撤销 CONNECT 权限通常比在pg_hba.conf中设置规则简单。
下面是pg_hba.conf记录的一些例子:
# 允许任何用户在本地系统上连接任何数据库
# 允许在本机上的任何用户使用 Unix 域套接字(默认本地连接)
#
# TYPE DATABASE USER ADDRESS METHOD
local all all trust
# 允许本机回环地址的(loopback)TCP/IP 连接
#
# TYPE DATABASE USER ADDRESS METHOD
host all all 127.0.0.1/32 trust
# 使用独立子网掩码字段的写法
#
# TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD
host all all 127.0.0.1 255.255.255.255 trust
# 允许 IP 地址为 192.168.93.x 的任何主机与 "postgres" 数据库相连,
# 用与他们在自己的主机上相同 ident 的用户名标识他自己(通常是他的操作系统用户名)
#
# TYPE DATABASE USER ADDRESS METHOD
host postgres all 192.168.93.0/24 ident
# 允许来自主机 192.168.12.10 的用户提供了正确的口令之后与 "postgres" 数据库连接。
#
# TYPE DATABASE USER ADDRESS METHOD
host postgres all 192.168.12.10/32 md5
# 如果前面没有其它 "host" 行,那么下面两行将拒绝所有来自 192.168.54.1 的连接请求(因为前面的记录先匹配)。
# 但是允许来自互联网上其它任何地方的有效的 Kerberos 5 认证的连接。
# 零掩码引起不考虑主机 IP 的任何位。因此它匹配任何主机。
#
# TYPE DATABASE USER ADDRESS METHOD
host all all 192.168.54.1/32 reject
host all all 0.0.0.0/0 krb5
# 允许来自 192.168.x.x 的任何用户与任意数据库连接,只要他们通过 ident 检查。
# 但如果 ident 说该用户是 "bryanh" 且他要求以 OushuDB 用户 "guest1" 连接,
# 那么只有在 pg_ident.conf 里有 "omicron" 的映射说 "bryanh" 允许以 "guest1" 进行连接时才真正可以进行连接。
#
# TYPE DATABASE USER ADDRESS METHOD
host all all 192.168.0.0/16 ident map=omicron
# 如果下面是用于本地连接的仅有的三行,那么它们将允许本地用户只和同名数据库连接。
# 只有管理员和 "support" 角色里的成员例外,他们可以连接到任何数据库。
# $PGDATA/admins 文件列出了那些允许与所有数据库连接的用户名。
# 在所有情况下都需要口令。
#
# TYPE DATABASE USER ADDRESS METHOD
local sameuser all md5
local all @admins md5
local all +support md5
# 上面最后两行可以合起来写成一行
local all @admins,+support md5
# 数据库字段也可以使用列表和文件名
local db1,db2,@demodbs all md5
认证方法#
trust#
如果声明了 trust 认证模式,OushuDB 会允许任何可以连接到服务器的人都可以以任何他声明的数据库用户名(包括超级用户名)连接。 当然,在database和user字段里面的限制仍然适用。 该方法应仅用于服务器已具备足够操作系统层级保护的环境。
trust认证适用于单用户工作站的本地连接是,通常不推荐用于多用户环境。不过,即使在多用户的机器上, 也可以通过文件系统权限限制服务器的 Unix 域套接字文件访问,从而安全使用 trust。 可以通过设置 unix_socket_permissions(以及可能的 unix_socket_group)参数,或设置 unix_socket_directories 将套接字文件放在受限目录下。
设置文件系统权限只能帮助 Unix 套接字连接,它不会限制本地 TCP/IP 连接。因此, 如果希望文件系统权限来控制本地安全,应删除pg_hba.conf文件中的 host … 127.0.0.1 …行,或者将其改为一个非trust的认证方法。
trust 认证模式只适合你信任所有相关主机和用户的 TCP/IP 连接。 一般不推荐使用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’)。如果没有明确设置口令,那么存储的口令是空并且该用户无法通过口令认证登录。
LDAP 身份验证#
请参考 LDAP 认证
PAM 认证#
除了使用PAM(可插入认证模块)作为认证机制之外,此认证方法与密码类似。 默认的PAM服务名称是postgresql。 可以选择在pg_hba.conf文件中的pam关键字后指定自定义服务名。 PAM仅用于验证用户名/密码对。 因此,在PAM可以用于认证之前,用户必须已经存在于数据库中。 有关PAM的更多信息,请阅读Linux-PAM页面和Solaris PAM页面。
SSL#
请参考 SSL 配置章节