Linux命令-ssh-keyscan(从主机收集公钥)

Linux命令-ssh-keyscan(从主机收集公钥)

ssh-keyscan 是一个批量收集 SSH 主机公钥的工具。与交互式的 ssh 首次连接确认不同,ssh-keyscan 非交互地从指定主机获取公钥,非常适合自动化脚本、主机清单管理和大规模部署前的 known_hosts 预填充。

快速参考

bash 复制代码
ssh-keyscan [选项] [主机...]

ssh-keyscan 从目标的 SSH 服务端口连接并获取公钥,输出可重定向到 ~/.ssh/known_hosts 文件,避免首次连接时的交互式确认提示。

基本用法

bash 复制代码
# 获取单台主机的公钥
ssh-keyscan server.example.com

# 获取并直接添加到 known_hosts
ssh-keyscan -H server.example.com >> ~/.ssh/known_hosts

# 指定非标准端口
ssh-keyscan -p 2222 server.example.com

# 获取多个主机的公钥
ssh-keyscan server1 server2 server3

# 从文件批量获取
ssh-keyscan -f hosts.txt

选项详解

选项 说明
-H 哈希主机名(推荐,增加安全性)
-p PORT 指定 SSH 端口
-T TIMEOUT 连接超时时间(秒)
-t TYPE 指定密钥类型(rsa/dsa/ecdsa/ed25519)
-f FILE 从文件读取主机列表
-4/-6 强制使用 IPv4/IPv6
-c 请求证书而非纯密钥
-v 详细输出
-D 打印调试信息

常见使用场景

bash 复制代码
# === 场景 1: 避免首次连接提示 ===
# 传统方式(交互式)
ssh new-server.example.com
# The authenticity of host 'new-server.example.com' can't be established.
# Are you sure you want to continue connecting (yes/no)?

# 使用 ssh-keyscan 预填充
ssh-keyscan -H new-server.example.com >> ~/.ssh/known_hosts
ssh new-server.example.com  # 无提示!

# === 场景 2: Ansible/自动化部署 ===
# 部署前批量添加所有主机公钥
ansible all --list-hosts | tail -n +2 | while read host; do
    ssh-keyscan -H "$host" >> ~/.ssh/known_hosts 2>/dev/null
done

# === 场景 3: 不同密钥类型收集 ===
# 仅收集 Ed25519 密钥
ssh-keyscan -t ed25519 host.example.com

# 收集多种类型
ssh-keyscan -t ecdsa,ed25519 host.example.com

# 收集全部可用类型
ssh-keyscan -t rsa,dsa,ecdsa,ed25519 host.example.com 2>/dev/null

批量操作

bash 复制代码
# 从 IP 范围批量收集
for ip in 192.168.1.{1..254}; do
    ssh-keyscan -T 2 "$ip" >> ~/.ssh/known_hosts 2>/dev/null &
done
wait

# 从主机清单文件批量操作
cat > hostlist.txt << 'EOF'
192.168.1.10
192.168.1.20
db.private.local
web.prod.internal
EOF

# 哈希存储(推荐)
ssh-keyscan -H -f hostlist.txt >> ~/.ssh/known_hosts

# 非哈希存储(调试时使用)
ssh-keyscan -f hostlist.txt > known_hosts_plain.txt

# 去重 known_hosts
sort -u ~/.ssh/known_hosts -o ~/.ssh/known_hosts

# 并行批量收集(超时 3 秒)
cat hostlist.txt | xargs -P 10 -I {} ssh-keyscan -T 3 -H {} >> ~/.ssh/known_hosts 2>keyscan_errors.log

# 验证收集结果
wc -l ~/.ssh/known_hosts

安全管理

bash 复制代码
# 清除特定主机的旧记录
ssh-keygen -R compromised-host.example.com

# 清除旧记录后重新扫描
ssh-keyscan -H new-server.example.com >> ~/.ssh/known_hosts

# 验证 known_hosts 中的记录
ssh-keygen -H -F server.example.com

# 审计 known_hosts 文件
echo "=== known_hosts 审计 ==="
echo "总记录数: $(wc -l < ~/.ssh/known_hosts)"
echo "MD5 哈希: $(md5sum ~/.ssh/known_hosts | cut -d' ' -f1)"

