Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Hello I am looking for assistance searching /root/.ssh/authorized_keys for a given public key (call it $pub_key) and removing it. Want to do this in bash script.

What's the best way to accomplish this?

share|improve this question

3 Answers 3

up vote 8 down vote accepted

Would grep -v $pub_key /root/.ssh/authorized_keys > /tmp/authorized_keys.new work? You can compared to two files to verify the work. Given the long strings of random characters that comprise the keys, it's probably sufficient to do this using a substring of $pub_key.

share|improve this answer
    
Actually, that just cleared out the entire file, it didn't just remove the passed in $pub_key –  Justin Sep 8 '11 at 23:27
    
I think I need to use sed, but can't figure out the syntax, here is what I have thus far: sed -i '/$pub_key/ d' /root/.ssh/authorized_keys –  Justin Sep 8 '11 at 23:36
    
Seriously, the grep didn't work? Try a substring. Something like "grep -v CqcQ9rbUrPBczdoHBAe72Z /root/.ssh/authorized_keys". There's so much entropy in these keys that any reasonably sized substring won't be repeated in any other key. You don't need to need the whole 500+ character key. The syntax on the sed is correct, though I would be nervous about using the "-i" option; make backups if you use it. –  cjc Sep 9 '11 at 0:10

Never forget the power of perl oneliners!

$pub_key="AAAABCD"; perl -i "/$pub_key/ or print" /root/.ssh/authorized_keys

That will perform an in-place edit and remove the offending key.

Or, perhaps you have a really really long authorized_keys file and you want to process it in parallel with gnu parallel?

pub_key="AAAABCD"; parallel -k "echo {} | grep -v $pub_key" </root/.ssh/authorized_keys

the possibilities are endless.

update: fixed typo that Ole pointed out. Thanks Ole!

share|improve this answer
    
Remove the first $ to set the variable. Apart from that you should consider using --pipe if your authorized_keys is of the size where it will benefit from parallel processing. –  Ole Tange Sep 9 '11 at 11:36
    
Ole is there a way to do 'edit in place' with parallel as above? –  Phil Hollenback Sep 9 '11 at 17:23

I think I need to use sed, but can't figure out the syntax, here is what I have thus far:

sed -i '/$pub_key/ d' /root/.ssh/authorized_keys

Remove the space before d, it will work as you expect:

sed -i '/$pub_key/d' /root/.ssh/authorized_keys
share|improve this answer
1  
My keys have a half-dozen slash characters in them that would need to be escaped. I would use '\|$pub_key|d' to get sed to use | as an alternate delimiter rather than adding backslashes to $pub_key –  DerfK Sep 9 '11 at 3:12
    
Hmm. If you insist on using $pub_key for the whole key, do something this: "$substring = echo $pub_key | cut -c30-60 ; mv authorized_keys authorized_keys.bak ; grep -v $substring authorized_keys.bak > authorized_keys". grep doesn't care about the delimiters. When it didn't work before, you probably expressed $pub_key as the whole thing, but there are spaces in there. In that case, you should have mentioned the error, and I would have suggested enclosing $pub_key in quotes. –  cjc Sep 9 '11 at 9:59

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.