If canonicalization is on this should behave like 'Match canonical'. If it isn't it should behave like 'Match all' or 'Host *'. See https://bugzilla.redhat.com/show_bug.cgi?id=1630166 for extra details, but: Basically if system /etc/ssh/ssh_config has a: Host * Key foo clause, then this trumps any ~/.ssh/config: Host blah.org Key bar setting if user attempts to 'ssh blah' (where blah canonicalizes to blah.org). This is because of config file parse order: first ~/.ssh/config which doesn't match on non-canonical hostname, then /etc/ssh/ssh_config which matches on * and sets Key=foo. Then on re-parse with canonical hostname user's Host blah.org matches, but it's too late to set Key=bar because it's already been set. (perhaps related, but perhaps there should also be some sort of special handling for 'Key +bar' or 'Key -bar' to treat it as append/remove instead of override, but that would be far more difficult to implement)
(and yeah I realize that there's a problem if canonicalization gets turned on *after* the match has already been analyzed - oh well, don't do that)
Created attachment 3179 [details] Match final Here's an implementation of a "Match final" criterion. If parsing encounters a "Match final" during the initial parse then re-parsing of the configuration files will be forced, regardless of whether CanonicalizeHostname is enabled.
What are the next steps here?
This has been committed and, barring catastrophe, will be in OpenSSH 8.0. commit 9e34e0c59ab04514f9de9934a772283f7f372afe (HEAD -> master, origin/master, origin/HEAD) Author: djm@openbsd.org <djm@openbsd.org> Date: Fri Nov 23 05:08:07 2018 +0000 upstream: add a ssh_config "Match final" predicate Matches in same pass as "Match canonical" but doesn't require hostname canonicalisation be enabled. bz#2906 ok markus OpenBSD-Commit-ID: fba1dfe9f6e0cabcd0e2b3be13f7a434199beffa
Thank you!
FYI, there is a twist with this option, if we use it in combination with Host blocks, that worked before. They do not follow these flags and are matched also in the second pass, which can cause unexpected results.
My bad. The Match blocks are still matched even during the final pass, which is not expected from the description in the manual page. The second pass should not match unless there is the final keyword.
AFAIK that's working as intended. All match and host blocks will match in the final pass unless told not to (Match !finalpass). This is the same behaviour as "Match canonical" has had since it was introduced.
Well, that probably makes sense, but with configurations like following (for simplicity rewritten from Host blocks): Match host ext Hostname bastion.ext.example.com Match host *.ext.example.com ProxyCommand ssh -q ext -W %h:%p Match final ... Connecting to host x.ext.example.com causes a infinite recursion of spanning ssh processes, while it works fine without the last match block. I am wondering, if the "match final" should not behave less like the canonical so in the second path, the host would be matched really against the host that was used on commandline (like originalhost) to avoid breaking existing configurations.
Is this perhaps not just a bug that ProxyCommand can apparently somehow trigger more than once?
Hmm or perhaps: Match host ext Hostname bastion.ext.example.com should actually be: Match host ext Hostname bastion.ext.example.com ProxyCommand none
btw. are you sure your example is correct? Perhaps you meant to have: Match host *.ext.example.com ProxyCommand ssh -q ext -W %h:%p Match host ext Hostname bastion.ext.example.com Match final ... (ie. opposite order) Because - while I haven't tested it - by my naive interpretation of the matching rules your example should have also resulted in infinite ssh's. For your example: x.ext.example.com triggers the proxycommand, so we ssh to ext ext gets converted to bastion.ext.example.com which then triggers the proxycommand (due to ordering) Match final should not be needed. With the ordering I gave above, I think Match final does introduce the problem, but then I think adding ProxyCommand none to the host ext block still solves it... ???
IMO the behaviour is consistent, so I'll close this
closing resolved bugs as of 8.6p1 release