10.12

查看英文版

10.12 开源与闭源

概述与动机

几乎所有现代系统都是自研软件、采购软件和免费获取软件的混合体。其中后两类都涉及一个根本性的选择:这个软件是开源还是闭源?开源软件(OSS)以一种许可证形式分发,赋予所有人使用、研究、修改和再分发源代码(即定义程序行为的人类可读指令)的权利。闭源软件,也称为专有软件,作为成品分发,其源代码由厂商保密。你在许可证下获得运行它的权利,但无权查看或更改其工作方式。还有一个中间类别,源码可见软件,会公开源代码供人阅读,但对使用、修改或再分发加以限制。按照标准定义,它是可见的,但并非开放的。

在比较两者之前,有两点需要澄清。首先,“free”一词含义模糊。社区将自由意义上的免费(可以修改和分享的自由,有时写作”libre”)与价格意义上的免费(零成本,“gratis”)区分开来。开源关乎自由,未必关乎价格。其次,开源许可证分为两大类。宽松式许可证(如 MIT、BSD 和 Apache 2.0)几乎允许你做任何事,包括将代码嵌入闭源产品之中。著佐权(Copyleft)许可证(如 GNU 通用公共许可证,GPL)要求你分发的衍生作品也必须以相同的开放条款发布,这是一种互惠规则,批评者称之为”病毒式”,支持者则称之为”share-alike(相同方式共享)“。

本章从两个角度审视这一选择。作为使用方,你要决定是采用开源组件还是专有组件。作为产出方,你要决定是否将自己开发的软件开源。对于大型企业,尤其是政府机构而言,这两项决策所涉及的分量都远超一份许可证文件。它们牵涉到采购(10.3 章)、数字主权(10.11 章)、供应链安全(4.2 章)、互操作性(3.8 章),以及自建还是采购的权衡计算(6.1 章)。

核心原则

  • 界定”开放”的是许可证,而非价格。 请阅读许可证;免费与开源是两个不同的概念。
  • 两种模式都不天然更安全。 两者都可能做得出色,也可能疏于维护;围绕代码的实践比它是否开放更重要。
  • 开放性是一种降低依赖的杠杆。 获取源代码是防止供应商锁定的终极保障。
  • 运维负担始终由你自己承担。 免费获取绝不等于免费运行;总体拥有成本才能揭示真实情况。
  • 保持差异化的部分闭源,商品化的部分可以开放。 将不构成你差异化优势的部分开源;守住能带来差异化优势的部分。
  • 著佐权(Copyleft)有其后果。 在把著佐权代码嵌入你要分发的产品之前,先理解其互惠义务。
  • 活跃的社区是资产;被遗弃的代码仓库是负债。 要评估项目本身,而不只是许可证。

建议

评估组件要看项目本身,而不只是许可证

在采用任何依赖项之前,无论开源还是专有,都要评估其健康状况:发布节奏、维护者的数量和多样性、对安全报告的响应速度,以及采用的广泛程度。一个只有单一维护者的开源库,与一家小型专有厂商,承担着相同的巴士系数风险(即如果一位或少数几位关键人员离开,项目就会崩溃的风险)。优先选择拥有广泛贡献者群体的组件,或财务状况稳健的厂商,并将这一评估记录为尽职调查的一部分(10.2 章、4.2 章)。

将许可证的阅读与跟踪作为一等义务

维护一份记录每个组件及其许可证的清单,并执行一项策略,规定哪些许可证类别适用于哪些用途。关键的区分在于著佐权(Copyleft)。宽松式代码(MIT、Apache 2.0)通常可以自由嵌入闭源产品中。强著佐权(GPL)可能要求你以相同条款发布自己分发的衍生作品。使用自动化的软件成分分析(SCA)工具,扫描你的依赖项以识别组件、许可证和已知漏洞,并生成软件物料清单(SBOM)()一份正式列出产品中每个组件的清单(10.3 章、4.2 章)。

依据实践而非开放性来判断安全性

