Is there a command (or a one-liner) to remove a ssh key on a server? Something like the opposite of ssh-copy-id?
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.
-
2
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.
-
1If 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 Mar 22 '18 at 23:30 -
@Juan The important special character in base64 is "
/
" that must be escaped by "\/
" forsed
regexp. (Also a character "+
" is possible in the output of base64, but it is not a special character if extended POSIX regular expressions that are not enabled by-E
option in sed.) It is usually easier to use the comment field, especially if the default form user@host is used. – hynekcer Mar 3 at 9:50
Nope. You'll need to SSH in and use sed
or grep
to remove the key from the file.
-
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 May 30 '12 at 11:56
-
2@grm : I'd suggest you keep the question open forever, or at least until a ssh-undo-copy-id is implemented ! ;-) – Max L. Jul 30 '15 at 18:28
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
-
2The '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 somesed
orgrep -v
instead. – Juan Mar 22 '18 at 23:24
ssh-keygen
does provide the-R
option for removing keys fromknown_hosts
, but sadlyssh-keygen -R <HOSTNAME> -f ~/.ssh/authorized_keys
doesn't work. I would use thesed
option below, instead. – Digital Trauma Mar 23 '18 at 18:27