Bug 1898 - possible unreasonable behaviour when using ProxyCommand with multiple IdentityFile(s)
Summary: possible unreasonable behaviour when using ProxyCommand with multiple Identit...
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: Miscellaneous (show other bugs)
Version: 5.8p1
Hardware: All All
: P2 normal
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks: V_6_3
  Show dependency treegraph
 
Reported: 2011-05-03 07:44 AEST by Christoph Anton Mitterer
Modified: 2015-08-11 23:03 AEST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Christoph Anton Mitterer 2011-05-03 07:44:28 AEST
Hi.

Maybe the following is an issue.
Consider the following scenario and ~/.ssh/config snippet:
-------------------------
Host login.example.org
        User loginUser
        ProxyCommand none

Host *.example.org
        User root
        IdentityFile ~/.ssh/internal_example_org_key.id_rsa
        ProxyCommand ssh login.example.org nc %h %p
-------------------------

The idea is that access to all nodes (but the login node) of example.org is only possible via login.example.org.
The interesting part is, that different keys are used, namely the default id_rsa to authenticate on login.example.org and internal_example_org_key.id_rsa, which is only used internally (e.g. because policy mandates this).

I'd have expected, that the above works, and that the default id_rsa is used for login.example.org (as no IdentityFile is specified) and the other key in the remaining cases.
It does however not.
It works if I:
1) Use ssh-agent (and it that one has all the keys loaded)
2) Use:
Host login.example.org
        User loginUser
        IdentityFile ~/.ssh/id_rsa
        ProxyCommand none
3) Or:
Host *.example.org
        User root
        IdentityFile ~/.ssh/id_rsa
        IdentityFile ~/.ssh/internal_example_org_key.id_rsa
        ProxyCommand ssh login.example.org nc %h %p


Seems as if the inheritance wouldn't work for the default identity file, unless its explicitly specified.


Cheers,
Chris.
Comment 1 Damien Miller 2011-05-05 16:26:41 AEST
I think you are misunderstanding how the configuration is applied by Host directives. Overrides are *per-configuration item*

In your first case you are not specifying an IdentityFile in your login.example.org block, so it is unset when the also-matching *.example.org block is applied. To do what you want, you should specify your normal IdentityFiles in the login.example.org block

Host login.example.org
        User loginUser
        ProxyCommand none
        IdentityFile ~/.ssh/id_rsa
        IdentityFile ~/.ssh/id_dsa
        IdentityFile ~/.ssh/id_ecdsa

Host *.example.org
        User root
        IdentityFile ~/.ssh/internal_example_org_key.id_rsa
        ProxyCommand ssh login.example.org nc %h %p

The rules for IdentityFile are a little different to most. IdentityFile adds to the list of keys, whereas most other directives are *first match wins*. This leads to the slightly undesirable effect of appending ~/.ssh/internal_example_org_key.id_rsa to the list of keys, even for login.example.org. We can't avoid that unless we support negated matching in Host blocks.
Comment 2 Christoph Anton Mitterer 2011-05-06 07:09:54 AEST
Well I guess I understood how it works and also that it's "appended" multiple IdentityFile statements are used.

And especially because of this, I think it should work even _without_ specifying an additional 
IdentityFile ~/.ssh/id_rsa
... or the documentation should be changed.

The ssh_config manpage says the default (i.e. when nothing is specified [0])
IdentityFile ~/.ssh/id_rsa
IdentityFile ~/.ssh/id_dsa
IdentityFile ~/.ssh/id_ecdsa

Right?

Ok, now in the login.example.org block, nothing is specified, so I'd expect this default to be taken, and then the ones from the other blocks _appended_.


[0] Now currently it seems like the meaning is:
"These are taken as defaults, if after all block merging at no block an IdentityFile was specified."

Personally I consider it this way less reasonable, but if you don't agree with that and/or can't change it easily, I'd suggest that you add to the documentation, that the default is only applied, _AFTER_ all block merging was done.


Of course all this is not a big issue ;-) ... but it took me quite some time to find the reason (which I eventually did before writing this bug report),... especially as with ssh-agent under some GUI (e.g. GNOME or so), everything worked just fine; while under plain console, it didn't.


Cheers,
Chris
Comment 3 Damien Miller 2011-06-03 10:33:52 AEST
ok, I have implemented negated host matching so starting with openssh-5.9 you can express your configuration as:

Host login.example.org
        User loginUser

