1

Is there a single line command to tell SSH to add a provided public key to the local machine's authorized_keys file? A local version of ssh-copy-id?

I am writing a chef recipe and want to ensure a specific ssh public key is set for a certain user. I could overwrite the ~/.ssh/authorized_keys file each time, or attempt to some hacky way to add the line, but if there's an official command, it'll be more robust and prevent duplication.

Something like:

ssh-add-local-key "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDeblahdeblah user@somwhere"

For apt systems like Ubuntu or Debian there is an apt-add-repository command, so I wonder if there's a SSH equivalent.

I know I could use "echo blah >> authorized_keys", but I want something idempotent, which I can run regularly. With >> the file will grow in size every time.

4
  • 4
    Usually I just use cat or similar to append the provided key to the keyfile. I agree that overwriting would be very bad, but you can avoid a specialist command without overwriting.
    – MadHatter
    Oct 19, 2017 at 9:47
  • cat id_rsa.pub >> /homedir/.ssh/authorized_keys or something like that. I use ansible to do the task Oct 19, 2017 at 10:02
  • If you do not want to cat it in there, you can of course just use ssh-copy-id you@localhost. Or you build some script (possibly grep -v the new key in the file and then append it to the output or similar), but be careful not to lock out yourself while testing it.
    – allo
    Oct 19, 2017 at 15:10
  • grep + test + cat wannabe your friend. Mar 15, 2020 at 19:22

3 Answers 3

1

I'm not aware of such a local command. I don't like ssh-copy-id foo@localhost (because it opens a SSH connection) and I even less like the error prone echo foo >> ~/.ssh/authorized_keys.

But since you're using chef, why don't you use the chef tools (mainly ruby) you have available?

For example:

ruby_block "authorized_keys" do
  block do
    file = Chef::Util::FileEdit.new("/home/#{username}/.ssh/authorized_keys")
    file.insert_line_if_no_match("/#{authorized_key}/", "#{authorized_key}")
    file.write_file
  end
end

insert_line_if_no_match documentation:

#insert_line_if_no_match(regex, newline) ⇒ Object

search the file line by line and match each line with the given regex if not matched, insert newline at the end of the file

This doesn't seem hacky all that much to me and provides an easy to understand way to solve your problem.

Another alternative would be Bill Warners answer to a similar question: https://stackoverflow.com/a/28283354/2376817

0

There's now a chef authorised keys cookbook. You simply add your key to your cookbook thus:

ssh_authorize_key '[email protected]' do
  key 'AAAAB3NzaC1yc2EAAAADAQABAAABAQCctNyRouVDhzjiP[...]'
  user 'root'
end

Note that if you use this cookbook, any keys added by hand will be deleted.

0

suggestion: run ssh-copy-id on loopback (localhost).

ssh-copy-id localhost

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .