Bug 2906 - Need something like 'Match finalpass'
Summary: Need something like 'Match finalpass'
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: ssh (show other bugs)
Version: 7.7p1
Hardware: All All
: P5 enhancement
Assignee: Damien Miller
URL:
Keywords:
Depends on:
Blocks: V_8_0
  Show dependency treegraph
 
Reported: 2018-09-18 19:27 AEST by Maciej Żenczykowski
Modified: 2021-04-23 15:03 AEST (History)
2 users (show)

See Also:


Attachments
Match final (10.22 KB, patch)
2018-09-21 14:17 AEST, Damien Miller
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Maciej Żenczykowski 2018-09-18 19:27:51 AEST
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)
Comment 1 Maciej Żenczykowski 2018-09-18 19:29:27 AEST
(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)
Comment 2 Damien Miller 2018-09-21 14:17:32 AEST
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.
Comment 3 Maciej Żenczykowski 2018-10-21 08:59:22 AEDT
What are the next steps here?
Comment 4 Damien Miller 2018-11-23 16:09:45 AEDT
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
Comment 5 Maciej Żenczykowski 2018-11-23 17:46:48 AEDT
Thank you!
Comment 6 Jakub Jelen 2019-02-15 01:02:26 AEDT
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.
Comment 7 Jakub Jelen 2019-02-15 03:25:58 AEDT
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.
Comment 8 Damien Miller 2019-02-18 15:48:06 AEDT
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.
Comment 9 Jakub Jelen 2019-02-19 21:23:37 AEDT
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.
Comment 10 Maciej Żenczykowski 2019-02-19 21:40:03 AEDT
Is this perhaps not just a bug that ProxyCommand can apparently somehow trigger more than once?
Comment 11 Maciej Żenczykowski 2019-02-19 21:43:28 AEDT
Hmm or perhaps:

Match host ext
      Hostname bastion.ext.example.com

should actually be:

Match host ext
      Hostname bastion.ext.example.com
      ProxyCommand none
Comment 12 Maciej Żenczykowski 2019-02-19 21:49:02 AEDT
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...

???
Comment 13 Damien Miller 2019-04-03 10:08:41 AEDT
IMO the behaviour is consistent, so I'll close this
Comment 14 Damien Miller 2021-04-23 15:03:56 AEST
closing resolved bugs as of 8.6p1 release