Command to remove a ssh authorized key on server

31

4

Is there a command (or a one-liner) to remove a ssh key on a server? Something like the opposite of ssh-copy-id?

grm

Posted 2012-05-29T06:21:13.307

Reputation: 2 164

3Excellent question, this is really missing functionality to ssh-copy-id to facilitate key rotation. – Zabuzzman – 2015-03-27T22:33:28.337

1

Its worth noting that ssh-keygen does provide the -R option for removing keys from known_hosts, but sadly ssh-keygen -R <HOSTNAME> -f ~/.ssh/authorized_keys doesn't work. I would use the sed option below, instead.

– Digital Trauma – 2018-03-23T18:27:53.930

2Some SSH server software support the RFC 4819 protocol for managing authorized SSH keys, but it's so rare it's almost nonexistent on Linux :( – user1686 – 2012-05-29T07:38:11.180

Answers

11

As Ignatio suggested this can be done with grep -v.

Here is a example which removes the key containing some unique string or just deletes the authorized_keys file when no other key remains.

if test -f $HOME/.ssh/authorized_keys; then
  if grep -v "some unique string" $HOME/.ssh/authorized_keys > $HOME/.ssh/tmp; then
    cat $HOME/.ssh/tmp > $HOME/.ssh/authorized_keys && rm $HOME/.ssh/tmp;
  else
    rm $HOME/.ssh/authorized_keys && rm $HOME/.ssh/tmp;
  fi;
fi

Replace some unique string with something that only exists in the key you wish to remove.

As a oneliner over ssh this becomes

ssh hostname 'if test -f $HOME/.ssh/authorized_keys; then if grep -v "some unique string" $HOME/.ssh/authorized_keys > $HOME/.ssh/tmp; then cat $HOME/.ssh/tmp > $HOME/.ssh/authorized_keys && rm $HOME/.ssh/tmp; else rm $HOME/.ssh/authorized_keys && rm $HOME/.ssh/tmp; fi; fi'

Tested on Linux (SLES) and HP-UX.

mleu

Posted 2012-05-29T06:21:13.307

Reputation: 234

2see below answer: sed is better at doing this – woohoo – 2016-07-12T01:31:47.693

27

sed provides a compact solution:

sed -i.bak '/REGEX_MATCHING_KEY/d' ~/.ssh/authorized_keys

This will save the original authorized_keys in authorized_keys.bak. If you don't want the backup then just change -i.bak to -i.

You can even remove multiple keys:

sed -i.bak '/REGEX1/d; /REGEX2/d' ~/.ssh/authorized_keys

The only tricky bit here is special characters in the regex need to be escaped.

Phil Frost

Posted 2012-05-29T06:21:13.307

Reputation: 460

If you only use the base64 characters in the public keyfile (e.g., awk '{print $2}' ~/.ssh/id_rsa.pub), then you don't need to worry about escaping any special characters. – Juan – 2018-03-22T23:30:21.180

7

Nope. You'll need to SSH in and use sed or grep to remove the key from the file.

Ignacio Vazquez-Abrams

Posted 2012-05-29T06:21:13.307

Reputation: 100 516

@grm : I'd suggest you keep the question open forever, or at least until a ssh-undo-copy-id is implemented ! ;-) – Max L. – 2015-07-30T18:28:37.693

Thank you. I will keep the question open a little longer to see if someone also can provide a script that does the opposite of ssh-copy-id – grm – 2012-05-30T11:56:20.460

0

Phil already answered this question but I want to do addition and make it easier for you. And since you are asking reverse of ssh-copy-id, I am assuming you want to run it on authorized machine.

ssh keys only contains base64 characters. So you can use a char as sed delimiter that not in that list. Let us use '#'.

ssh root@<hostname> -o PasswordAuthentication=no "sed -i.bak 's#`cat ~/.ssh/id_rsa.pub`##' ~/.ssh/authorized_keys"

Replace hostname with the server IP.

PasswordAuthentication option will cause ssh fail if it ask password

ibrahim

Posted 2012-05-29T06:21:13.307

Reputation: 123

1The 'comment' in the pub key might not have base64 characters. If it has a "#", then your example breaks. Maybe use awk '{print $2}' ~/.ssh/id_rsa.pub with some sed or grep -v instead. – Juan – 2018-03-22T23:24:25.333