不要因为“众目睽睽”论(Linus 定律:“只要有足够多的眼睛关注,所有缺陷都无所遁形”)就想当然地认为开源是安全的。也不要因为隐蔽式安全(认为隐藏源代码就能隐藏缺陷的错误观念)就想当然地认为专有代码是安全的。“众目睽睽”只有在真正有合格的人去审查时才有效,而许多被广泛使用的项目实际上维护力量十分薄弱。两种模式都存在供应链风险:开源软件的风险来自被攻陷或被遗弃的依赖项,专有软件的风险则来自你无法审查的不透明代码和更新渠道。无论采用哪种模式,都要固定版本、验证来源、持续扫描,并监控安全公告(4.2 章)。

为退出和互操作性而设计

优先选用支持开放标准和可移植数据格式的组件,以便日后能够替换它们(3.8 章、10.11 章)。使用开源软件,你能获得终极的退出方式:如果某个项目停滞不前,你可以分叉(fork)它(创建并维护你自己的副本)。使用专有软件时,则要提前协商好保护条款:开放格式的数据导出、有文档记录的 API,以及源代码托管(source-code escrow)(一种法律安排,厂商将源代码交由第三方保管,一旦厂商倒闭便释放给你)。在设计时确保无论哪种类型,都不会有单一组件能够挟持你的整个系统。

权衡总体拥有成本,而非标价

在总体拥有成本(TCO)()涵盖采购、集成、运营、支持、培训、升级及最终替换在内的全生命周期成本()的基础上比较各选项,而不仅仅比较许可费用。开源软件往往是用运维和人力成本换取许可成本的降低。专有软件则往往是用可预测的订阅费用换取更多的锁定和更少的掌控权。要把模式本身的成本也计算在内:自行支持的开源需要内部技能,而专有软件则需要供应商管理能力。

作为产出方,将不构成差异化的部分开源

把你自己的软件划分为两类:能带来竞争优势或使命优势的部分,以及未形成差异化的基础组件。将差异化部分保持专有。考虑将商品化的基础设施开源,让一个社区能够共同分担维护和改进的工作。对于政府机构而言,要权衡“公共资金,公共代码”原则(即纳税人资助的软件默认应当公开可用),将其作为推动透明度、复用和主权的驱动力(10.5 章、10.11 章)。要有意识地选择许可证:追求最大化采用时选宽松式,追求保持生态系统开放时选著佐权式。

权衡取舍:优缺点

维度开源闭源/专有
获取成本通常零成本获取许可费或订阅费
总体拥有成本成本转移到运营和人力上更可预测,但存在锁定溢价
掌控与定制完全掌控:你可以阅读并更改源代码仅限于厂商开放的范围
支持与问责依靠社区或付费第三方;没有单一的责任主体可以追究有合同支持,且有明确的责任方
安全态势可审计;若确实有人维护,则有”众目睽睽”之效由厂商管理;不透明;隐蔽本身不等于保护
长期存续/被遗弃风险若有维护,可以分叉;但也可能逐渐凋零取决于厂商的存续能力和路线图
供应商锁定低:源代码和开放格式便于退出高,除非通过标准和源代码托管加以缓解
生态系统开放的社区和互操作性经过策划、集成化,有时是封闭的

反复出现的张力是掌控与便利性、问责性之间的取舍。开源最大化了掌控力、可审计性和免于锁定的自由,但要求你自己提供能力、集成和支持。专有软件提供了一个有支持、有集成、可问责且有合同可以约束的产品,但代价是让渡掌控权并招致锁定。这个问题很少是非此即彼的。大多数成熟的技术资产会把开源基础与专有系统混合使用,在支持、问责或专业能力足以证明这种取舍合理的地方,选用专有系统。

