Bug 2331 - ssh-copy-id -i id_new.pub fails to copy that id, also: wrong error msg
Summary: ssh-copy-id -i id_new.pub fails to copy that id, also: wrong error msg
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: ssh-copy-id (show other bugs)
Version: -current
Hardware: All Linux
: P5 major
Assignee: Philip Hands
URL:
Keywords:
Depends on:
Blocks: V_7_2
  Show dependency treegraph
 
Reported: 2015-01-07 09:57 AEDT by Thomas Waldmann
Modified: 2016-08-02 10:41 AEST (History)
4 users (show)

See Also:


Attachments
BUGFIX patch (1.12 KB, patch)
2015-01-13 05:11 AEDT, Elias Toivanen
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Waldmann 2015-01-07 09:57:07 AEDT
On the server, password auth is disabled, I log in via pubkey auth and have an "old" pubkey installed there and can successfully log in with it.

Now I want to install a new (stronger) pubkey and use:

ssh-copy-id -i .ssh/id_new.pub user@remote

It fails with:

/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.

This is wrong, the pubkey I gave with -i ... does not exist on the remote system.

This is because it obviously has a broken check for which keys it needs to copy.

While it works perfectly if there is no key installed yet on the remote (and pw auth still enabled), it fails if it already has an old working pubkey there because it uses pubkey-login-failure to detect a missing key and assumes that only the key given with -i is used. But in fact, it also uses keys from the config (where I have my old key configured).

I could make -i work with this patch:

https://paste.thinkmo.de/Unr2wWqd#ssh-copy-id-with-i-arg.txt

This basically killed all the magic happening in the detection and just "does what I say". Of course this only works for the special -i xxx case and needs a better fix for the generic case.

I think it would need something like "CommandLineGivenIdentitiesOnly" as "IdentitiesOnly" does obviously not work as the author of that code expected.
Comment 1 Elias Toivanen 2015-01-11 10:48:34 AEDT
I cannot reproduce the bug

Here's what I did...

1. Have a key pair id_rsa_remote/id_rsa_remote.pub set up on the remote machine 

2. Configured the local machine to use this key pair, a copy of which I have

Host remote
  User me
  Hostname remote.machine.com
  IdentityFile ~/.ssh/id_rsa_remote

3. Have the pub key in id_rsa_remote.pub in the authorized_keys file.

# Public key authentication now works

4. Created a new key pair id_new/id_new.pub on the local machine.

5. ssh-copy-id -i id_new.pub me@remote

6. Observed that the public key has been appended correctly in the authorized keys file.

# Public key authentication now works with both key pairs


Could you clarify the situation a little bit. So, you have created a new key pair id_new/id_new.pub that are completely unrelated to any old key pairs? And the contents of id_new.pub are truly not in the authorized keys file? 

Note also that a pubkeys are not stronger or weaker...they are just public.
Comment 2 Thomas Waldmann 2015-01-12 23:51:37 AEDT
I just reproduced it:

sudo adduser bugtest
sudo vim /etc/ssh/sshd_config # enable ssh password login
sudo service ssh restart

ssh-copy-id -i .ssh/tw_rsa_2008.pub bugtest@localhost
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
bugtest@localhost's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'bugtest@localhost'"
and check to make sure that only the key(s) you wanted were added.


sudo vim /etc/ssh/sshd_config # disable ssh password login
sudo service ssh restart

ssh-copy-id -i .ssh/tw_rsa4096_2015.pub bugtest@localhost
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed

/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
Comment 3 Thomas Waldmann 2015-01-12 23:57:28 AEDT
My .ssh/config:

[stuff for other hosts - should not be relevant]

Host *
IdentityFile ~/.ssh/tw_rsa4096_2015
IdentityFile ~/.ssh/tw_rsa_2008
Comment 4 Thomas Waldmann 2015-01-13 00:10:50 AEDT
And this is why the magic in ssh-copy-id (which I removed in the patch I linked to) does not work, I used the same command as in the ssh-copy-id magic:

