具有多个匹配地址的 sshd_config

具有多个匹配地址的 sshd_config

我试图理解一个 sshd 配置,我认为该配置不应该起作用,但确实有效。前提来自于我正在开发的一个生产系统;不过,我为了自己的测试而简化了它。由于我无法解释为什么这个简单的示例有效,因此我也无法解释为什么更复杂的迭代有效。

我有两台服务器,用户分别为 Auser、Buser 和 Cuser。

我的客户端计算机的 IP 地址为 192.168.10.1

我的服务器有一个 sshd 配置,如下所示:

AllowGroups Cuser
Match Address 192.168.10.1
    AllowGroups Cuser Buser
Match Address 192.168.10.1
    AllowGroups Cuser Auser

根据 sshd_config(5) 的手册页

Match 引入条件块。如果匹配行上的所有条件都满足,则以下行中的关键字将覆盖配置文件全局部分中设置的关键字,直到另一个匹配行或文件末尾。如果某个关键字出现在多个满足条件的 Match 块中,则仅应用该关键字的第一个实例。

我的解释是,从客户端(192.168.10.1),只应允许 Cuser 和 Buser ssh 到服务器。

但是,当我对此进行测试时,所有三个用户:Auser、Buser 和 Cuser 都具有访问权限。如果我查看服务器的 sshd 日志,我会看到每个匹配块的应用位置:

Jul 25 10:48:59 server1 sshd[3525]: debug3: Trying to reverse map address 192.168.10.1.
Jul 25 10:48:59 server1 sshd[3525]: debug2: parse_server_config: config reprocess config len 854
Jul 25 10:48:59 server1 sshd[3525]: debug3: checking match for 'Address 192.168.10.1' user buser host client addr 192.168.10.1 laddr 192.168.10.4 lport 22
Jul 25 10:48:59 server1 sshd[3525]: debug1: connection from 192.168.10.1 matched 'Address 192.168.10.1' at line 138
Jul 25 10:48:59 server1 sshd[3525]: debug3: match found
Jul 25 10:48:59 server1 sshd[3525]: debug3: reprocess config:139 setting AllowGroups cuser buser
Jul 25 10:48:59 server1 sshd[3525]: debug3: checking match for 'Address 192.168.10.1' user buser host fedora addr 192.168.10.1 laddr 192.168.10.4 lport 22
Jul 25 10:48:59 server1 sshd[3525]: debug1: connection from 192.168.10.1 matched 'Address 192.168.10.1' at line 140
Jul 25 10:48:59 server1 sshd[3525]: debug3: match found
Jul 25 10:48:59 server1 sshd[3525]: debug3: reprocess config:141 setting AllowGroups cuser auser

因此,有趣的是,从我对手册页的解释来看,我预计只会应用第一个“reprocess config:139”行,因为它是AllowGroups关键字的第一个实例。但是,查看日志,由于我看到“重新处理配置:141 设置AllowGroups cuser auser”,我可能只希望应用第二个实例。

然而,这些解释似乎都不正确,因为所有三个用户都能够连接。

因此,通过一些额外的测试,我将 sshd_config 更改为如下所示:

AllowGroups Cuser
Match Address 192.168.10.1
    AllowGroups Cuser Buser
Match Address 192.168.10.1
    AllowGroups Auser

AllowGroups Cuser
Match Address 192.168.10.1
    AllowGroups Auser
Match Address 192.168.10.1
    AllowGroups Cuser Buser

所有三个用户仍然可以登录。

还有一个最终测试

AllowGroups Cuser
Match Address 192.168.10.1
    AllowGroups Buser
Match Address 192.168.10.1
    AllowGroups Auser

最后,只有 Auser 和 Buser 有权访问。

几乎就像第一个匹配块将覆盖任何默认设置,但后续匹配块会附加到任何先前的匹配块。

答案1

我无法像我希望的那样仔细地追踪代码,但我想我知道发生了什么。一个非常重要的线索是解析命令行参数的例程的源代码文件、sshd_config 文件及其包含的文件:

/*
 * The strategy for the Match blocks is that the config file is parsed twice.
 *
 * The first time is at startup.  activep is initialized to 1 and the
 * directives in the global context are processed and acted on.  Hitting a
 * Match directive unsets activep and the directives inside the block are
 * checked for syntax only.
 *
 * The second time is after a connection has been established but before
 * authentication.  activep is initialized to 2 and global config directives
 * are ignored since they have already been processed.  If the criteria in a
 * Match block is met, activep is set and the subsequent directives
 * processed and actioned until EOF or another Match block unsets it.  Any
 * options set are copied into the main server config.
 */

本质上有一个例程通过三个解析阶段读取配置关键字和参数(如Compression noAllowGroups foo bar baz):命令行参数、跳过块的第一遍Match以及读取块的第二遍Match。有几个标志变量可以跟踪解析所处的阶段 - 一个用于命令行解析,另一个用于第一个和第二个文件传递。

AllowGroups、DenyGroups、AllowUsers 和 DenyUsers 是采用多个值而不是单个值的参数。因此,该例程解析出该行的参数列表,并将每个参数附加到一个字符串数组中。虽然第一个和第二个文件传递有一个标志,但没有“这是一个新的匹配块”的标志。

这意味着当解析第一个 Match 块(第二遍开始)并且它包含 AllowGroups 参数时,现有值列表(在 Match 块之前)将被擦除并替换为 Match 块中的新参数。然而,当第二个 Match 块也匹配并被解析时,没有任何信号通知例程再次擦除列表。如果AllowGroups 是单值参数,则每个新实例都将被忽略,而优先于第一个实例。但是,由于它是多值参数,因此新参数将被附加到列表中。这是当你发现它时让你感到困惑的行为。 (我也是)

我的猜测是解析例程的作者没有设想像您的测试服务器那样的配置 - 具有多个设置相同多值参数的有效匹配块。更典型的情况是只有一个 Match 块会成功并被解析,因为它们匹配不同的东西。或者如果多个块成功,则多个块的原因是因为每个块设置了不同的参数。


在几天前的评论中,我提到这四个参数的工作方式并不直观。尽管这不是这个问题的直接答案,但我会在这里添加我的发现(为了后代)。

连接建立并完成第二遍配置解析后,代码会检查允许/拒绝组以查看哪些组适用。它们按以下顺序检查:DenyUsers、AllowUsers、DenyGroups 和AllowGroups。允许/拒绝的测试和决定的工作方式类似于以下伪代码:

if DenyUsers has > 0 items and user is one of them
    deny
if AllowUsers has > 0 items and user is not one of them
    deny
if DenyGroups has > 0 items and user is member of one of them
    deny
if AllowGroups has > 0 items and user is not a member of any of them
    deny

allow

一旦做出“拒绝”决定,例程就会停止进一步检查。因此“AllowUsers”列表不能以直观的方式工作。如果您将任何名称放入“AllowUsers”列表中,则所有其他用户(不在列表中)都会被拒绝。其他用户是否在“AllowGroups”列表中并不重要,因为代码在查阅“AllowGroups”之前会停止检查。 “AllowGroups”列表中的任何组都会导致不属于这些组的用户被拒绝,即使他们列在“AllowUsers”中也是如此。

相关内容