跳转至

许可证判断练习

主要作者

@Dreadful-Me

本节用途

这是第 3 次课「许可证与合规」的当次成果。练习以真实项目为素材,完成本节后你应当能够独立判断一个项目的许可证、判断自己的使用方式是否触发义务,并说明理由。

学习目标

完成本节后,你应当能够:

  1. 从仓库中定位许可证信息,并写出正确的 SPDX 标识符;
  2. 针对具体使用方式,列出需要履行的义务;
  3. 判断两个许可证能否组合,并给出理由;
  4. 用可追溯的方式(链接、LICENSE 原文、SPDX 标识符)记录你的判断依据。

一、先学会查证

在判断之前,先完成四个查证动作:

  1. 打开仓库根目录的 LICENSE(也可能是 LICENSE.txt、COPYING、LICENSE.md),确认许可证名称与版本;
  2. 查看包元数据中的许可证字段:package.json 的 license、pyproject.toml / Cargo.toml 的 license、pom.xml 的 <licenses>;
  3. 查看源码文件头是否使用 SPDX 标识符,例如 SPDX-License-Identifier: Apache-2.0;
  4. 用 SPDX License List 核对标识符的标准写法。

仓库里的许可证可能不止一个

大型项目常见"混合许可":主目录一个许可证,某些子目录另有许可证(例如固件、文档、图标)。查看 LICENSES/ 目录、NOTICE、README 中的许可说明,以及文件级 SPDX 标识符。

二、练习 A:识别许可证并写出 SPDX 标识符

阅读下表项目的许可证,写出标准 SPDX 标识符。若项目存在许可证变更历史,请注明"当前"。

# 项目 你在 LICENSE 中会看到的名称 你的答案(SPDX)
1 Linux 内核 GNU General Public License v2.0
2 Kubernetes Apache License 2.0
3 React MIT License
4 Nginx BSD 2-Clause "Simplified" License
5 Go BSD 3-Clause "New" or "Revised" License
6 Mozilla Firefox Mozilla Public License 2.0
7 glibc GNU Lesser General Public License v2.1 or later
8 Nextcloud GNU Affero General Public License v3.0(or later)
9 OpenTofu Mozilla Public License 2.0
10 Valkey BSD 3-Clause "New" or "Revised" License
参考答案
  1. GPL-2.0-only(注意:内核不是 or-later)
  2. Apache-2.0
  3. MIT
  4. BSD-2-Clause
  5. BSD-3-Clause
  6. MPL-2.0
  7. LGPL-2.1-or-later
  8. AGPL-3.0-or-later
  9. MPL-2.0
  10. BSD-3-Clause

易错点:第 1 题写成 GPL-2.0 或 GPLv2 不得分——SPDX 要求区分 only 与 or-later,这个区别直接决定兼容性判断。

三、练习 B:判断义务

对每个场景回答三个问题:(1) 我的产品可以闭源吗?(2) 我必须开源我的修改吗?(3) 我必须提供源码吗? 并写出一句理由。