与团队讨论的问题

  1. 我们是否在流水线中通过自动化的 SCA 和 SBOM 来执行许可证策略,尤其是在强著佐权代码发布之前就将其捕获? 将一个 GPL 库嵌入一个要分发的专有产品,可能会迫使你公开自己的源代码,而这种意外通常在为时已晚、纠正成本高昂时才会浮现。维护一份记录每个组件及其许可证的清单,执行哪些许可证类别适用于哪些用途的规则,并自动运行软件成分分析,让流水线在发布前就拦截违规,而不是等律师在发布时才发现。把生成 SBOM 作为常规做法。对于大型或政府技术资产而言,这也是供应链卫生的一部分,往往还是采购的强制要求。带上你们当前的许可证清单,或者如果没有清单,就带上这个事实本身,并确定由谁来负责这项策略。

  2. 在采用一项依赖之前,我们是否会将项目健康度和巴士系数作为尽职调查的一部分来评估? 一个只有单一维护者的开源库,与一家小型专有厂商,承担着相同的风险:如果一位或少数几位关键人员离开,项目就会崩溃。在采用任何组件之前,评估其发布节奏、维护者的数量和多样性、对安全报告的响应速度,以及采用的广泛程度,并记录这一评估。两种模式默认都不更安全;“众目睽睽”只有在真正有合格的人去审查时才有效,而许多被广泛使用的项目实际上维护力量十分薄弱。带上你们产品最依赖的三四个依赖项,逐一追问:需要多少人离开,这个问题才会变成你的问题。如果你答不上来,那正是你亏欠自己的一项评估。

  3. 当我们采购专有软件时,是否会提前争取退出保护? 专有软件用掌控权换取问责性和便利性,其隐藏成本是锁定:转换成本使厂商得以在你几乎无计可施的情况下提价或降低服务水平。要在签约之前、你还拥有议价能力的时候,协商好这些保护条款:开放格式的数据导出、有文档记录的 API,以及在厂商倒闭时会释放源代码的源代码托管。使用开源软件,你的退出方式是分叉的能力;使用专有软件,你则必须把退出条款写进合同里。带上你们最关键的专有系统,问一问:如果厂商把价格翻倍,或者倒闭了,实际会发生什么。如果答案是”我们就被困住了”,那就在续约时修改合同。

  4. 对于我们自己开发的软件,我们如何决定哪些开源、哪些保持闭源,又由谁有权做出这一决定? 一旦在某一方向上判断失误,你就会把真正构成你差异化优势的代码拱手让人;而在另一方向上判断失误,你就会囤积本可由社区乐于共同维护的商品化基础组件。这种相互竞争的压力是真实的:工程师希望获得公开代码仓库带来的招聘和声誉收益,而产品和法务部门则担心把优势拱手让给竞争对手,或暴露一个安全敏感的启发式算法。带上一份对你们系统的诚实分类,区分出使命差异化部分与未差异化的基础设施,并明确指出谁()个人或委员会()有权批准一次发布,因为由推送代码仓库的那个人临时做出的决定,正是核心资产泄露的常见途径。对于大型企业而言,这是一个组合策略问题;而对于政府机构而言,这还会与”公共资金,公共代码”原则相碰撞()即纳税人资助的软件默认应当公开()因此需要提前决定哪些例外情形(国家安全、欺诈检测、个人数据)足以证明保持代码闭源是合理的。

  5. 我们的自建还是采购比较,是否涵盖了完整的总体拥有成本,还是仍然把零许可费当作零成本? 关于开源最常见的财务错误,就是把”免费获取”误读为”免费运行”,然后才发现集成、运营、安全响应和付费支持的成本,远远超过了你所省下的那份许可费。这里的张力在于:专有订阅在发票上看起来昂贵,却隐藏着锁定溢价;而开源组件在发票上看起来免费,却把成本转嫁给了你自己的员工。针对两三项真实的决策,构建一个可比对的 TCO 模型:采购、集成、运营、支持、培训、升级、安全响应和最终替换,按整个生命周期而非第一年来计价。在企业或政府技术资产中,还要加上运营模式本身的成本,因为自行支持的开源需要你招募并留住内部技能人才,并把遗漏了这些项目的比较视为一种证据,而非一次真正的分析。

  6. 我们是依据实践来判断一个组件的安全性,还是依赖开放性标签()无论是”众目睽睽”还是闭源的保密性? 两种默认假设都是陷阱:“众目睽睽”只有在真正有合格的人审查代码时才能保护你,而许多被广泛使用的开源项目实际上依靠一位精疲力竭的维护者独自支撑;同时,依赖攻击者看不到代码而认为闭源安全,那是隐蔽式安全,而不是一项真正的控制措施。这场辩论之所以重要,是因为它决定了你把有限的安全投入用在何处,而诚实的答案是:两种模式都存在供应链风险,开源软件的风险来自被攻陷或被遗弃的依赖项,专有软件的风险则来自你无法审查的不透明更新渠道。针对你们最关键的组件带上证据:实际是谁在审查它们、安全公告的修补速度有多快、版本是否被固定、来源是否经过验证,以及你们是否生成了 SBOM。对于大型或政府技术资产而言,要把这一点与采购和持续扫描的义务挂钩,因为监管者会问你审查了什么,而不是源代码是否公开。

