Почему правила не объединяются в конфигурационном файле ssh?

12

Кажется, что следующее будет работать, как и ожидалось, то есть, что второе правило, имеющее имя хоста, соответствующее первому правилу, будет применять его.

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

Host blah
 HostName complicated.hostname.com

Однако при наборе ssh blahприменяется только второе правило (а не пользователь или файл идентификации первого).

У меня есть два вопроса:

  1. Почему это происходит?
  2. Можно ли (просто) сделать то, что я пытаюсь сделать?
Жереми
источник

Ответы:

9

Со ssh_configстраницы руководства :

Для каждого параметра будет использоваться первое полученное значение. Файлы конфигурации содержат разделы, разделенные спецификациями «Host», и этот раздел применяется только для хостов, которые соответствуют одному из шаблонов, приведенных в спецификации. Соответствующее имя хоста - это имя, указанное в командной строке.

Поскольку для каждого параметра используется первое полученное значение, в начале файла должны быть приведены более специфичные для хоста объявления, а в конце - общие значения по умолчанию.

Кроме того, я бы удостоверился, что понимаю эти 2 раздела, если вам непонятно, как работают Host и PATTERNS. Существует только 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"

Правила наложения

Проблема с вашим подходом заключается в том, что шаблон, соответствующий 1-му разделу хоста, не соответствует 2-му. Я обычно делаю что-то вроде этого:

Host *
 User myuser
 IdentityFile ~/.ssh/myidentity


Host blah
 HostName complicated.hostname.com

Одна вещь, которую люди обычно не воспринимают с этими правилами, это то, что они могут повторить. То, что я часто делаю, - это несколько разделов, и я разбиваю их, используя Host *s.

Host *
 User user1

Host blah1
 HostName complicated1.hostname.com

Host blah2
 HostName complicated2.hostname.com

Host *
 User user2
SLM
источник
3
В вашем примере, как вообще устанавливается user2? Я думал, что первое полученное значение для хоста используется, поэтому каждый хост будет соответствовать первому блоку и будет иметь "user1"?
JDM
@jdm - правила хоста, которые идут после 2-го, Host *которые будут сопоставлены, будут использовать user2 в качестве пользователя по умолчанию, если они сами не задают его явно.
SLM
@slm: я обнаружил, что это не работает. Если вы соедините два узла Host * User xxx, а затем Host * User yyy, следующее правило будет использовать «xxx» - если я не делаю что-то не так.
Жереми
@slm, твой пример не работает. В момент достижения 2-го Host *применяется правило «первое полученное значение для каждого используемого параметра», и поэтому это и все последующие Userопределения игнорируются. Исключением из этого правила являются IdentityFileключевые слова, кстати.
maxschlepzig
5

SSH применяет все разделы, которые соответствуют имени хоста, как указано в командной строке (т. HostNameЕ. Правила, с которыми он сталкивается, не влияют на последующие проверки условий). Если этот параметр CanonicalizeHostnameвключен, он будет повторно применять файлы конфигурации после завершения, используя обновленное имя хоста. (Некоторые версии SSH делали это независимо от того, CanonicalizeHostnameи ваш пример будет работать с этими версиями; но разработчики SSH считают это ошибкой. См. # 2267. )

Что означает, что вы можете использовать, CanonicalizeHostnameчтобы ваш пример работал, добавив

Host *
  CanonicalizeHostname yes
  CanonicalizeFallbackLocal no

который не будет выполнять никакой канонизации, но позволит выполнить второй проход с обновленным именем хоста. (Обратите внимание, что он все равно не сделает анализ конфигурации «рекурсивным», просто повторите его один раз. Поэтому, если вы измените имя хоста дважды, это не сработает.)

Tgr
источник
1
Я недавно обновил Ubuntu 14.04 до 16.04, и вместе с ним появилась эта ошибка. Этот ответ идеален; это возвращает меня к исходному поведению. Благодарность!
Брайан Малехорн
тьфу # 2267 означает, что Host nickname; Hostname hostnameстрофы больше не могут предоставлять псевдонимы. Это сработает, если вы добавите CanonizalizeHostname yesключевое слово в каждый блок псевдонимов, но это удваивает размер блоков псевдонимов и выглядит некрасиво.
Studog
1

Со страницы руководства

Для каждого параметра будет использоваться первое полученное значение. Файлы конфигурации содержат разделы, разделенные спецификациями '' Host '', и этот раздел применяется только для хостов, которые соответствуют одному из шаблонов, приведенных в спецификации. Соответствующее имя хоста - это имя, указанное в командной строке.

Поскольку для каждого параметра используется первое полученное значение, в начале файла должны быть приведены более специфичные для хоста объявления, а в конце - общие значения по умолчанию.

Попробуйте изменить порядок ваших записей.

spuder
источник
К сожалению, переключение порядка записей не работает (на самом деле это был порядок, который я изначально использовал).
Джереми
Если существует несколько определений хостов, соответствующих имени хоста, к которому вы подключаетесь, все параметры, определенные во всех них, будут объединены в одно определение. Когда он говорит «первое полученное значение», он говорит о вещах на уровне параметров, а не на уровне хоста. Это нелогично, если вы рассматриваете каждый блок хоста как определение.
Джованни Тирлони