嵌入式 Linux 网络安全知识框架

嵌入式 Linux 网络安全知识框架:从设备边界到远程运维

问题背景

嵌入式 Linux 设备一旦接入网络,就不再只是一个运行在现场的小系统,而是整个业务链路中的一个网络节点。它可能连接传感器、执行控制逻辑、上报数据、接收远程配置、执行 OTA,也可能暴露 Web 管理页面、SSH、MQTT、HTTP API 或私有 TCP 协议。只要设备长期在线,就需要面对弱口令、服务暴露、依赖漏洞、证书过期、固件篡改、接口滥用和日志缺失等问题。

很多初学者理解网络安全时,容易只盯着防火墙或加密通信。但在嵌入式 Linux 场景里,安全不是单点功能,而是一套从硬件启动、系统裁剪、网络服务、身份认证、数据保护、升级维护到现场排障的工程框架。本文不展开具体攻击技术,而是整理一个适合学习和项目检查的知识地图。

先确定设备的安全边界

做安全设计前,先要回答三个问题:设备暴露给谁、谁可以控制设备、设备里有什么值得保护的数据。

典型嵌入式 Linux 设备可能有几类边界:

  • 本地物理边界:UART 调试口、USB、SD 卡、网口、按键、恢复模式。
  • 局域网边界:Web 配置页面、mDNS/SSDP、Modbus TCP、私有配置协议。
  • 公网或蜂窝网络边界:MQTT、HTTPS、VPN、远程运维通道。
  • 云端控制边界:设备证书、Token、OTA 签名、远程命令下发。
  • 供应链边界:第三方库、基础镜像、厂商 SDK、构建服务器。

如果边界没有列清楚,后面的措施很容易变成零散补丁。例如只给 Web 页面加登录,但 SSH 还开着默认密码;或者 MQTT 用了 TLS,但 OTA 包没有签名校验。这类问题不是单个技术点不会,而是没有把设备当成完整系统来审视。

启动链路:确认运行的是可信固件

网络安全的第一层并不在网络,而在启动链路。因为一旦设备可以被刷入未授权固件,应用层做再多认证也可能被绕过。

常见关注点包括:

  1. Bootloader 访问控制:量产设备应关闭或限制 U-Boot 命令行,避免通过串口中断启动参数、修改 rootfs 或进入单用户模式。
  2. 启动参数保护 :内核 bootargs 不应留下调试后门,例如直接进入 shell、关闭鉴权或挂载可写 rootfs。
  3. 固件完整性校验:至少对升级包做哈希和签名校验,避免设备安装被篡改的镜像。
  4. Secure Boot:对安全要求较高的设备,可以使用 SoC 提供的安全启动能力,让 Boot ROM、Bootloader、Kernel、RootFS 形成信任链。
  5. 恢复分区策略:A/B 分区或 recovery 分区要同时考虑可靠性和安全性,不能让恢复模式变成绕过鉴权的入口。

对普通工业网关或采集设备来说,完整 Secure Boot 不一定第一阶段就能落地,但 OTA 包签名、关闭调试入口、限制 Bootloader 交互通常是比较现实的起点。

系统裁剪:减少可攻击面

嵌入式 Linux 的安全原则之一是:不用的东西不要放进系统。系统越大,开放端口越多,后台服务越多,未来需要维护的漏洞面也越大。

可以从几个方面做裁剪:

  • 关闭不必要服务:例如 telnet、ftp、未使用的 Web 服务、调试 daemon、测试脚本入口。
  • 最小化 rootfs:Buildroot、Yocto 或 OpenWrt 项目中,只启用业务真正需要的包。
  • 移除默认账号和弱密码 :不要保留 root/rootadmin/admin 这类出厂口令。
  • 限制 shell 工具:生产固件中减少调试工具,至少避免把内部测试脚本和敏感配置一起打包。
  • 只开放必要端口 :用 ss -tulpennetstat -tulpen 检查监听端口,并和设计文档对齐。

一个简单检查命令:

sh 复制代码
ss -tulpen
ps aux