行业视角

初创企业。 跑道有限,因此要建立在开源基础之上,因为你负担不起许可费用,也希望在某个项目停滞时拥有分叉的自由。在发布前运行一次成分分析扫描,以免一个强著佐权库悄悄迫使你公开自己的源代码,并将你唯一真正的差异化优势严格保持闭源。如果有助于招聘,可以把一个小型、非关键的工具开源,但不要为自己无法承担的维护负担配备人手。

小型企业。 没有内部法务或平台专家,因此要把许可证视为一项不能读错的风险,而不是一个你能够精通的课题。优先选用有支持的专有工具,或由厂商负责补丁和问责的商业开源发行版,因为自行支持一套你无力运维的技术栈是一种虚假的节省。当你确实采用一个免费组件时,要检查其许可证是否允许你的用途,以及该项目是否确实有人维护,而非已被遗弃。

企业。 在这个规模下,问题在于如何在众多团队之间保持一致性:一份书面的许可证策略、在每条流水线中自动化的软件成分分析和 SBOM 生成,以及基于 TCO 而非各团队各自习惯的自建或采购决策。将开源和专有软件作为同一个组合来管理,在采购中把开放格式和源代码托管等退出保护标准化,并跟踪关键依赖项的健康状况,以免单个被遗弃的项目演变成一次事件。同时也要治理产出方这一面,制定明确的规则,规定组织哪些内容开源、哪些保持闭源。

政府。 采购规则、透明度义务和公共问责制塑造着每一项选择。权衡”公共资金,公共代码”原则()即纳税人资助的软件默认应当公开()以推动跨机构的复用和数字主权,同时为安全敏感或涉及个人数据的代码划出狭窄的例外情形。要求任何专有供应商提供开放格式的数据导出和源代码托管,以免厂商倒闭导致公共服务陷入困境,并公开非敏感的源代码,让公民能够审查约束他们的规则。

示例

初创企业。 一家由三位创始人组成的初创公司,把整个产品建立在开源基础之上(Linux、一个开源数据库、一个 Web 框架),因为它负担不起许可费用,也希望在某个项目停滞时拥有分叉的自由。在发布前,一位创始人运行了一次成分分析扫描,发现了一个强著佐权库,本会迫使他们公开自己的专有匹配算法,于是他们将其替换为一个采用宽松式许可证的等效组件。他们把这个算法()公司唯一的差异化优势()严格保持闭源,只把一个小型的内部日志工具开源,用以积累口碑并吸引工程师。

企业。 一家大型保险公司在开源基础之上运行其核心平台:Linux、一个被广泛使用的开源数据库,以及一个容器编排系统。但它购买了一套专有的精算建模套件,因为厂商的领域专长、监管认证和支持合同都物有所值,而且市面上没有可比的开源替代品。它为商业开源(由厂商支持的开源组件发行版)支付订阅费,以获得基础组件上的问责保障和补丁支持,同时把构成其差异化优势的定价算法严格保持专有并留在内部。TCO 分析(10.10 章)驱动着每一项选择,而非意识形态。

