1

The ~/.ssh/authorized_keys file format can be briefly summarised as

  • a text file with one line per key;
  • empty lines and lines beginning with the octothorpe (#) are ignored;
  • there are four fields: options, keytype, key and comment;
  • fields one and four are optional;
  • field one may contain whitespace if double-quoted;
  • field four may contain whitespace without being quoted.

The full description is in man sshd.

Is there a reliable, scriptable (e.g. bash), way to manipulate keys in the ~/.ssh/authorized_keys file ?

For example, a script might:

  • extract a specific key (being the keytype, key and comment fields),
  • manipulate (add, modify or remove) the options field,
  • manipulate (add, modify or remove) the comment field,
  • iterate over all keys, or
  • remove a key.

There does not appear to be a SSH tool (e.g. ssh-keygen, ssh-add &c.) capable of modifying the ~/.ssh.authorized_keys file, and the nature of the options and comment fields make this very difficult to reliably achieve using the usual sed, awk or perl -pe approach.


Following comments, here is a simplified problem: imagine a script that reads the ~/.ssh/authorized_keys file and outputs all keys - only the keys: no options and no blank or comment lines.

I struggled to do this because each row is space-delimited but:

  • the options can contain whitespace or be absent altogether, and
  • the comments, due to whitespace, can be zero or more fields.

Therefore you have no idea how many fields that a row contains, and you can't easily tell how many of those fields the options spans.

You'd need a overly-complex regex that understands the scope of the options field so that it could remove it reliably before outputting the rest of the line. I tried to do this with sed and perl -pe.

A contrived use-case for such a script would be to list the fingerprints of all keys.

  • Given a key, you can add or remove comments to it, change its password, etc. with ssh-keygen. Beyond that, what you're asking doesn't make much sense. Let's say you have two keys with no comments, ssh-rsa AAAAB3NzaC1y... and ssh-rsa AAAAB3Nw3N2y.... How can you tell which one you want to extract / modify / remove? – Satō Katsura Feb 9 '17 at 10:47
  • Well you would have to refer to it somehow, perhaps by supplying it, or its fingerprint, or its bubblebabble text, etc. If the whole gamut of the question doesn't make sense, then consider the simpler scenario of extracting or iterating over all keys ignoring any options field. – starfry Feb 9 '17 at 10:50
  • It's still not clear what would be the input, and what would be the output of such operation. shrug – Satō Katsura Feb 9 '17 at 10:53
  • Ok, really simplify it... imagine a script that lists the keys without any options field. I tried with sed and perl -pe but it's hard to do it reliably when you consider how flexible the specification of options and comment is. – starfry Feb 9 '17 at 10:57
  • I've added a simplified problem to the end of the question. – starfry Feb 9 '17 at 11:16
1

From your description you seem to want to kill options and comment lines. According to man 8 sshd:

Public keys consist of the following space-separated fields: options, keytype, base64-encoded key, comment. The options field is optional. The keytype is “ecdsa-sha2-nistp256”, “ecdsa-sha2-nistp384”, “ecdsa-sha2-nistp521”, “ssh-ed25519”, “ssh-dss” or “ssh-rsa”; the comment field is not used for anything (but may be convenient for the user to identify the key).

Consequently you could do something like this:

sed '
    /^[ ]*$/d;
    /^#/d;
    s/^.* \(ecdsa-sha2-nistp256\|ecdsa-sha2-nistp384\|ecdsa-sha2-nistp521\|ssh-ed25519\|ssh-dss\|ssh-rsa\) /\1 /' \
        ~/.ssh/authorized_keys

This assumes key comments don't contain ssh-dss, ssh-rsa, etc. It also assumes a sed(1) implementation that supports OR (i.e. \|).

Using a text editor might prove both easier and safer. :)

  • That's qualifies as the nasty regex to which I alluded, but thanks - that's better than what I had. I had hoped for some utility that I hadn't heard of :) – starfry Feb 9 '17 at 12:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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