这两个命令可以快速看到当前系统暴露了哪些端口、运行了哪些后台进程。实际项目中,建议把"量产固件端口清单"写进交付检查项。

网络服务:认证、授权和输入校验

嵌入式设备常见网络服务包括 Web 管理端、SSH、MQTT 客户端、HTTP API、Modbus TCP、私有 TCP/UDP 协议等。每类服务都要考虑三个问题:谁可以访问、访问后能做什么、输入是否可信。

SSH 和远程登录

SSH 是运维很方便的工具,但也是常见风险点。量产设备中应尽量做到:

  • 禁止密码登录,改用密钥登录。
  • 禁止 root 直接远程登录,必要时使用普通用户加受控提权。
  • 修改默认账号策略,而不是只改端口。
  • 对公网设备,优先通过 VPN、堡垒机或云端受控通道进入,而不是直接暴露 SSH。

示例配置片段:

text 复制代码
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes

Web 管理页面

Web 页面是嵌入式网关、路由器和工业设备很常见的管理入口。需要重点关注:

  • 登录鉴权是否覆盖所有敏感接口。
  • Session 或 Token 是否有过期时间。
  • 修改配置、升级固件、重启设备等操作是否需要权限控制。
  • 表单、JSON、URL 参数是否做长度、类型和范围校验。
  • 上传文件是否限制类型、大小和保存路径。
  • 错误信息是否泄露系统路径、命令行参数或内部配置。

很多设备的问题不是没有登录页,而是后端 API 没有统一鉴权,前端隐藏按钮并不等于安全。

业务协议

MQTT、HTTP、WebSocket 或私有协议承载业务数据时,不能只检查"能不能连上"。还要检查:

  • 是否使用 TLS。
  • 服务端证书是否校验,而不是为了调试关闭校验。
  • 设备身份是共享 Token,还是每台设备独立证书或密钥。
  • 下行命令是否有权限边界和重放保护。
  • 业务字段是否做白名单校验,避免远程配置写入危险值。

如果所有设备共用一个密钥,一台设备泄露就可能影响整批设备。更稳妥的方式是每台设备拥有独立身份,并支持吊销或轮换。

防火墙和网络隔离

防火墙不是安全的全部,但它是非常重要的边界控制手段。嵌入式 Linux 上常见选择包括 iptablesnftables,以及 OpenWrt 场景中的 UCI firewall。

基本思路是默认拒绝不需要的入站连接,只允许明确的管理和业务流量。例如:

sh 复制代码
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

这只是示例,真实项目里要根据设备角色调整。例如采集终端通常不需要开放公网入站端口;网关设备可能需要区分 LAN、WAN、蜂窝、VPN 多个接口;工业协议网口还可能要求和管理网口隔离。

网络隔离的目标不是把规则写得复杂,而是让不同风险区域不要互相打穿。例如现场控制网络、设备管理网络、互联网出口、云端隧道最好有清晰边界。

数据保护:传输、存储和密钥

嵌入式设备里的敏感数据通常包括设备证书、云端 Token、Wi-Fi 密码、用户配置、采集数据、日志和升级密钥。保护这些数据要分传输和存储两层。

传输层优先使用成熟协议:

  • MQTT over TLS,而不是明文 MQTT。
  • HTTPS,而不是 HTTP。
  • VPN 或安全隧道,而不是直接暴露运维端口。
  • 证书校验开启,避免 --insecure 类配置进入量产。

存储层要关注:

  • 密钥不要硬编码在程序里。
  • 不要所有设备共用同一套证书或 Token。
  • 配置文件权限要收紧,例如 chmod 600
  • 日志不要打印完整 Token、密码或私钥。
  • 有条件时使用硬件安全单元、TPM、TEE 或 SoC 安全存储。

密钥管理往往比"加密算法选择"更容易出问题。使用成熟算法固然重要,但密钥如果写在源码仓库、打印在日志里,或者整批设备共享,系统仍然不安全。

OTA 安全:升级是能力,也是入口

