最近在给一块ARM开发板做远程管理方案,板子上跑的是一套裁剪过的最小化Linux系统,Flash空间只给到8MB,跑OpenSSH实在有点奢侈。折腾了一圈,最后换成了Dropbear,整体体积缩到OpenSSH的五分之一不到,功能却完全够用。这篇文章不打算写成工具手册,而是想把SSH协议本身、Dropbear的设计取舍、以及我在实际部署中踩过的坑串起来讲,希望对正在做嵌入式Linux项目的朋友有参考价值。
1. 为什么嵌入式设备需要一套独立的SSH实现
很多人会有疑问:嵌入式Linux直接用OpenSSH不行吗?x86服务器上能用,ARM板子上理论上也能编译过去。答案是可以,但代价很高。OpenSSH依赖OpenSSL、zlib等一堆库,编译出来的sshd和ssh客户端二进制动辄几百KB,加上依赖库要占掉好几MB的空间。对于Flash只有4MB、8MB的设备来说,这太奢侈了。
Dropbear的出现就是为了解决这个问题。它整个工程代码量在几万行级别,编译后服务端和客户端加起来通常不到500KB,静态链接时也就1MB左右。更关键的是,它刻意减少了对OpenSSL的依赖,很多加密算法直接内置实现,对那些连标准OpenSSL都不想带的系统非常友好。
我之前在一台内核配置了squashfs只读根文件系统的设备上做过对比:一个最小可用的OpenSSH方案(sshd + sftp-server + 依赖库)大约2.4MB,Dropbear的sshd和dbclient加起来大约240KB,差距接近十倍。而实际提供的核心能力——加密远程Shell、公钥登录、端口转发——两边都能完成。
另外还有一个容易被忽略的问题:部署周期。OpenSSH的编译配置比较复杂,选项多,依赖链长,交叉编译时经常会碰到“这个库需要更新版本而系统里没有”的尴尬。Dropbear的configure脚本简单直接,交叉编译的坑很少,这对嵌入式场景特别友好——毕竟不是所有人都愿意为了一个SSH服务折腾三天编译链。
当然,OpenSSH也不是没有优势:它的协议实现更全面,安全的默认配置更严格,管理大量用户时更灵活。但嵌入式设备的核心诉求是“够用且小”,在这条标准下,Dropbear几乎是当前开源社区唯一靠谱的轻量级选择。
提示:如果你的设备Flash空间在16MB以上,且团队已经熟悉OpenSSH的运维习惯,继续用OpenSSH没有原则性问题。但如果你在做极小系统、需要反复精简镜像体积,Dropbear的价值会非常直观。
2. SSH协议握手流程拆解:看轻量级实现如何做到标准兼容
要理解Dropbear为什么能保持小体积还能兼容标准SSH客户端,需要先了解SSH协议的基本工作流程。这里我按我自己的理解做一个拆解,不对的地方欢迎指正。
2.1 传输层协商:从TCP连接到算法协商
SSH协议整体分为三层:传输层、用户认证层、连接层。客户端连接服务端后,首先做的事是传输层协商,也就是确定后续通信使用哪些算法:密钥交换算法、主机密钥类型、加密算法、MAC算法、压缩算法。
这个过程有个专门术语叫算法协商。客户端和服务端各自发送自己支持的算法列表,按偏好顺序排列,然后取交集,选择双方共同支持的第一个算法。这个机制保证了不同实现之间可以互通——只要两边支持同一套标准算法,就能建立连接。
在Dropbear里,默认支持的算法覆盖了SSH协议规范里定义的主流套件:curve25519-sha256、ecdh-sha2-nistp256等密钥交换算法,aes128-ctr、aes256-ctr等加密算法,以及hmac-sha2-256等MAC算法。这些算法足以和Windows下的Bitvise SSH Client、macOS自带的ssh、Linux下的OpenSSH客户端正常互通。
2.2 主机密钥的角色与“首次连接信任”问题
算法协商完成后,服务端要证明自己的身份,这一步靠的是主机密钥(host key)。主机密钥是一对非对称密钥,服务端在启动时加载或自动生成,Dropbear默认使用RSA和ECDSA两种类型(分别存储在/etc/dropbear/dropbear_rsa_host_key和dropbear_ecdsa_host_key)。
你在电脑上第一次连接一台新服务器时,终端会提示“确认主机密钥指纹”,这个指纹就是主机密钥的哈希值。很多刚接触SSH的朋友不理解这个问题的意义:既然已经建立了加密连接,为什么还要确认密钥指纹?因为此时连接刚建立,加密参数已经交换完成,但服务器身份的合法性还没有被验证——攻击者如果提前伪造了主机密钥,就可以实施中间人攻击。
确认指纹本质上是“点对点信任”的终极防线。在嵌入式设备上,工程师第一次通过串口或者本地终端拿到设备的主机密钥指纹后,可以用这个指纹作为后续远程连接的安全锚点。Dropbear也支持通过-y参数打印主机密钥指纹,方便你在初次登录前核对。
2.3 用户认证:先看公钥再看密码
传输层建立完成后,进入用户认证层。SSH支持多种认证方式,最常用的是密码认证和公钥认证。
密码认证很好理解:客户端将用户名和密码通过加密隧道发送给服务端,服务端验证。Dropbear默认允许密码认证,但很多嵌入式安全方案会关闭它,只保留公钥认证——因为设备可能长期暴露在公网,密码爆破是最常见的攻击方式。
公钥认证的逻辑是:客户端持有私钥,服务端保存公钥列表(通常存于用户目录的authorized_keys文件)。认证时,服务端发送一个随机挑战值,客户端用私钥对挑战值签名并返回,服务端用公钥验证签名是否有效。因为私钥从未离开客户端,所以即使有人窃听了整个通信过程,也无法冒充客户端。
Dropbear对公钥认证的支持很完整,标准OpenSSH生成的公钥(ssh-rsa、ssh-ed25519等格式)都能直接使用,不需要转换,这一点在实际运维中非常省事。
2.4 连接层:一条加密隧道里的多路复用
认证通过之后,进入连接层。这个层负责在一个已经加密且认证的通道上维护多个“会话通道(channel)”。比如你用一条SSH连接同时执行命令、传输文件、做端口转发,这三个功能就是三个并行的channel,它们共享底层同一条加密隧道。
理解这一点对排查问题很有帮助。有时候你用SSH命令卡住了,但端口转发还好好的,这往往不是加密链路坏了,而是某个应用层的交互出了问题,或者某个channel的窗口尺寸满了等了一会儿。
Dropbear对连接层的实现是精简的,但基本功能都有:shell会话、exec(远程执行单条命令)、direct-tcpip(正向端口转发)、session-pty(分配伪终端)等。我在实际测试中,用scp协议传输文件时,通过tcpdump抓包观察,可以看到标准的SSH_MSG_CHANNEL_OPEN、SSH_MSG_CHANNEL_DATA等消息,说明协议交互和OpenSSH是同一套标准,不存在兼容性问题。
3. Dropbear交叉编译与busybox集成全流程
如果只是拿现成的开发板系统直接安装Dropbear,体验不到它作为工程项目的便利性。真正的价值在定制系统阶段:把Dropbear编译成目标架构的二进制,并集成进根文件系统。这一节我用比较完整的步骤讲讲怎么做。
3.1 交叉编译环境准备
交叉编译的前提是有一个可用的交叉编译器。假设你的板子是ARM Cortex-A系列,用的工具链是arm-linux-gnueabihf-gcc,那配置命令可以这样写:
./configure --prefix=/usr --host=arm-linux-gnueabihf CC=arm-linux-gnueabihf-gcc有几个配置选项建议关注:
--disable-zlib:如果系统没装zlib,可以禁用,Dropbear即使不用zlib也能工作。但建议默认启用zlib压缩,传输大文件时节省时间的收益很可观。--disable-pam:PAM(可插拔认证模块)在服务器上很常见,但嵌入式系统一般不需要,关闭它减少体积。--enable-static:如果不想动态依赖太多库,可以静态链接,缺点是可执行文件体积会增大。--with-libtomcrypt和--with-libtommath:Dropbear内置了LibTomCrypt和LibTomMath库的副本,默认直接用内置版本,不需要额外安装。
编译安装命令和普通Linux软件没区别:
make -j4 make install DESTDIR=/path/to/rootfs安装产物包括sbin/dropbear、bin/dbclient、usr/bin/dropbearkey、usr/bin/dropbearconvert这几个核心文件。dropbear是服务端,dbclient是客户端,dropbearkey用于生成主机密钥和解析公私钥,dropbearconvert用于导入OpenSSH格式的密钥。
3.2 与busybox的集成方式
嵌入式Linux系统里,busybox几乎是最基本的用户态工具集。它会把一堆命令(ls、cat、sh等)整合到一个二进制文件里,用符号链接的方式区分命令。但busybox的SSH实现(bb_sshd)并不是真正的SSH服务端,它只是提供一个telnetd式的远程Shell入口,并不具备完整的SSH协议和加密能力。所以在嵌入式系统里,常用方案是:busybox提供基础工具和Shell环境,Dropbear提供真正的SSH服务。
集成步骤大概是:
- 把编译好的dropbear相关文件复制到根文件系统的
usr/local/sbin或sbin目录。 - 在
/etc/init.d/下写启动脚本,让系统在启动时自动生成主机密钥(如果不存在)并启动sshd。 - 如果根文件系统是只读的,把密钥和用户数据放到可写的分区(通常是
/var或/data对应的分区)。 - 确保
/etc/passwd里有可登录用户,或者在Dropbear配置中指定允许的登录用户。
一个典型的启动脚本(以sysvinit为例)可能长这样:
#!/bin/sh # Dropbear SSH server init script case "$1" in start) if [ ! -f /var/dropbear/dropbear_rsa_host_key ]; then /usr/local/sbin/dropbearkey -t rsa -f /var/dropbear/dropbear_rsa_host_key fi /usr/local/sbin/dropbear -r /var/dropbear/dropbear_rsa_host_key ;; stop) killall dropbear ;; esac exit 0很多真实项目会把dropbear的密钥目录放到/var/dropbear,因为/var通常是可写的,而根分区可能是只读的。这个细节看着不起眼,实际部署时踩到会很耽误时间。
3.3 编译中可能遇到的问题整理
我把自己遇到过的问题和解决办法列成一个清单,供参考:
| 现象 | 原因 | 处理方法 |
|---|---|---|
| configure检查失败,找不到libtomcrypt | 系统装了旧版libtomcrypt而非内置版本 | 用--with-libtomcrypt指定使用内置版本 |
| 编译后文件体积偏大 | 未使用strip或未裁剪编译选项 | 检查Makefile,去掉调试符号(-g),或用--enable-small |
| dbclient无法连接到服务器 | 目标板缺少/etc/dropbear/dropbear_dss_host_key(旧版需求) | 新版不需要DSS密钥,确认版本 |
| 首次启动生成主机密钥很慢 | 设备熵源不足,/dev/random阻塞 | 配置--enable-random或添加熵源服务 |
| 静态链接后sfp传输失败 | 内存不足导致fork失败 | 减少同时连接数限制,调整内核进程数 |
提示:如果选择的工具链是uclibc或musl libc,而不是glibc,编译参数基本一致,但要注意Dropbear版本对新libc的兼容性。项目上用过musl的buildroot工具链,没有碰到编译错误,但个别版本需要注意
getpwnam等相关行为差异。
3.4 裁剪镜像后的空间收益实测
在我的测试环境上,用arm-linux-gnueabihf工具链,开启--enable-small并strip后,dropbear主程序大约180KB,dropbearkey大约90KB,dbclient大约120KB,三个文件加起来不到400KB。相比OpenSSH系列动辄2MB+的体量,在squashfs根文件系统上可以节省近2MB空间,这对常把Flash余量抠到几十KB的嵌入式工程师来说,差距非常明显。
把dropbear集成进busybox的根文件系统之后,整个系统依然保持“一个小工具集+一个SSH服务”的极简结构,没有引入重量级运行环境,非常适合量产设备的远程维护。
4. 密钥管理与远程登录的现场操作链
编译集成只是第一步,真正的日常工作是密钥管理和远程登录。这一部分我从实际操作角度来讲,包括怎么生成密钥、怎么配置免密码登录、怎么安全地做端口转发,以及一些我踩过坑后的调整。
4.1 密钥生成:选择合适算法
Dropbear的密钥管理和OpenSSH很接近,但命令稍有不同。生成服务端主机密钥时,用dropbearkey:
# 生成RSA主机密钥(2048位) dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key -s 2048 # 生成ECDSA主机密钥 dropbearkey -t ecdsa -f /etc/dropbear/dropbear_ecdsa_host_key -s 256客户端用户的密钥对一般不在设备上生成,而是用自己的电脑生成公钥,再把公钥添加到设备的authorized_keys文件里。常用的命令是:
ssh-keygen -t ed25519 -C "your_email@example.com"把生成的~/.ssh/id_ed25519.pub内容追加到设备上的/home/username/.ssh/authorized_keys,同时注意权限设置——很多朋友在这个地方被卡住:
chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys权限过松,Dropbear会直接拒绝使用这个公钥文件,而且日志里不一定有明显报错,排查起来挺耗时间。
4.2 通过Dropbear的authorized_keys实现免密登录
配置好公钥之后,从电脑端SSH登录设备:
ssh -i ~/.ssh/id_ed25519 user@device_ip -p 2222如果使用Windows,也可以直接用Bitvise SSH Client或者Windows自带的OpenSSH客户端。Bitvise的图形界面适合不习惯命令行的人,但核心认证逻辑一样。
Dropbear还支持在authorized_keys中对公钥加限制选项,比如:
command="/usr/bin/monitor_app",no-port-forwarding,no-agent-forwarding ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...这样即使有人拿到了这个公钥,也只能执行指定的命令,不能获得完整Shell,这对暴露在公网的采集设备很实用。
4.3 实际远程管理:scp文件传输与端口转发
除了远程Shell,scp文件传输是日常维护中最常用的功能。Dropbear服务端默认开启了scp支持,但需要SCP二进制存在于系统中。如果你的设备上没装openssh-sftp-server,scp也能通过scp命令走Dropbear自己的SFTP子系统,不过默认安装时可能没有,需要检查。
直接在电脑上执行:
scp -P 2222 firmware.bin user@device_ip:/tmp/如果在设备端需要传文件到外部服务器,也可以安装dbclient配合ssh-copy-id使用:
dbclient -T user@server_ip端口转发是另一个高频功能。比如把设备的某个本地端口映射到远端服务器,方便在设备外网环境通过服务器中转访问内网服务:
dropbear -R -L 0.0.0.0:8080:localhost:80 user@server_ip这条命令表示在远程服务器上监听8080端口,把流量转发到设备本地的80端口。这对远程调试Web控制台或API服务特别有用。
4.4 限制登录用户与权限收紧
嵌入式设备默认可能只有一个root用户,但为了安全和审计,建议按角色创建独立用户。
- 建立运维用户(例如ops),加入wheel组或admin组。
- 修改Dropbear配置文件(/etc/dropbear/dropbear.conf),限制允许登录的用户:
DROPBEAR_EXTRA_ARGS="-j -k -s -g -p 2222 -I 300"参数说明:
-p 2222:监听端口,避免默认22被扫描。-I 300:空闲超时300秒,防止连接挂死占用资源。-s:禁用密码登录,强制只能公钥认证。-j和-k:分别禁用端口转发和代理转发(如果不需要主动外连)。
只允许wheel组成员远程登录,可以使用PAM或者dropbear的-G选项,不过更稳妥的办法是在启动脚本里检查用户组。比如:
if id -nG "$USER" | grep -qw wheel; then /usr/local/sbin/dropbear -G wheel fi提示:如果设备长期无人值守,建议把监听端口改为非标准(如2222、8022),同时配合防火墙只放行指定IP段,这能显著降低被扫描爆破的风险。
4.5 与VSCode远程开发的无缝对接
现在很多嵌入式工程师习惯在VSCode里远程开发,直接用Remote-SSH插件连接开发板。因为Dropbear完全兼容标准SSH协议,VSCode的Remote-SSH同样可以直接使用。
不过在配置时有两个点比较麻烦:
- VSCode Remote-SSH默认走22端口,如果设备Dropbear监听了别的端口,需要在
~/.ssh/config中显式声明:
Host devboard HostName 192.168.1.100 Port 2222 User root IdentityFile ~/.ssh/id_ed25519- 设备上最好预先装好
sftp-server或者支持SFTP的子系统,否则VSCode的文件浏览功能会失效。Dropbear自带的dropbear可以配合/usr/libexec/sftp-server使用,也可以安装一个轻量的openssh-sftp-server(如果你能接受增加的体积)。
实际用下来,VSCode Remote-SSH连接Dropbear,无论是代码提示、终端操作还是文件同步,体验都和连接OpenSSH服务器差别不大。对“拿开发板当远程开发环境”的人来说,这是一个很实用的组合。
5. 安全加固与常见故障排查的心得
远程管理这件事,功能跑通只是第一步,能不能长时间稳定运行、能不能扛住扫描和攻击,才是真正考验工程经验的地方。这一节把我自己在生产环境里积累的安全配置和排查思路做个总结。
5.1 针对暴力破解的防御策略
Dropbear默认允许密码登录,这就给暴力破解留了门。即使你的密码够复杂,也建议直接关掉密码登录,只留公钥:
dropbear -s如果用-s禁用了密码认证,那么只有持有正确私钥的用户才能登录。这可能是最廉价也最有效的安全策略。
在此基础上还可以做几件事:
- 限制登录次数,通过
-T 5设置最大认证尝试次数,默认是5次,超时断开。 - 用防火墙限制来源IP:
iptables -A INPUT -p tcp --dport 2222 -s 192.168.1.0/24 -j ACCEPT iptables -A INPUT -p tcp --dport 2222 -j DROP- 如果设备能上网,可以考虑部署fail2ban类似的策略,但嵌入式环境资源有限,大部分时候用防火墙就够了。
5.2 网络中断、系统重启与连接卡死的处理
远程管理最怕的就是网络模块不稳定。嵌入式设备通常用Wi-Fi、4G模组或工业以太网,链路质量参差不齐。SSH连接卡死或者断开,不一定都是协议问题,也可能是底层链路的问题。
一个比较有效的做法是启用KeepAlive。在/etc/dropbear/dropbear.conf中设置:
DROPBEAR_EXTRA_ARGS="-K 30"-K 30表示每30秒发送一次keepalive包,让中间设备不会因为空闲而掐断连接。如果网络质量不好,还可以调小间隔,比如-K 10,但需要考虑功耗和带宽的平衡。
另外,建议在客户端配置ServerAliveInterval:
ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=3 user@device_ip这样即使突然断网,客户端也会及时感知,不会一直卡在死连接上。
5.3 常见错误:从“Connection refused”到“No supported authentication methods”
下面这些报错几乎每个玩嵌入式SSH的人都见过,我梳理了一份排查方向,定位时会快很多。
| 报错信息 | 常见原因 | 处理方向 |
|---|---|---|
| Connection refused | SSH服务未启动,或端口错误 | 检查dropbear进程、监听端口、防火墙规则 |
| No route to host | 网络不通 | 先ping设备,再检查路由、Wi-Fi连接 |
| Permission denied | 公钥未正确配置,或密码错误 | 检查authorized_keys权限、目录权限、用户名 |
| No supported authentication methods available | 服务端禁用了密码认证,客户端没有可用密钥 | 用公钥认证方式重新发起连接 |
| Connection reset by peer | 设备内核网络栈异常,或连接被中间设备重置 | 查看dmesg,检查防火墙、TCP keepalive设置 |
还碰到过一种情况:设备断网重连之后,SSH连接一直卡在“getting ready”状态,后来发现是TCP的半开连接没释放。解决办法是设置内核参数:
echo 30 > /proc/sys/net/ipv4/tcp_keepalive_time或者在设备重启后使用ss -s查看连接表,手动清理异常连接。
5.4 Dropbear在NAT网关与远程调试中的特殊配置
很多嵌入式设备部署在NAT后面,没有公网IP。这时候远程管理有两种思路:
- 设备主动建立反向隧道到公网服务器,运维人员通过服务器中转SSH到设备。Dropbear本身就支持反向隧道,和OpenSSH的
-R参数用法一致。 - 设备上跑一个WebSSH服务,运维人员通过浏览器来执行命令。这种场景下Dropbear作为后端SSH服务端配合WebSSH前端使用,也非常常见。
反向隧道的具体做法是在设备执行:
dropbear -R -R 0.0.0.0:2222:localhost:22 user@public_server这样公网服务器的2222端口就会转发到设备本地的22端口(Dropbear监听端口),运维人员只要登录公网服务器再SSH到localhost:2222即可。
如果怕反向隧道进程意外退出,可以用一个简单的重启脚本来守护,比如用cron每分钟检查一次进程,不存在就重启。实际项目中加了一个如下守护脚本:
#!/bin/sh if ! pgrep -f "dropbear -R" > /dev/null; then nohup dropbear -R -R 0.0.0.0:2222:localhost:22 user@public_server > /dev/null 2>&1 & fi5.5 设备空间不足时的日志清理策略
嵌入式设备的日志存储空间非常有限,SSH登录日志、dropbear自身日志如果一直在写,很快会把/var/log塞满。建议做两件事:
- 在dropbear的配置里显式指定日志级别:
DROPBEAR_EXTRA_ARGS="-j -k -s -g -p 2222 -I 300 -v 0"-v 0表示最少的verbose输出,只有严重错误才记录。
- 在系统的logrotate配置里增加dropbear日志轮转,定期清理:
/path/to/log/dropbear.log { weekly rotate 2 compress missingok notifempty }如果系统里没有logrotate,那就写一个简单的cron清理脚本,每天清一次日志大小:
if [ $(stat -c%s /var/log/dropbear.log) -gt 1048576 ]; then > /var/log/dropbear.log fi这些看着都是小事,但批量部署设备后,日志爆盘导致系统卡死的案例真不少。
6. 进一步优化的方向
Dropbear作为一个轻量级SSH实现,虽然已经很精简,但如果你对体积、性能或功能有更高要求,还有几个可以玩的方向。
6.1 二次裁剪与内核自带的CONFIG_KEYS
如果你的系统采用静态链接,可以尝试在编译时去掉不必要的算法支持,比如不需要DSS算法就取消定义,不需要旧版SSH1兼容代码也可以裁剪。Dropbear的源码里有很多#ifdef宏,可以通过修改localoptions.h来做精细化配置。
比如,如果想彻底去掉DSS公钥算法支持,可以在localoptions.h里设置:
#define DROPBEAR_DSS 0如果不需要旧版本的ssh-rsa签名算法,也可以做类似裁剪。每次裁剪后别忘了用make clean后重新编译,并做基本功能回归测试。
6.2 与TFTP、串口等传统方式的搭配
嵌入式设备不一定总是有网络。很多设备还保留了串口或TFTP作为兜底恢复手段。Dropbear并不能替代这些,但在实际运维流程中通常会和它们配合:
- 普通远程维护:SSH(Dropbear)为主,TCP端口转发辅助。
- 紧急恢复:串口+TFTP,或者U-Boot的netboot功能。
- 批量升级:通过脚本调用scp/sftp批量推送固件,再触发升级逻辑。
我见过不少成熟产品采用“双通道”设计:正常情况走Dropbear远程管理,系统异常时通过串口或USB RNDIS网络接口提供调试通道。两条路都通畅,产品在客户现场的存活率才会高。
6.3 在Docker容器或虚拟化环境里的使用
如果你在开发阶段不想直接刷机,可以在PC的Docker容器里先跑一个Dropbear,模拟目标环境做脚本验证。Dockerfile里几行就能搞定:
FROM alpine:latest RUN apk add --no-cache dropbear EXPOSE 2222 CMD ["/usr/sbin/dropbear", "-F", "-E", "-p", "2222"]这样可以在容器里测试公钥登录、端口转发、scp传输等流程,验证没问题后再部署到目标板,能省下不少刷机调试的时间。
我在实际项目里习惯先用Docker做一次“预验证”,再烧录到板子上跑真实测试,暴露的问题往往集中在文件系统权限、网络驱动等容器里测不到的部分,但至少协议和脚本层面的坑先在容器里排掉一批。
7. 关于Dropbear的常见困惑与我的理解
关于Dropbear,网上的讨论和提问不少,我挑几个高频问题,结合我的经验谈一些看法。
7.1 Dropbear和OpenSSH能混用吗?
可以。SSH是标准协议,理论上任何两端只要实现一致,就能互通。Dropbear作为服务端,OpenSSH作为客户端连接完全没问题;反过来,OpenSSH服务端也可以接受Dropbear客户端的连接。实现上的差异体现在细节,比如Dropbear默认不支持sftp子系统,但可以通过添加/usr/libexec/sftp-server来弥补;OpenSSH默认支持更多算法,但这也带来更大的攻击面和依赖面。
如果项目里既有大量x86服务器也有嵌入式设备,统一用OpenSSH做服务端、Dropbear做设备端,是一个比较务实的组合。
7.2 Dropbear为什么支持DSA/DSS密钥,但OpenSSH新版本默认禁用了?
DSA算法本身已经算老旧,很多安全规范建议停止使用。OpenSSH在高版本里默认拒绝DSA主机密钥,但Dropbear为了兼容老设备,仍保留了对DSS的支持。在实际部署中,不建议再生成DSS密钥,统一用RSA 2048或Ed25519更稳妥。
7.3 Dropbear的dbclient真的好用吗?
说实话,dbclient的体验和OpenSSH客户端还有差距,尤其在密钥管理、配置文件和选项丰富度上。我一般只在设备端主动向外连接时用dbclient,平时电脑上一个常规的SSH客户端就够用了。如果你习惯用Bitvise SSH Client这种图形化工具,在电脑端连接Dropbear设备完全没问题。
7.4 如何从OpenSSH的authorized_keys迁移到Dropbear?
基本不需要迁移,格式几乎一样。Dropbear支持加载OpenSSH格式的公钥,只要把~/.ssh/authorized_keys文件放到相应位置并设置好权限即可。如果你有OpenSSH的私钥想转换成Dropbear格式,可以用dropbearconvert:
dropbearconvert openssh dropbear ~/.ssh/id_rsa /etc/dropbear/dropbear_rsa_host_key不过一般情况下,直接用Dropbear自带的dropbearkey生成新的主机密钥更简单省事,客户端公钥根本不需要转换。
8. 部署Dropbear时我的一次完整复盘
最后,分享一次我在真实项目中部署Dropbear的完整过程,包括环境、问题、调整,希望给出一个更具体的参考样本。
那是一个工业数据采集项目,主控板为ARM Cortex-A7,Flash 4GB eMMC(实际运行分区只有几百MB),系统为Yocto构建的最小化Linux,内核5.10。板子平时在车间运行,偶尔需要远程排查设备数据不上报的问题。
需求很简单:远程能登录Shell、能抓取日志、能临时修改配置,最好还能在出差时随时通过公网服务器中转访问。
部署流程大致是:
- 在Yocto的recipe里加入dropbear,版本选最新稳定版。配置项打开
-s(禁用密码登录),监听端口设为8022。 - 编译后把dropbear加进rootfs,修改init脚本做主机密钥的首次生成和挂载目录准备。
- 把运维工程师的ed25519公钥写入设备的/tmp/ops/.ssh/authorized_keys。
- 测试本地SSH登录、scp传文件、端口转发。
- 配置反向隧道到云端跳板机,用cron做守护。
遇到的问题有三个:
第一个是首次启动时主机密钥生成卡了大约30秒。查日志发现/dev/random熵源不足,改为用--enable-random(该选项从系统熵池读取随机数)并预先用seed文件填充,启动时间降到1秒以内。
第二个是scp无法传输文件。排查后发现是rootfs缺少/usr/bin/scp,而Dropbear的scp依赖这个外部程序。解决方案是在busybox里启用scp applet,或者单独安装dropbear自带的scp兼容程序。最终选择在busybox配置中启用scp,体积增加有限。
第三个是反向隧道不稳定,运行几个小时后偶发断开。排查后确定是公网服务器SSH的空闲超时以及设备网络抖动导致,最后配合-K 30keepalive参数和cron守护脚本,就稳定了。
整套方案上线后,运维再没为远程登录浪费时间。哪怕设备在工厂内网环境,只要它能主动访问公网服务器,运维就能通过跳板机和反向隧道进入设备,效率提升非常明显。
对我个人来说,Dropbear最有魅力的地方,不是它比OpenSSH小几兆,而是它把“在资源受限环境里提供核心能力”这件事做到了极致。如果你正在设计需要远程管理能力的嵌入式设备,我建议别急着堆功能,先用一套轻量的SSH方案跑通主流程,再逐步加安全策略。这个思路在后续的产品维护里,会帮你省下大量时间。