政府。 一家国家税务机构,在”公共资金,公共代码”政策下,基于开源组件和开放标准(3.8 章)构建了一项新的福利资格审核服务,使其他机构能够复用它,公民也能审查其中的规则。它把非敏感代码发布在一个公共代码仓库中,仅出于安全原因将欺诈检测的启发式算法保持闭源。这降低了供应商锁定,并推进了数字主权(10.11 章)。采购规则(10.3 章)要求任何专有组件都提供开放格式的数据导出和源代码托管,以保证在供应商倒闭时服务仍能持续。

商业案例:动机、投资回报率与总体拥有成本

开源在财务上最具吸引力的一点()没有许可费用()恰恰是这个论证中最不可靠的部分,因为采购成本只占总体拥有成本的一小部分。真正持久的回报是战略性的:摆脱锁定的自由(能够更换或放弃某个供应商而无需重新架构)、便于安全与合规审计、因为工程师能够先试用再决定而带来的更快采用速度,以及整个行业共同分担商品化代码的维护工作。与之相抵的成本是真实存在的。你必须自行提供集成、运营和安全响应,往往还需要付费支持,一个选择不当、无人维护的项目在事件上造成的损失,可能超过任何许可费用。

专有软件的商业理由在于问责性和便利性:单一厂商对产品负责,一份你可以据以追责的支持合同,集成化的功能,以及可预测的预算。它的隐藏成本是锁定,即让厂商得以在你几乎无计可施的情况下提价或降低服务水平的转换成本,再加上对厂商偿付能力和路线图的依赖。常见的商业模式模糊了这条界限:开源核心(open core)(开放的基础加上专有的付费附加功能)、双重许可(同一代码同时以著佐权许可证和付费商业许可证提供)、软件即服务(SaaS)(软件作为托管服务运行,你按需租用,由于你从未持有二进制文件,源代码是否开放可能无关紧要),以及围绕本来免费的代码销售服务的支持/订阅模式。

对于产出方而言,将自己非差异化的软件开源所带来的投资回报率可能相当可观。外部贡献者能减轻你的维护负担。这个项目会成为招聘和声誉方面的资产。外部采用会让你的方案成为事实上的标准。对政府而言,这还能带来跨公共部门的透明度和复用。战略性的规则很简单:将商品化部分开源,以分摊其成本并培育一个生态系统;将差异化部分保持闭源,以保护支撑其他一切的那份优势。

反模式与陷阱

  • “免费即等于免费”: 把零采购成本当作零总体拥有成本,随后对运营和支持投入不足。
  • 对许可证视而不见: 将强著佐权代码嵌入一个要分发的专有产品,触发你从未计划过的义务。
  • 对”众目睽睽”深信不疑: 假定一个开源项目已被充分审查,而实际上它只有一位疲于奔命的维护者,且没有任何安全评审。
  • 隐蔽式安全: 仅仅因为攻击者无法阅读源代码,就认为闭源是安全的。
  • 意识形态上的绝对主义: 强制要求”全部开源”或”全部专有”,而不是根据实际情况和 TCO 逐个组件做出选择。
  • 忽视来源验证: 拉取没有 SBOM、没有版本固定、没有供应链验证的依赖项(4.2 章)。
  • 把核心资产开源: 发布了真正构成你差异化优势的那部分代码,把自己的优势拱手让人。
  • 分叉后弃之不顾: 分叉了一个被遗弃的项目,却没有能力真正维护这个分叉版本。

成熟度模型

第 1 级(启动)。 开源和专有组件随意进入技术资产。许可证无人阅读,没有清单或 SBOM,开源还是专有的选择仅凭习惯或价格决定。被遗弃和许可证风险只有在出问题时才会浮现,而且每个团队都是各自独立应对的。