Host *.example.org !login.example.org
        User root
        IdentityFile ~/.ssh/internal_example_org_key.id_rsa
        ProxyCommand ssh login.example.org nc %h %p

I'll update ssh_config(5) to describe the behaviour better too.
Comment 4 Christoph Anton Mitterer 2011-08-14 04:24:02 AEST
Hi Daimen.

Well this is a very nice feature, but I think the unclear documentation remains (and I asked several friends of mine how they'd interpret the manpage an they've agreed).

It says "The default is ~/.ssh/identity for protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa and ~/.ssh/id_rsa for protocol version 2." as well as "It is possible to have multiple identity files specified in configuration files; all these identities will be tried in sequence."
So as I've mentioned in Comment 2 one should at least add something like "These are taken as defaults, if after all block merging at no block an IdentityFile was specified." (or a better wording of this).


Regarding your added feature could you - in addition - add something like this:
Host a.foo.example
   bla

Host b.foo.example!
   bla

Host c.foo.example
   bla

Host *.foo.example !a.foo.example.
   bla

Now "a" wouldn't match the wildcard, as you've already implemented it.
"c" would match.
My idea of "b" (where the exclamation mark is at the end of the hostname) is that when host matches that is postfixed by an "!" matching stops here (after that block) for that name. So effectively, *.foo.example wouldn't be applied for "b".
Now you can argue that this is similar to what you've done, but the advantage is, that if you have many hostnames to be excluded (e.g. a. to z. or even more) you don't have to re-write them all at the wildcard block (which is quite error-prone).

You should however not remove your !-prefix syntax... IMHO both would be quite reasonable.


Cheers,
Chris.
Comment 5 Damien Miller 2011-09-06 10:34:15 AEST
Retarget unresolved bugs/features to 6.0 release
Comment 6 Damien Miller 2011-09-06 10:36:28 AEST
Retarget unresolved bugs/features to 6.0 release
Comment 7 Damien Miller 2011-09-06 10:39:02 AEST
Retarget unresolved bugs/features to 6.0 release

(try again - bugzilla's "change several" isn't)
Comment 8 Damien Miller 2011-11-04 11:56:13 AEDT
I don't think there is a need to further clarify the IdentityFile documentation with regard to how the default is applied - the rules here are the same as all other configuration items.
Comment 9 Christoph Anton Mitterer 2012-02-07 03:03:09 AEDT
Hey Damien.

Two notes:

a) Thought about adding such a "stop-matching-here" syntax, as I've proposed in comment #14?

b) You're right with respect to the documentation, more or less ;-)
I know understood how you meant the merging to be... but then the following might sense to be added:
Now you say:
>     ssh(1) obtains configuration data from the following sources
>     in the fol‐
>     lowing order:
>
>           1.   command-line options
>           2.   user's configuration file (~/.ssh/config)
>           3.   system-wide configuration file (/etc/ssh/ssh_config)
etc..

If you add a:
4. ONLY if none of the ones before specified an options, that option's default is used.

Then the thing I've always meant (why is the default of IdentityFile not added) is clear.


Cheers,
Chris

btw: reopening in order to get your attention,.. just close it again if you disagree :)
Comment 10 Damien Miller 2012-02-24 10:34:24 AEDT
Retarget from 6.0 to 6.1
Comment 11 Damien Miller 2012-02-24 10:38:02 AEDT
Retarget 6.0 => 6.1
Comment 12 Damien Miller 2012-09-07 11:38:00 AEST
Retarget uncompleted bugs from 6.1 => 6.2
Comment 13 Damien Miller 2012-09-07 11:40:30 AEST
Retarget bugs from 6.1 => 6.2
Comment 14 Damien Miller 2013-03-08 10:23:37 AEDT
retarget to openssh-6.3
Comment 15 Damien Miller 2013-07-12 11:16:59 AEST
(In reply to Christoph Anton Mitterer from comment #9)
> Hey Damien.
> 
> Two notes:
> 
> a) Thought about adding such a "stop-matching-here" syntax, as I've
> proposed in comment #14?

I'm not sure it's needed, given you can just set anything you want at the match point anyway.

> If you add a:
> 4. ONLY if none of the ones before specified an options, that
> option's default is used.

This isn't necessary, that is what a default is.
Comment 16 Damien Miller 2015-08-11 23:03:35 AEST
Set all RESOLVED bugs to CLOSED with release of OpenSSH 7.1