Por que as regras não estão combinando em um arquivo de configuração ssh?

12

Parece que o seguinte funcionaria conforme o esperado, ou seja, que a segunda regra, com um nome de host que corresponda à primeira regra, a aplicaria.

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

Host blah
 HostName complicated.hostname.com

No entanto, a digitação ssh blahaplica apenas a segunda regra (e não o arquivo de usuário ou identidade da primeira).

Eu tenho duas perguntas:

  1. Por que isso está acontecendo?
  2. É possível (simplesmente) fazer o que estou tentando fazer?
Jérémie
fonte

Respostas:

9

Na ssh_configpágina do manual:

Para cada parâmetro, o primeiro valor obtido será usado. Os arquivos de configuração contêm seções separadas pelas especificações de "Host", e essa seção é aplicada apenas aos hosts que correspondem a um dos padrões fornecidos na especificação. O nome do host correspondente é o fornecido na linha de comando.

Como o primeiro valor obtido para cada parâmetro é usado, mais declarações específicas do host devem ser fornecidas perto do início do arquivo e os padrões gerais no final.

Além disso, certifique-se de entender essas duas seções se você não souber como o Host e os PADRÕES funcionam. Há apenas 1 nível de correspondência em andamento. Esse recurso é muito básico em seus recursos de regex, mas ainda é poderoso quando você o obtém.

Seções de host

 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.

PADRÕES

 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"

Regras de estratificação

O problema com sua abordagem é que o padrão que corresponde à seção do 1º host não corresponde à 2ª. Eu normalmente faço algo assim:

Host *
 User myuser
 IdentityFile ~/.ssh/myidentity


Host blah
 HostName complicated.hostname.com

Uma coisa que as pessoas geralmente não seguem essas regras é que elas podem repetir. Então, o que costumo fazer é ter várias seções e as separo usando Host *s.

Host *
 User user1

Host blah1
 HostName complicated1.hostname.com

Host blah2
 HostName complicated2.hostname.com

Host *
 User user2
slm
fonte
3
No seu exemplo, como o "user2" é definido? Eu pensei que o primeiro valor obtido para um host é usado, para que cada host corresponda ao primeiro bloco e tenha "user1" definido?
jdm
@jdm - As regras de host que vierem depois do 2º Host *que corresponderem usarão o user2 como usuário padrão, a menos que elas especifiquem explicitamente.
slm
@ SLM: Na verdade, eu achei que não funciona. Se você encadear dois Host * User xxx e Host * User yyy, a próxima regra estará usando "xxx" - a menos que eu esteja fazendo algo errado.
Jérémie
@ slm, seu exemplo não funciona. No momento em que o segundo Host *é atingido, a regra 'primeiro valor obtido para cada parâmetro é usado' se aplica e, portanto, esta e todas as Userdefinições a seguir são ignoradas. Uma exceção a essa regra são IdentityFilepalavras-chave, btw.
maxschlepzig
5

O SSH aplica todas as seções que correspondem ao nome do host, conforme fornecido na linha de comando (ou seja, as HostNameregras que ele encontra não afetam as verificações de condições subsequentes). Se CanonicalizeHostnameestiver ativado, ele reaplicará os arquivos de configuração novamente quando terminar, usando o nome do host atualizado. (Algumas versões do SSH fizeram isso independentemente, CanonicalizeHostnamee seu exemplo funcionaria com essas versões; mas isso é considerado um bug pelos desenvolvedores do SSH. Consulte # 2267. )

O que significa que você pode usar CanonicalizeHostnamepara fazer o seu exemplo funcionar, adicionando

Host *
  CanonicalizeHostname yes
  CanonicalizeFallbackLocal no

que não fará nenhuma canonização, mas permitirá fazer uma segunda passagem com o nome do host atualizado. (Observe que ainda não tornará a análise de configuração "recursiva", basta repeti-la uma vez. Portanto, se você alterar o nome do host duas vezes, isso não funcionaria.)

Tgr
fonte
1
Atualizei recentemente o Ubuntu 14.04 para 16.04, e com ele veio esse bug. Essa resposta é perfeita; isso me leva de volta ao comportamento original. Obrigado!
Brian Malehorn 7/09/16
ugh # 2267 significa que as Host nickname; Hostname hostnameestrofes não são mais capazes de fornecer apelidos. Funcionará se você adicionar a CanonizalizeHostname yespalavra - chave em cada bloco de apelidos, mas isso dobrará o tamanho dos blocos de apelidos e parecerá feio.
Studog 23/05/19
1

Na página do manual

Para cada parâmetro, o primeiro valor obtido será usado. Os arquivos de configuração contêm seções separadas pelas especificações '' Host '', e essa seção é aplicada apenas aos hosts que correspondem a um dos padrões fornecidos na especificação. O nome do host correspondente é o fornecido na linha de comando.

Como o primeiro valor obtido para cada parâmetro é usado, mais declarações específicas do host devem ser fornecidas perto do início do arquivo e os padrões gerais no final.

Tente mudar a ordem das suas entradas.

spuder
fonte
Infelizmente, alternar a ordem das entradas não funciona (na verdade, era a ordem que eu havia usado originalmente).
Jérémie
Se houver várias definições de Host que correspondam ao nome do host ao qual você está se conectando, todos os parâmetros definidos em todos eles serão mesclados em uma única definição. Quando diz "o primeiro valor obtido", está falando sobre coisas no nível do parâmetro, não no nível do host. Isso é contra-intuitivo se você estiver pensando em cada bloco Host como sendo uma definição.
Giovanni Tirloni