Dropbear SSH 完全指南 / 05 - 认证方式
第五章:认证方式
5.1 Dropbear 支持的认证方式
Dropbear 支持 SSH-2 协议定义的多种认证方式。以下是 Dropbear 支持的认证方式总览:
| 认证方式 | 服务端支持 | 客户端支持 | 安全性 | 推荐度 |
|---|---|---|---|---|
| 密码认证 (Password) | ✅ | ✅ | ★★☆☆☆ | ⚠️ 配合强密码 |
| 公钥认证 (Public Key) | ✅ | ✅ | ★★★★★ | ✅ 首选 |
| 公钥+密码 (多因素) | ⚠️ 部分 | N/A | ★★★★★ | ✅ 高安全 |
| Keyboard-Interactive | ❌ | ✅ (客户端) | ★★★☆☆ | — |
| Hostbased | ❌ | ❌ | ★★★☆☆ | — |
| Kerberos/GSSAPI | ❌ | ❌ | ★★★★☆ | — |
| PAM | ❌ | N/A | ★★★★☆ | — |
注意: Dropbear 不支持 PAM、Kerberos 和 Keyboard-Interactive 认证方式。如果需要这些,请使用 OpenSSH。
5.2 密码认证
基本原理
客户端 服务器
│ │
│──── SSH_USERAUTH_REQUEST ─────────▶│
│ method: password │
│ user: admin │
│ password: ****** │
│ │
│ 服务器验证 /etc/shadow │
│ │
│◀─── SSH_USERAUTH_SUCCESS ─────────│
配置密码认证
# 启用密码认证(默认)
dropbear
# 禁用密码认证
dropbear -s
# 或
dropbear -g # 服务端专用,优先级更高
# 允许空密码登录(极不推荐)
dropbear -B
密码认证安全考量
风险因素:
┌─────────────────────────────────────────────┐
│ 暴力破解 ──▶ 强密码策略 + fail2ban │
│ 中间人攻击 ──▶ 配合主机密钥验证 │
│ 密码泄露 ──▶ 定期更换 + 公钥认证替代 │
│ 嗅探攻击 ──▶ SSH 已加密,风险较低 │
└─────────────────────────────────────────────┘
与系统密码集成
Dropbear 直接读取 /etc/shadow 文件验证密码,不经过 PAM:
# 确保 shadow 文件可读(通常由 setuid 处理)
ls -la /etc/shadow
# -rw-r----- 1 root shadow 1234 ... /etc/shadow
# 设置用户密码
passwd admin
# 验证密码是否已设置
passwd -S admin
# admin P 2026-05-10 0 99999 7 -1
加固密码认证
# 使用 fail2ban 防御暴力破解
# /etc/fail2ban/jail.d/dropbear.conf
[dropbear]
enabled = true
port = ssh
filter = dropbear
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
# fail2ban filter: /etc/fail2ban/filter.d/dropbear.conf
[Definition]
failregex = ^.*dropbear\[.*\]:.*Login attempt for nonexistent user from <HOST>.*$
^.*dropbear\[.*\]:.*Bad password attempt for .* from <HOST>.*$
^.*dropbear\[.*\]:.*Exit before auth \(user '.+', \d+ tries\): .+ from <HOST>.*$
ignoreregex =
5.3 公钥认证
公钥认证是 SSH 最安全的认证方式,也是推荐的方式。
基本原理
客户端 服务器
│ │
│──── SSH_USERAUTH_REQUEST ──────────────▶│
│ method: publickey │
│ algorithm: ssh-ed25519 │
│ pubkey: AAAAC3NzaC1lZDI1NTE5... │
│ │
│◀─── SSH_USERAUTH_PK_OK ───────────────│ ← 服务器确认拥有此公钥
│ │
│──── SSH_USERAUTH_REQUEST ──────────────▶│
│ method: publickey │
│ signature: (用私钥签名的数据) │
│ │
│ 服务器用公钥验证签名 │
│ 服务器检查 authorized_keys │
│ │
│◀─── SSH_USERAUTH_SUCCESS ──────────────│
服务端配置
# 公钥认证默认启用
dropbear
# 仅公钥认证(推荐)
dropbear -s
客户端配置
# 使用指定私钥
dbclient -i ~/.ssh/id_ed25519 user@server
# 使用 Dropbear 格式密钥
dbclient -i ~/.ssh/id_dropbear user@server
# 使用多个密钥(尝试多个)
dbclient -i ~/.ssh/id_ed25519 -i ~/.ssh/id_rsa user@server
公钥认证自动化脚本
#!/bin/bash
# setup_pubkey_auth.sh - 为嵌入式设备配置公钥认证
DEVICE_IP="$1"
DEVICE_USER="${2:-root}"
PUBKEY_FILE="$HOME/.ssh/id_ed25519.pub"
if [ -z "$DEVICE_IP" ]; then
echo "用法: $0 <设备IP> [用户名]"
exit 1
fi
# 检查公钥文件
if [ ! -f "$PUBKEY_FILE" ]; then
echo "公钥文件不存在: $PUBKEY_FILE"
echo "请先生成密钥: ssh-keygen -t ed25519"
exit 1
fi
# 读取公钥
PUBKEY=$(cat "$PUBKEY_FILE")
echo "正在为 $DEVICE_USER@$DEVICE_IP 配置公钥认证..."
# 通过密码登录将公钥添加到设备
sshpass -p "$(read -sp '请输入设备密码: ' pw; echo $pw)" \
ssh -o StrictHostKeyChecking=no "$DEVICE_USER@$DEVICE_IP" "
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo '$PUBKEY' >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
echo '公钥已添加'
"
echo "配置完成,现在可以使用公钥登录:"
echo " dbclient $DEVICE_USER@$DEVICE_IP"
5.4 多因素认证
方案一:受限 authorized_keys + 密码
虽然 Dropbear 不直接支持 PAM 多因素认证,但可以通过 command 选项实现伪多因素:
# ~/.ssh/authorized_keys
# 公钥认证通过后,强制执行交互式验证脚本
command="/usr/local/bin/mfa-verify.sh" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...
#!/bin/sh
# /usr/local/bin/mfa-verify.sh - 第二因素验证脚本
# 要求输入 TOTP 验证码
echo -n "请输入 TOTP 验证码: "
read -r code
# 验证 TOTP(需要 oathtool)
if oathtool --totp -b "YOUR_BASE32_SECRET" -- "$code" 2>/dev/null | \
grep -q "^${code}$"; then
# 验证通过,启动 shell
exec /bin/sh -l
else
echo "验证失败"
exit 1
fi
方案二:链式认证(两台不同服务器)
用户 → 第一台服务器(公钥认证) → 第二台服务器(密码认证) → 目标设备
# 使用 ProxyCommand 实现链式认证
dbclient -o "ProxyCommand dbclient -i ~/.ssh/id_ed25519 jumphost nc %h %p" user@target
方案三:基于时间的一次性密码 (TOTP)
#!/bin/sh
# /usr/local/bin/totp-shell.sh - TOTP 认证 Shell
TOTP_SECRET="JBSWY3DPEHPK3PXP" # Base32 编码的密钥
MAX_ATTEMPTS=3
attempt=0
while [ $attempt -lt $MAX_ATTEMPTS ]; do
printf "TOTP 验证码: "
read -r code
expected=$(oathtool --totp -b "$TOTP_SECRET" 2>/dev/null)
if [ "$code" = "$expected" ]; then
echo "认证成功"
exec /bin/sh -l
fi
attempt=$((attempt + 1))
echo "验证失败 ($attempt/$MAX_ATTEMPTS)"
done
echo "超过最大尝试次数"
exit 1
5.5 Agent 转发(Agent Forwarding)
SSH Agent 转发允许通过跳板机(Bastion Host)访问目标服务器,而私钥始终保存在本地。
工作原理
本地机器 跳板机 目标服务器
┌──────────┐ ┌──────────┐ ┌──────────┐
│ ssh-agent│◄────────│ Agent │ │ │
│ (私钥) │ Socket │ Forward │──────▶ │ 验证签名 │
│ │ 转发 │ │ │ │
└──────────┘ └──────────┘ └──────────┘
dbclient -A dbclient authorized_keys
跳板机 目标服务器 检查公钥
配置 Agent 转发
# 服务端启用 Agent 转发(默认启用,编译选项控制)
# localoptions.h:
# #define DROPBEAR_SVR_AGENTFWD 1
# 客户端启用 Agent 转发
dbclient -A user@jumphost
# 或在配置中设置
# ~/.ssh/config
Host jumphost
ForwardAgent yes
使用 ssh-agent
# 启动 ssh-agent
eval $(ssh-agent)
# 输出: Agent pid 1234
# 添加私钥到 agent
ssh-add ~/.ssh/id_ed25519
# 查看已加载的密钥
ssh-add -l
# 256 SHA256:xR3bP7kF9v2mL5nQ4wJ8hT6yU1iO3pA5sD7fG9hJ admin@host (ED25519)
# 通过跳板机连接
dbclient -A admin@jumphost
# 在跳板机上,可以直接连接目标服务器
dbclient admin@target-server
Agent 转发安全警告
安全风险: Agent 转发意味着跳板机的 root 用户可以冒充你的身份连接到任何你有密钥的服务器。仅在信任跳板机时使用。
风险缓解措施:
┌─────────────────────────────────────────────────┐
│ ✅ 仅在完全信任的跳板机上使用 │
│ ✅ 使用 -o "AddKeysToAgent confirm" 确认每次使用 │
│ ✅ 在跳板机上限制文件权限 │
│ ❌ 不要在公共/共享跳板机上使用 │
│ ❌ 不要在多租户环境中使用 │
└─────────────────────────────────────────────────┘
替代方案:ProxyJump
比 Agent 转发更安全的替代方案:
# 使用 ProxyJump(-J)通过跳板机连接
dbclient -J admin@jumphost admin@target-server
# 等效于 ProxyCommand
dbclient -o "ProxyCommand dbclient -W %h:%p admin@jumphost" admin@target-server
ProxyJump 的优势:
- 私钥不离开本地
- 不需要在跳板机上存储或转发密钥
- 加密流量端到端传输
5.6 认证日志与审计
查看认证日志
# Debian/Ubuntu
grep "dropbear" /var/log/auth.log
# CentOS/RHEL
grep "dropbear" /var/log/secure
# systemd
journalctl -u dropbear --since "1 hour ago"
# 实时监控
tail -f /var/log/auth.log | grep dropbear
日志事件类型
| 事件 | 日志示例 | 说明 |
|---|---|---|
| 连接建立 | Login attempt for user 'admin' from 192.168.1.50:54321 | 新连接 |
| 密码成功 | Password auth succeeded for 'admin' | 密码认证通过 |
| 密码失败 | Bad password attempt for 'admin' | 密码错误 |
| 公钥成功 | Pubkey auth succeeded for 'admin' with key ssh-ed25519 | 公钥认证通过 |
| 用户不存在 | Login attempt for nonexistent user 'test' | 用户名错误 |
| 连接断开 | Exit (admin): Disconnect received | 正常断开 |
| 超时 | Exit before auth: Timeout | 认证超时 |
认证监控脚本
#!/bin/sh
# monitor_auth.sh - Dropbear 认证监控
LOG_FILE="/var/log/auth.log"
ALERT_EMAIL="admin@example.com"
FAILED_THRESHOLD=5
echo "=== Dropbear 认证监控 ==="
echo "时间: $(date)"
echo ""
# 统计最近 1 小时的认证事件
echo "最近 1 小时认证统计:"
echo " 密码成功: $(grep -c 'Password auth succeeded' "$LOG_FILE" 2>/dev/null || echo 0)"
echo " 公钥成功: $(grep -c 'Pubkey auth succeeded' "$LOG_FILE" 2>/dev/null || echo 0)"
echo " 认证失败: $(grep -c 'Bad password\|nonexistent user' "$LOG_FILE" 2>/dev/null || echo 0)"
# 检测暴力破解
echo ""
echo "潜在暴力破解 IP:"
grep 'Bad password\|nonexistent user' "$LOG_FILE" 2>/dev/null | \
grep -oP '\d+\.\d+\.\d+\.\d+' | sort | uniq -c | sort -rn | head -10
# 告警
FAILED_COUNT=$(grep -c 'Bad password\|nonexistent user' "$LOG_FILE" 2>/dev/null || echo 0)
if [ "$FAILED_COUNT" -gt "$FAILED_THRESHOLD" ]; then
echo "⚠️ 警告: 检测到大量认证失败 ($FAILED_COUNT 次)"
fi
5.7 认证安全最佳实践
认证策略矩阵
| 安全级别 | 密码认证 | 公钥认证 | Agent 转发 | 适用场景 |
|---|---|---|---|---|
| 最低 | ✅ | ❌ | ✅ | 开发测试 |
| 低 | ✅ | ✅ | ✅ | 内网环境 |
| 中 | ❌ | ✅ | ❌ | 生产环境 |
| 高 | ❌ | ✅ | ❌ + fail2ban | 高安全要求 |
| 最高 | ❌ | ✅ + IP 白名单 | ❌ | 关键基础设施 |
综合加固方案
# 1. 禁用密码认证
dropbear -s -w
# 2. 仅监听内网
dropbear -p 10.0.0.1:22
# 3. 限制超时
dropbear -T 60 -I 300 -K 60
# 4. 完整启动命令
dropbear -s -w -F -E -R \
-p 10.0.0.1:22 \
-T 60 -I 300 -K 60 \
-P /var/run/dropbear.pid
5.8 本章小结
| 要点 | 说明 |
|---|---|
| 密码认证 | 默认启用,配合 fail2ban 使用 |
| 公钥认证 | 推荐方式,-s 强制仅公钥 |
| 多因素 | 通过 command 选项模拟 |
| Agent 转发 | 方便但有安全风险,推荐 ProxyJump 替代 |
| 认证监控 | 通过日志分析检测异常登录 |