6.2. 身份验证相关的配置文件
6.2.1. sys_hba.conf文件
客户端认证是由一个配置文件(通常名为sys_hba.conf
并被存放在数据库集簇目录中)控制(HBA表示基于主机的认证)。在initdb
初始化数据目录时,它会安装一个默认的sys_hba.conf
文件。不过我们也可以把认证配置文件放在其它地方,可配置hba_file参数。
sys_hba.conf
文件的常用格式是一组记录,每行一条。空白行将被忽略, #
注释字符后面的任何文本也被忽略。记录不能跨行。一条记录由若干用空格和/或制表符分隔的域组成。如果域值用双引号包围,那么它可以包含空白。在数据库、用户或地址域中引用一个关键字(例如,all
或replication
)将使该词失去其特殊含义,并且只是匹配一个有该名字的数据库、用户或主机。
每条记录指定一种连接类型、一个客户端 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] hostgssenc database user IP-address IP-mask auth-method [auth-options] hostnogssenc database user IP-address IP-mask auth-method [auth-options]
各个域的含义如下:
local
这条记录匹配企图使用 Unix 域套接字的连接。如果没有这种类型的记录,就不允许 Unix 域套接字连接。
host
这条记录匹配企图使用 TCP/IP 建立的连接。
host
记录匹配SSL或者non-SSL连接企图,也匹配GSSAPI加密或non-GSSAPI加密的连接企图。注意
除非服务器带着合适的 listen_addresses 配置参数值启动,否则将不可能进行远程的 TCP/IP 连接,因为默认的行为是只监听在本地环回地址
localhost
上的 TCP/IP 连接。
hostssl
这条记录匹配企图使用 TCP/IP 建立的连接,但必须是使用SSL加密的连接。
要使用这个选项,编译服务器的时候必须打开SSL支持。此外,在服务器启动的时候必须通过设置 ssl 配置参数(详见 SSL客户端证书认证 )打开SSL。否则,
hostssl
记录会被忽略,并且会记录一个警告说它无法匹配任何连接。
hostnossl
这条记录的行为与
hostssl
相反;它只匹配那些在 TCP/IP上不使用SSL的连接企图。
hostgssenc
这条记录匹配企图使用 TCP/IP 建立的连接,但必须是使用GSSAPI加密的连接。
要使用这个选项,编译服务器的时候必须打开 GSSAPI 支持。 否则,
hostgssenc
记录会被忽略,并且会记录一个警告说它无法匹配任何连接。注意,只支持使用GSSAPI加密的认证方法是
gss
、reject
。
hostnogssenc
这条记录的行为与
hostgssenc
相反;它只匹配那些在 TCP/IP上不使用GSSAPI加密的连接企图。
database
指定记录所匹配的数据库名称。值
all
指定该记录匹配所有数据库。值sameuser
指定如果被请求的数据库和请求的用户同名,则匹配。值samerole
指定请求的用户必须是一个与数据库同名的角色中的成员(samegroup
是一个已经废弃了,但目前仍然被接受的samerole
同义词)。对于一个用于samerole
目的的角色,超级用户不会被考虑为其中的成员,除非它们是该角色的显式成员(直接或间接),而不是由于超级用户的原因。值replication
指定如果一个物理复制连接被请求则该记录匹配(注意复制连接不指定任何特定的数据库)。在其它情况里,这就是一个特定的KingbaseES数据库名字。可以通过用逗号分隔的方法指定多个数据库,也可以通过在文件名前面放@
来指定一个包含数据库名的文件。
user
指定这条记录匹配哪些数据库用户名。值
all
指定它匹配所有用户。否则,它要么是一个特定数据库用户的名字或者是一个有前导+
的组名称(回想一下,在KingbaseES里,用户和组没有真正的区别,+
实际表示“匹配这个角色的任何直接或间接成员角色”,而没有+
记号的名字只匹配指定的角色)。出于这个目的,如果超级用户显式的是一个角色的成员(直接或间接),那么超级用户将只被认为是该角色的一个成员而不是作为一个超级用户。多个用户名可以通过用逗号分隔的方法提供。一个包含用户名的文件可以通过在文件名前面加上@
来指定。
address
指定这个记录匹配的客户端机器地址。这个域可以包含一个主机名、一个 IP 地址范围或下文提到的特殊关键字之一。
一个 IP 地址范围以该范围的开始地址的标准数字记号指定,然后是一个斜线(
/
) 和一个CIDR掩码长度。掩码长度表示客户端 IP 地址必须匹配的高序二进制位位数。在给出的 IP 地址中,这个长度的右边的二进制位必须为零。 在 IP 地址、/
和 CIDR 掩码长度之间不能有空白。这种方法指定一个 IPv4 地址范围的典型例子是:
172.20.143.89/32
用于一个主机,172.20.143.0/24
用于一个小型网络,10.6.0.0/16
用于一个大型网络。 一个单主机的 IPv6 地址范围看起来像这样:::1/128
(IPv6 回环地址), 一个小型网络的 IPv6 地址范围则类似于:fe80::7a31:c1ff:0000:0000/96
。0.0.0.0/0
表示所有 IPv4 地址,并且::0/0
表示所有 IPv6 地址。要指定一个单一主机,IPv4 用一个长度为 32 的 CIDR 掩码或者 IPv6 用 长度为 128 的 CIDR 掩码。在一个网络地址中,不要省略结尾的零。一个以 IPv4 格式给出的项将只匹配 IPv4 连接并且一个以 IPv6 格式给出的项将只匹配 IPv6 连接,即使对应的地址在 IPv4-in-IPv6 范围内。请注意如果系统的 C 库不支持 IPv6 地址,那么 IPv6 格式中的项将被拒绝。
你也可以写
all
来匹配任何 IP 地址、写samehost
来匹配任何本服务器自身的 IP 地址或者写samenet
来匹配本服务器直接连接到的任意子网的任意地址。如果指定了一个主机名(任何除 IP 地址单位或特殊关键字之外的都被作为主机名处理), 该名称会与客户端的 IP 地址的反向名字解析(例如使用 DNS 时的反向 DNS 查找)结果进行比较。主机名比较是大小写敏感的。如果匹配上,那么将在主机名上执行一次正向名字解析(例如正向 DNS 查找)来检查它解析到的任何地址是否等于客户端的 IP 地址。如果两个方向都匹配,则该项被认为匹配(
sys_hba.conf
中使用的主机名应该是客户端 IP 地址的地址到名字解析返回的结果,否则该行将不会匹配。某些主机名数据库允许将一个 IP 地址关联多个主机名,但是当被要求解析一个 IP 地址时,操作系统将只返回一个主机名)。一个以点号(
.
)开始的主机名声明匹配实际主机名的后缀。因此.example.com
将匹配foo.example.com
(但不匹配example.com
)。当主机名在
sys_hba.conf
中被指定时,你应该保证名字解析很快。建立一个类似nscd
的本地名字解析缓存是一种不错的选择。另外,你可能希望启用配置参数log_hostname
来在日志中查看客户端的主机名而不是 IP 地址。这个域只适用于
host
、hostssl
和hostnossl
记录。注意
用户有时候会疑惑为什么这样处理的主机名看起来很复杂,因为需要两次名字解析(包括一次 客户端 IP 地址的反向查找)。在客户端的反向 DNS 项没有建立或者得到某些意料之外的主机 名的情况下,这种方式会让该特性的使用变得复杂。这样做主要是为了效率:通过这种方式,一次 连接尝试要求最多两次解析器查找,一次逆向以及一次正向。如果有一个解析器对于该地址有问 题,这仅仅是客户端的问题。一种假想的替代实现是只做前向查找,这种方法不得不在每一次连接 尝试期间解析
sys_hba.conf
中提到的每一个主机名。如果列出了很多 名称,这就会很慢。并且如果主机名之一有解析器问题,它会变成所有人的问题。另外,一次反向查找也是实现后缀匹配特性所需的,因为需要知道实际的客户端主机名来与模式进行匹配。
注意这种行为与其他流行的基于主机名的访问控制实现相一致,例如 Apache HTTP Server 和 TCP Wrappers。
IP-address
IP-mask
这两个域可以被用作``IP-address``
/
``mask-length``记号法的替代方案。和指定掩码长度不同,实际的掩码被指 定在一个单独的列中。例如,255.0.0.0
表示 IPv4 CIDR 掩码长度 8,而255.255.255.255
表示 CIDR 掩码长度 32。这些域只适用于
host
、hostssl
和hostnossl
记录。
auth-method
指定当一个连接匹配这个记录时,要使用的认证方法。下面对可能的选择做了概述。
reject
无条件地拒绝连接。这有助于从一个组中“过滤出”特定主机,例如一个
reject
行可以阻塞一个特定的主机连接,而后面一行允许一个特定网络中的其余主机进行连接。
scram-sha-256
执行SCRAM-SHA-256认证来验证用户的口令。详见 口令加密认证 。
md5
执行SCRAM-SHA-256或MD5认证来验证用户的口令。详见 口令加密认证 。
password
要求客户端提供一个未加密的口令进行认证。因为口令是以明文形式在网络上发送的,所以我们不应该在不可信的网络上使用这种方式。详见 口令加密认证 。
gss
用 GSSAPI 认证用户。只对 TCP/IP 连接可用。详见 GSSAPI身份验证 。它可以与GSSAPI加密结合使用。
sspi
用 SSPI 来认证用户。只在 Windows上可用。详见 SSPI身份验证 。
ident
通过联系客户端的 ident 服务器获取客户端的操作系统名,并且检查它是否匹配被请求的数据库用户名。Ident 认证只能在 TCIP/IP连接上使用。当为本地连接指定这种认证方式时,将用 peer 认证来替代。详见 Ident身份验证。
peer
从操作系统获得客户端的操作系统用户,并且检查它是否匹配被请求的数据库用户名。这只对本地连接可用。详见 Peer身份验证 。
ldap
使用LDAP服务器认证。详见 LDAP身份验证。
radius
用 RADIUS 服务器认证。详见 RADIUS身份验证 。
cert
使用 SSL客户端证书认证 。详见 SSL客户端证书认证 。
pam
使用操作系统提供的可插入认证模块服务(PAM)认证。详见 PAM身份验证。
bsd
使用由操作系统提供的 BSD 认证服务进行认证。详见 BSD身份验证 。
auth-options
在``auth-method``域的后面,可以是形如``name``
=
``value``的域,它们指定认证方法的选项。关于哪些认证方法可以用哪些选项的细节请见下文。除了下文列出的与方法相关的选项之外,还有一个与方法无关的认证选项
clientcert
,它可以在任何hostssl
记录中指定。这个选项能够设置verify-ca
或verify-full
。这两个选项都要求客户端提供一个有效的(受信任的)SSL证书,而verify-full
还要求证书中的cn
(Common Name)匹配用户名或适用的映射。 此行为类似于cert
身份验证方法(参见 SSL客户端证书认证 ),但允许将客户端证书的验证与支持hostssl
条目的身份验证方法配对。
用@
结构包括的文件被读作一个名字列表,它们可以用空白或者逗号分隔。注释用#
引入,就像在sys_hba.conf
中那样,并且允许嵌套@
结构。除非跟在@
后面的文件名是一个绝对路径, 文件名都被认为是相对于包含引用文件的目录。
因为每一次连接尝试都会顺序地检查sys_hba.conf
记录,所以这些记录的顺序是非常关键的。通常,靠前的记录有比较严的连接匹配参数和比较弱的认证方法,而靠后的记录有比较松的匹配参数和比较强的认证方法。
在启动以及主服务器进程收到SIGHUP信号时, sys_hba.conf
文件会被读取。 如果你在活动的系统上编辑了该文件,您需要向邮件管理员发出信号(使用sys_ctl reload
,调用SQL函数sys_reload_conf()
,或使用kill -HUP
)使其重新读取文件。
注意
前面的说明在Microsoft Windows上不为真:在Windows上,sys_hba.conf
文件中的任何更改会立即被应用到后续的新连接上。
系统视图 sys_hba_file_rules 有助于预先测试对sys_hba.conf
文件的更改,该视图也可以在该文件的装载没有产生预期效果时用于诊断问题。该视图中带有非空error
域的行就表示该文件对应行中存在问题。
提示
要连接到一个特定数据库,一个用户必须不仅要通过sys_hba.conf
检查,还必须要有该数据库上的CONNECT
权限。如果你希望限制哪些用户能够连接到哪些数据库,授予/撤销CONNECT
权限通常比在sys_hba.conf
项中设置规则简单。
下列示例中展示了sys_hba.conf
项的一些例子。不同认证方法的详情请见下一节。
例如 ``sys_hba.conf`` 项
# 允许来自任意具有 IP 地址192.168.93.x 的主机上任意 # 用户以 ident 为该连接所报告的相同用户名连接到 # 数据库 "kingbase"(通常是操作系统用户名)。 # # TYPE DATABASE USER ADDRESS METHOD host kingbase all 192.168.93.0/24 ident # 如果用户的口令被正确提供, # 允许来自主机 192.168.12.10 # 的任意用户连接到数据库 "kingbase"。 # # TYPE DATABASE USER ADDRESS METHOD host kingbase all 192.168.12.10/32 scram-sha-256 # 如果前面没有“host”行, # 这三行将拒绝来自192.168.54.1的所有连接 # (因为那些项将首先被匹配), # 但是允许来自互联网其他任何地方GSSAPI加密连接。 # 零掩码导致主机IP 地址中的所有位都不会被考虑 # 因此它匹配任意主机。 # 允许不加密的GSSAPI连接(“fall through” # 到第三行,因为“hostgssenc”只匹配加密的GSSAPI连接), # 但是只能从192.168.12.10开始。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.54.1/32 reject hostgssenc all all 0.0.0.0/0 gss host all all 192.168.12.10/32 gss # 如果没有前面的 "host" 行,这两 # 行将拒绝所有来自 192.168.54.1 # 的连接(因为那些项将首先被匹配), # 但是允许来自互联网其他任何地方的 # GSSAPI 连接。零掩码导致主机 # IP 地址中的所有位都不会被考虑, # 因此它匹配任意主机。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.54.1/32 reject host all all 0.0.0.0/0 gss # 允许来自 192.168.x.x 主机的用户 # 连接到任意数据库,如果它们能够 # 通过 ident 检查。例如,假设 ident # 说用户是 "bryanh" 并且他要求以 # KingbaseES 用户 "guest1" 连接, # 如果在 sys_ident.conf 有一个映射 # "omicron" 的选项说 "bryanh" 被 # 允许以 "guest1" 连接,则该连接将被允许。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.0.0/16 ident map=omicron # 如果这些是本地连接的唯一三行, # 它们将允许本地用户只连接到它们 # 自己的数据库(与其数据库用户名 # 同名的数据库),不过管理员和角 # 色 "support" 的成员除外(它们可 # 以连接到所有数据库)。文件 # $KINGBASE_DATA/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
6.2.2. 用户名映射
当使用像 Ident 或者 GSSAPI 之类的外部认证系统时,发起连接的操作系统用户名可能不同于要被使用的数据库用户(角色)。在这种情况下,一个用户名映射可被用来把操作系统用户名映射到数据库用户。要使用用户名映射,在sys_hba.conf
的选项域指定map
=``map-name``。此选项支持所有接收外部用户名的认证方法。由于不同的连接可能需要不同的映射,在sys_hba.conf
中的``map-name``参数中指定要被使用的映射名,用以指示哪个映射用于每个个体连接。
用户名映射定义在 ident 映射文件中,默认情况下它被命名为sys_ident.conf
并被存储在集簇的数据目录中(不过,可以把该映射文件放在其他地方,见 ident_file 配置参数)。ident 映射文件包含的行的一般格式:
map-name system-username database-username
以在sys_hba.conf
中同样的方式处理注释和空白。``map-name``是一个任意名称,它将被用于在sys_hba.conf
中引用该映射。其他两个域指定一个操作系统用户名和一个匹配的数据库用户名。相同的``map-name``可以被反复地用在同一个映射中指定多个用户映射。
对于一个给定操作系统用户可以对应多少个数据库用户没有限制,反之亦然。因此,一个映射中的项应该被看成意味着“这个操作系统用户被允许作为这个数据库用户连接”,而不是按时它们等价。如果有任何映射项把从外部认证系统获得的用户名和用户要求的数据库用户名配对,该连接将被允许。
如果``system-username``域以一个斜线(/
)开始,域的剩余部分被当做一个正则表达式(KingbaseES的正则表达式语法详见 正则表达式细节 )。正则表达式可以包括一个单一的捕获,或圆括号子表达式,然后它可以在``database-username``域中以\1
(反斜线一)被引用。这允许在单个行中多个用户名的映射,这特别有助于简单的语法替换。例如,这些项
mymap /^(.*)@mydomain\.com$ \1 mymap /^(.*)@otherdomain\.com$ guest
将为用户移除以@mydomain.com
结束的系统用户名的域部分,以及允许系统名以@otherdomain.com
结束的任意用户作为guest
登入。
提示
记住在默认情况下,一个正则表达式可以只匹配字符串的一部分。如上例所示,使用^
和$
来强制匹配整个系统用户名通常是明智的。
在启动以及主服务器进程收到SIGHUP信号时, sys_ident.conf
文件会被读取。如果你在活动的系统上编辑了该文件,您需要向邮件管理员发出信号(使用sys_ctl reload
,调用SQL函数sys_reload_conf()
,或使用kill -HUP
))使其重新读取文件。
下列示例中展示了一个可以联合sys_hba.conf
文件使用的sys_ident.conf
文件。在这个例子中,对于任何登入到 192.168 网络上的一台机器的用户, 如果该用户没有操作系统用户名bryanh
、ann
或robert
,则他不会被授予访问权限。只有当 Unix 用户robert
尝试作为KingbaseES用户bob
(而不是作为robert
或其他人)连接时,他才被允许访问。ann
只被允许作为ann
连接。用户bryanh
被允许以bryanh
或者guest1
连接。
例如,一个示例 ``sys_ident.conf`` 文件
# MAPNAME SYSTEM-USERNAME KDB-USERNAME omicron bryanh bryanh omicron ann ann # bob 在这些机器上有用户名 robert omicron robert bob # bryanh 也可以作为 guest1 连接 omicron bryanh guest1