Warum werden Regeln nicht in einer ssh-Konfigurationsdatei kombiniert?

12

Es scheint, als würde das Folgende wie erwartet funktionieren, dh die zweite Regel, deren Hostname mit der ersten Regel übereinstimmt, würde sie anwenden.

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

Host blah
 HostName complicated.hostname.com

Bei der Eingabe wird jedoch ssh blahnur die zweite Regel angewendet (und nicht die Benutzer- oder Identitätsdatei der ersten).

Ich habe zwei Fragen:

  1. Warum passiert dies?
  2. Kann ich (einfach) tun, was ich versuche?
Jérémie
quelle

Antworten:

9

Von der ssh_configManpage:

Für jeden Parameter wird der erste erhaltene Wert verwendet. Die Konfigurationsdateien enthalten Abschnitte, die durch Hostspezifikationen voneinander getrennt sind. Dieser Abschnitt gilt nur für Hosts, die einem der in der Spezifikation angegebenen Muster entsprechen. Der übereinstimmende Hostname ist der in der Befehlszeile angegebene.

Da der erste ermittelte Wert für jeden Parameter verwendet wird, sollten am Anfang der Datei weitere hostspezifische Deklarationen und am Ende allgemeine Standardwerte angegeben werden.

Außerdem stelle ich sicher, dass ich diese beiden Abschnitte verstehe, wenn Sie sich nicht sicher sind, wie Host und PATTERNS funktionieren. Es gibt nur eine Stufe des Matchings. Diese Funktion ist in Bezug auf die Regex-Funktionen sehr einfach, aber auch dann noch leistungsfähig, wenn Sie sie einmal aktiviert haben.

Host-Abschnitte

 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.

MUSTER

 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"

Überlagerungsregeln

Das Problem bei Ihrem Ansatz ist, dass das Muster, das mit dem ersten Hostabschnitt übereinstimmt, nicht mit dem zweiten übereinstimmt. Ich mache normalerweise so etwas:

Host *
 User myuser
 IdentityFile ~/.ssh/myidentity


Host blah
 HostName complicated.hostname.com

Eine Sache, die die Leute normalerweise nicht mit diesen Regeln aufnehmen, ist, dass sie sich wiederholen können. Also habe ich oft mehrere Abschnitte und teile sie mit Host *'s auf.

Host *
 User user1

Host blah1
 HostName complicated1.hostname.com

Host blah2
 HostName complicated2.hostname.com

Host *
 User user2
slm
quelle
3
Wie wird in Ihrem Beispiel "user2" festgelegt? Ich dachte, der erste erhaltene Wert für einen Host wird verwendet, so dass jeder Host mit dem ersten Block übereinstimmt und "user1" gesetzt hat.
JDM
@jdm - Host-Regeln, die nach der 2. Host *übereinstimmen, verwenden Benutzer2 als Standardbenutzer, sofern sie dies nicht ausdrücklich selbst festlegen.
slm
@slm: Ich habe tatsächlich festgestellt, dass das nicht funktioniert. Wenn Sie zwei Host * User xxx und dann Host * User yyy verketten, verwendet die nächste Regel "xxx" - es sei denn, ich mache etwas falsch.
Jérémie
@slm, dein Beispiel funktioniert nicht. Zum Zeitpunkt des Host *Erreichens des zweiten Wertes gilt die Regel "Der erste ermittelte Wert für jeden Parameter wird verwendet". Daher werden diese und alle folgenden UserDefinitionen ignoriert. Eine Ausnahme von dieser Regel sind IdentityFileübrigens Stichwörter.
Maxschlepzig
5

SSH wendet alle Abschnitte an, die mit dem in der Befehlszeile angegebenen Hostnamen übereinstimmen (dh die HostNameRegeln, auf die es trifft, wirken sich nicht auf nachfolgende Bedingungsprüfungen aus). Wenn CanonicalizeHostnamediese Option aktiviert ist, werden die Konfigurationsdateien nach Abschluss erneut angewendet, wobei der aktualisierte Hostname verwendet wird. (Einige SSH-Versionen haben dies unabhängig davon getan, CanonicalizeHostnameund Ihr Beispiel würde mit diesen Versionen funktionieren. Dies wird jedoch von den SSH-Entwicklern als Fehler angesehen. Siehe # 2267. )

Das heißt, Sie können CanonicalizeHostnameIhr Beispiel durch Hinzufügen zum Laufen bringen

Host *
  CanonicalizeHostname yes
  CanonicalizeFallbackLocal no

Dies führt keine Kanonisierung durch, ermöglicht jedoch einen zweiten Durchgang mit dem aktualisierten Hostnamen. (Beachten Sie, dass die Konfigurationsanalyse dadurch immer noch nicht "rekursiv" wird. Wiederholen Sie sie einfach einmal. Wenn Sie also den Hostnamen zweimal ändern, funktioniert dies nicht.)

Tgr
quelle
1
Ich habe vor kurzem Ubuntu 14.04 auf 16.04 aktualisiert, und mit ihm kam dieser Fehler. Diese Antwort ist perfekt; es bringt mich zurück zum ursprünglichen Verhalten. Vielen Dank!
Brian Malehorn
ugh # 2267 bedeutet, dass Host nickname; Hostname hostnameStrophen keine Spitznamen mehr liefern können. Es wird funktionieren, wenn Sie das CanonizalizeHostname yesSchlüsselwort in jedem Kurznamenblock hinzufügen , aber das verdoppelt die Größe der Kurznamenblöcke und sieht hässlich aus.
Studog
1

Von der Manpage

Für jeden Parameter wird der erste erhaltene Wert verwendet. Die Konfigurationsdateien enthalten Abschnitte, die durch Hostspezifikationen voneinander getrennt sind. Dieser Abschnitt gilt nur für Hosts, die einem der in der Spezifikation angegebenen Muster entsprechen. Der übereinstimmende Hostname ist der in der Befehlszeile angegebene.

Da der erste ermittelte Wert für jeden Parameter verwendet wird, sollten am Anfang der Datei weitere hostspezifische Deklarationen und am Ende allgemeine Standardwerte angegeben werden.

Versuchen Sie, die Reihenfolge Ihrer Einträge zu ändern.

Spuder
quelle
Leider funktioniert das Umschalten der Reihenfolge der Einträge nicht (es war eigentlich die Reihenfolge, die ich ursprünglich verwendet hatte).
Jérémie
Wenn es mehrere Hostdefinitionen gibt, die mit dem Hostnamen übereinstimmen, zu dem Sie eine Verbindung herstellen, werden alle in allen definierten Parameter zu einer einzigen Definition zusammengeführt. Wenn hier "der erste erhaltene Wert" steht, handelt es sich um Dinge auf der Parameterebene, nicht auf der Host-Ebene. Dies ist nicht intuitiv, wenn Sie sich jeden Host-Block als Definition vorstellen.
Giovanni Tirloni