OTA 是嵌入式 Linux 设备长期维护的基础能力,但它本身也是高风险入口。安全的 OTA 至少要考虑:

  1. 升级包签名:设备端验证签名后再安装。
  2. 版本回滚策略:支持失败回滚,但要防止被恶意降级到有漏洞的旧版本。
  3. 下载通道安全:使用 HTTPS 或受控通道,避免中间人替换升级包。
  4. 升级权限控制:只有可信云端、管理员或本地受控流程可以触发升级。
  5. 升级日志留存:记录版本号、时间、结果、失败原因,便于追踪问题。

如果只能先做一件事,优先做"升级包签名校验"。因为下载链路加密可以降低传输风险,但签名校验才能确认包本身来自可信发布方。

日志、审计和可观测性

安全事件如果没有日志,后期几乎无法定位。嵌入式设备资源有限,但仍然应保留关键审计信息:

  • 登录成功和失败记录。
  • 配置修改记录。
  • OTA 升级记录。
  • 网络连接异常记录。
  • 证书过期、认证失败、Token 刷新失败。
  • 防火墙丢弃统计或关键端口访问记录。

日志要避免两个极端:一种是几乎什么都不记,现场出问题只能猜;另一种是把敏感信息完整打印出来,导致日志本身成为泄露源。比较合理的方式是记录事件类型、时间、来源、结果和错误码,对密钥类字段做脱敏。

开发与供应链安全

嵌入式 Linux 项目通常依赖交叉编译工具链、第三方库、内核补丁、厂商 SDK 和构建脚本。网络安全不能只看运行时,也要看开发链路:

  • 固定依赖版本,记录来源。
  • 跟踪 OpenSSL、BusyBox、Dropbear、curl、libxml、Web 框架等组件的安全更新。
  • 避免把私钥、生产 Token、服务器密码提交到 Git。
  • 区分开发固件和生产固件,生产版本关闭调试开关。
  • 构建产物可追溯,能知道某个固件由哪个 commit、哪个配置生成。

如果项目使用 Yocto 或 Buildroot,建议把 defconfig、layer、patch 和 package 版本纳入版本管理。这样后续修漏洞时,才能知道该改哪里、影响哪些固件版本。

一个实用检查清单

可以把下面清单作为嵌入式 Linux 网络安全的第一轮自查:

  • 量产固件是否关闭 telnet、默认 SSH 密码和调试后门。
  • ss -tulpen 看到的监听端口是否都能解释用途。
  • Web/API 是否做了后端鉴权,而不是只靠前端隐藏入口。
  • MQTT/HTTP 是否使用 TLS,并开启证书校验。
  • 每台设备是否有独立身份,密钥是否支持轮换或吊销。
  • OTA 包是否做签名校验。
  • Bootloader 是否限制交互入口。
  • 配置文件和密钥文件权限是否收紧。
  • 日志是否记录安全关键事件,并避免泄露敏感信息。
  • 构建系统是否能追溯固件来源和依赖版本。

踩坑记录

第一个常见坑是"内网设备就不需要安全"。很多工业设备最初只部署在局域网里,但后期为了运维方便,会被接入 VPN、4G 路由器、云平台或临时端口映射。原本只在内网暴露的弱口令和未鉴权接口,就会变成真实风险。

第二个坑是"用了 TLS 就安全"。TLS 解决的是传输链路问题,但如果设备不校验证书、所有设备共用 Token、后端命令缺少权限检查,仍然可能被伪造服务端、批量冒用或滥发命令。

第三个坑是"调试方便优先"。开发阶段留下的串口 shell、测试账号、万能恢复包、免签名升级入口,如果没有在量产前清理,很容易成为后期最难补的安全债。

总结与延伸

嵌入式 Linux 网络安全不是某个单独模块,而是一条贯穿设备生命周期的工程主线。可以按"启动可信、系统最小化、服务有鉴权、通信有加密、密钥可管理、升级可验证、日志可追踪、供应链可追溯"这几个层次建立知识框架。后续继续学习时,可以分别深入 Secure Boot、Linux 权限模型、iptables/nftables、TLS 证书体系、OTA 签名、SBOM 与漏洞管理,把安全能力逐步落到真实项目流程里。