IoT边缘节点容器化的安全困境
去年帮一个工厂部署边缘采集网关,设备用的是RK3588工控板,跑着Docker化的数据采集服务。上线两周后客户反馈网关偶发性重启,排查发现是容器内进程拿到了CAP_SYS_BOOT,一次异常调用直接把整块板子重启了。这不是个例。很多团队把Docker当作轻量级隔离手段直接搬到IoT场景,却忽略了Docker默认的隔离能力相当有限。容器共享宿主机内核,一旦容器内进程拿到高权限,横向渗透到宿主机只是时间问题。
Docker默认给容器的capabilities列表里有14项,包括CAP_NET_RAW、CAP_SYS_PTRACE这些高风险权限。对云服务器来说,攻击面主要在外部网络。但IoT边缘节点不同,设备经常部署在物理环境不可控的现场,攻击面来自物理接口、调试串口、甚至本地网络内的其他设备。### securityContext:四道关键防线
Kubernetes和Docker都提供了securityContext来收紧容器权限。对IoT场景,以下四项配置是必须的:yamlapiVersion: v1kind: Podmetadata: name: iot-gatewayspec: securityContext: runAsNonRoot: true runAsUser: 1000 seccompProfile: type: RuntimeDefault containers: - name: collector image: huwangkeji/iot-collector:1.2 securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL各项配置的作用:| 配置项 | 防护效果 | IoT场景必要性 ||--------|---------|--------------|| runAsNonRoot | 禁止root身份运行 | 高,防止容器逃逸后直接root || drop ALL capabilities | 剥离全部Linux能力 | 高,默认14项中多数用不到 |
| readOnlyRootFilesystem | 根文件系统只读 | 中,防止恶意写入持久化 || seccomp RuntimeDefault | 限制系统调用集合 | 高,阻断高危syscall |readOnlyRootFilesystem在IoT场景有个注意点。很多采集程序需要写临时文件或日志,配置只读后必须在容器内挂载emptyDir或hostPath作为可写目录,否则程序启动就会崩。
seccomp自定义配置:精确管控系统调用RuntimeDefault方案用的是Docker维护的默认seccomp配置文件,已经过滤了44个高危系统调用。但IoT场景可以进一步收紧。下面是一个针对数据采集容器的自定义seccomp配置,只放行网络通信和文件读取相关的syscall:```json
{ "defaultAction": "SCMP_ACT_ERRNO", "syscalls": [ { "names": ["read", "write", "open", "openat", "close", "socket", "connect", "sendto", "recvfrom", "bind", "getsockname", "getpeername",
"exit", "exit_group", "rt_sigreturn"], "action": "SCMP_ACT_ALLOW" } ]}这个配置的思路是白名单模式,默认拒绝所有系统调用,只放行15个采集程序实际需要的。部署到Kubernetes集群时,将JSON文件放到`/var/lib/kubelet/seccomp/`目录下,在securityContext中引用即可。 对裸Docker环境(多数IoT边缘节点的实际情况),在docker-compose中通过security_opt字段引用:yamlservices: collector: image: huwangkeji/iot-collector:1.2
security_opt: - seccomp:./seccomp-iot.json cap_drop: - ALL read_only: true user: "1000:1000" tmpfs: - /tmp:size=10M```tmpfs挂载到/tmp解决了只读文件系统下临时文件写入的问题,10MB对采集日志来说够用,用完即弃不落盘。
从一次容器逃逸复盘看防护链路前面提到的那次工厂网关重启事故,事后复盘的攻击链路是这样的:容器内采集程序以root运行,拿到CAP_NET_RAW后伪造ARP报文干扰本地网络,进一步通过内核漏洞拿到宿主机shell,最终触发CAP_SYS_BOOT重启了设备。如果当时配置了drop: ALL和runAsNonRoot: true,容器内进程根本没有发送原始网络报文的权限,后续的攻击链路直接断在第一步。这就是纵深防御的价值,每一层都让攻击者的成本指数级上升。
沧州虎王科技在边缘网关容器化部署中,已经将安全基线配置固化到CI流水线。每个镜像构建时自动注入非root用户和最小capability集,seccomp配置文件按业务类型匹配。团队在GitHub(https://github.com/huwangkeji)维护了一套IoT容器安全基线模板,包含多种采集场景的seccomp配置和compose文件,可以直接复用。相关实践文章也在持续更新到技术博客(https://www.heicat.com)。
容器安全没有银弹,但对IoT边缘节点来说,收紧capabilities、启用seccomp、强制非root运行这三板斧,已经能挡住绝大多数低成本攻击。花在安全配置上的时间,远少于事后排查事故的代价。