$ ssh -v -i .ssh/tw_rsa4096_2015.pub -o PreferredAuthentications=publickey -o IdentitiesOnly=yes bugtest@localhost exit
OpenSSH_6.6.1, OpenSSL 1.0.1f 6 Jan 2014
debug1: Reading configuration data /home/tw/.ssh/config
debug1: /home/tw/.ssh/config line 37: Applying options for *
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
debug1: Connecting to localhost [127.0.0.1] port 22.
debug1: Connection established.
debug1: identity file .ssh/tw_rsa4096_2015.pub type 1
debug1: identity file .ssh/tw_rsa4096_2015.pub-cert type -1
debug1: identity file /home/tw/.ssh/tw_rsa4096_2015 type 1
debug1: identity file /home/tw/.ssh/tw_rsa4096_2015-cert type -1
debug1: identity file /home/tw/.ssh/tw_rsa_2008 type 1
debug1: identity file /home/tw/.ssh/tw_rsa_2008-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2
debug1: Remote protocol version 2.0, remote software version OpenSSH_6.6.1p1 Ubuntu-2ubuntu2
debug1: match: OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 pat OpenSSH_6.6.1* compat 0x04000000
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client chacha20-poly1305@openssh.com <implicit> none
debug1: kex: client->server chacha20-poly1305@openssh.com <implicit> none
debug1: sending SSH2_MSG_KEX_ECDH_INIT
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: Server host key: RSA a1:27:ba:68:70:26:fe:47:dd:96:0e:7c:b8:63:43:6f
debug1: Host 'localhost' is known and matches the RSA host key.
debug1: Found key in /home/tw/.ssh/known_hosts:938
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: Roaming not allowed by server
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
XXX debug1: Offering RSA public key: /home/tw/.ssh/tw_rsa_2008
XXX debug1: Server accepts key: pkalg ssh-rsa blen 277
XXX debug1: Authentication succeeded (publickey).
Authenticated to localhost ([127.0.0.1]:22).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
debug1: Sending command: exit
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0
debug1: channel 0: free: client-session, nchannels 1
Transferred: sent 2344, received 2340 bytes, in 0.0 seconds
Bytes per second: sent 807179.7, received 805802.2
debug1: Exit status 0
$ echo $?
0

See the 3 lines I marked with XXX - it gets in using the old key. So the magic is using a wrong assumption (that not getting in means the identity given with -i is still missing on the remote and that getting in means the identity given with -i is already present on the remote), see also what I said in the first post.
Comment 5 Elias Toivanen 2015-01-13 05:11:31 AEDT
Created attachment 2527 [details]
BUGFIX patch
Comment 6 Elias Toivanen 2015-01-13 05:17:39 AEDT
Hi,

Indeed, it is a bug as ssh_config(5) has this to say:

"It is possible to have multiple identity files specified in configuration files; all these identities will be tried in sequence.  Multiple IdentityFile directives will add to the list of identities tried (this behaviour differs from that of other configuration directives)."

I am not a OpenSSH developer, but IMO the correct thing to do is to ignore configuration files (add -F /dev/null to the ssh argument list in ssh-copy-id) so that multiple id files won't screw up the login test.

I attached a patch that fixes the issue. Devs? Hopefully you accept it.
Comment 7 Thomas Waldmann 2015-01-31 16:43:23 AEDT
May I suggest to just kill that magic that tries to determine whether the key is already installed in a problematic way?

I somehow have the impression that this is causing more troubles than it solves.

Especially bug #2110 seems to be related - it would not need to access the private key if it would not try to login to do that magic, right?
Comment 8 bugzilla.mindrot.org 2015-02-13 19:31:13 AEDT
Relevant Q&A session: https://unix.stackexchange.com/questions/184209/how-to-force-ssh-copy-id-to-ignore-existing-authorized-keys

Could we add an option to ignore the configuration? Making it default "off" would avoid changing the current behaviour. Making it default "on" would make it do the obvious thing in *this* case, but would confuse for example users which use `Hostname` and `User` in their configuration.
Comment 9 Philip Hands 2015-11-29 06:11:35 AEDT
I've recently been updating things in my git repo:

  http://git.hands.com/ssh-copy-id

including the addition of a '-f' (for "force") option, that reverts to the old behaviour of simply trying to install the key regardless of whether it's already installed.  In addition to that, I've modified the warning message one gets in the case described here, to suggest using the -f option:

  http://git.hands.com/?p=ssh-copy-id.git;a=commitdiff;h=ab185eea5a03cdd846c909d83e5dd0a07a44fb54;hp=6fa6f1e3dbec32636e77d01228ceecfa3851c7e8

Do you think this is sufficient to address the problem?

Cheers, Phil.
Comment 10 Philip Hands 2016-02-17 19:03:13 AEDT
BTW it was the addition of the -f option that unconditionally copies the key, rather than doing checks first (that might fail if there's an IdentityFile specified in the config)
Comment 11 Philip Hands 2016-02-17 21:29:28 AEDT
Hmm, that wasn't exactly clear -- what I should have written was:

> BTW the thing that closes this bug was the addition of the -f option,
> that unconditionally copies the key rather than checking first.
> Doing those checks can incorrectly succeed if there's an IdentityFile
> specified in the config, which stops the key from being installed,
> hence this bug.

Hopefully that makes a bit more sense.
Comment 12 Damien Miller 2016-08-02 10:41:52 AEST
Close all resolved bugs after 7.3p1 release