# 场景
1 在闭源商业 App 中使用 MIT 许可的库
2 把 BSD-2-Clause 的组件嵌入自研闭源网关设备
3 修改 LGPL-2.1-or-later 的 glibc,并以动态链接方式用在对外分发的闭源产品中
4 基于 Apache-2.0 的 Kubernetes 制作闭源发行版并对外销售
5 修改 GPL-2.0-only 的 Linux 内核驱动,随硬件出货
6 原样运行 AGPL-3.0-or-later 的 Nextcloud,供员工在内网使用(未修改源代码)
7 修改 AGPL-3.0-or-later 的 Nextcloud,部署为对外提供服务的 SaaS
8 把 BUSL-1.1 的 Terraform 打包成托管服务对外售卖
9 修改 MPL-2.0 的 Firefox 中某一个源文件后分发整个浏览器
10 使用 ODbL-1.0 的 OpenStreetMap 数据生成衍生数据库并公开提供
参考答案与理由
  1. 可以闭源;不必开源修改;不必提供源码。 只需在产品中保留版权声明与 MIT 许可证文本。
  2. 可以闭源;不必开源修改;不必提供源码。 保留声明与免责声明即可。
  3. 可以闭源(你的程序);但你修改后的 glibc 需要以 LGPL 提供源码,并且必须让用户能够替换该库版本。 LGPL 是库级 copyleft,这些义务由向他人分发触发——本题题设即对外分发;若只在组织内部运行、不对外分发,则修改与运行本身都不触发源码提供义务。动态链接通常已满足「可替换」要求;静态链接需额外提供目标文件以便重新链接。
  4. 可以闭源;不必开源你的修改,也不必让修改部分继续采用 Apache-2.0。 Apache-2.0 第 4 节允许你以不同条款发布修改或衍生作品;你只需继续满足:保留版权与许可证声明、附上许可证文本、保留 NOTICE 文件的内容、并在修改过的文件中标注修改。Apache-2.0 没有传染性——把它当成 copyleft 是常见误解。
  5. 不可以只在"整体"层面理解:内核是 GPL-2.0-only,分发即触发源码义务,必须提供修改后的内核源码(含你的驱动修改),以及构建与安装所需的脚本。你自己的用户态 App 若通过系统调用使用内核,通常不被视为衍生作品。
  6. 未修改时不触发第 13 条的源码提供义务。 AGPLv3 第 13 条的表述是"if you modify the Program"——它针对的是修改后的版本在用户通过网络与之交互时生效。因此原样部署并不自动产生源码义务(但仍须遵守许可证的其它条款、保留声明)。关键在"是否修改",不在"是否对外"。
  7. 必须向使用者提供对应源码。 第 13 条的触发条件是"修改 + 用户通过网络与之交互",没有内外部之分:修改后的版本必须向所有通过网络使用它的用户(包括公司内网的员工)显著提供获取对应源码的机会,且不以分发二进制文件为前提。"只在内网用""没有对外发布"都不是豁免理由。
  8. 不被允许。 BUSL-1.1 是 source-available 许可证,不是开源许可证;它限制把软件作为竞争性服务提供。需要与版权方另行取得商业授权。
  9. 需要提供所有 MPL 覆盖文件的源码,但不包括你自己的独立文件。 MPL-2.0 §3.2 规定:分发可执行版本时,必须提供全部 Covered Software(即所有以 MPL 授权的文件,无论你是否修改过)的 Source Code Form;你不能只提供自己改过的那一个文件。同时,MPL 的 copyleft 不扩散到你新增的、不属于 Covered Software 的文件——它们可以作为 Larger Work 的一部分保持闭源。这才是"文件级 copyleft"的准确含义。
  10. 公开使用衍生数据库时需要履行的不是一条义务,而是三条。 ODbL-1.0 里分别规定:

  11. §4.4(Share Alike):你公开使用(Publicly Use)衍生数据库,该衍生数据库本身只能按 ODbL-1.0、其后续版本或兼容许可证授权;

  12. §4.6(Access to Derivative Databases):只要你公开使用衍生数据库,或公开使用由它产生的 Produced Work,就必须向接收者提供机器可读形式的:① 完整的衍生数据库,或 ② 包含你对原数据库所作全部改动的文件(例如算法或差分文件)。这条不要求你"以数据库形式分发"——公开一张由该衍生数据库生成的地图或报告同样会触发;经互联网提供时还必须免费;
  13. §4.3(Notice for using output):公开使用 Produced Work 时,必须附带足以让接触者知道"内容来自该数据库、且依本许可证提供"的声明。

需要区分的是:只在内部使用、既不公开使用也不分发时,不触发上述开放义务。

四、练习 C:兼容性判断

判断下列组合是否可以在同一个项目中同时使用。若不兼容,说明原因并给出两种可行的处理方式。

# 组合
1 MIT 库 + GPL-3.0-only 主程序
2 Apache-2.0 组件 + GPL-2.0-only 内核模块
3 GPL-2.0-only 代码 + GPL-3.0-or-later 主程序
4 MPL-2.0 库 + GPL-2.0-or-later 主程序
5 SSPL-1.0 组件 + MIT 主程序(对外宣称项目"开源")
参考答案与理由
  1. 兼容。 宽松许可证不附加冲突条件,组合后整体按 GPL-3.0-only 履行义务,并保留 MIT 声明。
  2. 不兼容。 Apache-2.0 的专利与免责条款附加了 GPLv2 不允许的额外限制;GPL-2.0-only 又无法按 v3 使用。处理方式:① 由相关版权方专门授予兼容性例外(例如针对该代码的双许可声明)——注意内核 COPYING 中关于「正常使用系统调用」的说明只用于区分独立的用户态程序,并不构成让 Apache-2.0 代码进入 GPL-2.0-only 内核模块的通用例外;② 用独立进程/RPC 隔离,使两者不构成同一衍生作品;③ 换成 GPL-2.0-only 兼容的组件。
  3. 不兼容。 GPL-2.0-only 明确不允许按后续版本使用,因此无法与 v3 代码链接。处理方式:① 取得把该组件按 or-later 授权的许可;② 替换为 GPL-2.0-or-later 版本或 MIT/Apache-2.0 组件。
  4. 有条件兼容。 MPL-2.0 原文 §1.12 把次级许可证定义为 GPL 2.0、LGPL 2.1、AGPL 3.0 以及这些许可证的后续版本;§3.3 允许在与次级许可证作品组合的 Larger Work 中,额外按该次级许可证分发 MPL 覆盖的代码。前提是 Covered Software 不属于 §1.5 定义的 Incompatible With Secondary Licenses:既没有初始贡献者附上的 Exhibit B 不兼容声明,也不是原先按 MPL 1.1 或更早版本提供、却未同时按次级许可证提供的代码。须逐个文件核查声明及原始授权历史,不能仅凭文件头没有 Exhibit B 声明就判定兼容。注意 only 后缀限制的是被许可人自行升级版本,并不把该版本排除出次级许可证列表。
  5. 不可以称为开源。 SSPL 未通过 OSD,不是开源许可证。处理方式:① 替换为 AGPL-3.0-or-later 等真正的开源组件;② 明确项目定位为 source-available 并如实描述,不得声称开源。

