authorized_keys 是什么
SSH 公钥认证的本质是:客户端用私钥签名,服务端用该用户 authorized_keys 文件里登记的公钥验签,验签通过即登录成功。所以文件里多出的任何一行,等于给对应私钥的持有者发了一张长期免密通行证。攻击者拿到一次 shell 后往这里追加公钥,就同时绕过了口令强度要求、失败锁定与部分审计手段,比留 webshell 更安静。排查目标很明确:把每个可能登录的账号的这份文件都看一遍,逐行确认归属。
基本信息
| 默认路径 | ~/.ssh/authorized_keys(root 为 /root/.ssh/authorized_keys) |
|---|---|
| 生效路径由谁定 | sshd_config 的 AuthorizedKeysFile,可被改成 /etc/ssh/authorized_keys/%u 等自定义位置 |
| 权限要求 | StrictModes 开启时 .ssh 需 700、authorized_keys 需 600,属主必须是该用户,否则登录直接被拒 |
| 可否带限制选项 | 可以,行首可加 command="..."、from="IP"、no-pty、restrict、no-port-forwarding 等前缀 |
| 指纹工具 | ssh-keygen -lf 文件(对 authorized_keys 整体取指纹亦可) |
| 常见忽略点 | 注释字段(行末 comment)由写文件的人随意填写,不能作为归属依据 |
典型使用场景
- SSH 爆破或可疑登录告警后,确认是否已被写入攻击者公钥
- 木马清理完成后做反弹复查,确认免密通道已彻底关闭
- 离职或交接时核对哪些公钥还在,避免遗留账号长期可登录
- 运维侧推行密钥认证时核对存量用户是否合规配置
- 与 last、auth.log 联用,把公钥写入时间与登录时间对上
全用户扫描与指纹比对
全用户扫描与指纹比对
for h in /root /home/*; do f="$h/.ssh/authorized_keys"; # 遍历所有家目录
if [ -f "$f" ]; then echo "== $f"; ls -l --time-style=full-iso "$f"; cat "$f"; fi; done
sudo sshd -T | grep -i authorizedkeysfile # 先确认生效的密钥文件路径
ssh-keygen -lf /root/.ssh/authorized_keys # 生成指纹,与台账逐条比对
sudo grep -RIn 'command=\|no-pty\|from=' /root/.ssh /home/*/.ssh 2>/dev/null # 带限制前缀的可疑行
sudo sha256sum /root/.ssh/authorized_keys | tee /evidence/ak_hash.txt # 先存证再动手逐行读法
| 行内元素 | 含义 | 判断要点 |
|---|---|---|
| 算法前缀 | ssh-rsa、ssh-ed25519、ecdsa-sha2-* | ssh-rsa 若只有 1024 位属老旧弱密钥,需重点关注 |
| 公钥体 | Base64 编码内容 | 无法肉眼判断归属,必须用 ssh-keygen -lf 取指纹比对台账 |
| 注释字段 | 行末自由文本,常是 user@host | 可以被随意伪造,不能凭它认定是谁的密钥 |
| 选项前缀 | command=、from=、restrict、no-pty | command= 常被用来做固定动作后门,from= 说明来源被限定 |
| 文件权限与属主 | 600 属主为该用户,.ssh 为 700 | 权限不对会导致登录失败,排查时顺手核对 |
| mtime | 文件最后修改时间 | 与入侵时间窗对得上就是强线索,务必先记录 |
保全优先于清理:先把文件复制到独立介质、算好 sha256 并记录 mtime,最安全的现场处理是把可疑行用 # 注释掉(sshd 会忽略注释行),确认无人受影响后再删除。
只清理 authorized_keys 不算完:AuthorizedKeysFile 可能被改成其他路径,sshd_config 里还可能有 AuthorizedKeysCommand,PAM 与 sshd 的 ForceCommand 也要一起核对,否则通道照样存在。
配套检查项
配套检查项
sudo ls -la /root/.ssh /home/*/.ssh 2>/dev/null | head -n 40 # 目录整体过一遍
sudo ls -la /etc/ssh/authorized_keys* /etc/ssh/ssh_host_* 2>/dev/null # 排查自定义集中存放位置
sudo grep -RIn 'authorizedkeys\|forcecommand' /etc/ssh/sshd_config /etc/ssh/sshd_config.d 2>/dev/null
sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub # 顺手核对主机密钥有没有被换换过主机密钥(HostKey)的主机第一次连接会报指纹不匹配,这既可能是重装系统,也可能是中间人;应急现场发现指纹变化要记录时间点并核对重装记录。
SSH 后门的常见形态
| 形态 | 痕迹位置 | 清除要点 |
|---|---|---|
| 追加公钥 | 各用户 .ssh/authorized_keys | 按行核对指纹,污染行注释保全后再删 |
| 固定命令后门 | authorized_keys 中带 command= 前缀的行 | 删除整行,并检查被它调用的脚本文件 |
| 集中公钥路径 | sshd_config 的 AuthorizedKeysFile 被改向 | 恢复配置并清理被指向目录中的全部条目 |
| 外部密钥命令 | sshd_config 的 AuthorizedKeysCommand | 恢复为空并检查被调用的脚本是否存在 |
| 提权账号 | /etc/passwd 新增 uid 0 条目 | 与密钥排查同批完成,避免只堵一条路 |
清理前后核对清单
- 清理前:复制文件内容、记录 mtime 与 sha256、导出当前在线会话与来源 IP
- 清理中:只注释不删除,确认无业务账号依赖该公钥后再移除
- 清理后:用 ssh -o PreferredAuthentications=publickey 重试登录确认通道失效
- 清理后:复查 sshd -T 的生效配置与 /etc/ssh 下所有相关文件
- 归档:把证据目录、变更记录与验证结果写入处置报告