# 提取所有主机名(需要先取消哈希,安全注意!)
ssh-keygen -F "*" -f ~/.ssh/known_hosts 2>/dev/null

# 对比新旧主机密钥(检测 MITM 攻击)
ssh-keyscan server.example.com | while read line; do
    if grep -qF "$line" ~/.ssh/known_hosts; then
        echo "✅ 密钥匹配: server.example.com"
    else
        echo "❌ 密钥不匹配!可能存在中间人攻击"
    fi
done

高级用法

bash 复制代码
# 为特定子网生成 known_hosts 文件
NETWORK="10.0.0"
mkdir -p /tmp/ssh_scan
for octet in {1..50}; do
    ssh-keyscan -T 1 -H "${NETWORK}.${octet}" >> /tmp/ssh_scan/network_hosts 2>/dev/null &
done
wait
echo "收集完成,条目数: $(wc -l < /tmp/ssh_scan/network_hosts)"

# 按密钥类型分类输出
ssh-keyscan -t rsa -H host.example.com > rsa_keys.txt
ssh-keyscan -t ed25519 -H host.example.com > ed25519_keys.txt

# 导出为 SSHFP DNS 记录格式
ssh-keyscan host.example.com | ssh-keygen -r host.example.com

# 扫描域名对应的多个 IP(处理负载均衡)
HOST="cdn.example.com"
for ip in $(dig +short "$HOST"); do
    echo "# IP: $ip"
    ssh-keyscan -T 3 "$ip" 2>/dev/null
done

# 脚本化:检查密钥是否已存在于 known_hosts
check_known_host() {
    local host="$1"
    if ssh-keygen -F "$host" -f ~/.ssh/known_hosts > /dev/null 2>&1; then
        echo "✅ $host 已存在于 known_hosts"
        return 0
    else
        echo "⚠️ $host 未在 known_hosts 中,正在添加..."
        ssh-keyscan -H "$host" >> ~/.ssh/known_hosts 2>/dev/null
        return $?
    fi
}
check_known_host "new-server.local"

安全注意事项

安全警告:

  • ssh-keyscan 不验证主机身份------它只是收集公钥。收到的主机公钥在首次使用时都应通过带外方式(如电话、当面确认)进行验证
  • 始终使用 -H 选项哈希主机名,防止主机名信息泄露
  • 在生产环境中,应使用 SSH CA 证书签名代替手动 known_hosts 管理
  • 定期使用 ssh-keygen -R 清理不再需要的 known_hosts 记录
bash 复制代码
# SSH CA 模式(企业推荐方案,避免手动管理 known_hosts)
# 客户端配置 ~/.ssh/config
cat >> ~/.ssh/config << 'EOF'
Host *.company.com
    CertificateFile ~/.ssh/user_key-cert.pub
EOF

# 这样就不需要逐台收集主机密钥了

ssh-keyscan 是自动化 SSH 部署中的先遣工具。虽然它不验证主机身份,但在可信任的私有网络环境中,它极大地简化了首次 SSH 连接的工作流程。

相关推荐
mgaofeid3 小时前
Ubuntu 24.04 中文输入法安装
linux·运维·ubuntu
xywww1683 小时前
真实后台页实测:Opus 5 看图写前端的可用边界在哪
linux·服务器·前端·数据库·人工智能·gpt
qetfw5 小时前
Debian OpenSSL CA 证书配置参考:根证书、服务证书与验证
linux·debian·ssl·openssl
测试运维日常笔记5 小时前
RHEL/CentOS 离线部署指南:配置本地 ISO 镜像作为 YUM 仓库
linux·运维·centos
梓沂6 小时前
CentOS 7.9 静默安装 Oracle 11gR2 企业版全记录
linux·oracle·centos
蜀道山老天师6 小时前
Zabbix监控Docker容器应用实践完整指南
linux·运维·docker·容器·zabbix
hweiyu006 小时前
Linux命令:info
linux·运维
wsad05326 小时前
CentOS Stream 10 Docker 容器无法访问外网:xt_addrtype 内核模块缺失解决方法
linux·网络·docker·云原生·eureka·centos
x17388062736 小时前
Linux
linux