本文的初稿在公众号草稿箱里面压箱底好久。
原因是之前因为要转信创了,打算分析一下国产操作系统的上下游关系,殊不知信创疾风劲吹之下,一众国产操作系统纷纷抛弃之前的上下游关系,转而强调自己是“基于 Linux 社区开源代码原生”。
虽然大家都很务实地没说自己是从 int main() {} 开始重写,但这个转变就导致本文写到一半就扔到了一边。
笔者:国际注册信息系统审计师、软考系统分析师、软件工程硕士
这段时间因为《CISecurity.org 已经拒绝中国大陆 IP 地址访问》的原因,重新关注起安全加固基准这事,然后发觉,上下游关系又值得一说。
因为国产操作系统的安全加固基准,和国产操作系统的上下游关系脱不开干系。不过原稿还是扔掉一半内容。
本文的国产操作系统仅指基于 Linux Kernel 建立的操作系统。
Linux 发行版的上下游关系是了解一个发行版来龙去脉的关键知识点,网络上介绍的文章不少,笔者简单说两句作为科普。
由于 GPL 协议开放源码的原因,任何人都应该能获得发行版的源代码,从而自行修改、构建出最小使用范围仅属于自己的 Linux 操作系统。笔者曾经最喜欢做的事情就是通过各种改 Kernel 而突破限制实现软超频。
如果进一步地将这个自己用的操作系统通过传播渠道进行分发,比如放在网站上让人下载,那这个自己用的操作系统就成了一个发行版。
但是,Linux 操作系统不仅仅是个玩具。将其用于生产场合时,它需要具备足够的可靠性和兼容性这两个最低要求的特性。
为此,Linux 发行版的开发商需要付出成本:从开发源码社区获取构成操作系统各个组件的源代码,耗费时间解决这些组件代码之间的版本依赖关系,调校编译器参数编译出兼顾效率和稳定性的目标代码(C++编译器是有性格的,懂的都懂),还要进行各种测试确保其没有明显的缺陷,这才只实现了可靠性一件事。
要在操作系统生命周期内维持兼容性,就还要坚持进行向后移植(参见:《一线大厂是如何实施代码向后移植的》),所以,仅此两项就可以说明在发行版生命周期内,发行版开发商的总成本其实相当高。
这也是为何能提供详尽的产品文档的发行版并不多,因为编写产品文档是构成总体成本的另一重头成份。而安全加固基准就是产品文档之一,发行版厂商自然就能省则省了。
如果市场上已经有某个 Linux 发行版的稳定性是已经得到了时间检验的,那么基于这个发行版的源代码而构建出新的发行版,就是最理性的做法。也因此,原发行版和新发行版两者就构成了上下游关系。
下游发行版通常是专门针对某一个特定领域对原发行版进行修改,既可能是组件功能上的,也可能是用户使用方向上的。前者最常见就是换桌面,后者典型如裁减适配工业用途,比如非实时的嵌入式计算。
大多数国产操作系统的起源都是从替换桌面开始。
上下游关系的重要性在于结合软件供应链安全而充分掌握自己的IT环境的风险因素,从而能采取有效的缓解和控制措施。
这一点在之前《国产化替代:观察漏洞修补的及时性以供应链关系选择操作系统》和《9.9 高分漏洞!国产操作系统发补丁谁最快?》里面已经充分表达了。
首先当然是看发行版开发商自己的说明。
比如国内发行版 Circle Linux,其网页上明确指出自己就是充当了以前 CentOS 的角色,也就是 RHEL 的下游。 类似的还有 Rocky Linux。
其次可以看一些表面特征。这不是说 UI,而是说比如预编译的软件仓库能否共享。
因为,如果一个发行版能直接使用另一个发行版的软件仓库,那么两者之间很大程度上就会有上下游关系。比如,Ubuntu 的下游发行版如 Linux Mint 和 elementary OS 都能直接利用 Ubuntu 的软件仓库。如果发行版是基于 RHEL 的,那么除了应该能使用 EPEL 仓库之外,还应该能使用包括 Remi 和 RepoForge 等第三方的软件仓库。
如果预编译的软件包可以直接安装使用,不会出现安装后各种报找不到动态加载库甚至直接就 Segmentation Fault 的情况,那这上下游关系性质就是很直接的。
再技术一点,还可以通过源代码 RPM 包 REBUILD 的方式间接地判断是否存在上下游关系。
比如有软件A,在与发行版B直接相关的任何软件仓库内都没有提供预编译的 RPM 包。假如在发行版C获得软件A的源代码 RPM 包,不加任何修改地在发行版B的环境执行 REBUILD 过程,就可以获得能正常运行的目标代码 RPM 包,那么发行版B和C之间就存在上下游关系,且发行版C大概会是发行版B的上游。
这个操作的性质,和基于软件分发源代码 tarball 进行例牌的 configure / make / make install 三部曲是有区别的。因为不仅需要 Linux Kernel、GLIBC 这两个最基本的依赖项是能兼容的版本,还需要其他相关依赖项都要兼容,尤其是这些依赖项都可能被原发行版厂商实施过代码向后移植。
另外,国产操作系统很常见的情况是保持用户态软件环境兼容某一上游发行版,Linux Kernel 就用比较新的 LTS 版本替换掉。对于这种做法,笔者认为是存在风险的,替换后需要进行大量的测试以确保稳定性和兼容性。
道理其实很简单:
因为 Linux Kernel 被 GLIBC 调用,GLIBC 被几乎所有用户态软件调用,所以“只替换 Linux Kernel”并不能简单地保证兼容性,潜在还要替换上新版本的 GLIBC,继而影响所有的用户态软件,这还未算上 GCC 编译器的版本也可能需要变更。
虽然有多种方法可以应对不重新编译而继续使用原有目标代码时可能出现的兼容性问题,比如运行 Docker 容器,但这不是对所有用户态软件都适用的办法,尤其是没理由作为操作系统本身组成部分的软件组件都要用 Docker 等兼容性处置方法。
对 Linux 操作系统结构感兴趣会动手的朋友必定像笔者那样尝试过自己编译替换 Kernel 和 GLIBC,知道这坑有多大。
存在上下游关系的发行版之间,下游的发行版可以直接使用上游的安全加固基准。
假如前面说的发行版B。其厂商没有发布任何加固基准,那么用户就可以基于发行版B是发行版C的下游这一关系,直接使用发行版C的安全加固基准对发行版B的安装实例进行加固。
这对于现在很多国内操作系统厂商都没有专门编写和发布属于自己产品的安全加固基准文档的情况来说,是可行的做法。
如果要在管理上严谨一点,在参照实施之前,先进行一次验证确认,并将过程和结论文档化。
笔者尝试整理目前新的国产操作系统上下游关系,花了一个星期整理了一张表,所以公众号隔了这么长时间才发。
但从公开信息和当前的实验结果来看,根本无法保证表格内容的正确性和全面性,所以最终还是把表格从本文删掉了。
粗略来看,要整理这个关系存在两个主要困难:变化大和复杂性高。
有些国产发行版,不同的大版本有不同的上游。
有些国产发行版,同一大版本内细分多个子版本,每个子版本对应不同的上游。
有些国产发行版,上游说它是我下游,它说我的上游是另一个。
对于这种乱状,只能用“转型期的阵痛”来概括,具体就不点名了。
到这里可能会有读者吐槽,你这文是“听君一席话如听一席话”,实际是啥都没说,我要的是你没整理完的那个表。
笔者也觉得挺无奈的。
结合上面第四、五两点来说,笔者建议是用户直接向厂家咨询,究竟自己在用的操作系统,有无成文的安全加固基准,如果没有,可以参照谁家的。厂家没理由不回答这个问题。
从信创转型现状,加上最近一些国标设计的条款内容来看,国产操作系统的安全加固基准文档化这件事短期内是难以获得发行版厂商给予足够的投入的。
除了像 Windows 10 生命周期终结在即,TC260 有可能再牵头出加固实践指南之外,其他操作系统尤其是国产的,TC260 依然不可能牵头。
所以笔者估计,自己写完这篇之后,加固基准这件事也只能再扔下一段时间。
注:题头图用豆包生成,命名为《操作系统之树》。
本站微信订阅号:
本页网址二维码: