ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

嵌入式Linux系统安全加固:从最小化裁剪到轻量防火墙的实战指南

嵌入式Linux系统安全加固:从最小化裁剪到轻量防火墙的实战指南 1. 这一讲先解决什么问题嵌入式系统的威胁模型与四条加固主线很多做嵌入式Linux开发的朋友特别是做过量产产品的普遍有个心态功能跑通了、功耗下去了、成本压住了就算完工。安全问题经常被当成“最后再说”的部分有时候甚至整个产品生命周期里都不会有人认真碰它。但这两年实际做项目你会发现不管是物联网设备被拉进僵尸网络还是网关、工控屏被篡改固件出事之后第一个被追责的往往不是网络部门而是当初写BSP和裁剪系统的嵌入式工程师。这一讲的核心就是把这些“迟早要还的债”提前还掉。所谓系统级安全加固不是装个杀毒软件也不是上什么重型安全网关。对嵌入式Linux来说硬件资源就摆在那里很多通用服务器上的加固方案直接搬过来是跑不动的。我的思路是把加固拆成四个方向同时推进最小化裁剪、权限硬化、日志审计、轻量防火墙。这四条线各管一段组合在一起才是完整的一道防线缺了哪一个都会留下明显短板。先说最小化裁剪。这条线解决的是“攻击面”问题。系统里每多一个驱动、一个守护进程、一个setuid程序就等于多给攻击者开了一扇窗户。嵌入式设备的软件栈通常是自己亲手搭的精简起来比通用发行版容易得多所以完全有条件把攻击面收得很小。再说权限硬化。它的任务是“即使被攻破损失也有限”。嵌入式设备上很多程序习惯用root跑各种文件权限也是怎么方便怎么来一旦一个漏洞被利用就直接拿到最高权限这是最危险的场景。日志审计解决的是“事了之后能查”的问题。设备被渗透之后如果连日志都没有或者日志被攻击者一键清空那就真的成了无头公案。对嵌入式设备来说日志方案必须轻但绝不能没有。最后是轻量防火墙。很多嵌入式工程师觉得防火墙是服务器才有资格用的东西。实际上一个简单的iptables策略在几十MHz的CPU上都能跑得很稳关键是规则要少而精别给自己制造麻烦。这一讲的内容我自己整理过很多遍。第一版太偏理论什么零信任、纵深防御讲了一大堆对做板子的工程师来说基本是废话。第二版把每个知识点落成具体配置和命令之后团队里的同事照着做一遍就能上手。所以我在这里也坚持这个原则每一条都有明确的操作对象和验证方法你能亲手在板子上验证而不是听我讲道理。2. 最小化裁剪把攻击面从源头收掉2.1 内核配置裁剪砍掉一个驱动就是关一扇门内核裁剪是整条链路里性价比最高的一步但也是最容易被忽略的一步。很多团队用的是SoC厂商给的默认内核配置那个配置为了兼容各种评估板开了大量当前产品根本用不到的驱动和协议栈。有一说一厂商默认配置对快节奏的原型验证很友好但直接拿它量产等于把一个装满工具的百宝箱交给攻击者。我实际做裁剪时一般先按这几个维度过一遍menuconfig文件系统和块设备产品用UBIFS还是ext4就把其他不用的文件系统全部关掉。像什么NTFS、FAT、F2FS除非真有需求否则留着就是白给。块设备驱动同理只保留eMMC/NAND对应的驱动SATA、NVMe、USB存储这些看产品外设决定。网络协议栈很多嵌入式设备其实只需要TCP/IP ARP ICMP。IPv6如果暂时不用建议直接关掉SCTP、DCCP这些更冷门的协议更是用不到。如果产品是纯局域网设备甚至可以考虑把路由转发、NAT这些能力关掉。驱动总线USB、PCIe、I2C、SPI这些总线的驱动以及它们下面挂的摄像头、WiFi、蓝牙、CAN等子驱动全部按实际硬件列表核对一遍。不用的设备驱动直接不编译一来省内存二来少漏洞。debug相关内核里那些debugfs、kprobes、ftrace、kexec量产固件里应该统统关掉。还有个容易被忽略的“魔术键”SysRq生产环境建议关掉否则物理接触设备的人可以通过串口执行一些危险操作。内核模块机制如果对模块加载没有硬性需求我建议把内核模块加载功能直接禁掉。所有驱动静态编译进内核一方面启动时不依赖rootfs里的模块目录另一方面攻击者以后想往内核里insmod一个恶意模块会直接失败。一个配置项干掉一整类攻击手法。裁剪完之后建议执行一遍make savedefconfig把裁剪后的配置以最小diff形式保存下来。以后内核升版本可以直接把这份defconfig套到新内核上再微调不用每次从头开始点菜单。这个习惯能帮你省下大量重复劳动。2.2 根文件系统裁剪每一KB都有讲究rootfs是另一个攻击面重灾区。很多嵌入式系统用的是busybox这没问题busybox本身就足够轻。问题在于有人图省事把busybox全部applet都编译进去结果一个急救箱里塞了一堆设备从没用到过的工具比如nc、telnetd、ftpget这些网络工具。这些东西平时不显眼但一旦被利用就成了现成的攻击工具。我的习惯是busybox配置里只保留产品核心功能和调试必需的工具网络服务类的applet除了dropbear如果有ssh需求和tftp开发期收发文件很有用量产前再删之外一律不要。文件操作类保留ls、cat、cp、mv、rm、mount、umount、ps、kill、ifconfig、route、sed这些就够了。debug相关工具如果产品已经稳定能删也删掉。除了busyboxrootfs里的动态库也值得清理。用到的程序逐个执行ldd查看依赖把用不到的.so文件全部移出去。有些库带了-dev版本的头文件编译完之后对运行时是垃圾必须从rootfs里剔除。这一步做下来rootfs体积通常能再瘦一圈加载速度也更快。还有一点很多人踩过坑rootfs里不要放置源码、编译中间文件、.git目录、编译脚本。哪怕只是几KB的文件都在泄露你的项目信息和潜在漏洞线索。我见过有产品把编译主机路径直接写在二进制里攻击者顺着路径就能推测内部开发环境这个细节一定要清理干净。2.3 开机自启项清理少一个守护进程少一分被利用可能内核和rootfs搞完之后接着看init进程和开机脚本。很多嵌入式系统用的是busybox init也有一些用systemd或者openrc里面列了一堆开机自启的服务。我的处理原则很简单默认不友好的全部禁止只开产品真正需要的。以busybox的/etc/init.d/rcS为例逐行检查每一项凡是产品运行所必需的比如挂载、启动主应用、启动网络管理保留其余注释掉。特别要注意的是下面几类telnetd开发期方便但没有任何理由出现在量产固件里。即使内网访问也不行telnet协议本身是明文的密码和命令全都裸奔。各种upnp、mdns、智能组网组件除非产品要互联互通否则建议关掉。这类协议经常被利用做局域网内横向渗透。升级服务如果有OTA升级端口和验证逻辑要做单独保护不要把OTA服务做成一个常开的无鉴权入口。清理完之后用ps -ef在板子上核对一遍确保常驻进程列表和设计文档完全一致。我有一个习惯把允许的进程清单写进项目README每添加一个新守护进程必须走代码审查说明“为什么需要常驻”“如果被攻破影响范围是什么”。这套流程看着麻烦但对长期维护的项目非常值。3. 权限硬化让每一个进程都只拥有最低限度的权力3.1 文件权限与SUID审计先清掉历史遗留的“后门”文件权限这部分很多嵌入式系统上属于一眼没看过的状态。rootfs做出来之后权限经常是打包工具默认给的该有人读的没人读不该可写的全都可写。我的做法是拿一个标准Linux发行版做参照把rootfs里关键目录和文件的权限过一遍。优先检查项目是SUID/SGID位。find / -perm -4000 -o -perm -2000这个命令在板子上跑一遍凡是有SUID/SGID的程序逐一确认是不是必须的。要知道setuid程序是提权漏洞的高发地一个setuid的ping如果本身有漏洞攻击者就能借它拿到root权限。能去掉setuid位的就去掉ping在嵌入式场景里完全可以改用普通权限实现或者干脆不用。文件权限还有一个隐蔽问题可写目录太多。/tmp、/var这些本来就是临时数据目录可写正常。但要小心rootfs里出现像/usr/bin、/etc这样的大目录变成可写。一旦这些目录可写攻击者就能直接往里面扔一个同名恶意程序或者篡改配置。具体检查方法find / -type d -perm -ow看到可疑的可写目录除非有明确理由一律收掉写权限。3.2 用户与进程权限不是所有程序都配用root跑嵌入式设备为了省事经常所有进程都用root跑。应用本身可以理解但至少要做到下面几点专门建一个普通用户跑应用。busybox里没有useradd也没关系直接在/etc/passwd和/etc/group里手工加两行在rootfs里创建好对应目录并chown。应用以普通用户跑即使被攻破权限也只是那个用户的权限。配置了sshd/dropbear的话禁止root直接登录强制用普通用户登录登录后再su或者通过sudo授权。dropbear的配置项-w可以禁止root登录/etc/dropbear/authorized_keys只放普通用户的公钥。如果某些操作确实需要root优先用capabilities代替完整root。比如程序只需要绑定低端口就只给它CAP_NET_BIND_SERVICE这一个capability而不是让它以root身份运行。除了用户权限还有一个容易被忽略的点挂载参数。mount的时候能加限制就加限制。比如/tmp挂成nosuid,nodev,noexec这样即使攻击者往里面放一个可执行文件也不能直接执行它。/etc可以只读挂载/home如果有挂nosuid。这些挂载参数改起来非常快但效果立竿见影。3.3 内核sysctl加固十分钟把所有危险开关关掉sysctl这块是权限硬化里最出名也最容易操作的部分但很多人只是一知半解随便copy一段网上配置就完事。我的建议是先明白哪些项是干什么的再按需启用。下面这套是我在资源受限设备上实际验证过的全部启用不依赖额外软件修改/etc/sysctl.conf之后sysctl -p立即生效# 防SYN攻击嵌入式设备内存小半连接队列一满基本就是死机 net.ipv4.tcp_syncookies 1 # 不响应ICMP重定向防止路由表被篡改 net.ipv4.conf.all.accept_redirects 0 net.ipv4.conf.default.accept_redirects 0 # 禁止IP转发设备如果不需要做路由就关闭 net.ipv4.ip_forward 0 # 减小攻击者可利用的探测面不响应广播ping net.ipv4.icmp_echo_ignore_broadcasts 1 # 记录那些“来源不可达”的诡异包方便排查 net.ipv4.conf.all.log_martians 1这里做个提醒不要盲目把网上的“服务器加固大礼包”整段搬过来。比如kernel.randomize_va_space的ASLR、kernel.kptr_restrict这些嵌入式平台有些SoC的内核配置没开对应选项设置不报错但也不生效花时间配了等于白配。我踩过的坑是在某个老内核平台上把net.ipv4.conf.all.rp_filter设为1之后多网卡设备的转发出现丢包后来查出来是用到了不对称路由这种场景就得改成0。每个参数都要理解它干什么再加到自己的设备上验证别当成模板无脑祭天。3.4 只读文件系统让持久化攻击无处扎根权限硬化做到最后很多产品会考虑把根文件系统做成只读。这个思路我非常支持尤其是对存储介质容易写坏的设备只读rootfs既能防数据损坏又能防止恶意代码持久化。实现起来有几种路子。简单粗暴的rootfs用squashfs这类只读文件系统可写数据单独挂一个可写的jffs2/UBI卷到/data或者/var。更灵活一点的rootfs保持ext4但用overlayfs做双层上层tmpfs放运行时改动重启即恢复。两种方案各有取舍。squashfs压缩率高、加载快缺点是想改rootfs内容得重新做镜像overlayfs则方便调试但要小心上层tmpfs容量太小导致运行时写满。我个人的推荐是量产版本用squashfs开发版本用overlayfs两边都不耽误。如果产品有OTA需求只读rootfs还要配合双分区设计升级时写入另一个分区然后切换启动这也是现在带完整系统的嵌入式产品最常见的方案。这样即使攻击者把当前系统改得面目全非重启或者双分区切换之后系统又恢复原状。4. 日志审计不追求大而全但出事时必须查得到4.1 轻量日志方案选型busybox syslogd够不够用说到日志很多嵌入式工程师的第一反应是“我设备天天正常跑要日志干什么”。但真正出过一次安全事故之后你就知道日志是唯一能还原攻击路径的东西。而且嵌入式日志方案完全可以做到很轻加不加它都对性能影响不大。先看最基础的方案busybox自带的syslogd。它的-s参数设置缓冲区大小默认只有64KB对嵌入式场景来说几乎不会额外占内存。它能把日志写到内存环形缓冲区也能落盘到文件。真出问题的时候至少能告诉你系统是什么时候、因为什么重启或者异常的。如果觉得busybox syslogd太简陋可以考虑syslog-ng。它有更强的过滤和转发能力可以把不同级别的日志分流也可以直接通过UDP/TCP把日志远程发到日志服务器。缺点是体积比busybox syslogd大一点占内存多几MB。64MB内存以下的设备我建议谨慎考虑128MB以上基本没有压力。另外从内核视角看要确保/proc/sys/kernel/printk设置合理。默认的printk级别如果把所有debug信息都打出来日志会满天飞。把控制台级别调成4只显示KERN_WARNING以上既不会让console被刷屏又能在Kernel panic时留下必要信息。4.2 关键日志的采集与轮转日志不是越多越好日志采集要有目的性而不是什么日志都收。按照安全审计的需求下面几类日志在我负责的项目里是必留的登录日志谁在什么时间通过ssh/telnet登录过远程IP是什么。dropbear和sshd都有相应日志level调到info。内核日志dmesg的内容特别是系统重启、驱动报错、网络接口up/down这些。应用崩溃日志主应用异常退出时的堆栈和退出码至少要知道是段错误还是被人kill掉的。防火墙丢弃日志后面讲防火墙时会说被防火墙丢掉的包一定要有日志否则你看不到任何被探测的痕迹。日志文件的轮转同样重要。嵌入式设备存储空间有限日志一写就停不下来最典型的坑是把存储写满了。busybox syslogd本身不带轮转功能我的做法是加一个简单脚本定期mv日志文件。如果是syslog-ng直接在配置里加logrotate或者使用它自带的file destination的size参数即可。可以参考下面的配置片段destination d_syslog { file(/var/log/messages owner(root) group(root) perm(0640) create_dirs(yes)); file(/var/log/messages size(500k) rotate(5)); };轮转策略我建议做到两层大小限制和数量保留。比如单文件超过500KB就轮转保留最近5份其余删除。这样既能保证有足够历史的日志又不会把flash写爆。注意轮转脚本本身要确认真的在跑这个坑我在后面章节会单独讲。4.3 日志防篡改让日志成为可信证据日志如果只写在本地攻击者拿到root后可以一键清空或者改写。很多嵌入式设备日志审计的漏洞就出在这里。要解决这个问题在资源允许的情况下有几种思路。远程日志是效果最好的方案。设备通过syslog协议把日志实时发到内网某台日志服务器上攻击者能清掉本地日志但清不掉服务器上的那份。设置很简单syslog-ng里加一个tcp(192.168.1.10 port(514))的destination就行。要注意负载和网络可靠性设备如果经常离线本地日志的保留就特别重要不然中间断档的日志完全是空白。如果实在不具备远程日志条件至少要给日志文件加防篡改属性。比如把日志文件放在可写分区用chattr a设置append-only属性让日志只能追加不能删除。不过这个属性对root同样生效攻击者拿到root之后可以用chattr -a解除防不了全能攻击者但至少能挡住一些脚本小子。还有一个实用技巧在系统里加入一个简单的心跳日志。主应用每隔一段时间往日志里写一条带序号的心跳记录如果被人把日志里关机/重启的痕迹抹掉了心跳的断档也能暴露问题。这个方法不需要额外软件几行代码就搞定我建议每个带状态机的嵌入式应用都加上。5. 轻量防火墙内存再小也得有个门卫5.1 iptables还是nftables按内核版本和资源决定嵌入式Linux上的防火墙选择核心就两个iptables和nftables。iptables是老字号几乎所有Linux内核都支持资料多出了问题好排查。nftables是新一代Netfilter前端语法更清晰、规则集更紧凑但要求内核版本和用户态工具都比较新。我的选择逻辑很简单内核版本老、资源极紧的设备用iptables因为兼容性好规则数量少的时候性能和nftables差距几乎看不出来。内核版本较新4.19以上、内存有余量的设备可以用nftables配置体验确实比iptables好一些尤其是在处理规则集更新时nftables能做到原子替换不会出现iptables那种“删一半断网”的尴尬。两个工具都能跑关键要记住一点嵌入式环境下防火墙的规则一定要少而精。每多一条规则每个包就要多遍历一次。规则数量上了百条损耗就很明显了。所以我写规则之前会先把“产品到底需要哪些端口和方向”的问题列清楚再落到规则上。5.2 一套够用且不乱的最小规则集我拿一个常见的IoT网关设备举例它对外提供三个能力SSH管理仅限内网网段、MQTT上报主动外连服务器、以及Web状态页面内网查看。需要被允许的流量很清晰其余全部拒绝。下面是一套iptables最小规则集# 先清空历史规则注意顺序避免把自己锁在外面 iptables -F iptables -X iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT # 允许回环和已建立的连接 iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 内网SSH只允许内网段来源 iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -j ACCEPT # 内网Web状态页面 iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 8080 -j ACCEPT # MQTT是设备主动连服务器走OUTPUT方向INPUT侧只需要放行回包 # 上面ESTABLISHED规则已经覆盖了回包 # 丢弃的包留日志方便排查谁在扫你 iptables -A INPUT -j LOG --log-prefix fw-drop: --log-level 4这段规则里有两个细节值得说。默认策略全DROP这个动作极其关键意味着所有没被明确放行的流量都被丢弃。很多嵌入式设备默认是ACCEPT策略只在末尾加几条DROP那等于大门敞开只拦几个路人跟没拦差不多。还有个细节是LOG规则放在最后它会把没被上面任何规则匹配到的包全部记录下来这对事后排查入侵痕迹特别有用。5.3 规则持久化与自启动别让防火墙变成一次性摆设防火墙规则配好之后最大的坑就是重启失效。iptables规则默认只保存在内存里重启就没有了。嵌入式设备上常见的持久化方式有两种。用iptables-save保存规则到文件。iptables-save /etc/iptables.rules然后在init脚本里加一条iptables-restore /etc/iptables.rules。这个方法简单直接适用于busybox init和systemd都行。systemd的话可以写一个oneshot服务在network就绪之后执行restore。要注意执行顺序防火墙规则一定要在网络接口配置完成后加载。有同事遇到过规则写在网络配置之前重启后发现规则没了其实不是规则没保存是restore执行太早iptables还没拿到接口信息就报错了。这种问题排查起来特别费时间。类似地如果用了systemd-networkd服务依赖要写对。nftables的持久化类似nft list ruleset /etc/nftables.rules开机后nft -f /etc/nftables.rules。不过我还是建议嵌入式场景写成init脚本减少对systemd的依赖毕竟很多裁剪过度的系统里根本没有systemd。6. 第16篇课后思考题完整解析6.1 思考题回顾与解答思路上一讲核心围绕嵌入式Linux系统的启动流程和根文件系统设计课后留了三道思考题。这里统一解析也帮大家把上一讲的内容串一下。先说第一道题。思考题1为什么嵌入式Linux推荐使用只读根文件系统如何设计可写数据区这道题考察的是对“只读rootfs”这个设计模式的理解。答案可以从稳定性、安全性、可恢复性三个角度展开。稳定性方面只读文件系统能避免运行时意外写入导致文件系统损坏这在突然掉电的嵌入式场景尤其重要。安全方面只读意味着恶意代码无法通过修改启动脚本、替换二进制实现持久化它是系统自愈能力的基础。可写数据区设计要遵循“最小可写”原则把日志、配置、运行数据单独挂到一个可写卷如UBI卷或单独分区挂载参数用nosuid,nodev应用数据与系统数据分离。这样即使数据区被写坏系统核心依然完好恢复只需要重新格式化数据区。思考题2启动时检测到根文件系统损坏如何实现自动恢复这题的核心是“双备份加回滚”。生产环境中一般把系统分成A/B两个分区加上一个bootloader级别的启动计数。系统每次启动时主应用启动成功后向某个标志位写入“本次启动正常”如果连续N次启动都失败bootloader自动切换到另一个分区。实现这个机制常用的工具是uboot的bootcount环境变量或者systemd的boot counting特性前提是uboot或者内核够新。还有个小技巧恢复分区里的系统可以做成一个精简的救援系统只包含网络、文件系统检查、以及向另一个分区刷写镜像的必要工具体积做到很小。思考题3嵌入式设备的动态配置如网络参数如何保存才能在异常重启后依然一致这道题比较实际。动态配置如果直接写在rootfs里重启就丢如果写在可写区又怕写入半途掉电把配置写坏。推荐的做法是“边写边更替”策略先把新配置写入临时文件校验通过后mv覆盖正式配置文件保证任何时刻磁盘上都存在一份完整的配置。比这更进一步可以把配置做成一个小的KV存储很多产品直接用一个文本文件加fsync每次写入后调用sync确保落盘。要注意的是不要用NFS之类的网络文件系统保存配置网络断了配置就丢了。这题能答到“双备份原子替换同步落盘”这个层次基本上就完整了。6.2 解析这组思考题的用意这三道题表面上在问启动和rootfs实际上是在为安全加固做铺垫。只读文件系统引出的是权限硬化和最小化裁剪的核心思路双分区回滚讲的是系统在极端情况下的自愈能力配置保存则引入了日志、数据这类“运行时内容”的安全处理方式。看起来是独立的问题其实落点都在“攻击者无法通过一次入侵永久控制设备”这个目标上。这也是这一讲安全加固所有措施的最终目的。7. 常见问题与排查技巧实录7.1 规则配置对了却不生效排查顺序比看文档更关键我遇到最多的一个坑就是“sysctl配了iptables配了重启后全没了”。第一次遇到别急着怀疑配置有问题先按顺序查硬件和启动时间线。先看网络接口起来了没有。在init脚本里echo一下确认防火墙规则是在接口up之后执行的。再看sysctl.conf有没有被init引用。busybox系统里/etc/sysctl.conf默认会被/etc/init.d/rcS里的一段脚本处理但如果厂商的rootfs改过启动逻辑这段脚本可能被删掉了。我在某款国产SoC的SDK上就遇到过rcS完全不处理sysctl.conf所有的sysctl配置全都静默失效。解决办法就是在rcS末尾手动加一句sysctl -p。还有一个细节iptables规则如果写在rcS里注意rcS里的不同脚本是按顺序执行的规则必须放在网络配置之后。如果顺序反了规则会加载到不存在的接口上直接报错。排查时先用iptables -L -n -v确认规则是否加载再考虑是不是里边的-i eth0参数跟实际接口名对不上。嵌入式系统里接口名可能会因为设备树配置不同而变成eth1或者是在usb0上这是最容易看走眼的地方。7.2 加固之后功能异常如何快速定位是哪条加固策略误伤了安全加固有时候会“误伤”正常功能这是常态不用慌。最典型的例子是配了只读rootfs之后某个应用启动时报“Read-only file system”或者配了防火墙DROP之后原来能通信的对端突然连不上。我的排查习惯是先把加固项列成清单一条一条回滚来定位。比如功能异常了先临时把防火墙默认策略改成ACCEPT如果恢复正常说明是防火墙误拦截再把只读rootfs临时挂成可写如果恢复正常说明是文件系统权限问题。不要同时回滚多项否则永远定位不到问题根源。有些问题一眼看不出来需要看日志。这里就体现出前面日志审计的价值了。被防火墙DROP的包会在LOG规则里留下fw-drop前缀日志通过它你能看到是哪个源IP、哪个端口被拦下来了然后对照产品需求判断是规则太严还是确实不该放行。同理dmesg | tail能看到sysctl、内核模块相关的报错。7.3 日志刷爆存储轮转配置的常见坑日志导致的存储写满是嵌入式设备的高频故障而且一旦发生问题往往比表面看到的更严重。之前帮一个客户排查过一台网关设备运行几个月后频繁重启最后发现是/var/log/messages写满了整个可写分区导致主应用无法创建临时文件直接触发OOM。这个案例里日志轮转确实配了但轮转任务挂在cron上而那颗设备上的cron因为裁剪过度根本没被编译进busybox所以轮转从来没执行过。检查方法很简单在板子上手动执行一遍轮转脚本看看文件是否真的被切分再确认cron进程是否真的在跑。如果没有cron把轮转脚本放进一个while循环里用sleep 300每隔五分钟检查一次效果是一样的。另外logrotate如果是从发行版搬过来的默认配置里往往带着weekly这样的频率对嵌入式设备来说按大小轮转更可靠因为日志产生的速率完全不可控。7.4 保留最小调试后门关键时刻的救命通道安全加固做到最后很多朋友会把所有调试入口全部封死这其实也会带来麻烦。设备部署到现场之后如果出了网络问题你连不上设备连本地串口都没有那就只能派人跑一趟现场了。我的建议是保留两条受控的调试通道。一条是串口控制台量产时可以把串口登录关闭但保留uboot和内核的启动信息输出关键时刻通过串口能恢复。另一条是受IP白名单限制的SSH访问只允许特定网段或者通过密钥登录平时不开放但至少留一条路。这里要注意所有调试通道都要记录在案并且和管理员权限严格分离别让调试通道变成攻击者的后门。7.5 安全加固的推进节奏一步一步来别指望一次到位最后再分享一点自己做多个项目总结出来的节奏。安全加固最怕的是“一口吃成胖子”。如果你在一台已经跑了大半年的设备上突然做全套加固大概率会把系统搞挂而且难以定位问题。我建议按下面的顺序分步落地先把最小化裁剪做好从编译层面减少攻击面然后做只读rootfs和权限硬化让攻击者即使打进来也拿不到持久化能力再配置日志审计确保有“现场记录”最后再上防火墙。每一步做完都要在设备上做一轮完整的回归测试至少跑几天看稳定性。等这套流程在项目里跑顺了后续的新项目可以直接复用这套加固模板工作量会小很多。我个人在实际操作中最深的体会是安全加固这项工作七分靠流程三分靠技术。单点技术做得再漂亮如果没有“新增组件必须走评审、发布固件必须跑加固检查”这样的流程约束过几个月配置就会悄悄被改回原样。反过来流程一旦立住哪怕团队换人这套防线也能持续生效。这也是为什么我在这个专栏里坚持把“可落地、可验证”放在比“理论高深”更优先的位置。
返回列表