第 2 级(发展)。 一些团队开始了基本的实践:组件与许可证清单、对可接受许可证的大致认识,以及偶尔进行的软件成分分析。自建或采购、开源或闭源的决策会被记录下来,但这一纪律在不同团队之间参差不齐,因此在尚未养成习惯的地方,著佐权或巴士系数方面的意外仍可能悄然发生。

第 3 级(标准化)。 一套有文档记录的框架在全组织范围内统一治理使用和产出两个方面。组件的选择依据 TCO 和项目健康状况,许可证在流水线中自动强制执行,违规会阻断构建,SBOM 的生成已成为常规做法,并有一项明确的政策规定组织哪些内容开源、哪些保持闭源。开放格式和源代码托管等退出保护措施已成为采购中的标准做法,每个团队都遵循统一的规则,而非各行其是。

第 4 级(管理)。 该项计划相对于基线被度量和控制。组织跟踪的指标包括:产品间的 SBOM 覆盖率、违反政策的依赖项占比、已披露依赖漏洞的平均修补时间、关键项目的巴士系数和健康度评分,以及实际达成的 TCO 相对于当初支撑该决策的预估值。阈值会触发相应行动:一个维护停滞或补丁延迟超出目标的组件,会依据证据被标记为需要替换,开源或闭源、自建或采购的决策也会依据这些数据而非习惯来复核。

第 5 级(编排)。 开源战略是一项经过深思熟虑、在组织内部集成并持续改进的业务能力。组织会为其所依赖的项目做出贡献,有时还会承担其管理责任,把不构成差异化的软件开源已成为常规做法,并将依赖健康度和 TCO 数据反馈到采购、安全和产品规划之中。组织会常态化地重新平衡其开源与专有软件的组合,在成本、风险、主权和战略优势发生变化迫使危机发生之前,主动做出调整。

讨论思路

  • 在你们的技术资产中,哪些地方一旦失去某个供应商或维护者会造成生死攸关的影响,你们的退出计划是什么?
  • 你们自己的哪些系统属于可以开源的商品化部分,哪些是需要保护的真正差异化优势?
  • 你们的组织是把”众目睽睽”当作一项真正的安全控制措施,还是一个从未被审视过的假设?
  • 对公共部门的读者而言:一项默认的”公共资金,公共代码”政策,会给你们下一次采购带来什么改变?
  • 你们的 TCO 比较,在多大程度上真实捕捉到了开源转嫁给你们的运营和支持成本?

关键要点

  • 开放与闭源由许可证界定,而非由价格界定;要理解自由意义上的免费与价格意义上的免费之间的区别,以及宽松式与著佐权式许可证之间的区别。
  • 两种模式都不天然更安全或更便宜。 要评估项目的实践和完整的 TCO,而不是仅凭开放性这个标签。
  • 开放性是对抗锁定的最有力手段,能带来可审计性、可移植性和分叉的能力;专有软件则是用掌控权换取问责性和便利性。
  • 逐个组件依据实际情况做决定,并有意识地混合使用不同模式,而非依赖意识形态。
  • 作为产出方,把商品化部分开源,把差异化部分保持闭源,而在政府场景中,要为透明度、复用和主权权衡”公共资金,公共代码”原则。

参考文献与延伸阅读

  • Eric S. Raymond,The Cathedral and the Bazaar
  • Nadia Eghbal,Working in Public: The Making and Maintenance of Open Source Software
  • Karl Fogel,Producing Open Source Software: How to Run a Successful Free Software Project
  • Adrian Cockcroft 等,多本关于开源战略与运营的 O’Reilly 书目
  • Free Software Foundation,The Free Software Definition(以及 GNU 通用公共许可证文本)
  • Open Source Initiative,The Open Source Definition 及获批许可证列表
  • Free Software Foundation Europe,Public Money, Public Code 活动资料
  • Yochai Benkler,The Wealth of Networks