为什么规则不合并在ssh配置文件中?


12

似乎以下内容将按预期工作,即,具有与第一个规则匹配的主机名的第二个规则将应用它。

Host *.hostname.com
 User myuser
 IdentityFile ~/.ssh/myidentity

Host blah
 HostName complicated.hostname.com

但是,键入ssh blah仅适用第二条规则(而不适用第一条规则的用户或身份文件)。

我有两个问题:

  1. 为什么会这样呢?
  2. 是否可以(简单地)做我想做的事情?

Answers:


9

ssh_config手册页:

对于每个参数,将使用第一个获得的值。配置文件包含由“主机”规范分隔的部分,并且该部分仅适用于与规范中给定的模式之一匹配的主机。匹配的主机名是在命令行上给定的主机名。

由于使用每个参数的第一个获得的值,因此应在文件开头附近给出更多特定于主机的声明,并在结尾处给出常规默认值。

另外,如果您不清楚主机和模式的功能,请确保我理解这两部分。仅进行1级匹配。该功能的正则表达式功能非常基本,但是一旦您使用它,它仍然功能强大。

主机部分

 The possible keywords and their meanings are as follows (note that keywords 
 are case-insensitive and arguments are case-sensitive):

 Host    Restricts the following declarations (up to the next Host keyword) 
         to be only for those hosts that match one of the patterns given
         after the keyword.  If more than one pattern is provided, they 
         should be separated by whitespace.  A single ‘*’ as a pattern can 
         be used to provide global defaults for all hosts.  The host is the 
         hostname argument given on the command line (i.e. the name is not
         converted to a canonicalized host name before matching).

         A pattern entry may be negated by prefixing it with an exclamation 
         mark (‘!’).  If a negated entry is matched, then the Host entry is      
         ignored, regardless of whether any other patterns on the line 
         match.  Negated matches are therefore useful to provide exceptions 
         for wildcard matches.

         See PATTERNS for more information on patterns.

模式

 A pattern consists of zero or more non-whitespace characters, ‘*’ (a 
 wildcard that matches zero or more characters), or ‘?’ (a wildcard that
 matches exactly one character).  For example, to specify a set of 
 declarations for any host in the “.co.uk” set of domains, the following
 pattern could be used:

       Host *.co.uk

 The following pattern would match any host in the 192.168.0.[0-9] network 
 range:

       Host 192.168.0.?

 A pattern-list is a comma-separated list of patterns.  Patterns within 
 pattern-lists may be negated by preceding them with an exclamation
 mark (‘!’).  For example, to allow a key to be used from anywhere within an 
 organisation except from the “dialup” pool, the following entry
 (in authorized_keys) could be used:

       from="!*.dialup.example.com,*.example.com"

分层规则

您的方法存在的问题是,与第一个主机部分匹配的模式与第二个主机部分不匹配。我通常会这样做:

Host *
 User myuser
 IdentityFile ~/.ssh/myidentity


Host blah
 HostName complicated.hostname.com

人们通常不遵循这些规则的一件事就是他们可以重复。因此,我经常做的是有多个部分,然后使用进行拆分Host *

Host *
 User user1

Host blah1
 HostName complicated1.hostname.com

Host blah2
 HostName complicated2.hostname.com

Host *
 User user2

3
在您的示例中,如何设置“ user2”?我以为使用主机的第一个获得的值,所以每个主机都将匹配第一个块并设置“ user1”?
jdm 2014年

@jdm-在第二个之后Host *匹配的主机规则将使用user2作为其默认用户,除非它们自己明确指定。
slm

@slm:我实际上发现这不起作用。如果将两个Host * User xxx和Host * User yyy链接在一起,则下一个规则将使用“ xxx”-除非我做错了。
热雷米

@slm,您的示例不起作用。在Host *达到第二个值时,将应用“每个参数使用的第一个获得值”规则,因此User将忽略此定义和所有以下定义。此规则的例外是IdentityFile关键字btw。
maxschlepzig

5

SSH应用命令行中提供的与主机名匹配的所有部分(即,HostName它遇到的规则不会影响后续条件检查)。如果CanonicalizeHostname启用,它将在完成后使用更新的主机名再次重新应用配置文件。(无论如何,某些SSH版本都执行此操作,CanonicalizeHostname并且您的示例可以使用这些版本;但是SSH开发人员认为这是一个错误。请参阅#2267。)

这意味着您可以CanonicalizeHostname通过添加以下内容来使示例工作

Host *
  CanonicalizeHostname yes
  CanonicalizeFallbackLocal no

不会进行任何规范化,但可以使用更新后的主机名进行第二次传递。(请注意,它仍然不会使配置解析为“递归”,只需重复一次即可。因此,如果两次更改主机名,将无法使用。)


1
我最近将Ubuntu 14.04升级到16.04,并伴随此错误。这个答案是完美的。它使我又回到了原来的行为。谢谢!
Brian Malehorn

ugh#2267意味着Host nickname; Hostname hostname节不再能够提供昵称。如果您CanonizalizeHostname yes在每个昵称块中添加关键字,它将起作用,但这会使昵称块的大小增加一倍,并且看起来很丑。
studog

1

从手册页

对于每个参数,将使用第一个获得的值。配置文件包含由“主机”规范分隔的部分,该部分仅适用于与规范中给定的模式之一匹配的主机。匹配的主机名是在命令行上给定的主机名。

由于使用每个参数的第一个获得的值,因此应在文件开头附近给出更多特定于主机的声明,并在结尾处给出常规默认值。

尝试切换输入顺序。


不幸的是,切换条目的顺序不起作用(实际上是我最初使用的顺序)。
热雷米

如果有多个与您要连接的主机名匹配的主机定义,则所有定义中的所有参数都将合并为一个定义。当它说“第一个获得的值”时,它是在参数级别而不是主机级别谈论事物。如果您将每个Host块视为一个定义,这是违反直觉的。
Giovanni Tirloni 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.