五、练习 D:综合场景(固件产品)

某公司要发布一款智能音箱,技术栈如下:

  • 内核:Linux(GPL-2.0-only),并修改了两个驱动;
  • 用户态工具:一个 GPL-3.0-or-later 的媒体解码工具,修改后静态编译进固件;
  • 自研 App:闭源,内部使用一个 MIT 库和一个 Apache-2.0 库(含 NOTICE 文件);
  • 设备:启用安全启动,禁止用户刷入修改后的固件与内核。

请回答:

  1. 哪些部分必须提供源码?向谁提供?
  2. 自研 App 是否可以闭源?
  3. "禁止用户刷机"是否违反许可证?如果内核改用 GPL-3.0-only,结论会怎样变化?
  4. 公司应当准备哪些合规材料?
参考答案与评分要点
  1. 必须提供:修改后的内核源码(含驱动修改)、修改后的 GPL-3.0-or-later 解码工具源码,以及构建、安装所需的脚本与信息。提供对象是获得该二进制固件的任何用户(购买设备即获得)。MIT 与 Apache-2.0 库不需要提供源码,但需随固件附带其许可证文本与 NOTICE。
  2. 可以闭源。 自研 App 若未链接 GPL 代码(静态编译解码工具时需要确认是否与 App 构成同一作品,若构成则整个作品受 GPL 约束——这是本题的陷阱)。
  3. 在 GPLv2 下,"禁止刷机"本身不直接违反许可证,因为 v2 没有反 Tivoization 条款——这正是 Linux 内核停留在 GPLv2 的现实原因之一。若内核改用 GPL-3.0-only,第 6 条要求提供"安装信息"(Installation Information),使修改后的软件能够被安装并运行;此时继续用安全启动阻止用户刷机将违反 GPLv3。
  4. 至少准备:许可证清单与 SPDX 标识符、SBOM、修改文件的差异记录、源码获取方式(随附或可长期访问的下载地址)、第三方声明与 NOTICE 汇总、合规审查记录。

评分要点:能否区分"分发触发"与"网络交互触发";能否识别静态编译带来的衍生作品风险;能否说明 GPLv2 与 GPLv3 在反 Tivoization 上的差异。

六、练习 E:找错

下面是一份同学提交的合规结论,请指出其中的所有错误并改正:

我们的产品使用了一个 MIT 许可的库和一个 GPL-3.0-or-later 的工具。因为 MIT 是"无传染"的,GPL 是"传染"的,所以整个产品必须开源。另外我们没有修改 GPL 工具,所以不需要提供源码。许可证写在 README 里就可以了,不必单独放 LICENSE 文件。

参考答案

错误 1:"整个产品必须开源"——错误。需要判断 GPL 工具与产品是否构成同一衍生作品。若只是独立进程调用,产品可闭源;若静态链接或复制代码,则整个作品受 GPL 约束。

错误 2:"没有修改就不需要提供源码"——错误。GPL 的义务源于分发,而不是修改。分发二进制时必须提供对应源码(即使未修改)。

错误 3:把 Apache-2.0 之外的许可证简化为"传染/无传染"二元——错误,忽略了 Apache-2.0(宽松但含专利条款)、MPL-2.0(文件级)等中间类型。

错误 4:"许可证写在 README 里就可以"——错误。应在仓库根目录放置完整的 LICENSE 文件,并在包元数据与源码文件头使用 SPDX 标识符;README 中的说明不能替代许可证文本。

七、评分标准

维度 分值 达标要求
许可证识别 20 SPDX 标识符完全正确,能区分 only 与 or-later
义务判断 30 四类行为(使用/修改/分发/网络服务)的判断准确,理由指向具体条款
兼容性判断 25 结论正确且能说明冲突来源,能给出可执行的替代方案
综合场景 15 能区分内核与用户态的边界,能说明 GPLv2/v3 的差异
证据与规范 10 判断均附 LICENSE 原文或 SPDX 链接,术语使用规范

完成标志

你能够对一个你从未见过的真实仓库,在 15 分钟内给出:SPDX 标识符、四类行为的义务判断、是否存在兼容性风险,以及一句可写入贡献提案的结论。