嵌入式Linux下的Dropbear轻量级SSH:从原理到安全实践

发布时间:2026/9/6 9:42:36
嵌入式Linux下的Dropbear轻量级SSH:从原理到安全实践 1. 为什么嵌入式设备需要 Dropbear 这样的轻量级 SSH先从一个很现实的场景说起。我手上有一块跑 Linux 的开发板CPU 主频不到 800MHz内存只有 128MBFlash 存储 256MB。系统跑起来之后可用内存已经所剩无几。我想远程登录它做维护第一反应是装一个 OpenSSH。结果编译完一放进去光是二进制文件就占了几 MB运行时还要额外吃掉十几 MB 内存这对嵌入式设备来说有点奢侈。这时候 Dropbear 的价值就体现出来了。它是一款专门为嵌入式 Linux 和资源受限环境设计的轻量级 SSH 服务端和客户端实现二进制体积通常只有几百 KB运行时内存占用也能控制在个位数 MB 级别。我实际测过一块板子Dropbear 跑起来后常驻内存大概 3MB 到 5MB这个开销对绝大多数嵌入式系统来说是可以接受的。很多人会把 SSH 当成一个装上就能用的工具但真正做嵌入式开发时你会发现事情没有那么简单。设备可能没有屏幕、没有键盘唯一的维护通道就是网络。而网络环境又可能是内网、跨网段、甚至需要通过串口先做一次引导。Dropbear 在这种场景下几乎是标配它解决的问题很朴素让我在资源有限的前提下依然能获得一个安全、可靠的远程管理通道。这篇文章不打算只讲怎么编译安装那太浪费了。我会从 SSH 协议的基本原理讲起再深入到 Dropbear 的移植、配置、密钥管理、安全加固最后聊聊我在实际项目中踩过的坑和排查思路。这样无论是刚接触嵌入式 Linux 的新手还是已经在做维护的老手都能从里面拿到一些能直接用的东西。2. SSH 协议原理一次安全的远程登录到底发生了什么要理解 Dropbear 为什么是现在这个设计得先搞明白 SSH 协议本身在做什么。SSH全称 Secure Shell它解决的核心问题有三个加密、认证、完整性。打个比方。你在公司工位上想远程操作家里的一台电脑。如果你直接通过明文 Telnet 连过去中间任何一台路由器、交换机都能看到你敲的每一个字符包括密码。这就相当于你把家门钥匙的照片发在了公开朋友圈里门锁形同虚设。SSH 做的事情就是在这条不可信的网络链路上先建立一条加密隧道然后再在这条隧道里传数据。SSH 协议的工作流程大体可以分为三个阶段。第一阶段是传输层握手。客户端连上服务端的 22 端口后双方交换版本信息、协商加密算法和密钥交换算法。这一阶段最重要的成果是生成一个对称加密的会话密钥。为什么要用对称加密因为非对称加密计算量太大不适合传输大量数据。常见的做法是用 ECDH 或 DH 算法做密钥交换双方各自生成一个临时密钥对通过数学运算得到一个共享的秘密值这个秘密值只有双方知道即使中间人截获了交换过程中的所有报文也无法反推出这个共享密钥。第二阶段是用户认证。这一阶段用的还是非对称加密。客户端持有私钥服务端持有对应的公钥。客户端用私钥对一段随机挑战数据进行签名服务端用公钥验签验签通过就认为客户端身份可信。这个过程可以看成是你带着身份证去银行办业务柜员核验你的身份后才允许你操作账户。第三阶段是连接协议。认证通过后客户端可以请求建立多个通道比如 shell 通道、端口转发通道、文件传输通道。每个通道有独立的编号数据在加密隧道里被封装成一个个包按通道号分发。这也是为什么 SSH 可以同时支持远程命令行、SFTP 文件传输、X11 转发等多种功能。Dropbear 在实现上并没有像 OpenSSH 那样把协议栈做得非常庞大而是只保留了最核心的部分。它支持 SSH-2 协议支持 RSA、ECDSA、Ed25519 等密钥算法支持密码认证和公钥认证支持端口转发。但对一些不那么常用的功能比如 Kerberos 认证、GSSAPI、以及 SSH-1 协议支持它就直接砍掉了。这种取舍在嵌入式场景下非常明智因为你不可能在一个 128MB 内存的设备上跑一个为服务器设计的重量级软件。还有一个很关键的细节Dropbear 的密钥交换和加密算法选型主要倾向于计算开销较小的曲线密码学算法。例如 ECDH 和 curve25519。原因很简单嵌入式 CPU 通常没有 AES-NI 之类的硬件加速指令也没有大整数运算加速单元。如果选用 RSA 2048 做密钥交换一次握手可能耗时几百毫秒甚至更久。而 curve25519 的计算量小得多握手延迟可以控制在几十毫秒级别。这一点在低主频设备上差异非常明显。理解了协议原理再看 Dropbear 的代码结构会清晰很多。它的事件循环、缓冲管理、通道管理都是为了在单线程模型下高效处理多个并发连接而设计的。相比 OpenSSH 那种多进程模型Dropbear 在内存占用和启动延迟上都有明显优势。当然多进程模型有更好的隔离性一个会话崩溃不会影响其他会话但嵌入式场景通常不会同时有几十个活跃 SSH 会话Dropbear 的取舍是合理的。3. 编译与移植从源码到开发板完整操作记录3.1 获取源码与编译选项Dropbear 的源码托管在 GitHub 上官方发布版本也会打包成 tar 包。建议使用稳定版本不要追最新 commit因为有些开发分支的代码可能在特定架构上存在问题。下载解压后进入源码目录首先要做的是配置。Dropbear 使用 autoconf 体系常见的配置方式是./configure --prefix/usr --hostarm-linux-gnueabihf CCarm-linux-gnueabihf-gcc如果你的交叉编译器前缀不同比如是 aarch64-linux-gnu-就把 --host 和 CC 换成对应的即可。configure 脚本会检测目标平台的特性比如是否支持 ptrace、是否有 /dev/urandom、字节序是什么然后生成对应的 config.h。这里有几个比较重要的编译选项值得关注。第一个是静态编译。嵌入式设备上目标文件系统的动态库可能不完整为了避免运行时出现 libc.so.6 not found 这类问题建议直接静态编译./configure --prefix/usr --hostarm-linux-gnueabihf CCarm-linux-gnueabihf-gcc LDFLAGS-static静态编译的代价是二进制文件体积会变大因为 libc 的代码被打进去了。但在资源紧张、依赖不确定的嵌入式环境里这个代价是值得的。我实测过静态编译的 dropbear 主程序大概 700KB 左右dropbearkey 大概 500KBdropbearclient 大概 600KB加起来不到 2MB。如果用 musl libc 做静态编译体积还能再小一些。第二个是裁剪特性。Dropbear 提供了一些 configure 开关可以按需裁剪功能./configure --disable-zlib --disable-pam如果你不需要压缩功能就禁用 zlib能省不少代码。PAM可插拔认证模块在嵌入式系统里通常用不到也建议禁用。还有 --disable-lastlog、--disable-utmp、--disable-wtmp 这些开关如果你的系统没有对应的日志机制禁用后可以避免编译错误也能减小体积。第三个是配置安装路径。嵌入式系统通常没有完整的目录结构我一般会把 Dropbear 的二进制安装到一个独立目录然后打包进 rootfsmake PROGRAMSdropbear dropbearkey dropbearclient make install DESTDIR/path/to/rootfs注意如果你想同时编译客户端工具必须显式指定 PROGRAMS默认情况下 make 只会编译服务端和密钥工具。3.2 最小文件系统集成编译完成后要在嵌入式系统里跑起来需要做几件事。第一创建运行时目录。Dropbear 需要 /etc/dropbear 目录存放密钥文件需要 /var/run 目录存放 pid 文件和 socket 文件。如果系统重启后是只读根文件系统记得把 /var/run 做成 tmpfs否则进程启动时会报错。第二生成主机密钥。这一步通常在系统首次启动时自动完成也可以在打包 rootfs 时预先生成。推荐预生成因为这样所有设备的公钥指纹是固定的方便后续做主机信任管理。生成命令dropbearkey -t ed25519 -f /etc/dropbear/dropbear_ed25519_host_key dropbearkey -t ecdsa -f /etc/dropbear/dropbear_ecdsa_host_key dropbearkey -t rsa -s 2048 -f /etc/dropbear/dropbear_rsa_host_key关于密钥算法我的经验是优先使用 ed25519其次是 ecdsa尤其是 prime256v1最后才考虑 rsa。原因有两方面一是长密钥的 rsa 在低端设备上生成和签名都更耗 CPU二是 ed25519 的签名短、计算快安全性也满足要求。但要注意一些老的 SSH 客户端可能不支持 ed25519如果你的维护终端比较老旧那就保留 rsa 2048 作为兜底。第三如果使用 busybox 作为 init 系统可以在 inittab 里加入 dropbear 启动项或者在 rcS 脚本里显式调用/usr/sbin/dropbear -R -p 22-R 参数表示如果主机密钥不存在则自动生成。首次启动时这个参数很有用。但如果预生成了密钥就不需要 -R 了。第四如果设备有防火墙或者使用定制网络策略需要确保 TCP 22 端口或你指定的其他端口可以访问。很多嵌入式系统没有 iptables 规则默认放行所有流量但如果你用了一些商业路由器固件可能有默认的安全策略这一点要格外注意。3.3 与 busybox 集成说到嵌入式 Linuxbusybox 几乎是绕不开的。它提供了一套精简的 shell 和常用命令但 busybox 本身不包含 SSH 服务端。有些发行版会在 busybox 里集成一个残缺的 SSH 客户端但我个人建议不要依赖它因为功能太弱不支持密钥文件指定、不支持端口转发等高级特性排查问题时会很痛苦。正确的做法是busybox 负责基础命令Dropbear 负责 SSH 服务端和客户端两者各司其职。在 rootfs 打包脚本里把 dropbear 的二进制放到 /usr/sbin 或 /usr/bin然后创建一个软链接比如ln -s /usr/sbin/dropbear /usr/bin/dbclientdbclient 是 Dropbear 自带的 SSH 客户端用法和 OpenSSH 的 ssh 类似但参数略有差异。习惯 OpenSSH 的朋友可能会不太适应。更推荐的方案是在嵌入式系统里同时保留 OpenSSH 的 sftp-server 或 scp 兼容工具配合 Dropbear 使用。Dropbear 本身不提供 SFTP 服务但它支持通过子系统机制调用外部的 sftp-server 程序。如果你的 rootfs 里已经有 openssh-sftp-server可以在启动 dropbear 时加上 -s 参数并配置子系统路径。我在实际项目里一般这样组合开发板运行 Dropbear 作为服务端宿主机上安装 OpenSSH 客户端几乎所有 Linux 发行版和 Windows 10 以上系统都自带。这样平时从宿主机连板子用 scp 或者 rsync 传文件都能正常工作。4. 配置与密钥管理从账号认证到免密登录4.1 基本认证方式Dropbear 支持两种认证方式密码认证和公钥认证。密码认证是默认开启的配置上很省事但安全性相对弱一些。如果你的设备暴露在公网密码认证很容易被暴力破解。嵌入式设备通常没有 fail2ban 之类的防护工具所以我建议在非必要情况下关闭密码认证。公钥认证是更安全的方式。流程是这样的客户端生成一对密钥把公钥放到服务端的 authorized_keys 文件里。连接时客户端用私钥签名服务端用公钥验签。私钥不出客户端网络传输的只是签名结果所以即使网络被监听也不会泄露私钥。配置公钥认证时注意文件权限。authorized_keys 文件位于目标用户的 ~/.ssh 目录下权限不能太宽松。一般要求chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys如果权限过大部分 SSH 实现会直接拒绝读取。Dropbear 在这点上和 OpenSSH 行为一致。4.2 让密钥登录和 root 登录按需配置嵌入式开发中我遇到过不少需求比如设置只有 wheel 组的用户可以 SSH 远程登录或取消 root 用户的 SSH 登录限制。这几点顺着说一下。第一个限制特定用户组才能登录。Dropbear 本身不直接支持组过滤但可以通过 PAM 或者系统层的访问控制来实现。如果你编译时启用了 PAM可以在 /etc/pam.d/dropbear 里配置 pam_wheel 模块只允许 wheel 组的成员通过认证。如果没有 PAM也可以修改 /etc/security/access.conf或者用以下方式在 /etc/ssh/sshd_config 类似的配置里Dropbear 没有原生的 AllowGroups 指令但你可以利用系统用户权限配合 shell 环境中的检测脚本实现过滤。更简单粗暴的方式是在 inittab 或启动脚本里控制只启动一个受限的登录环境。第二种情况取消 root 用户 SSH 登录限制。很多人会碰到 root 用户使用公钥登录失败而普通用户却正常的情况。原因往往是 Dropbear 默认不允许空密码登录或者 /etc/dropbear/authorized_keys 路径不对。针对 root 用户的 authorized_keys如果使用 SSH 2 协议默认路径是 /root/.ssh/authorized_keys。但有些发行版为了方便把 Dropbear 的 authorized_keys 路径设置成了 /etc/dropbear/authorized_keys此时你需要根据启动参数中的 -A 或系统配置来调整。我的习惯是确认目标用户的 home 目录有 .ssh 目录和正确的 authorized_keys 文件然后启动 dropbear 时不要加任何限制参数。默认情况下root 用户的公钥认证是可以正常工作的只要密钥文件权限正确。第三种情况免密登录。这是嵌入式开发里最实用的功能。我在调试阶段经常要同时操作几十台设备一台一台输密码会疯掉的。配置免密登录的步骤如下在宿主机生成密钥对如果还没有的话ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519将公钥复制到所有目标设备的 /root/.ssh/authorized_keysssh-copy-id -i ~/.ssh/id_ed25519.pub root设备IP或者手动追加用脚本批量处理也可以。测试连接ssh -i ~/.ssh/id_ed25519 root设备IP需要注意的是如果您在 Windows 上使用 Terminal 或 PowerShell 内置的 OpenSSH 客户端密钥路径一般不需要额外设置默认会读取 ~/.ssh 下的 id_rsa 或 id_ed25519。而 VSCode 的 Remote-SSH 插件也是读取同一个用户 SSH 配置所以配置好密钥之后VSCode 连接嵌入式 Linux 板子也会变得非常顺畅。4.3 密钥生成算法选择的实操建议密钥算法这块我再展开说说。Ed25519 是目前我用得最多的密钥类型。它的优势在于密钥短、生成快、签名快而且安全性经过了多年验证。在嵌入式设备上如果你用 ssh-keygen -t ed25519 生成密钥大概几十毫秒就完成了。而如果用 RSA 4096在低端开发板上可能需要几秒到十几秒这个等待时间在批量初始化设备时很难受。ECDSA 也是不错的选择尤其是基于 prime256v1 曲线的密钥。它兼容性好几乎所有的 SSH 实现都支持。但要注意ECDSA 的安全性依赖于随机数质量如果你的设备熵源不足比如没有硬件随机数发生器理论上存在风险。不过实际测试中这类问题很少见。RSA 是兼容性最好的选择但也最慢。在为了兼容老版本 SSH 客户端时我一般会在 server 端保留一个 RSA 主机密钥但客户端密钥尽量用 Ed25519 或 ECDSA。关于主机密钥Dropbear 会在首次启动时自动生成但如果你需要批量部署多台设备建议统一在打包时生成一致的密钥这样方便预置主机信任关系。当然如果你担心安全性每台设备单独生成也可以只是会增加管理成本。5. 远程管理实战从端口转发到文件传输5.1 用 Dropbear 建立转发隧道SSH 隧道是嵌入式运维中非常实用的功能。很多时候开发板处于内网环境外部无法直接访问它的 Web 管理界面或者视频流端口但开发板可以主动向外发起 SSH 连接。这时候就可以利用 SSH 反向隧道remote port forwarding让外部服务器可以通过一条安全的通道访问开发板。假设开发板上有一个 Web 服务监听 8080 端口而你在公网上有一台跳板机IP 为 1.2.3.4。在开发板上执行dbclient -R 8888:localhost:8080 -N -f root1.2.3.4这个命令的意思是在跳板机上开启 8888 端口所有发送到该端口的数据通过 SSH 隧道转发到开发板的 8080 端口。这样你在跳板机上访问 localhost:8888就相当于访问开发板的 Web 服务。-N 参数表示不执行远程命令只做端口转发-f 参数表示后台运行。如果你希望这个隧道在设备重启后自动建立可以写成一个 systemd 服务或者加入 rcS 启动脚本。正向隧道也很有用。假设你在办公电脑上想访问开发板的 SSH 服务但开发板在另一个网段且这个网段只有一个跳板机可以访问。你可以这样ssh -L 2222:开发板IP:22 root跳板机IP然后在另一个终端连接本地端口 2222就能到达开发板的 SSH 了ssh -p 2222 rootlocalhost这种正向隧道特别适合跨网段访问尤其是在复杂的办公网络环境里省去了配置路由的麻烦。5.2 文件传输scp、rsync 与 sftp 的取舍日常维护中文件传输是高频操作。Dropbear 自带的客户端支持 scp 接收但不支持发起 scp 发送实际上更普遍的做法是使用 OpenSSH 客户端配合 Dropbear 的服务端。我在宿主机上使用的是 OpenSSH 客户端因此 scp 命令可以直接用scp ./app.elf root192.168.1.100:/opt/服务端是 Dropbear客户端是 OpenSSH这个组合工作中我天天用。但有个坑需要提醒Dropbear 默认不支持 sftp如果你的 scp 命令依赖 sftp 子系统可能会报错。解决办法有两种一是使用 scp 的降级模式强制走 scp 协议OpenSSH 9.0 之后默认使用 sftp 协议不再支持 scp 协议但可以通过 -O 参数指定使用旧版 scp 协议scp -O ./app.elf root192.168.1.100:/opt/另一种办法是在 rootfs 里放一个 sftp-server 程序并给 Dropbear 配置子系统路径。如果你用 BusyBoxbusybox 的 sftp-server 可能不完整建议直接使用 OpenSSH 的 sftp-server 二进制体积不大几 MB 而已但功能完整。对于大量小文件或者目录同步我更推荐 rsync。rsync 可以先 ssh 转发再调用带协议传输。使用方法rsync -avz -e ssh -i ~/.ssh/id_ed25519 ./rootfs/ root工具IP:/opt/rootfs/这里的 -e 参数指定远程 shell 为 SSH并指定密钥文件。只要 SSH 能连通rsync 就能用和服务端是不是 Dropbear 无关。5.3 远程命令执行与批量管理嵌入式设备的批量运维最常见的一个场景是我有 50 台设备需要对每一台执行同样的升级命令、修改配置、重启服务。手工一台一台做太累写脚本批量执行是正解。写一个简单的 bash 循环for ip in $(cat device_list.txt); do ssh root$ip cd /opt ./upgrade.sh reboot done如果设备数量很多可以并行执行但要注意不要一次性并发太多否则网络和设备 CPU 都会扛不住。建议同时并发 10 台左右等到执行完毕再下一批。在这个过程里Dropbear 的快速启动显得尤为重要。每次 ssh 连接时Dropbear 都是 fork 一个子进程出来处理启动速度很快。实测在几百 MHz 的 CPU 上一次 SSH 连接建立的时间在 100ms 量级这个开销完全可以接受。5.4 使用 VSCode 和 PyCharm 连接嵌入式 Linux很多开发者喜欢用 VSCode 编辑代码再通过 SSH 远程到开发板编译运行。这个流程在配合嵌入式 Linux 时非常好用。VSCode 的 Remote-SSH 插件就是基于 OpenSSH 客户端实现的。只要宿主机上配置好了 SSH 密钥VSCode 就能直接连接。连接后你可以在 VSCode 里打开开发板上的目录编辑代码然后通过终端在板子上编译。这和本地开发的体验差别不大。PyCharm 的远程解释器功能也是类似的。它会通过 SSH 配置远程 Python 环境然后自动同步代码。如果你的开发板上跑的是 Python 应用这个功能能省去很多来回拷贝文件的麻烦。需要注意的一点是开发板的内存可能不大跑一个 VSCode Server 或 PyCharm 的后台同步进程会占用一些资源。如果板子内存小于 128MB建议关掉 VSCode 的自动保存同步或者干脆只在板子上做编译代码编辑放在宿主机上。6. 安全加固不要让你的设备成为别人的跳板6.1 密码认证与暴力破解嵌入式设备暴露在公网上最容易遇到的就是暴力破解攻击。攻击者会不停地尝试用户名和密码尤其是 root 账户。Dropbear 服务器默认开启密码认证会有一定风险。最直接有效的做法是关闭密码认证只保留公钥认证。在 Dropbear 的启动参数里没有直接对应 OpenSSH 的 PasswordAuthentication 选项但可以通过编译时配置或参数控制。具体做法是在启动 dropbear 时加上 -s 参数这会禁用密码登录只允许公钥认证dropbear -s -p 2222如果你需要保留密码登录至少要保证密码足够强壮不要使用出厂默认密码。很多设备被攻击不是技术问题纯粹是密码太弱。6.2 修改默认端口与限制来源 IPSSH 默认监听 22 端口几乎所有的扫描工具都会优先扫描这个端口。改到一个高位端口比如 2222、8022、22022能有效减少无关扫描流量。这不算严格的安全措施只是降低暴露面。更有效的是限制来源 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这样只有 192.168.1.0/24 这个网段的 IP 才能访问 SSH 端口其他来源一律拒绝。如果使用 IPv6也不要忘记配置对应的 ip6tables 规则。6.3 禁用 root 登录或改用 sudo我之前提到过root 登录经常被用到在嵌入式调试阶段确实很方便。但如果设备是面向生产环境的建议禁用 root 的 SSH 登录改用普通用户加 sudo 的方式。Dropbear 启动时加 -w 参数可以禁止 root 登录但这个参数在某些版本中可能需要看编译配置是否支持。更通用的做法是把 root 用户的 shell 改成 /sbin/nologin这样即使公钥认证成功也会因为无法启动 shell 而拒绝会话。但要注意这会影响 root 的其他服务比如 cron 任务。如果你不确定是否要这么做建议先保持 root 登录但要确保密钥足够安全并且关闭密码认证。6.4 密钥轮换与审计生产环境里密钥要定期轮换。轮换指的是重新生成客户端密钥对并在所有设备上更新 authorized_keys。这个操作听起来麻烦但可以使用配置管理工具批量完成。嵌入式环境没有太复杂的配置管理工具的话写一个简单的脚本也能完成。我习惯每半年生成一批新的运维密钥。旧密钥可以保留一阵子作为回退但不推荐长期保留。如果怀疑有密钥泄露需要立即更新所有设备。审计方面Dropbear 支持日志输出。启动时加上 -E 参数可以将日志写到 stderr适用于需要集中收集日志的场景。结合系统日志可以看到谁在什么时候登录成功、失败多少次、使用的 IP 是什么。这些信息在排查安全问题时非常关键。7. 常见问题与排查技巧实录7.1 连接失败Connection refused 还是 Timeout遇到 SSH 连接不上先分清楚是连接被拒绝Connection refused还是超时Timeout。这两个现象对应的原因完全不同。Connection refused 说明 SYN 包到了服务器但服务器没有进程监听对应的端口。可能原因有Dropbear 没有启动成功。去设备上执行 ps 查看进程是否存在。端口配置错误。Dropbear 实际监听的端口和你连接的端口不一致。用 netstat -tlnp 查看监听情况。防火墙拦截后显式拒绝返回 RST。有的 iptables 配置会直接 REJECT表现为 Connection refused。Timeout 说明 SYN 包根本没到服务器或者服务器没有返回响应。可能原因有网络不通。ping 一下测试基础连通性。防火墙静默丢弃。有些策略是 DROP 而不是 REJECT表现就是超时。跨网段路由问题。这种情况只能用 traceroute 来定位。7.2 密钥认证失败Server refused our key这个报错很常见明明是同一个公钥有时候能登录有时候不能。排查顺序如下第一确认目标用户是否是 root 或对应账户。authorized_keys 文件路径是否正确。第二检查文件权限。我前面强调过权限太宽松会导致拒绝。执行chmod 755 /root chmod 700 /root/.ssh chmod 600 /root/.ssh/authorized_keys注意 /root 目录本身的权限也很重要。如果 /root 对其他用户可写SSH 会认为不安全而拒绝读取。第三确认服务器启动时是否加了一些限制参数比如有没有禁用公钥认证。第四检查客户端的私钥是否匹配公钥。可以在宿主机执行ssh-keygen -y -f ~/.ssh/id_ed25519输出的公钥内容和 authorized_keys 里的是否一致。7.3 scp 或 SFTP 报错我在前面提过Dropbear 不支持原生的 SFTP 子系统除非额外配置。如果你在 VSCode 或其他 SFTP 客户端里直接连接 Dropbear 服务器可能会看到 subsystem request failed 或者 connection closed。解决办法使用 scp 的 -O 参数强制使用旧版 scp 协议。在 Dropbear 启动时配置 SFTP 子系统路径-s /usr/lib/openssh/sftp-server。干脆用 rsync 代替有些环境下更稳定。7.4 系统重启后 Dropbear 没有自动启动嵌入式设备最常见的坑之一。检查点启动脚本是否正确加入到 rcS、inittab、systemd 或对应的 init 系统。检查 /var/run 是否可写。如果根文件系统是只读的需要把 /var/run 挂载成 tmpfs。检查主机密钥目录是否存在。如果 /etc/dropbear 在只读文件系统里且没有预生成密钥dropbear 启动时会尝试创建密钥文件但失败。解决方法是确保密钥目录可写或者预生成密钥打包进 rootfs。7.5 熵不足导致的性能问题低端嵌入式设备如果缺少硬件随机数发生器SSH 握手时的密钥生成可能会非常慢。因为内核的熵池得不到补充随机数生成会阻塞等待。检查方法cat /proc/sys/kernel/random/entropy_avail如果这个值长期小于几百说明熵源不足。解决办法启用内核的 CONFIG_RANDOM_TRUST_CPU 选项把 CPU 的 RDRAND 指令作为熵源。如果设备有网络接口可以安装 haveged 守护进程利用中断时序变化生成随机数。在设备上运行一些外部熵源工具比如 rng-tools。这个问题在批量部署时特别明显初期几台设备还好设备一多每个都卡在密钥生成阶段非常头疼。7.6 其他值得提的问题有些设备使用 AArch64 架构编译 Dropbear 时如果报 undefined reference to getrandom 之类的错误需要检查 libc 版本和内核版本。较老的内核可能不支持 getrandom 系统调用。这种情况下可以在 configure 时加上ac_cv_func_getrandomno ./configure ...强制不使用 getrandom回退到 /dev/urandom。另外如果 Flash 空间非常紧张可以只编译 dropbear 和 dropbearkey不编译 dbclient。减少一个二进制能省几百 KB 空间。8. 我的经验嵌入式项目里 SSH 方案的整体规划最后说一些我自己的体会算是给这个主题收个尾。在嵌入式项目里SSH 往往不是一个单独的技术点而是整个远程运维体系的基础设施。所以我建议在项目初期就要把 SSH 相关的方案定下来不要等设备量产了再补课。第一要决定使用哪个 SSH 实现。在资源受限的 Linux 设备上Dropbear 几乎是首选。它能满足绝大多数远程管理需求而且移植成本低、稳定性好。如果你需要完整的企业级功能比如 LDAP 集成、复杂的 PAM 模块、证书认证等再考虑 OpenSSH但那时候你也要接受它更大的资源占用。第二要确定认证策略。我强烈建议生产环境一律使用公钥认证密码认证只保留在出厂恢复模式。密钥可以由工厂统一生成并注入设备下线、员工离职时及时在服务器端更新 authorized_keys。第三要规划好端口和网络拓扑。测试环境怎么连生产环境怎么连是否需要做端口转发和隧道都要提前想清楚。我曾经在一个项目里设备分布在多个网段现场网络复杂最后靠跳板机和反向隧道解决了远程问题但如果没有提前规划调试阶段会浪费大量时间。第四日志和监控。不要忽视 SSH 日志。即使是最简单的系统也建议把登录日志写到一个稳定的存储介质定期查看有没有异常登录。嵌入式设备规模一大日志的集中采集和分析能帮你发现很多问题。第五不要忘了配套工具。scp、rsync、sftp 这些文件传输工具和 SSH 配合使用才能高效。操作系统中可能还需要支持串口终端的工具比如 screen 或 minicom。整套工具链要先在开发板上验证通过形成内部文档后续维护人员照着文档操作就行。再说一个小技巧。如果你使用的是 musl libc 的静态编译环境结合 strip 工具把 debug symbol 去掉Dropbear 的二进制还能再缩小一些。有需求的朋友可以自己尝试。9. 一些值得继续深入的方向如果你把基础配置和实战做完接下来可以从这几个方向继续深入。一个是研究 Dropbear 的源码。它的代码量不大但组织非常清晰是学习嵌入式网络编程的绝佳教材。你可以从 canal 结构看起了解事件循环、缓冲管理、状态机的实现方式。深入研究之后你会发现很多设计理念和大型网络软件是相通的。另一个是研究 SSH 协议本身。用 Wireshark 抓包看一次完整的 SSH 握手过程了解密钥交换、算法协商、用户认证的每个报文。这个过程的乐趣不亚于实际部署一个服务。还可以研究一些周边生态。比如把 Dropbear 与 mDNS 服务配合让设备在网络中自动被发现或者把它与 Web 管理面板结合通过浏览器管理 SSH 密钥又或者把它和 OTA 升级系统打通实现远程升级时的安全认证。这些方向都能让 Dropbear 在嵌入式系统里发挥更大的价值。有一点我特别想说嵌入式 Linux 开发很多时候不是拼谁的技术更炫而是拼谁的基础更扎实。SSH 看起来是基础设施但越是基础的东西越值得花时间吃透。很多看起来复杂的远程故障归根结底就是当初没把 SSH 这条链路设计清楚。