是否可以通过 ksh/bash 自动化,以便通过 schellscript 检查所有用户 ~/.ssh/authorized_keys 文件是否有错误的 = 或 == 结尾?
我的一位朋友删除了 SSH 密钥末尾的 = 和 ==,因此用户被锁定,因为这是他们密钥的一部分:)
它的模式是这样的(可能是 ssh-rsa 并具有不同的密钥长度):
from="1.2.3.4" ssh-dss AAAAB....0bOJKs= COMMENTHERE COMMENTHERE
对此:
from="1.2.3.4" ssh-dss AAAAB....0bOJKs COMMENTHERE COMMENTHERE
示例解决方案:密钥有固定长度吗?如何过滤掉坏钥匙?
答案1
该=
标记只是填充,用于填写 Base64 转换。您可以阅读更多相关内容
- SSH 公钥末尾的等号 = 或 == 是什么意思?,它从获取信息RFC 4716“SSH 公钥文件格式
- 为什么base64编码的字符串末尾有=号, 基于RFC 2045:多用途互联网邮件扩展 (MIME)
您可以自动修复/检查此问题,因为 base64 值中的字符总数(忽略那些外部编码(例如空格)将是 4 的倍数。
答案2
Perl 中的快速修复:
perl -lane '$a = -1; for(0..$#F) {$a = $_ + 1 if $F[$_] =~ /^ssh-|^ecdsa-/; };
die if $a == -1; $p = (4 - length($F[$a]) % 4) % 4;
$F[$a] .= "=" x $p; print join " ", @F' < authorized_keys > authorized_keys2
对于每一行(-n
)将-a
字段自动拆分( )为@F
沿空格,然后找到包含键类型的字段,接下来就是键。用 4 减去长度模 4,得到我们需要添加的符号数量=
,除非在字段已经是正确长度的情况下再取模将 4 转换为 0。
手册上说
协议 2 公钥由:选项、密钥类型、base64 编码密钥、注释组成。 options 字段是可选的;它的存在取决于该行是否以数字开头
但这不太正确,因为 v2 键类型也不以数字开头。选项字段包含空格,因此键类型的位置可以是任何位置。我们实际上应该解析选项以查找任何带引号的字符串,但应该试探性地查找已知的键类型。
答案3
cut -d: -f6 /etc/passwd |
while read oneuserraw; do
if [ -s "${oneuserraw}/.ssh/authorized_keys" ]; then
echo "${oneuserraw}/.ssh/authorized_keys"
fi
done |
perl -pe 's/\/\//\//g' |
while read oneuser; do
echo checking: "$oneuser"
cat "$oneuser" | while read oneline; do
if [[ "$oneline" == from* ]]; then
key=$(echo "$oneline" | cut -d' ' -f3)
fi
if [[ "$oneline" == ssh* ]]; then
key=$(echo "$oneline" | cut -d' ' -f2)
fi
length=$(echo "$key" | awk '{ print length }')
if ! (( $length % 4 == 0 )); then
echo "$oneline"
fi
done
done
我自己也写了一个检查器。
这甚至会抛出有人在 ex.: ssh key 中间按 Enter 键并且不能被 4 整除的错误行。
在 AIX/Linux 上测试了 ksh 和 bash。