文件~/.ssh/authorized_keys
格式可以简单概括为
- 每个键一行的文本文件;
- 空行和以 octothorpe (
#
) 开头的行将被忽略; - 有四个字段:选项,按键类型,钥匙和评论;
- 字段一和字段四是可选的;
- 如果使用双引号,字段 1 可能包含空格;
- 第四个字段可以包含空格而不用引号引起来。
完整的描述位于man sshd
.
是否有可靠的、可编写脚本的(例如bash
)方法来操作~/.ssh/authorized_keys
文件中的键?
例如,脚本可能:
- 提取一个特定的密钥(即按键类型,钥匙和评论字段),
- 操纵(添加、修改或删除)选项场地,
- 操纵(添加、修改或删除)评论场地,
- 迭代所有键,或者
- 移除一把钥匙。
似乎没有能够修改该文件的 SSH 工具(例如ssh-keygen
,ssh-add
&c.)~/.ssh.authorized_keys
,并且该文件的性质选项和评论sed
字段使得使用通常的,awk
或perl -pe
方法很难可靠地实现这一点。
关注评论,这是一个简化的问题:想象一个读取文件~/.ssh/authorized_keys
并输出所有键的脚本 - 仅输出键:没有选项,也没有空白行或注释行。
我很难做到这一点,因为每一行都是以空格分隔的,但是:
- 选项可以包含空格或完全不存在,并且
- 由于空格,注释可以是零个或多个字段。
因此,您不知道一行包含多少个字段,并且您无法轻松判断其中有多少个字段选项跨度。
您需要一个过于复杂的正则表达式来理解选项字段,以便在输出该行的其余部分之前可以可靠地删除它。我尝试用sed
和来做到这一点perl -pe
。
这种脚本的一个人为用例是列出所有按键的指纹。
答案1
从你的描述来看,你似乎想删除选项和注释行。根据man 8 sshd
:
公钥由以下空格分隔的字段组成:选项、密钥类型、base64 编码密钥、注释。选项字段是可选的。密钥类型为“ecdsa-sha2-nistp256”、“ecdsa-sha2-nistp384”、“ecdsa-sha2-nistp521”、“ssh-ed25519”、“ssh-dss”或“ssh-rsa”;注释字段不用于任何用途(但可能方便用户识别密钥)。
因此你可以这样做:
sed '
/^[ ]*$/d;
/^#/d;
s/^.* \(ecdsa-sha2-nistp256\|ecdsa-sha2-nistp384\|ecdsa-sha2-nistp521\|ssh-ed25519\|ssh-dss\|ssh-rsa\) /\1 /' \
~/.ssh/authorized_keys
这假设关键注释不包含ssh-dss
、ssh-rsa
等。它还假设sed(1)
支持OR
(ie \|
) 的实现。
使用文本编辑器可能会更容易、更安全。 :)