开源雨林

开源雨林是由华为技术有限公司和开放原子开源基金会、中国软件行业协会、中国科学院软件研究所、中国信息通信研究院等组织共同发起,围绕开源通识、开源治理和开源使用实践等方向构建一个用于收集、分享开源知识分享社区的经验。

编译开源雨林

开源雨林的内容实用 mdbook 进行编写,并通过 开源雨林 发布。

安装 mdbook

  1. 在本地安装 mdbook 命令编译预览页面。在 mdbook 的官方发布页面 下载对应架构的程序包,并将其解压到本地的目录,并把目录添加到 PATH 环境变量中。
  2. 在本地通过安装 Rust ,然后通过 Rust 安装 mdbook 命令。
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo install mdbook
# 或
cargo install --git https://github.com/rust-lang/mdBook.git mdbook

编译开源雨林

下载开源雨林到代码到本地,并解压编译

wget https://github.com/opensource-rainforest/osr/archive/refs/heads/main.zip
tar -xzf main.zip
cd osr-refs-main
mdbook build
mdbook serve

在浏览器中打开 http://localhost:3000 访问开源雨林的内容页面。

品牌

开源雨林 Logo

开源雨林网站(以及内容托管平台)上使用和显示的所有商标、标志皆属开源雨林社区所有,但注明属于其他方拥有的商标、标志除外。未经开源雨林社区或其他方书面许可,开源雨林网站(以及内容托管平台)所载的任何内容不应被视作以暗示、不反对或其他形式授予使用前述任何商标、标志的许可或权利。 未经事先书面许可,任何人不得以任何方式使用开源雨林的名称及开源雨林的商标、标记,除非你使用前述名称、商标和标记是出于个人、教育和非商业目的。任何人不得在未获得第三方同意的情况下使用第三方拥有的商标和标志。

License

开源雨林使用 Creative Commons Attribution-ShareAlike 4.0 International 协议。

开源文化与认知

第一节 - 开源软件的定义和它的发展历程

1.1 开源软件的三大组成要素

开源软件是一种源代码免费向公众开放的软件,任何团体和个人都可以在其 License 规定下对其进行使用、复制、传播及修改,并将修改形成的软件衍生版本再发布。(来源于 OSI 开源软件定义 [1])

开源软件的六大特点:

  1. 有特定的 License
  2. 可获得源代码
  3. 无许可费
  4. 无任何担保
  5. 可自由使用
  6. 享有版权

目前较为活跃的开源维权组织:

  1. 开源促进委员会(Open Source Initiative,OSI)(https://opensource.org)

    OSI 一直致力于提高对开源软件的认识和采用,并在开源实践社区之间架起桥梁。作为一个全球性的非营利组织,OSI 通过教育、协作和基础设施,管理开源定义(OSD),并防止滥用开源运动固有的理想和精神,在社会中倡导软件自由;

  2. FSF 自由软件基金会(https://www.fsf.org)

    自由软件意味着用户可以自由地运行、编辑、贡献和共享软件;

  3. Software Freedom Law Center(https://softwarefreedom.org)

    软件自由法律中心为免费、自由和开源软件的开发者提供无偿的法律服务。

1.2 开源推动着各领域发展

  • 萌芽期(1969-1990)主要由个人和大学发起 [2]
  1. 1971 年,作为哈佛大学的新生,Stallman 就开始在麻省理工学院(MIT)的人工智能实验室(后来的计算机科学与人工智能实验室)工作,他和 James Gosling 一起用 C 语言编写了 Emacs 文本编辑器。
  2. C 语言是美国计算机科学家 Dennis M. Ritchie 在 1969 - 1973 年与 UNIX 操作系统的早期开发一起设计的 计算机编程语言。该语言基于 CPL(组合编程语言),由美国计算机科学家 Ritchie 及其同事 Ken Thompson 于 1969-1970 年创建,首先被浓缩成了精简的 B 编程语言。之后,Ritchie 重写并恢复了 CPL 的功能创建了 C 编程语言并重写了 UNIX 操作系统。
  3. 1984 年,因担心 MIT 软件版权发生规则变化,Stallman 离开了麻省理工学院,并于次年创建非营利性自由软件基金会,专注于为 GNU 项目提供支持。
  4. 1990 年,获得麦克阿瑟奖学金,被誉为“天才奖”。该奖项帮助 Stallman 为 GNU 项目编写各种实用程序,例如 GNU Emacs 编辑器、GNU 编译器和 GNU 调试器。这些工具后来与芬兰计算机科学专业学生 Linus Torvalds 开发的内核相结合,制作了 1994 年的操作系统 GNU/Linux。
  • 成型期(1990-2005)非盈利组织(基金会)
  1. Linux 基金会 [3] :成立于 1991 年 10 月 5 日,是一个基于 Linux 内核的免费开源操作系统家族。基于 Linux 的操作系统被称为 Linux 发行版或发行版。
  2. Apache 软件基金会 [4] :成立于 1999 年 3 月 25 日,是一个专注于支持开源软件项目的非营利性组织。在它所支持的 Apache 项目和子项目中,所发行的软件产品都遵循 Apache License。
  3. Eclipse 基金会 [5] :成立于 2004 年 2 月 2 日,旨在为个人/组织的全球社区提供成熟、可伸缩、业务友好的开源软件协作和创新环境。
  • 快速发展期(2005-至今)
  1. 目前,各行各业的现代企业、大型 IT 企业都参与到开源中。Intel、IBM、Google 等企业均贡献了许多开源项目,如 OpenStack、Cloud Foundry、Kubernetes 等,包括华为的 openEuler、MindSpore 等项目都在创新引领着技术和商业的发展。现如今,开源软件已不再是单纯的个人业余爱好,而是企业间角逐商业利益和开放标准的战场。

第二节 - 开源不等于免费

2.1 开源≠免费

  • 经典案例:Cisco 产品因 GPL 传染遭开源维权诉讼!最终向 FSF 捐款数千万美金![6]
  1. Broadcom 在其 802.11 芯片中使用了 GPL 的 GUN/Linux 系统,Linksys WRT 54G 无线路由器使用了 Broadcom 的芯片,2003 年 Cisco 收购 Linksys 但未按照 GPL 规定将使用了该芯片的产品代码开源。
  2. FSF 于 2003 年开始与思科就该问题进行沟通,并帮助该公司了解其许可义务。当时,思科承认了自己的错误并陆续开放了 116 个型号路由器的源代码,但仍未达到 FSF 的要求。
  3. 2008 年,FSF 与 Cisco 之间的谈判破裂,FSF 对该公司提起了 GPL 侵权诉讼。
  4. 截至 2008 年,Cisco 依然拒绝开放所有相关源代码,FSF 与 cisco 谈判破裂,FSF 于同年 12 月 12 日对该公司提起了 GPL 侵权诉讼,Cisco 作出让步并根据 GPL 规定对开放源码进行调整。
  5. 2009 年 5 月 20 日,FSF 与 Cisco 达成和解,使用 FSF 软件的 Linksys 产品开放全部源代码。
  • 虽然开源软件使用者享有自由使用的权利,但其必须按照 License 的规定履行相应的开源义务,否则即违反了开源 License
  1. 使用声明义务:在对外分发产品时,需附上声明文档,注明产品所使用的开源软件名称、版权、License 内容等信息。
  2. 代码开源义务:将一定范围内的代码对公众开放,开源范围视具体 License 的要求和产品具体使用方式而定。

第三节 - 开源 License 合规风险

3.1 不同 License 约束内容的区别

以下 8 种 License 覆盖了开源软件中 90% 以上的代码,采用这些 License 的开源软件在业界应用也最为广泛;其中 GPL V2 对于开发者和二次开发者的义务要求最多,在使用时需加以关注。

类别典型项目许可证注意事项应用建议
BSD类Apache V2.0ACE Tomcat1、允许各种链接,无开源义务 2、允许修改,无开源义务 3、软件所有人授予专利许可商业友好型许可证
BSD类BSDFreeBSD1、允许各种链接,无开源义务 2、允许修改,无开源义务 3、无专利规定商业友好型许可证
BSD类MITASN.11、允许各种链接,无开源义务 2、允许修改,无开源义务 3、无专利规定商业友好型许可证
MPL类CPL V1.0JUnit1、允许各种链接,无开源义务 2、允许修改,但修改部分需要开源 3、截取部分或全部开源代码与私有源代码混合将视为对原始软件的修改,从而导致私有代码开源 4、软件所有人授予专利许可需关注修改后对应的开源义务
MPL类MPL V1.0FireFox1、允许各种链接,无开源义务 2、允许修改,但修改部分需要开源 3、截取部分或全部开源代码与私有源代码混合将视为对原始软件的修改,从而导致私有代码开源 4、软件所有人授予专利许可需关注修改后对应的开源义务
MPL类CDDL V1.0OpenSolaris1、允许各种链接,无开源义务 2、允许修改,但修改部分需要开源 3、截取部分或全部开源代码与私有源代码混合将视为对原始软件的修改,从而导致私有代码开源 4、软件所有人授予专利许可需关注修改后对应的开源义务
GPL类LGPL V2Jboss ml、 OpenOffice、UcLibc、SDL1、允许各种链接,动态链接无开源义务,静态链接需要开放与之链接私有软件的 .o 文件和 makefile. 2、允许修改再链接到私有软件,但修改增加的功能实现不能依赖私有软件的数据或功能 3、允许不受限制的使用头文件中的 numerical parameters(数值参数)、data structure layouts(数据结构布局) and accessors(存取)、or small macros(小宏)、inline functions(内联参数) and templates (ten or fewer lines in length)(十行以内的模板) 4、仅原则性声明专利应免费许可,无详细规定只允许动态链接方式使用
GPL类GPL V2Linux1、允许各种链接,但被链接的整个产品需要开源 2、允许修改,但被修改部分及整个产品均需开源 3、通过 pipes、sockets 和命令行参数与 GPL 软件进行通信,不会导致私有软件被传染 4、仅原则性声明专利应免费许可,无详细规定可能导致产品整体负有开源义务

3.2 “宽松”型 License ? 小心有坑!

  • 开源 License:所有开源软件都有其特定的 License,法律赋予用户相关权利和义务,任何开源应用行为都必须围绕此“游戏规则”进行。

    1. 权利:授予用户免费使用、修改、分发、商用等权利,包含版权授权,部分还有专利授权;
    2. 义务:规定用户在应用开源过程中必须履行的义务,如做出特定声明、开放特定代码等。
  • 案例:

    1. Facebook 在 Github 上发布了一系列开源项目,其中如 React(https://reactjs.org/)、Fresco (https://frescolib.org/)等,凭借先进的技术和宽松的 License(BSD),其项目广受用户欢迎;
    2. Facebook 除 BSD License 外,还额外增加了一份专利授权 License,将这些软件可能存在的 Facebook 专利授权给用户使用,但也正是这份专利 License,为这些软件的商业应用埋下了“地雷”,Apache 基金会甚至禁止 Facebook 的软件或代码进入 Apache 项目。
  • 解析:Facebook 的专利授权 License 除了授予用户使用其专利的权利外,还增加了对 Facebook 的专利保护条款,即如果 A 公司使用了该软件,如果 Facebook 在其业务范围内与 A 公司有任何其他专利冲突,A 公司均不得向 Facebook 发起诉讼保护自身的专利。[7]

  • 启示:

    1. 某些开源项目表面声明的 License 看似“宽松”,但可能潜藏风险,产品在引入开源软件时应获取其完整的 License;
    2. 若无法确定 License 风险,可先向企业法务部咨询,由法务部评估风险后再决定是否引入。

第四节 - 开源安全风险

4.1 开源社区安全

  • Linux [8]
  1. 项目诞生(1991)

  2. 支持 SELinux(2003)[9]

    安全增强型 Linux(SELinux)是一种采用安全架构的 Linux® 系统,它能够让管理员更好地管控访问系统的人员清单。最初由美国国家安全局(NSA)利用 Linux 安全模块(LSM)开发,用作 Linux 内核的一系列补丁。

  3. Syzkaller Fuzz关键(2016)[10]

    Syzkaller 是一个无监督的覆盖引导的内核模糊器。Linuxkernel fuzzing 的支持最多,akaros , freebsd , fuchsia , netbsd 得到 windows 不同程度的支持。

  4. KSPP 安全项目(2017)[11]

    为了让 Linux 内核本身具有对漏洞利用的防御能力,通过参考 PaX/Grsecurity 的实现来移植或重新实现类似的功能,并将其推进到 Linux 内核主线。

  5. Sigstore 签名服务(2021)[12]

    Sigstore 是由 Google,Red Hat 和 Purdue University 支持的 Linux 基金会项目,旨在通过便捷的加密软件签名提升软件供应链的安全性。

  • ASOP(https://asop.org/)
  1. 项目诞生(2008)
  2. 漏洞致谢(2009)
  3. 支持 SEAndroid(2014)
  4. 原生支持 Fuzzing(2017)
  5. 奖励开源软件安全研究(2019)

业界主流社区正逐步从单点安全特性向整体安全架构、供应链安全和安全基础设施等系统化建设方向发展。围绕开源件健康度和依赖度评估、漏洞感知与修复等系统化建设,是供应链安全发展的关键。

  • 开源软件存在的安全薄弱点:
  1. 缺少安全 Metadata(缺乏文档、LICENSE、反馈渠道、维护状况等);
  2. 未做到默认安全(使用不安全的加密算法、协议、设计等);
  3. 软件依赖链不明确(较难获知依赖链的安全状况)。
  • 开源软件漏洞风险:
  1. 漏洞库信息缺乏;
  2. 代码质量参差,存在漏洞风险。
  • Google 安全实践:
  1. 2020 年布局 OpenSSF 社区 [13](https://openssf.org/),构建开源社区安全能力量化评估体系;
  2. 2021 年发布 OSI(Open Source Insights: https://deps.dev/), 建立开源软件依赖链信息库;
  3. 2021 年发布 OSV(Open Source Vulnerabilities: https://osv.dev/),建立开源软件漏洞信息库,支持开源版本漏洞查询,开源的分布式漏洞数据库,一种用于生成和使用开源漏洞信息的开放、精确和分布式方法;
  4. 发布 OSS-Fuzz(https://github.com/google/oss-fuzz),平台及 Patch 奖励项目,提供 Fuzz 算力和修复资源,增强开源软件漏洞挖掘力量。

4.2 网络安全:OpenSSL 心脏滴血事件影响之大!

  • 心脏滴血已经是过去式了吗?NO!

    尽管许多网民在漏洞披露后都纷纷更新软件以修复该漏洞,但事隔一年多,臭名昭著的“心脏滴血安全漏洞”并未完全消失,其仍对近 20 万台网络设备存在安全威胁。大量设备未更新补丁,仍可被攻击! Shodan 创始人 John Matherly 在 Twitter 上发布了一张地图,上面列出了全球范围内仍受到该安全问题影响的国家:美国有 57272 台存在心脏滴血漏洞的设备,位居第一;德国 21060 台;中国 11300 台;法国 10094 台;英国 9125 台。

    安全顾问 Graham Cluley 指出:“很显然,有些制造商和 IT 团队并没有更新存在漏洞的系统。我敢打赌,肯定有些联网设备存在心脏滴血漏洞。” Matherly 指出,管理员们可以利用 Shodan 搜索工具检查它们的联网设备是否仍然存在心脏滴血漏洞。除了更新 OpenSSL 之外,管理员们还可以采取更进一步的安全措施:更改密钥、转储会话 cookies。

  • 开源安全漏洞传播速度快、影响大,快速排查并修复受影响的产品是降低影响的关键。

  • HeartBleed 漏洞概括:

  1. 2014 年,心脏滴血首次被发现,由于该漏洞允许攻击者利用 OpenSSL 软件库中的安全漏洞窃取目标设备上的密码等敏感信息,引发诸多恐慌。
  2. Heartbleed 漏洞是由于在 memcpy () 调用受害用户输入内容作为长度参数之前,未能正确进行边界检查,攻击者通过追踪 OpenSSL 所分配的 64 KB 缓存,将超出必要范围的字节信息复制到缓存中,再返回到缓存内容,从而使受害者的内存内容以 64 KB/次的速度进行泄露。

4.3 网络安全: Log4Shell漏洞影响面之广!

  • 案例:2021 年 11 月 24 日,在 Web 服务器软件阿帕奇(Apache)下的开源日志组件 Log4j 2.x 内发现漏洞,这个后来编号为 CVE-2021-4428 的漏洞花名为 Log4Shell。这一漏洞的存在,可以让网络攻击者无需密码就能访问网络服务器。网络安全管理公司 Cloudflare 首席安全官乔·沙利文(Joe Sullivan)表示,该漏洞允许恶意攻击者“远程执行代码”以获取对其他系统的访问,鉴于 Log4j 软件被广泛使用,这可能是迄今为止“最大的漏洞”。

  • 启示:

  1. 识别产品中正在使用的关键开源项目;
  2. 大规模使用开源软件的公司对开源软件要谨慎选择、持续维护。

第五节 - 开源治理构建基础能力

5.1 开源治理方法论

5.1.1 开源应用不当会导致的问题

主要考虑开源软件特点会带来的问题
License部分开源软件 License 强调回馈社区不遵守其 License 会被投诉甚至起诉。迄今相关纠纷超过百起,最严重的情况为侵权方被判停止销售侵权产品。
安全部分开源软件存在安全漏洞开源软件安全漏洞相对透明,传播快,影响大。
专利权开源软件的合作开发模式需要处理好不同开发者的知识产权问题开源软件领域知识产权纠纷的频频发生,如果将一些流行的私有软件代码公开,追溯知识产权的归属,也一定难逃诉讼。
采购开源软件应用十分广泛,外购软件也可能应用开源软件产品外购软件可能存在违规使用开源软件的风险,采购时需加于关注。
维护成本活跃开源软件更新很快,且将代码放入主版本需要技巧若自行修改了开源软件,就可能形成“私有开源代码”,需自行维护全部开源代码,成本极高。
保障社区不承诺技术支持职责需有外部或者内部团队掌握相关关键技术及获取社区技术支持的技能,否则将面临缺乏技术支撑保障的风险。

5.1.2 使用开源最基本要求:安全可信、合法合规

  1. 开源软件获取来源可信
    • 开源软件获取到来源需要从社区官网、供应商官网或开发商官网
    • 由供应商或合作企业提供的开源软件需要确认来源、版本、更新频率和更新方式等
    • 开源软件有明确的许可证或和供应商、合作企业签订有相关使用协议以及其他相关协议,确保软件使用的责任和权利是合法的
  2. 开源软件的网络安全可靠
    • 对开源软件的网络安全进行充分的评估,确认其安全性是在企业、产品的可控范围内
    • 对开源软件的漏洞处理能力进行评估
    • 对开源软件的漏洞收集、分发、处理、预警设计完整的流程
  3. 使用开源软件合法合规
    • 按照开源软件使用按许可要求,避免知识产权、License 带来法律风险
    • 如果使用供应商或合作伙伴提供的开源软件,要在合同上具有明确的授权才能使用,避免合同上没有明确授权,导致软件使用风险
  4. 企业内部使用开源软件过程透明
    • 使用开源软件化的企业,都应该在使用过程中明确告知开发商、供应商、合作伙伴等相关人员,避免使用开源软件的风险
    • 所有使用开源软件化的企业,需要在企业内部建立完整的使用流程,包括开源软件中央仓库,对于开源软件的使用需要管理,有修改记录可查
    • 对于开源软件的漏洞 E2E 需要 E2E 闭环管理

5.1.3 来源可信:植入木马案例

  • 案例:非官方 Xcode 被植入恶意代码

    这是一起发生于 2015 年 9 月的事件,起初大家以为只是个别开发者使用了非官方渠道下载的 Xcode,导致开发的应用编译出来含有恶意代码,并未引起大家的注意。 然而,事情绝非大家想象的那么简单。Appstore 中的很多应用相继检测出了恶意代码,其中包含:微信、网易、12306 等。虽然恶意代码的行为并不复杂,但其传播方式却非常独特。

    图灵奖获得者 Keen Thompson 一语成谶:看你还敢用网盘上共享的编译器!

  • 启示: 必须从官方渠道获取开源版本,使用前确保其来源可靠。

5.2 选择开源软件需要的考虑的因素

如何选择开源软件以满足企业的开发产品和平台需求?可以从以下几个方面加以考虑:

  1. 开源项目的功能是否满足产品的需求满足度
  2. 开源许可证是否满足产品分发和销售的要求
  3. 开源项目的技术是否领先
  4. 开源项目的软件成熟度如何(可参考 CHAOSS https://chaoss.community 基金会对开源项目的评估)
  5. 开源项目的运维能力,如何保证项目的可用性?
  6. 开源项目是否存在商业支持
  7. 开源项目的社区活跃度
  8. 开源项目对 Issue、CVE 的响应时间
  9. 开源项目是否存在健康的软件生态
  10. 是否需要对开业软件的社区旅行贡献义务
  11. 开源软件是否有第三方服务商提供商业支持

5.2.1 优选引入:以 XML 类软件选型为例

  • 从官网获取软件版本基本信息

    注意:是官网,不是代码托管网站(Maven/Pypi/Cargo 等代码托管网站并不是官网)

软件名称tinyxml2libxml2PugiXMLXerces-C++
语言C++CC++C++
最新版本7.0.12.9.9v1.93.2.2
最新版本发布时间2018/11/182019/1/42018/4/42018/3/14
官网http://leethomason.github.io/tinyxml2/http://xmlsoft.org/http://pugixml.org/http://xerces.apache.org/
Github/代码库https://github.com/leethomason/tinyxml2https://github.com/GNOME/libxml2https://github.com/zeux/pugixmlhttp://svn.apache.org/viewvc/xerces/c/?root=Apache-SVN
  • 分析开源软件 License
  1. 如果遇到 GPL 等高危 License,优先找商业友好 License 的替代软件
  2. 对于多 License 软件,需要解包进行 License 分析
  • 从漏洞、补丁的可获得性分析软件网络安全特征
  1. 从 NVD 漏洞库查询软件版本历史漏洞信息,检查备选版本是否有未修复的高危漏洞
  2. 看官网是否给出漏洞披露渠道,漏洞披露渠道不明确的不建议引入
  • Libxml2 提供完整的 bug 及漏洞披露跟踪页面

  • TinyXML2 仍有未修复的漏洞

  • 从软件活跃度看生命周期

  1. 处于研发衰退的阶段:
    • 无新 LTS 版本,或 2 个 minor 历史发布周期内无新 minor 版本发布
    • 代码几乎无增长,仅有少量开发者,没有新的 Maintainer 加入社区维护版本

5.3 License 遵从

5.3.1 开源使用声明义务

在对外分发或销售产品时,需附上声明文档,注明产品所使用的开源软件名称、版权、License 内容等信息。

  • 开源使用声明内容
    1. Software: 软件名称+软件版本号
    2. Copyright notice: 软件版权信息 (软件包中版权或说明文件/官网/代码文件头)
    3. License: 软件 License 信息(包含具体内容)

开源软件声明

  • 发布原则:随外软件的分发, 且显而易见。必须遵守“易于获取”原则,即能够让用户较为容易地获取查看声明文档的全量内容,实际发布方式由产品根据自身情况确定。

  • 代码要约文本(Written offer):若产品涉及代码对外开源义务的履行(如使用了 GPL、LGPL 等具有对外开源义务的软件),必须在使用声明中附上代码要约文本。

  • 软件版权信息 Copyright notice: Copyright© 1999-2004 busybox project. Copyright (c)

5.3.2 代码对外开源义务

常见 License 代码开源要求:

常见许可证类型典型软件触发代码开源义务前提条件开源要求和范围
BSD 类 如:Apache/BSD/MIT 等Tomcat、OpenSSL
MPL 类 如:MPL/EPL 等FireFox、Eclipse1、产品集成使用该软件,并对外分发或销售 2、产品对该软件进行了修改1、若无修改,则无需开源; 2、若对其进行了修改,需将修改的部分开源。
LGPLHibernate、glibc产品集成使用该软件,并对外分发或销售1、软件本身须开源; 2、具有传染性,静态链接部分的代码必须以 LGPL 许可开源,动态链接不被传染; 3、若对其进行修改,修改后增加的功能实现依赖于产品软件的数据或功能,则产品代码也会被传染。
GPL(GPLV2,GPLV3)Busybox、linux kernel产品集成使用该软件,并对外分发或销售1、软件本身须开源; 2、具有传染性,与其有链接关系的代码都必须以 GPL 许可对外开源,即与该软件在同一进程中运行的代码都必须开源。
AGPLBerkeley_DB产品集成使用该软件即便不对外分发,只要在网络服务器上使用 AGPL 软件提供网络服务,就需要履行相关开源义务。 例如:Berkeley_DB,即使没有“分发”动作,通过 WEB 形式为用户提供服务,也要履行对外开源义务。
  • 除 AGPL License 外,是否履行代码开源义务均与产品是否对外分发强相关。若产品需对外分发,则必须履行开源义务,反之亦然。

  • 部分产品中还集成了来自供应商的软件,若供应商软件中也使用了开源软件,产品应向供应商获取相应开源软件清单以及相关代码,以确保产品能对下游用户履行代码义务。

5.3.3 开源多 License 分析

  • 文件 LICENSE.txt 明确 License 可二选一:如 SJCL
  • 官网 LICENSE.txt 明确 License 唯一:如 cJson
  • License 文件明确不同的文件夹使用不同的 License:如 e2fsprogs,产品仅使用了 libdw 和 libelf,所以 License 是 GPL 2.0。

5.3.4 开源使用声明义务案例

  • **案例:**2015 年,德国开源维权人 McHardy 向多家 Android 手机厂商发起开源维权,涉案企业包括三星、MOTO、中兴等,赔款金额达数百万欧元,维权理由之一就是以上厂商销售产品时没有正确履行使用声明义务。[14]

  • **解析:**涉案的 Android 手机都使用了 Iptables 软件,其 License(GPL)明确要求分发者履行使用声明义务,但涉案手机的使用声明文档中并没有包含 Iptables 的声明。

  • 启示:

  1. 几乎所有可商用的开源软件 License 都具有开源使用声明义务要求。
  2. 涉及对外分发销售的产品中若使用了开源软件,必须在分发时使用声明文档中全量声明,不得缺失。

5.3.5 代码对外开源义务案例

  • **案例 1 :**2009 年,SFC 代理 busybox 社区起诉三星、百思买等 14 家公司,指控其生产的电视、DVD 播放器等产品违反了 GPL 协议,法院首次下达开源软件禁令,涉案产品被禁售。[15]

  • **解析:**涉案产品都使用了 Busybox 软件,但企业并没有按照 GPL 义务要求开放相应源代码,因此违反了 GPL v2 协议。

  • 启示:

  1. 产品在引入开源软件时,应明确其是否有开源义务要求,评估产品履行能力后再使用,并在发布前做好开源准备;
  2. 一旦发生开源维权诉讼,企业往往是弱势方,多为败诉/赔款和解收场,甚至会导致产品被禁售。
  • **案例 2 :**2016 年,著名开源维权人 Harald Welte 向某公司索取某产品的开源代码,但该产品自身并未引入任何开源软件。经排查发现,该产品集成的某供应商软件中使用了 GPL 开源软件,经过一系列交涉,花费了大量的时间、人力,才从供应商处获取到相应的代码提供给维权人。

  • **解析:**若产品集成的供应商软件中包含了开源软件,产品作为再次分发方,也必须履行相应开源义务。

  • 启示:

  1. 产品在引入供应商软件时,在合同中需明确开源义务履行保障条款(对于免费软件则推动供应商签署补充协议),确保供应商能够履行开源义务。
  2. 产品在发布前应向供应商索取开源软件清单与相应代码(若有强制开源义务),保证产品能够完整履行开源义务。

5.4 过程透明

5.4.1 建立结构化开源软件 SwBOM 是解决来源可靠、可追溯和漏洞管理的基础

通过软件的 BOM(Bill of Material),也就是软件清单(SBOM)。

SBOM:软件中的组件列表。软件供应商通常通过组装开源和商业软件组件来创建产品。SBOM 描述了产品中的组件,类似于食品包装上的成分清单,通过一整套可追溯缺陷跟踪系统来实现。

  1. 跟踪软件或开源组件里的漏洞:哪个产品使用了开源软件、哪些漏洞影响了产品,甚至哪些客户感受到了漏洞。整个链条上的元素都可以在该追踪系统里展现,帮助开发者快速、及时地修复漏洞,识别合规风险;
  2. 分析软件嵌套:通过软件分析有多少包以及包与包之间的依赖关系,并反推出它是怎样的软件。

5.4.2 建立从开源漏洞发现到客户升级的漏洞E2E处理流程机制,确保漏洞及时被修复

通过漏洞追踪系统,包括舆情感知系统帮助发现漏洞。发现漏洞后,应急响应团队应第一时间在满足 SLA 的情况下修补漏洞,并和客户一起发布漏洞处理方案及影响范围,帮助客户尽快解决相应的安全风险。

5.4.3 企业如何修复开源软件漏洞

开源软件漏洞通过缺陷单跟踪处理,根据漏洞的风险等级,企业依据合同对漏洞修复的相应 SLA 要求进行修复。

  1. 基于对客户的承诺,企业产品在研发阶段需划分漏洞风险等级,便于漏洞管理策略的制定。例如,企业可以要求高风险开源软件漏洞(CVSS>=7)必须在产品版本发布前修复;中低风险漏洞(CVSS<7)经风险评估后,可以遗留到下个补丁或版本修复,但修复时间必须符合漏洞相应 SLA 要求。

    1. 通用漏洞评分系统(CVSS)是一个用于传达软件漏洞特征和严重性的开放框架。CVSS 由三个度量组成:基本、时间、环境。基本指标产生 0-10 的分数,通过对时间和环境指标的评分修改该分数。CVSS 分数也表示为向量字符串,即用于导出分数的值的压缩文本表示。因此,CVSS 非常适合作为需要准确且一致的漏洞严重性评分的行业、组织和政府的标准测量系统。
    2. CVSS 的两个常见用途:
    • 计算在一个系统上发现的漏洞的严重性
    • 作为漏洞修复活动优先级的一个因素
  2. 进入维护阶段后,所有开源软件漏洞都必须依据合同对漏洞修复的相应 SLA 要求进行修复。

  3. 对于开源软件漏洞的修复,更倾向于跟随社区,与社区保持同步。

5.5 生命周期维护

5.5.1 产品研发注意事项:避免“自维护成本陷阱”

自维护成本陷阱是我们在使用开源软件时,希望将开源软件中植入一些产品的竞争力而导致的。植入产品竞争力必然会对开源软件拉分支,甚至于大量的修改。修改前期可将开源软件的维护能力和功能特性迅速拉升一个档次,随着版本的不断更新,拉的分支越来越多,每个不同的分支都要进行相应的回复。

5.5.2 案例分析

  • 案例:产品团队 A 负责维护 OpenSSL 历史版本 1.1.1a/1.1.1b/1.1.1c 以及社区最新版本 OpenSSL 1.1.1d;产品团队从社区官网发现 OpenSSL 1.1.1d 版本存在漏洞 CVE-2019-1551,则产品团队通过官网或 NVD 披露的漏洞影响版本范围分析漏洞 CVE-2019-1551 是否也影响 OpenSSL 1.1.1a/1.1.1b/1.1.1c。如受影响,则需将漏洞影响开源软件的版本刷新至漏洞库,同时修补 OpenSSL 1.1.1a/1.1.1b/1.1.1c 版本的漏洞。

  • 产品团队自行搭建构建环境,至少确保社区提供的构建方案能够编译通过。

  • 产品团队需不断审视社区当前所有软件新版本中的漏洞是否在维护版本存在且受影响,同时产品团队启动对所有受漏洞影响的选型引入的维护版本的漏洞修补。

5.6 开源软件生态

5.6.1 什么是开源软件生态

  • 基金会的两项重要工作:
  1. 中立协调:厂商与厂商之间是有竞争关系的,但在有基金会的中立场合下,厂商之间可以针对某个问题进行讨论。
  2. 赋予目标,维护项目:仅靠一家企业的力量长期维护一个开源项目是很难的。基金会赞助开源项目的方式会产生很多新的问题,例如 Linux Foundation 支撑 Linux,逻辑上可能是可行的,但在其之后,没有任何一个项目以同样的方式成功。
  • 项目成功的核心:
  1. 技术价值
  2. 商业生态价值
  • 金字塔型
  • 沙漏模型

5.6.2 开源软件商业模式

开源软件商业变现模式说明典型案例
企业版开源版本免费,企业版获得许可和支持服务收入;通过开源向商业版引流MySQL,Docker,Cloudera
高级功能收费对面向规模使用的的可靠性、安全、管理等进阶功能和工具软件收费Redis 核心部分的组件是开源的,但工具类软件和进阶功能(如多租户,无共享分布式架构等)是收费的
订阅服务开源许可证免除了开源社区对软件质量与缺陷修复的责任,由 OSS 厂商提供软件订阅服务Red Hat, Hortonworks
开源软件集成服务通过软件实施等技术服务收费SourceLabs 和 SpikeSource 不主推自己的产品品牌,而是与多方开源软件厂商或社区合作
云服务在公有云上提供基于开源软件的云服务;可通过开源向云服务引流MongoDB, Databricks, Elastic Search 等提供基于 Azure 和 AWS 上的云服务收费
通过硬件盈利提供开源软件 + 硬件的一体化方案,通过硬件变现Intel/NVidia/AMD
SaaS服务开源核心平台,对接更广泛的应用生态,通过 SaaS 服务变现GitLab 提供开源代码托管服务,开源本身平台以对接更多应用;Salesforce 等
应用和流量变现通过开源促成应用,形成行业事实标准,并与应用生态形成绑定进行变现,如广告或 Marketplace 等Google 基于 Android 生态的广告收入每年超百亿美元

5.6.3 微软围绕 Azure,通过持续投资和并购布局开源

  • 加入开源专利联盟 OIN(open invention network: https://openinventionnetwork.com/),同意向所有 OIN 成员开放其所有专利,包括 IDE Visual Studio Code、开源 JavaScript 扩展,.Net 开源核心类库,开源 Linux 环境 BashOnWindows 等; [16]

  • 面向开发者打通 To B、To C 平台,通过周期管理方式多路径做大开发者生态,建立完整渠道覆盖各级伙伴资源;

  • 加大对开源厂商扶持力度,包括云上部署及提供销售变现通道。

5.6.4 亚马逊:从开源业务收割者到新领域贡献者

  • 最大化利用开源价值为自身业务创收
  1. 大规模促进开源软件的云服务化(计费、监控、超卖等)
  2. 补齐开源软件应用的最后一公里(工具、文档、北向接口等)
  • 新领域贡献者
  1. Neo 作为 Apache 软件许可下的开源代码发布,支持广泛的框架和算法以及多样化的硬件架构;
  2. AWS 通过开源打通自家 MXnet->Neo->Inferentia 软硬件全栈,通过软件适配硬件、云服务释放算力应对来自 Google 和 NVIDIA 的竞争。

参考资料

[1] OSI 开源软件定义 https://opensource.org/

[2] Richard Stallman:American computer programmer https://www.britannica.com/biography/Richard-Stallman

[3] Linux 基金会 Linux.org

[4] Apache 软件基金会 https://www.apache.org/

[5] Eclipse 基金会 https://www.eclipse.org/

[6] Cisco settles FSF GPL lawsuit, appoints compliance officer https://arstechnica.com/information-technology/2009/05/cisco-settles-fsf-gpl-lawsuit-appoints-compliance-officer/

[7] Apache disallows the Facebook BSD+patent license https://lwn.net/Articles/728178/

[8] The History of Linux https://linuxhint.com/history-of-linux/

[9] SELinux是什么? https://www.redhat.com/zh/topics/linux/what-is-selinux

[10] syzkaller - kernel fuzzer https://fuchsia.googlesource.com/third_party/syzkaller/+/usb-fuzzer/README.md

[11] Linux 内核自防护项目 KSPP https://linux.cn/article-7411-1.html

[12] ABOUT SIGSTORE https://docs.sigstore.dev/#about-the-project

[13] OpenSSH Project History https://www.openssh.com/history.html

[14] Patrick McHardy 事件对开源社区的影响 https://mp.weixin.qq.com/s?__biz=Mzg4NDcyNjEwNw==&mid=2247484568&idx=1&sn=82e1d1cc11f90a0d8851bcfd6bff5b74&chksm=cfb284acf8c50dba38a92d13e64aa84fbc2d5be7c131788007e2de7f19105fd3595daa678827&token=1720883671&lang=zh_CN#rd

[15] Best Buy, Samsung, And Westinghouse Named In SFLC Suit Today https://lwn.net/Articles/366467/

[16] The History of OpenInventionNetwork https://en.wikipedia.org/wiki/Open_Invention_Network#History

社区规则和潜规则

一、开源的前世今生

1、从考古学的角度,来认识历史

《第五次开始》这本书是由一名考古学家写的历史书,其中不是只写了考古学,而是从一个考古学家的角度,看待历史的发展。比如,很多历史学家在描述一件事情时,会用到“有史以来......最......的一个......”,然后这名考古学家会说,“你们历史学家说的最多也就几千年的事情,所谓有史以来也就最近几千年发生的事情,但是咱考古学家是以上万年为起点...”。因此这本书从600万年前开始阐述,将600万年的历史,浓缩成一本仅有280页的书籍,且专为普通读者所著,其中精彩程度堪比《人类简史》。

为什么要叫做《第五次开始》?该书描述的是五段人类的发展史,如何给人类发展史进行断代的问题:

1)第一次:“技术”让人类从动物界胜出。通过考古,发现人类开始使用某种技术,比如开始使用火,或者开始使用砍、砸器等工具,在这些考古遗迹上可以发现人类和动物已经不一样了,人类从动物界中脱颖而出,成为能够使用工具、驾驭技术的一群动物,这也是“人”的诞生。

2)第二次:“文化”让人真正成为人。在考古学里,开始发现很多遗迹里存在各种图腾、绘画以及雕塑等,这些东西表明人不仅仅是人,也在追求文化上的东西,记录自己的生活,观察自然甚至崇拜自然,这时,“人”变成了真正的人,“文化”因此诞生。

3)第三次:“农业”让人类从游猎走向定居。这时开始从农业耕种的遗迹上可以发现有种子、农田,甚至有育种的痕迹,这些都表明人类从游牧狩猎采集走向了定居的生活,因此可以看到家、洞穴、房子以及城堡等。

4)第四次:“国家”让文明打上不平等、暴力与战争的烙印。国家是怎么出现的呢?通过考古遗迹发现巨大的城池,也发现了攻防、战争、暴力、武器等的印记。在这样一个过程中,人类已经跟原来不一样了,开始从小型的部落走向了国家,而国与国之间的战争也随之而来。

5)第五次:正在发展中的“全球化”。该部分也是作者描述最多的部分,如果现在再去看考古遗迹,尤其是最近500年,会发现很有趣的现象--原本在更早期的历史地层里,很多东西是局限在当地,比如这种种子只会在当地出现,这种动物化石也只会在当地出现,不会在很远的其他地方出现,但是近500年,世界各地的创作物已经不再局限于一个区域,比如一艘沉船,打捞之后发现里面有世界各地的创作物,陶器、瓷器、丝绸、香料等,这也就说明,整个世界的各种各样的物质、文化、人造物等都开始在全球化流动。

那第六次开始,会是什么情况?

作为一个IT从业人员,我会认为“第六次开始”对考古学家可能是一个悲剧,因为从考古学来看,总归是可以挖出点遗迹来作为证据,但到了第六次,我们会发现很多重大历史事件,不是发生在物理世界中,而是发生在网络数字空间里,当然如果将来考古学家能够进一步努力变成数字世界的考古学家,在网上进行考古则另说。所谓第六次开始,相较于前面五次开始完全不同,前面所述的打引号的考古证据将变成数字化,这是我们的世界真正开始变得不同的一个起点。

2、从社会学的角度,来认识世界

《社会变迁》这本书是1922年美国社会学家 W.F.奥格本 所著,由我国著名社会学家、人类学家费孝通和王同惠翻译,本书讨论了社会是如何进行演变。《第五次开始》说的是时间跨度非常大的以万年计的阶段性变化,但近三四百年,甚至近二三十年,社会的变迁越来越快,不能再只靠考古学进行研究,因此社会学派上用场。社会变迁作为一种文化现象,讲述了发明是如何产生的、每一个发明之间是如何积累起来的、发明是如何传播出去的,以及发明是如何让这个世界变化得越来越快。

在古代传统社会中,人的流动性很少,社会与社会之间互不相通,东西方之间很多年都处于相互不了解的状态,各自的圈子就相当于一个个小泥潭,很难想象能从一个泥潭跳到另一个泥潭里,但当人开始流动,就好比泥潭活化融合逐渐变成池塘,当圈子里发生一件大事,就像往池塘里扔了一颗小石子,消息就会如涟漪般逐渐往外扩散,等池塘与池塘也联通之后,整个世界就成了一个地球村,在这个地球村里,任何一个发明都会以飞速的方式传播到全世界,再到有互联网之后,世界上的发明产生得更快 ,传播的东西除了技术、发明、创新等本身之外,还有一项东西也进行了传播,即产生技术、发明、创新等背后的方法论。

不难发现,这种事情在开源领域非常明显,开源首先是一种源代码开放的技术,当代码一旦开放出来,再加上互联网的加持,全世界就能够马上看到并且使用它,因此技术发明创新的传播速度非常之快,同时开源也是一种开放式协作的方法论,这种方法论能帮助任何一个国家、社会的每一个领域,让全世界以更加开放的方式进行协作。可以预期的是,未来的十年或者二十年的变化一定是越来越快,而在这过程中,开源是最核心的主导力量。

3、开源出现之前

1946年,第一台计算机诞生;1960年,小型计算机(PDP-1)诞生;40年代到60年代间,是小型机、中型机、大型机的时代,这个时代最大的特征是大多数人都买不起计算机,而有能力购买计算机的都是机构,或者是大学,比如五角大楼、麻省理工、哈佛、耶鲁等,聚集了大量的科研人员,我们对这些科研人员有一个尊称“Computer Scientists”(计算机科学家),对于他们来说,代码是科研产品,或者是科研交流的必备物品,就像交流学术论文发paper一样,需要将代码发出来,因此代码的交流是自然而然的,丝毫不考虑copyright、license以及挣钱等事情,在这种时代,代码在世界上自由流通,但还没有开源这件事。

在那个年代,也有发生一些事情。当时麻省理工大学有一个俱乐部,叫铁道模型俱乐部,该俱乐部有个小组叫信号与控制小组,这个小组一开始只是计划控制火车,让火车在他们搭建的铁路模型上更好运行,能够控制启停、转弯、换轨道等诸如此类的信号控制,直到有一天,这个小组拿到一个新玩具,这个新玩具就是一台PDP-11这样的电脑,这时,对他们来说这是最新鲜、最有趣的玩具,火车的好玩程度远远没有计算机的好玩程度大,但这个玩具特别特别贵,对于学校来说,这是属于学校的宝贵资产,一定得有人看护,因此产生了一个尖锐矛盾:学校教授/管理机构严格控制对计算机的使用,使用得预约时间,不在预约时间内不允许使用,这对于这个小组来说非常痛苦,竟然不能一天24小时,一周7天,7*24小时的时间都在那里玩?!竟然还会被赶走?!因此黑客伦理的第一句话就是:对计算机的访问(以及任何可能帮助你认识我们这个世界的事物)应该是不受限制的、完全的。任何人都有动手尝试的权利!

剩下五条黑客伦理分别是:

-- 所有的信息都应该可以自由获取。

-- 不迷信权威——促进分权。

-- 评判黑客的标准应该是他们的技术,而不是那些没有实际用途的指标,比如学位、年龄、种族或职位。

-- 你可以在计算机上创造艺术与美。

-- 计算机可以让你的生活更美好。

这就是一群爱玩、爱闹、爱钻研、爱探索的大男孩黑客给自己规范的伦理,他们认为这样才是正确的做法。

4、软件行业兴起

1975年,IBM发明了PC,到了1976年,苹果发布了Apple I,这时个人计算机、微型计算机开始兴起,大多数人咬咬牙也都能买得起了,因此产生了一大群爱好者,他们有一个很大的乐趣,就是互相之间交换盗版拷贝程序,也因此激怒了另一个人——比尔·盖茨。比尔·盖茨是微软的创始人,微软当时成立没几年,做了一个非常著名的软件叫BASIC,比尔·盖茨发现,很多人在用BASIC,但是销售量并不好,也就是说大家都不是付钱给他,所以比尔·盖茨写了一封公开信——《写给电脑爱好者的公开信》:有谁会在没有任何报酬的情况下来做这些专业的工作?什么样的爱好者可以为他的产品投入三个人年的开发时间,并且发现所有的错误、编写文档以及免费发布这个产品?这段话非常符合资本主义商业伦理价值观。

到1980年,美国的版权法修改,软件开始有版权,软件行业开始兴起。回顾之前那段历史,不能再说微软是商业魔头了,而是正因为有了这样一群商业软件公司,才能通过这些公司实现写软件赚钱的路径,现在才会有上千万的程序员,而如果仅仅只是一群爱好者,那么现在程序员的数量可能就只有几万个。

事物总是存在两面性,在软件行业兴起之后,不可避免的有人受到了伤害。Richard Stallman,被人称之为“最后一个黑客”,那时他正在MIT的人工智能实验室,与朋友一起研究UNIX,但当商业软件公司成立之后,各自将软件闭源,UNIX也不例外,Richard Stallman再没有了原来的幸福环境——能够一起写代码然后彼此交换代码,不断探索计算机能力。因此在1985年,Richard Stallman发表了GNU宣言,即GNU’s Not Unix,大致意思是:我不是要做一个UNIX,但是我要做一个完全自由的UNIX。而且他还提出了Copyleft的概念,同时开发出很多GNU的相关工具,包括Emacs、GCC等工具。1990年,Linus Torvalds在芬兰赫尔辛基大学读书期间,开始开发Linux,1991年发布最初版本,并飞速发展至今,而GNU和Linux两者之间结合非常紧密:从1983年开始的GNU计划致力于开发一个自由并且完整的类UNIX操作系统,包括软件开发工具和各种应用程序,到1991年Linux内核发布的时候,GNU已经几乎完成了除了系统内核之外的各种必备软件的开发,在Linus Torvalds和其他开发人员的努力下,GNU组件可以运行于Linux内核之上,整个内核是基于GNU通用公共许可,也就是GPL(General Pubic License)。

1991年,Linux发布了第一个开源版本,通过互联网聚集了大量的志愿者,没有严格的质量标准,没有强有力的机构协调管理,每周进行发布,然后接受反馈,通过不断迭代,在1993年底,Linux在稳定性与可靠性上,已经与很多商业UNIX不相上下,并能支持比商业UNIX多得多的软件,也就是说兼容性及可扩展性都非常的强,于是很多小型的UNIX供应商倒闭,且原因是显而易见:供应商的操作系统需要收钱,现在有免费开源版本,源代码都可以获得,而且这样一个操作系统还越做越好,有越来越多志愿者愿意免费帮忙做事情。

1997年,大神Eric S. Raymond写了一本书——《大教堂与集市》,最开始不是一本书,而只是一场在Python的大会上进行的演讲,就“开源是什么”这个主题展开,讨论“为什么会有这么多人一起做开源?这么多人来做开源,还能够把事情做成了?”。《大教堂与集市》一经发布,一纸风行传遍天下,被称之为开源运动的“圣经”,彻底颠覆传统软件开发思路,影响着整个软件开发。这本书最重要的两个要点:

1)大教堂与集市,这两种软件的开发模式到底有什么区别?在Linux这种开源的操作系统诞生之前,绝大多数的软件开发模式都是大教堂式,或者称之为瀑布模式,意思是从最开始,有一个总设计师,一层一层把工作任务分解下去,分门别类、分工合作,最后将事情做成。然而到了集市模式,好比一群人跑到集市上,一个人贡献点东西,另一个人也贡献点东西,看上去没有明确规范,没有很好的协调开发方式,但却能把事情做成,而且带来更多创新与可能性,这颠覆了传统软件工程模式。

《人月神话》中有一段描述,当有一群人,在做一个项目的时候,发现快要超期,这个时候有老板说我增派人员,是否就能缩短工期呢?然而这个时候的工期是无法缩短的,因为人多了之后,人与人之间的沟通成本会迅速上升,新增人力反而会被大量的沟通成本损耗,以致工作效率无法提升。但Eric S.Raymond认为,如果找到了好的工具,好的协作模式,以及好的技术手段,人越多效率越高、速度越快。这恰恰与《人月神话》是完全相反的,同时也是非常重要的贡献,给软件开发提供了全新的思路,但不是完全否定《人月神话》,而是集市化的开发同样是一种可能性,把一些原本没有想到的事情做成。

2)礼物文化。这也是《大教堂与集市》里非常重要的篇章,主要阐述的是为什么开源开发者愿意义务为这些开源项目做贡献。在当今这个物质丰裕的时代里,命令以及花钱并不会让他们听话,但是如果他们所做的这些事情,能够换来更多荣誉、地位以及社区影响力时,他们反而更愿意去做,正如原始社会里所看到的夸富宴,部落的酋长举办非常铺张非常奢华的宴会,通过这种夸富宴,酋长能够赢得在部落里的地位,同理,在开源社区里,当真正的大牛,写代码写得最好的人,向社区贡献最好的代码时,能够赢得社区里最好的地位,好比向社区贡献了礼物,相应就会收获尊崇。这就是一种礼物文化,也是Eric S.Raymond对开源世界的一种总结。

5、时间线

1983 年,Richard Stallman 发起了 GNU 项目;

1985 年,Richard Stallman发表了 GNU 宣言;

1989 年,GNU 通用公共许可证的第一个版本发布。1991 年GPL v2发布;

1991 年,Linus Torvalds 发起 Linux 内核项目;

1993 年,Red Hat 诞生;

1997 年,Eric S. Raymond 发表了《大教堂与集市》;

1998 年 1 月,网景公司宣布将 Navigator 开源;

1998 年 4 月, Tim O’Reilly 组织“开源峰会”,OSI成立;

1999 年 3 月,Apache基金会成立;

2000 年 10 月,Sun Microsystems 公司在 GNU Lesser General Public License 下将 StarOffice 办公套件作为自由软件发布。这个自由软件版本被重新命名为 OpenOffice.org,并与 StarOffice 共存。

2004 年 8 月,Ruby on Rails 发布;

2005 年 4 月,Git 发布;

2008 年 2 月,GitHub诞生;

2018年,IBM收购Red Hat,微软收购GitHub;

6、Free Software & Open Source 的区别

1)自由软件:任何用户都可以自由的运行软件、修改软件,之后再分发这些软件;

①自由度0:无论用户出于何种目的,必须可以按照用户意愿,自由地运行该软件。

②自由度1:用户可以自由地学习并修改该软件,以此来帮助用户完成用户自己的计算。作为前提,用户必须可以访问到该软件的源代码。

③自由度2:用户可以自由地分发该软件的拷贝,这样就可以助人。

④自由度3:用户可以自由地分发该软件修改后的拷贝。借此,用户可以把改进后的软件分享给整个社区令他人也从中受益。作为前提,用户必须可以访问到该软件的源代码。

2)开源软件的定义:

①自由再散布(Free Distribution)

②原始码(Source Code)

③派生著作(Derived Works)

④原创作者程序原始码的完整性(Integrity of The Author’s Source Code)

⑤不得对任何人或团体有差别待遇(No Discrimination Against Persons or Groups)

⑥对程序在任何领域内的利用不得有差别待遇(No Discrimination Against Fields of Endeavor)

⑦散布许可协议(Distribution of License)

⑧许可协议不得专属于特定产品(License Must Not Be Specific to a Product)

⑨许可协议不得限制其他软件(License Must Not Restrict Other Software)

⑩许可协议必须技术中立(License Must Be Technology-Neutral)

自由软件与开源软件最大的区别在于开源软件里第⑨条许可协议不得限制其他软件,相应自由软件也有一条相关条款,在GPL里面有说明:不能将自由软件,和非自由软件捆绑在一起,可以将自由软件卖钱,但不能捆绑非自由软件一起卖钱。因此两者之间真正的差异在于有没有妨碍其他人赚钱:自由软件崇尚的是自由,如果软件不自由,那么不可以捆绑销售,属于理想主义;开源软件不妨碍其他人赚钱,大家可以一起赚钱,属于实用主义。

二、开源世界的规则与潜规则

1、何为规则

①情:人情世故、基本伦理;

②礼:礼仪、礼节、礼物

③法:成文法、成文规范、授权协议

④code:代码限制、自动规则

2、何为潜规则

规则之前:在制定规则之前,比如我们有一个群,最开始这个群只有十几个人,所以没有什么规则,每个人都凭本能,大家在一起无冲突相处很好。直到群越来越大,人越来越多,开始有人在群里发广告,其他人觉得不太好,决定在群里定一个规则,这个规则可能有两种,第一种是只要发广告,一律从群里踢走;第二种就是有些群主比较开明,只要发红包就可以发广告,这两种方式都是一种规则。那么这种规则是怎么确认下来的呢?这就是所谓的判例法,就是一点点的积累下来,到后面潜规则逐渐变成规则。

概率生效:潜规则在还没有明确的变成稳定的、不可变更的规则之前,这些规则就是概率生效,即有时候有效,有时候无效。比如某人在群里发了个红包,群主说以后不允许发红包,但下次这个人还在发红包,而群主又不再说他了,可能是群主忘了,或者群主在忙,或者这个人是群主的朋友,情况很复杂,各种原因导致群主不一定会把这个人从群里踢掉。

概率公开:有些时候,某个人前几天还在群里,后面就被踢掉了,群主也没有解释原因,可能是私下处理,或者群主私底下另外找个理由说这个人行为不端,总之就是踢掉了。这都是潜规则的一种表现,这个规则并没有被公开执行,也没有被公开解释。

各自解读:在一个社区里面有很多小圈子,这些小圈子会各自揣摩,为什么这个人可以这么干,那个人不能这么干呢?大家就会进行解读,可能这个人的贡献比较大,所以大家对他比较宽容,也可能是管理员的朋友,所以大家也不好意思多说什么。

诸如此类的这些都是潜规则的一种表现。

3、何为社区

最早的时候,一群志同道合的人组成一个社区,来共同创造一些东西,然后逐渐完善这个作品,这个作品可能是一个开源项目的一个版本,版本发布之后,吸引了更多对这个项目感兴趣的人来到这个社区,他们可能只是看看,也可能是试用,甚至有可能会参与贡献,总之社区的人越来越多,原来比较少的一些规则,或者不成文的规定、潜规则就不太够用,于是大家开始一起完善这些规则,进一步明确志向:之所以要定这些规则,之所以大家团结起来一起做事情,那我们的志向是什么?我们的目标是什么?在这个过程当中,通过不断的凝聚共识,社区变得越来越成熟,才会越来越健康地发展下去。

4、普通伦理与社区伦理

普通伦理:己所不欲勿施于人;君臣父子,长幼有序;仁义礼智信等

社区伦理:黑客伦理。特别强调不迷信权威,评判标准不看地位,而看实际的贡献,强调有所追求,创造艺术和美。

社区伦理中的两个现象:人人平等与精英治理。人人平等不是指每个人都有同等的权重,而是每个人都有平等的机会,是一种机会平等,好比在一个社区里,每个人都可以点fork,当做了某种修改以后,每个人都可以发PR等,这些机会是平等的。至于别人会不会接受你的代码呢?会不会接受你的贡献?提的一个issue会不会有人理睬?这些并不是平等的,社区看ID,如果某个ID大家都见过很多次,彼此都很熟悉,那么会有更多的人关注这个ID的言行、发布的代码、提的意见等,这个背后就是所谓的精英治理,即一个人在社区的贡献越大,他的话语权就越大,虽然这个权重可能不会体现在某些数量上,比如大家来投票,但是他一个人有5票,这是不可能的,但事实上,他的投票会有更大的示范效应,因为社区里的投票是公开的,如果他率先投票,他在社区里有很大的号召力,很多人可能就会跟他投一样的票。精英治理跟人人平等并不矛盾,相当于一个硬币的两面,两者是结合起来的。

5、社会之礼与社区之礼

礼仪方面,社会上有很多的婚丧嫁娶的礼仪,到了社区里就有面基大会,比如线下的技术大会等,能够跟更多的朋友一起聚一聚聊聊天。

在待人接物方面,社会上讲究为人要有礼貌,说话要有道理,不要乱说话,不要口出恶言。在社区里,大部分时候都是在网络上进行文字交流,但提问也有艺术,一开口就是:“急!有个问题谁能帮我解答一下?”,这种提问方式就不太建议,好的提问一定是描述的很清楚,过程条理清晰的列出来,然后再提问求助,而不是如上述显得很着急的样子。

社会上强调礼尚往来,而在社区里有礼物文化,在社区里,给的礼物越重,别人越会觉得这个人是个高手。同样社区里也会有礼尚往来的现象,比如某个人在社区里用到了很多好的东西,好的软件,好的代码,然后认为自己有义务贡献回馈给这个社区,这本质上也是一种礼尚往来。

6、社区中的成文法

社区里面有很多的成文法,谈及最多的是License(许可证),以及商标法、社区的章程、知识产权保护、隐私保护等,在社区里,但凡涉及开源跟软件相关的法/条款/合同/约定,都是成文列出来的,甚至比如说code style(代码风格),很多社区都非常重视,会将要求列出来,让社区内的人按照相应方式来写代码。这些都是社区的成文法,是大家需要遵从的规则。

7、社区中的自动化规则

1)Code is Law:通过代码方式,自动执行的规则。

2)BBS问答社区的积分规则:之前我在的一个社区叫ITEye,它是一个BBS问答社区,这个BBS背后有一个积分规则,当有人回答了一个问题,或者发了一个帖,或者回了一个帖,其他人会点赞,有向上的大拇指,也有向下的大拇指,基于规则相应会被加分或者被减分。随着被加分和被减分之后,个人积分发生变化,随之这个社区里面的等级也会变。当年在ITEye的时候,刚刚入门时是一颗星,到五颗星,然后是一皇冠到五皇冠。积分最高、权重最大的就是五皇冠,当时有一个规则——如果有一篇帖子,大家都觉得写的不好,那么会给它投大拇指向下的投票,如果得了20票,这篇帖子就会从普通的板块被扫到垃圾桶,而五皇冠的权重是一个人能投19票,再有一个人加一票,则这个帖子就进会垃圾桶。

3)Github 的自动化规则:Action、Robot、 Issue & PR Template 等,也是通过代码来做自动化执行,而这些自动化的规则会成为社区运作的一部分,如果有人在社区里提交代码,或者参与贡献时,会有机器人在下面留言,提醒需要注意的内容,或者需要签署一个 CLA。

4)Gerrit 里的 Code Review规则。

8、社区中的潜规则

1)社区里的人设

①莫得感情的发帖机器:在群里只发广告/文章,这类人完全没有把自己当成这个群或者社区的一份子,而只是将群当成一个传播渠道,这种只是转发文章的方法实际非常低效,很多人都非常厌恶这种方式。

②杠精体质:有些人有事没事喜欢杠一句话,以显示自己的存在感,或者认为这样能更显得自己知识渊博。对付杠精的方法就是不理会,你是杠精你说的都对。

③大妈体质:这种人设非常好,社区“大妈”会帮忙张罗很多事。社区里多多少少会有一些琐事,需要有人去做,任何一个社区都需要这样的“大妈”人设,或者叫扫地僧。

④其他……

2)规则的宽容度:

①对于新人,社区可能会更加严厉

②贡献越大,越不容易被惩罚

3)社区内部的沟通渠道:社区内有人打小报告这个事无法避免,同时社区内部除了公开的渠道外,还有很多小圈子,这也是社区里常见的现象,总会有些更合得来的朋友,一起拉个小群聊点别的事情,这种沟通渠道都会存在。

4)社区运营者的直觉:对于社区运营者来说,需要有对社区发生事情的敏感度,因为社区运营者不可能出现在每一个小圈子,不可能了解任何一个小群,知道任何一个圈子在讨论什么,但得有直觉,能清楚知道社区内到底发生了什么事情,当前社区的氛围如何,是否健康?讨论是热闹、热烈、激烈,还是剧烈的争论?是否已经有崩溃的预兆?社区运营者必须有这些敏锐的直觉。

三、开源世界里的人设与个人成长

1、个人参与开源的价值

1)如何让一个孩子痛恨学习?

强迫他学习就好。有一次我去游泳时,发生了一件这样的事情——一位妈妈带小孩在游泳,小孩才刚刚开始学,所以怕水不敢游,但妈妈言辞间非常严厉,要求孩子一定要踢水,一定要把头闷下去,一定要学会换气等等,导致小孩一脸苦相,最后跟妈妈说不想游了。那天游泳回来以后,我最大的感受就是:如果想让一个小孩痛恨游泳,那么只需要像这位妈妈一样,强迫他游泳。

2)英语学渣,如何精通十国外语?

找到“享受学习过程的方法”。有一个号称是英语学渣的人,却精通十国外语,他为何能学会这么多门外语呢?通过他在TED上的分享,了解到他并没有要求自己今天一定要学这门语言,今天一定要背10个单词等这类强制学习计划,而是一直在寻找一种方式让自己享受学习,当出现倦怠时,再发明一种新方法再去学,让自己一直保持在享受学习这个过程。

这种方法在开源上特别常见。

3)Linus关于生活的意义的“理论”

①首先是生存,人类做事,最基础的动机,就是为了生存。

②其次是社会关系,有时候也会被称之为“秩序”。无论是为了维系社会关系,还是为了维持社会秩序,这都是重要的动机。

③最后是娱乐,或者说乐趣,在 Linus 看来,这才是动机的最高境界。

到底是什么力量,支撑Linus开发了30年的Linux操作系统?

Linus:“我本可以在1991年底就收手不干了,因为那时我已经完成了大量有意思的工作......幸好接下来发生了两件事,我才有了继续下去的动力:第一,我不小心损坏了Minix系统的分区;第二,人们不断给我发来反馈意见。”

敢吹牛的人,才能成为技术大牛

Linus Torvalds在1991年发了一个邮件:我在做一个开源的操作系统…这其实是在吹牛,但别人都觉得很厉害,竟然有人做了一个操作系统!感兴趣的人蜂拥而至,提 Bug报告、需求、补丁等等,在这个过程中,Linus也得以成长,成为一代大神。

这就是个人参与开源能够得到的一种价值。

2、个人成长的正循环

1)创造:在创造的过程中,产生真实的练习目标。

2)刻意练习:在练习过程中,找到越来越多的乐趣。

3)乐趣:在获得乐趣的过程中,产生创造的冲动。

开源社区作为个人成长的催化剂。举个例子,比如我想做一个操作系统内核,但发现做不出来,不懂的东西太多了,但我发现可以通过学习与刻意练习,积累做操作系统内核的能力,最后真的把操作系统做起来了,而在这个过程中,因为学到了不少东西,从而获得越来越多的乐趣,这个乐趣指引着我去创造更多,于是想将0.1版做到0.2版,再做0.3版,然而进一步的发现我需要学更多的东西,否则后面版本做不出来,再次通过学习...而这个过程就是个人成长的正循环:可能一开始只是想做一个自己玩的小玩具,到最后却让自己变成了大牛。

3、如何在社区里树立自己的人设

1)本色出演:建议本色出演,因为不可能装一辈子,本身是什么样就是什么样,假装成另外一个人是不真诚且不长久的行为,且人设崩塌往往就在一瞬间,总会有说漏嘴、说错话的时候,做自己最重要。

2)不卑不亢:大牛确实很牛,但是在见到大牛时,不需要卑躬屈膝、跪求大牛,只需要正常平等与其交流,比如“我有一个问题,请问能否帮我解答一下?”这种自然平等的对话即可。

3)努力成为有用的人:不论在哪个领域,打杂、写代码、提BUG、做测试、做宣传、做翻译等任何社区需要的事情,只要愿意去做,一点一滴地贡献,社区会逐渐将其定位为在某种情况下能做这件事的人,或者发现这个人这也能做,那也能做,是个多方面人才,这种人设一旦定下,很多时候社区在遇到其他事情的时候也会想着找这个人问一问,这个是否也能解决?


社区规则和潜规则(二)

一、为何要为开源贡献力量

在 [自由代码] 下工作,让我学习到了职业生涯中非常重要的技能,无论是大学还是实际的工作,我认为从开源项目中得到的收获的远大於我的贡献! — @errietta , “我为何是如此的热衷于为开源软件贡献力量”

为开源贡献力量,得到的回报就是能够学习到很多、受教很多、且能够锻炼任何你能够想到的经验。 为什么会有人为开源做贡献?这可能是很多人都不明白的地方,这里不妨列出一些!

1、巩固现有技能

无论是撰写代码、设计用户界面、图形设计、撰写文档、亦或是组织活动,只要有实践的愿望,总能在开源项目中找到位置。

例如,作为一个学生,在一个项目中实习,一般不会参与到核心代码的开发,因为实习生很难能够直接进入生产环境的开发,对于公司的业务不熟悉,代码的技能不够,对架构的理解也不够,因此研发管理者不会让学生立马进入(特别优秀者除外)。 如果希望很快进入到生产环境中,则需要很多编码经验,尤其是与生产环境相关的开发经验,但在公司之外,很难有像开源这样更好的一个机会。因为现在开源出来的代码,在国内环境上,一些平台的代码是其生产上已经使用的一些项目、代码开放出来,通过此参与到这些代码中,无论是文档编写还是代码编写,都会从中学到很多,这能够让一个新手很快的接触到生产环境上的一些东西,能够理解业务上的问题。

对已有开发技能者来说,这也是一种学习方式。例如做后端开发者,想学习前端的内容,不论是Vue,还是React,或是CSI 4等,通过参与开源软件、学习开源软件,能够快速了解前端代码如何去写。

参与开源项目,不论是新手,还是已经掌握了一定开源技能但需要拓展更多技术领域者,或是学习更好的业务实践,这都是一种很好的方式。

2、遇见那些和你“臭味相投”的人

开源项目一般都会有一个和谐、热心的社区,以让大家团结一致。实际上,开源界经常发生这样的情形,很多人的深厚友谊都是通过共同参与开源所建立起来的,至于具体的方式,可能是在一次技术研讨会上相谈甚欢,也可能是一直在聊天室中探讨问题。

在社区里,能够相互交流是建立在对项目有共同兴趣的基础之上,且每个参与相同开源项目者的技术背景具有一定的相似性,因此在交流问题时能有共同语言。在社区里能够找到一些有趣的人,通过此来拓展人脉关系以及社交。

3、寻找导师,并且尝试帮助他人

和他人共同在一个共享的项目下工作,这意味着需要向他人解释清楚自己是如何做的,同理,也需要向他人求助,询问别人是如何做的。相互学习和彼此教学对于每位参与者都能满载而归。

现在很多开源项目,都有导师机制,有些导师可能提供的是方向性指导,有些则是实际指导,但无论如何,都是有一定帮助的。

同时在帮助其他人时也能够更好地理解该项目,当有人提出问题,在深入思考他所遇到的环境及面临的事情后,再帮他解决问题,能学到更多的东西。因此不论是得到他人的帮助,还是帮助他人,都会有所收获,同时在社区能够建立一个更好的人际关系。

4、在公众间建立你的声誉(职业口碑)

根据开源的定义,你在开源下所有的工作都是公开的,这也就意味着开源项目是一个很好展示你实力的地方。

当参与到开源中,有更多的演讲机会时,会在公众间建立口碑。现国内很多工作者会以“参与了某些开源项目/是某个项目的maintainer”为标签,包括一些公司在招聘时,都会选择在例如Apache等项目里作为maintainer,因为当他在公司内部从事某项工作时,是无法得知他的工作情况(代码不开放),但在开源项目设计中,只要参与过,就会留下足迹,因此在开源设计里就能很清楚的知道这个人的技术能力、架构能力以及为人处事方式等,以此来匹配团队岗位需求。

5、学习领导和管理的艺术

开源为实践领导力和管理技能提供了很好的机会,比如解决冲突、组织团队、工作的优先级排列。

其中存在一定条件,因为开源项目是一个分布式且是异步的模式,不是像在办公室内,能够面对面进行交流、沟通问题。开源项目是由不同的公司、不同的人参与进来,因此需要协调每个人在技术上、方向上的问题,保证项目的发展,这一点会比办公司管理更为困难,当然也存在优势,开源项目中的人彼此之间没有太多的利益关系,因此不会经历一些办公室内存在的斗争与纠纷。总之,如果能在社区里领导一个大型项目,那么其管理能力就是非常不错的。

6、鼓励作出改变,哪怕改变是很微小的

在开源的世界里,作出贡献的不一定非得是花了很长时间拥有大量经验的人。你是否遇到过浏览某些网站发现有拼写错误,希望有人能修改它?其实,在开源的项目中,你只需要做就可以了。没有那么多的顾忌,开源让人们在很舒服的状态做事,而这才是这个世界应有的体验。

这一点也是开源的精髓。在开源事业里,不论做了很多事,还是做的很少,包括帮他人改过文档,甚至是只改过错别字,也包括在社交媒体场合中讲述一个开源项目,虽然可能没有在编码上作出贡献,但以上这些都是对他人的贡献。

二、贡献的具体含义是什么

如果你是一名开源界的新手,可能会对贡献的流程心生畏惧。比如:该如何找到正确的项目?不懂编码又想参与怎么办?万一做错事情了怎么办?

其实没有关系的啦!条条大路通罗马,开源项目有太多的路径可以参与!

比如说可以做一些logo的设计,也可以参与文档的编写,也可以做测试类的工作,或者组织一些活动等等。例如国内开源社的理事林旅强是一个非常熟悉开源合规方面的专家,他参与组织了很多社区的活动,这也是对开源的一种贡献。正如上述,在邮件列表回复他人,或者给其他人发链接,指引他如何去做等,这每一件事情都是在帮助他人,开源社就是一个很典型的例子,开源社热衷于组织各种事件(其本身未持有代码,在技术层面也未曾领导过某一方向),也支持其他社区区组织一些活动,为社区提供了很多帮助,比如说偏向于设计,或者整理一个风格指南,存在统一的视觉设计(类似于设计类工作),然后做出来之后会被其他的项目比如高斯、罗根等使用。

同样也存在喜欢写文档/新闻的人,这种有写作能力的人,会帮助开源项目的传播,这也是非常重要的一部份。很多项目很优秀,但是不为人所知(可能写这些项目的工程师,其文化烙印较重,不喜欢公开交流,并且没有好的文章或媒体渠道进行宣传),因此为这些项目做贡献更容易,根据自身的特点,然后决定去做相应的事情,比如组织活动等,或者编码等多件事情。

因此做开源软件帮助其他人时多方面的,不一定是开源,也不一定是软件项目。例如国外会有一些课程,这些课程也是开源的一部份,虽然没有编码,但课程会传授如何学习操作系统;比如一些面试题,在网上有 Rust 解答 LeetCode 题目的内容,这些题目的解析也是开源的一部份。

开源是文化精神,是一种理念,而非行动准则,不是一定要做某件事情才称之为参与开源/开源贡献,而是有这种精神、想法,知道自身工作内容是什么,这就是参与开源。

以下是一些实用的技巧,帮助你快速的获得经验。

1、你不具备编码的能力

对于为开源做贡献常见的误解就是:为开源做贡献必须得提交代码。事实上,代码固然重要,但是项目中不需编码的重要部分 经常被忽视 。你若做了这部分,对于项目来说可是莫大的贡献,而这根本就不需要什么撰写代码!

我被大家所熟知是因为为 CocoaPods 做了一些事, 其实大伙并不知道我实际并没有为 CocoaPods本身做了什么,我大多数的工作是诸如撰写文档、品牌宣传之类的。 — @orta , “默认迁移到开源软件”

即使你是以为开发者,非代码的贡献对于项目来说也是举足轻重的,尤其是对于社区的其他成员来说。用心维系这些关系能够让你有工作到项目其它部分的机会。我第一次接触Python开发团队(简称 python-dev)是在 2002年6月17日,当时我是向其邮件列表发送了一份邮件,是关于请求通过我的补丁的。我很快就又发现了开源的bug,于是决定开始为小组收集邮件摘要,然后他们给了我一个澄清问题的理由,但是更加重要的是,我能够捕获到某人指出需要修复的问题。 — @brettcannon , “维护者的故事”

2、是否热衷于规划事件?

  • 为项目组织研讨会或线下分享, 一如 @fzamperin 为 NodeSchool 所做的那样

  • 为项目组织大型会议(假如它有的话)

  • 帮助社区成员寻找合适的技术会议,且帮助有实力的成员提交演讲的拟稿

3、是否偏向于设计?

  • 重新布置布局以提高项目的可用性

  • 进行用户研究以重新组织和完善项目的导航或菜单

  • 整理一个风格指南,以帮助项目有一致的视觉设计

  • 创建t恤的艺术或一个新的标志, 就像 hapi.js 的贡献者那样

4、你是否热衷于写作?

  • 撰写和改进项目的文档

  • 能够以实例来展示项目该如何使用的

  • 为项目撰写新闻稿,或者到邮件列表高调布道

  • 为项目撰写教程, 一如 pypa 的贡献者所做的

  • 翻译项目的文档为本土语言

说真心话, [文档] 是非常重要的. 目前Babel的文档已经很棒了,这也是其杀手锏的特性之一。当然,还有一些章节需要大家的完善,即使是随便在哪儿增加一个段落都很感激。 — @kittens , “贡献者召集令”

5、你喜欢组织活动吗?

  • 链接重复的问题,并建议新的问题标签,使事物井井有条

  • 通过开放的问题,并建议关闭旧的, 就像 @nzakas 为 eslint 做的

  • 把最近开放的问题阐述清晰,以推动讨论

6、享受编码的乐趣?

  • 找到一个开放的问题并解决它, 就像 @dianjin 为 Leaflet 做的

  • 想一想你是否可以帮忙写一个新的功能

  • 自动化项目设置

  • 改进工具和测试

7、热衷于帮助他人?

  • 回答关于项目的问题,例如在 Stack Overflow( 像 Postgres 的这个示例 )或者 reddit 上

  • 为人们解答公开的问题

  • 帮助缓和讨论板或对话渠道

8、在编码方面是否喜欢帮助他人?

9、其实不必一定是软件项目!

尽管人们一提起“开源”二字,默认就是指开源软件,其实不尽然,开源可以是任何事情的修饰,而不仅仅是指软件而言的。比如图书、食谱、列表、以及任何可以开源的项目类。

举例来说:

尽管你是一名软件开发者,也可以去撰写一些文档去帮助新的入门者。其实项目中那些看起来令人生畏的项目并不是写代码,做开发者总得挑战自己,其实在做得过程中可以增强信心和获得全新的体验。

三、根据项目定位自我

如果你跟着了一条issue,还发现了令人感到困惑的事情,这很正常,不是你一个人这样。这些工具需要大量的隐式的知识,但是总会有人带着你熟悉这些,当然你要找他们问对的问题。 — @shaunagm , “如何为开源做贡献”

为开源做贡献,除了单词拼写错误之外,大多数时候就像是走在陌生人中间,浑身上下不适。这就像人们已经在西边讨论的非常深入了,你突然开始讲东,肯定会让人感到不舒服。

与其盲目的在项目中游荡,不如静下心来学习规则。这样反而会让你的想法被注意到,也会有人听到你的声音。

1、分析感兴趣的开源项目

每一个开源社区都是不一样的。

在某一个开源项目扎根多年,这意味着你只是对这一个开源项目无比的熟悉。若是切换到不同的项目,可能会发现完全是另外一回事,所谓的使用词汇、习惯用语、沟通方式都发生了变化。

然而,很多的开源项目还是遵循类似的组织结构的。理解不同的社区角色和全部的流程,可以很好的帮助你快速的切入新的项目。

一个典型的开源项目均会有如下类型的人:

  • 作者:项目的创始人或创始组织

  • 归属者:代码仓库或组织的管理员(不一定和作者是同一个人)

  • 维护者:贡献者,负责项目的未来走向和组织的管理(他们通常也是项目的作者或归属者。)

  • 贡献者:只要是为项目做出了贡献,就算。

  • 社区成员:那些实用项目的人们。他们或许是积极的讨论者,又或者是为项目的方向提出意见的人。

一个较大的项目,可能下面还会细分子社区,或者是针对不同的任务分成不同的小组,比如工具小组、分流、社区事务、以及活动组织等。径直到项目到web站点,找到“团队”页面,或者是查看治理文档,从而获得类似到信息。

靠谱的开源项目,一般都会有一个文档的,这些文档文件通常会在代码仓库的顶级目录列出。

  • 许可协议:根据开源软件的定义,每一个开源项目必须是有 开源许可协议 的。可以这么认为:假如说某个项目源码开放,但是没有任何的许可协议,那么它就不能叫做开源。

  • README:README 是一个介绍性的说明文件,对初次光临社区对人们表示欢迎,它通常会解释项目有何用处,为何发起,以及如何快速入门等。

  • 贡献:READMES 帮助人们来认识项目,贡献这个文件则是帮助对项目如何做贡献。它解释了目前项目需要什么样类型对贡献者,社区对流程是啥样的。并非所有的项目都会有这个文件,它某种程度上也是展示项目对于贡献者的友好程度。

  • 行为准则:顾名思义,即是一些参与社区时的一些礼仪、说话方式、行为等,帮助形成一种友好的氛围,不是所有的项目都会撰写行为准则文件,它某种程度上也是展示项目对于贡献者的友好程度。

  • 其它文档:有些项目也许还有其它文档,例如教程、导游,或者是治理规则,这在大型项目中常见。

此外,开源项目还会利用如下一些工具来进行组织讨论,阅读这些归档对于理解社区的想法、是如何工作的有非常大的作用。

  • 问题追踪:这里是人们讨论项目相关问题的地方。

  • Pull Requests:审核代码、以及相关的问题讨论。

  • 论坛或邮件列表:一些项目会实用会话式的主题(例如 “How do I*…“* 或 *“*What do you think about…“ 来替代Bug报告或特性请求)。然而有一些项目关于讨论全部实用问题追踪。

  • 即时在线聊天:有一些项目会实用聊天频道(诸如 Slack 或 IRC),从而能够随意的谈话、协作和快速交流。

国内开源其实都不太习惯用issue包括PR的方式去提交代码(包括在论坛外做一些讨论),国内更喜欢使用一些即时聊天工具,尤其是封闭平台,例如微信,这些对开源来说并不是一个特别好的方式。

四、寻找打算做贡献的项目

假如你之前从来都没有为开源做过贡献的话,那么请记住来自美国总统约翰 F.肯尼迪的这段话:不要问你的国家能为你做什么,要问你能为国家做什么。

开源项目的方方面面都需要贡献者,你先不要通盘考虑该往哪里贡献,或者是它将如何看。相反,从你已经使用到的或者打算用到项目开启贡献之路,在你积极的贡献过程中,项目也会反馈给你,让你更好的定位自己。

一旦进入某项目,不论何时,你都要听从自己的直觉,做你认为更好或者不同的事情。

开源并不是高级俱乐部;它就是由你这样的人所浇铸和打造。“开源”只是针对这个世界的需要修复的问题的一个梦幻术语罢了。

你或许在查看 README的时候,发现了损坏的链接,又或者拼写错误。又或者是你是一名新手,使用的过程中发现了问题,又或者是某问题应该在文档中注明。请不要坐视不理,径直绕开,或者是请求他人修复,伸出你的援助之手,解决这些你能看到的问题。而这正是开源的精髓之所在!

28% 的随意贡献 就是说明了贡献文档,诸如拼写错误,段落语句调整、或者是翻译。

你也可以利用如下列出的资源来找到合适的新项目:

1、提交贡献之前应做的检查列表

当你找到了你打算贡献的项目时,在进一步行动之前,作一个快速的扫描工作,以确保项目是否接受贡献的。否则,你煞费苦心的工作可能没有任何的回报。 这是一个简易的检查表,用来评估一个项目是否适合新的贡献者。

符合开源的定义

  • 有许可协议吗?通常情况下,会在根目录有一个叫做 LICENSE 的文件。

项目被接收的提交活跃度

在主干上确认提交的活跃度。在GitHub上托管的开源项目,你可以在仓库主页上看到这些信息。

  • 最后一次提交是在什么时候?

  • 项目目前有多少贡献者?

  • 人们提交的频繁吗? (在 GitHub,可以在顶栏里点击“commits”来展现。)

接下来,就是看项目的 issue 数量。

  • 目前有多少个还处于开放状态的 issue?

  • 项目的维护者对于处于开放状态的issue响应是否迅速?

  • 是否有讨论很活跃的issue?

  • issue 均是近期产生的吗?

  • 有没有关闭的issue? (在 GitHub, 点击 "closed" 标签就可以看到所有已经关闭的 Issue 。

同样再来看看 PR的情形。

  • 现下有多少处于开放状态的PR?

  • 当提交了PR后,维护者响应是否迅速?

  • 是否有活跃讨论的 PR?

  • 均是近期的RP吗?

  • 最近有多少PR合并? (在 GitHub, 点击 RP页面的 "closed" 的标签页来查看已经关闭的标签页。)

项目的受欢迎程度

一个项目的友好程度和受欢迎意味着更能吸引新的贡献者。

  • 在issue的问题中,维护者的回答是否非常有帮助?

  • 人们在issue的讨论中、在线聊天室、论坛是否很友好?

  • PR是否被review?

  • 维护者是否对做贡献的人们道声”谢谢”?

当你看到一个很长当对话时,来自核心开发者的零星的响应排在列表的后面。你就得考虑,他们在作建设性的总结?是否保持风度的情况下做出最后的决定?如果你看到的是更多的口水仗,而且还在继续,这通常意味着社区的能量重心已经不在开发上了。 — @kfogel , 开源软件生产力

五、如何提交成果

你已经找到了你喜爱的项目,也已准备好贡献了,迫不及待、跃跃欲试了。好吧!以下就是带领你如何以正确的姿势作贡献。

提交成果,就是提交PR,第一步是说清楚上下文,表明这个PR是做些什么事,一个好的PR相当于一篇小的作文/论文,需要解释清楚在什么场景下做什么事情。第二步是要达到什么目标,能解决什么问题,以及解决之后对其进行什么测试,最终得到什么结果。

PR的内容应该简单直接,而非充满不确定性的“比较好”/“我更优”(PR里并不能证明该解决方案最优),因此如何去写PR是国内工程师普遍的一个问题(国内大多数以代码为导向而非文档为导向)。

重要的是,尊重社区的决定,相关的社区_开源项目都具有自身的目标,做什么事情以及解决什么问题,大家的想法不一样(因为不在同一家公司,也不解决同一问题,具有差异性),需要大家一起讨论这个差异性,当然可以说服其他人,希望他们接受,如果不能接受,也没必要沮丧,这并不是技术问题或者其他核心问题。因此经常会遇到一个比较矛盾的问题,我希望使用一个项目,因为该项目做了70%的功能,但还有10%的功能我没有,那我则希望这10%的功能贡献到社区,但社区并不接受,因为这并不是社区_项目要解决的问题。

所以就面临一个问题:是 Fork 重新做,还是保持分支 Patch 然后每次进行合入。这就是技术和运营双包括架构选择的综合性结果,并不代表 Fork 就是不尊重社区/分裂社区,但在欧美有些极端的人会产生这种想法:在做一个事情,Fork 它就是在分裂社区。因此需要以一个开放的心态去做这件事。

1、有效沟通

无论你处于什么样的目的:仅仅是一次性的贡献,亦或是永久性的加入社区,都的和他人进行沟通和交往,这是你要在开源圈发展必须修炼的技能。

[作为一名新手,] 我很快的就意识到,我若是要关闭一条 Issue 时,我不得不问更多的问题。我浏览了代码库,一旦我觉得有什么问题的时候,我就得需要更多的指点,瞧! 在我得到所有的所需要的信息后,我就可以解决这个问题! — @shubheksha , 一名菜鸟进入开源世界的坎坷之旅

在你开启一个 Issue 或 PR之 前,或者是在聊天室问问题之前,请牢记下面所列出的几点建议,会让你的工作更加的高效。 给出上下文 以便于让其他人能够快速的理解。比方说你运行程序时遇到一个错误,要解释你是如何做的,并描述如何才能再现错误现象。又比方说你是提交一个新的想法,要解释你为什么这么想,对于项目有用处吗(不仅仅是只有你!)

😇 “当我做 Y 的时候 X 不能工作” 😢 “X 出问题! 请修复它。” 在进一步行动前,做好准备工作。 不知道没关系,但是要展现你尝试过、努力过。在寻求帮助之前,请确认阅读了项目的 README、文档、问题(开放的和关闭的)、邮件列表,并搜索了网络。当你表现出很强烈的求知欲的时候,人们是非常欣赏这点的,会很乐意的帮助你。

😇 “我不确定 X 是如何实现的,我查阅了相关的帮助文档,然而毫无所获。” 😢 “我该怎么做 X ?” 保持请求内容短小而直接。 正如发送一份邮件,每一次的贡献,无论是多么的简单,都是需要他人去查阅的。很多项目都是请求的人多,提供帮助的人少。相信我,保持简洁,你能得到他人帮助的机会会大大的增加。

😇 “我很乐意写 API 的教程。” 😢 ” 有一天我驾驶汽车行驶在高速公路上,在某个加油站加油的时候,突发奇想,我们应该这么做,不过在我进一步解释之前,我先和大家展示一下。。。” 让所有的沟通都是在公开场合下进行。 哪怕是很不起眼的小事,也不要去给维护者发私信,除非是你要分享一些敏感信息(诸如安全问题或严重的过失)。你若能够保持谈话是公开的,很多人可以你们交换的意见中学习和受益。

😇 (评论) “@维护者 你好!我们该如何处理这个PR?” 😢 (邮件) “你好,非常抱歉给发信,但是我实在很希望你能看一下我提交的PR。” 大胆的提问(但是要谨慎!)。 每个人参与社区,开始的时候都是新手,哪怕是非常有经验的贡献者也一样,在刚进入一个新的项目的时候,也是新手。出于同样的原因,甚至长期维护人员并不总是熟悉一个项目的每一部分。给他们同样的耐心,你也会得到同样的回报。

😇 “感谢查看了这个错误,我按照您的建议做了,这是输出结果。” 😢 “你为什么不修复我的问题?这难道不是你的项目吗?” 尊重社区的决定。 你的想法可能会和社区的优先级、愿景等有差异,他们可能对于你的想法提供了反馈和最后的决定的理由,这时你应该去积极的讨论,并寻求妥协的办法,维护者必须慎重的考虑你的想法。但是如果你实在是不能同意社区的做法,你可以坚持自己!保持自己的分支,或者另起炉灶。

😇 “你不能支持我的用例,我蛮失望,但是你的解释仅仅是对一小部分用户起作用,我理解是为什么。感谢你的耐心倾听。” 😢 “你为什么不支持我的用例?这是不可接受的!” 以上几点,要铭记在心。 开源是由来自世界各地的人们共同协作实现的。面临的问题是跨语言、跨文化、不同的地理为止、不同的时区,另外,撰写文字的沟通更是难上加难,无法传达语气和情绪。请让这些会话都充满善意吧!在以下情形中请保持礼貌:推动一个想法、请求更多的上下文、进一步澄清你的立场。既然你在互联网找到了自己的所需,那么请尝试让它变得更好!

2、收集上下文

在正式开始之前,做一些快速的检查项,以确保你的想法是没有被讨论过的。遍历项目的 README、问题(开放的和关闭的都算)、邮件列表、Stack Overflow。毋需去花好几个小时去全部折腾一遍,但是使用几个关键的词汇来搜索一下是必要的。

如果你没有找到和你想法一样的内容,你就可以继续了。如果项目是在 GitHub上的话,你可以通过开启一个issue或PR:

  • Issues 开启一次对话或讨论

  • Pull requests 请求接受自己的解决方法

  • 少量的沟通, 诸如澄清或how-to的问题,尝试到 Stack Overflow 、IRC、Slack或其它聊天频道。

在你创建 Issue 和 PR 之前,请检查项目的贡献者文档(文件名通常叫做 CONTRIBUTING,或者就直接包含在 README 中),找一些你需要的较具体的东西,例如,他们会要求你遵循某个模版,或者是要求你使用某个测试。

如果你做的是一个非常实际的贡献,在正式开启之前,先创建一个issue。监视项目是很有帮助的(在GitHub, 点击 “Watch” ,所有的对话都会通知到你),要让社区的成员们知道你要做的工作,免得你做了之后,再让他们知道,他们不同意,就浪费了。

你能够从单个的项目学习到 很多 ,只要你踊跃的去使用,在GitHub上密切观察项目,并阅读每一个 issue 和 PR。 — @gaearon 参与项目

3、创建 issue

你应该在遇到下列情况下,去创建一个 issue:

  • 报告你自己无法解决的错误

  • 讨论一个高级主题或想法(例如. 社区、远景、政策等)

  • 期望实现某新的特性,或者其它项目的想法

在issue的沟通中几点实用的技巧:

  • 如果你刚好看到一个开放的issue,恰是你打算解决的,添加评论,告诉他人你将负责这个。这样的话,可以避免他人重复劳动

  • 如果说某个issue已经开放很久了,这可能是已经有人正在解决中,又或者是早已经解决过了,所以也请添加评论,在打算开启工作之前,最好是确认一下。

  • 如果你创建了一issue,但是没多久自己解决了,也要添加评论,让其他人知道,然后关闭该issue。记录本身就是为社区的贡献。

4、创建 pull request

在下面的情形时,请你务必使用PR:

  • 提交补丁 (例如,纠正拼写错误、损坏的链接、或者是其它较明显的错误)

  • 开始一项别人请求的任务,或者是过去在issue中早就讨论过的

一个 PR 并不代表着工作已经完成。它通常是尽早的开启一个PR,是为了其他人可以观看或者给作者反馈意见。只需要在子标题标记为“WIP”(正在进行中)。作者可以在后面添加很多评论。

如果说项目是托管在 GitHub上的,以下是我们总结出的提交RP的建议:

  • Fork 代码仓库 并克隆到本地,在本地的仓库配置“上游”为远端仓库。这样你可以在提交你的PR时保持和“上游”同步,会减少很多解决冲突的时间。(更多关于同步的说明,请参考 这里 .)

  • 创建一个分支 用于自己编辑。

  • 参考任何相关的issue或者在你的RP中支持文档(比如. “Closes #37.”)

  • 包含之前和之后的快照 如果你的改动是包含了不同的 HTML/CSS。在你的PR中拖拉相应的图片。

  • 测试你的改动! 若测试用例存在的话,跑一遍,以覆盖你的更改,若没有的话,则创建相应的用例。无论测试是否存在,一定要确保你的改动不会破坏掉现有的项目。

  • 和项目现有的风格保持一致 尽你最大的努力,这也就是意味着在使用缩进、分号、以及注释很可能和你自己的风格大相径庭,但是为了节省维护者的精力,以及未来他人更好的理解和维护,还请你容忍一下。

如果这是你第一次提交PR。可以浏览 PR制造 的文档,这是 @kentcdodds 专门为初次创建PR的人写的公开的资料。

六、在提交完之后需要善后事宜

很不错,你做到了!恭贺你成为开源贡献者。我们希望这是一个良好的开端。 在你提交了贡献之后,下面几种情形中的某种是可能发生的:

1、😭 没有人响应你。

希望你确认在开始工作之前检查过了项目的活跃度,不过即使检查过了,也不保证一个活跃的项目,没有人理会你的贡献也是很正常的。 如果过去了一周,依旧没有人响应,请心平气和的在后面跟帖,询求他人帮助你审核下。如果你熟悉某个人可以审核你的贡献,你可以使用@+名字,直接提醒他一下。

千万不要 私下里去联系他人;一定要记住,开源项目所有的沟通都应该是公开的。

如果你做了所有该做的事情,还是没有人理你,那就是真的没有人对你的贡献做出响应。这可能感觉上不太好受,但是千万不要灰心。每个人都会遇到这样的情况。其实有太多种原因没有人响应你的提交了,包括很多个人情形都是不在你控制范围的。再接再厉,换一种方法去提交,或者换一个项目。这年头,很多社区成员都在积极的参与和响应他人,都在抢夺优秀的人才,若没有人搭理你,你换地方是没有任何不对的地方的。

这一点在国外比较明显,包括国内很多项目的一些大型技术会议都是做开源项目的人聚集在一起,开一个类似于workshop的会,有些PR_issue写的不好,无法从中了解到相应的项目是想做些什么,因此在这类会议上,大家会有一个面对面交流的机会,在这个讨论之下,就能得到对该项目的理解,然后再决定此PR是否合入_这个方向是否继续往下做。私下联系这个事情并非100%禁止,联系他人应尽量是公开的。

2、🚧 其他人的要求你对自己的提交做出变更。

对于自己的提交作出变更这件事非常的普遍,可能是你获得了反馈,也可能是变更了代码。

当有人提出变更时,请表现出大度的地方,要及时响应。他们花时间审核了你的提交,要尊重他们。开启了PR,然后一走了之,是一种恶习。如果你不知道如何修改,请花时间深入研究问题的所在,如果还是没有想到好的办法,那么是该向他人求助的时候了。

如果你因为没有时间而无法继续在此issue继续工作(举例来说,如果对话已经过去了一个月了,没有任何的回复和进度,环境肯定变得不一样了),那么请向维护者告知你无法在及时的响应了,肯定有人非常乐意接替你的工作的。

3、👎 你的贡献没有获得通过。

  • 你的提交最后可能没有被接受。真心希望你没有在此作出过多的努力。如果你不确定为什么没有被接收的话,这正是一个很好的询问维护者反馈和澄清的机会。最终,无论如何,你都要对他们的决定表示尊重。不要去做过多无谓的争论或者是充满敌意的谩骂。如果你坚持自己,你可以随意的fork项目,按照自己的思路发展出分支来。

    • 很多开源项目也是这样来的。

4、🎉 你的贡献被接收。

太棒了!你已经成功的做到了,为开源做贡献也不过如此!

七、你已经做到了!

你刚刚完成了自己的开源贡献处女秀,接下来,你可能打算寻找另外的方法来做贡献,希望本文给你提供了灵感和实践。即使是你的贡献没有被采纳或接收,也不要有失风度,请对帮助过你的维护者表示感谢!

开源就是由你这样的人所铸造:开启一个issue,在提交PR,评论、讨论、收集反馈,直到被接收。就是这么简单。 Back to all guides

七、在 GitHub 上贡献开源项目的一般步骤

在正确的场合,以正确的方式表达、参与。 作者: @nixzhu 引用:

我并不是 Git 的专家,也不太会用 GitHub。但对于开源项目,如果我在使用其过程中遇到了问题,我会很乐意去其项目代码托管处(通常是 GitHub)看看有无其他人报告同样的问题,甚至解决办法。如果没有,那我可能会写一个 Issue。同时,我也会尽我所能去研究遇到的问题,寻找其根源。如果确定能修复此问题,我也会提交一个 Pull Request。

开源项目是很好的学习材料,而且一个好的开源项目在很大程度上可以减少使用它的程序员们的工作,让他们更专注于自有的业务逻辑。但我们不该止步于此,若能共同维护一个开源项目,让其越来越好,是一件对所有人都好的事情。

有了参与的主观意愿还不够,我们得学会参与的规则和流程。我们以托管在 GitHub 上的开源项目为例(GitHub是一个运作比较良好的开源项目)。

一般方式上需要先写一个issue,这个issue有两种方式:第一种先阐述遇到什么问题、遇到该问题的场景(在什么机器上,当执行什么命令时,遇到什么结果,经过分析认为时这个程序的一个bug);第二种就是提PR说希望来做这个什么事情,认为这个项目的什么特性可以如何去开发,把这些东西作为一个issue提出来,经过反复讨论,一致认为没问题,则可根据提的issue来提一个pull request(是Git分支的一个模型的管理方式)。

1、Issue

假如你使用某个开源项目时遇到了问题,那么你首先应该去其 Issues 页面看看,例如 Yep 的 Issues 。除了 Open 的之外,还可以看看 Closed,甚至以可能的关键字进行搜索。如果你找到了某个类似的问题,你可以进去留言,说明你所遇问题的情况,或与已有描述的差别。

假如你没有找到描述类似的问题的 Issue,那么你可以点击 New Issue 来新建一个。在 Title 里简明扼要地写下问题的描述,再在 comment 里详细描述所遇问题。除了产生问题的条件,如果可能,加上一些自己对问题的推断甚至可能的解决方案。如果你对问题没有头绪,比如代码在运行中产生了一个死锁,那么你可以将程序的调用栈贴出来。这些信息有利于项目的维护者定位问题的根源。

写 Issue 的重要原则就是不要随意,要将其看成一种参与,一种帮助和自助。因此,词句要清晰,描述要详尽。若发完 Issue 后发现还有需要补充的地方,可以进一步增加 comment。

最后,在提交新的 Issue 之前,应该检查一遍,确保没有明显的错别字和语法错误。

2、Pull Request

我想,有能力的程序员不会止步于发 Issue,他们会更想直接以修正代码的方式解决问题,这就需要明了 Pull Request 的流程。

简单来说,Pull Request 是外部开发者参与开源项目的主要方式。因为通常一个开源项目不会允许所有人都去直接修改代码,这会让项目变得混乱,难以维护和测试。

因此,外部开发者需要先 Fork 已有项目,然后在自己 Fork 的项目上进行修改,最后这两个项目就产生了差异,GitHub 可以检测到这样的差异。当外部开发者修改完成,就可以利用 GitHub 将自己的改动以 Pull Request 的方式提交到原项目,原项目维护者再对改动进行检查和测试。在确定没有问题后,将改动合并到项目中。这样外部开发者的这一次参与就完成了。

听起来似乎有些复杂,但正是这样的流程保证了代码的持续稳定。因为写代码和写文章一样,并不是一件随意的事情。

  • Fork。例如在 Yep 的项目上,点击右上角的 Fork 按钮(请大胆地点击,这不会对世界造成任何明显的伤害),然后你就得到了当前 Yep 项目的一个拷贝。

  • Clone。因为我们通常在本地电脑上做修改,因此先将 Fork 的项目 Clone 到本地,大家应该很熟悉吧。例如git clone https://github.com/XXX/Yep.git,其中 XXX 为你的 GitHub 用户名。

  • 保持同步。大多数学会 Fork 的开发者都会自然地产生一个疑问:如果原项目被改动了,那我们自己的拷贝该怎么同步原项目的改动呢?因为之前的拷贝是以那个时候的原项目为原本的。这也不难,在本地项目中,运行 git remote add upstream https://github.com/CatchChat/Yep.git,这就将原项目作为了本地项目的上游。你可以在运行此命令之前和之后运行git remote -v来观察改动。之后,若你想同步原项目的改动,执行git fetch upstream即可,这会将原项目所有分支的改动都存储在本地,例如原项目 master 分支会存为 upstream/master,不过这还不会对本地的项目造成影响。将如你想将上游 master 的改动合并到本地,只需先切换到 master 分支 git checkout master,再执行合并 git merge upstream/master 即可。同理可以按需要处理 develop 分支等。

如果你的改动很小,那么修改所持续的时间不会很长,你可以不做“保持同步”这一步。当你发出 Pull Request 后,若被维护者合并,你就可以从 GitHub 上删除你 Fork 的项目了。若下次你还想再修改,完全可以重新 Fork,这一次同样会以最新的代码为基础进行拷贝。

如果你想长期参与,那在做完第三步后,还可以 git branch --set-upstream-to=upstream/master master,这样当上游的 master 有改动后,只需在本地 master 分支 git pull 即可。同理,你也可以处理 develop 等分支。

通常,我们都在新分支里做修改,在测试改动没有问题后才合并到主分支。大家经过总结,出现了一套叫做 Git Flow 的流程。简单来说,在 master 外,建立一个 develop 分支用于开发,而且,每一个新特性的开发都会从 develop 分支创建新分支,新特性开发完成后再合并到 develop 分支。

我们也并不需要精通 Git Flow,只需记住两个命令 git flow feature start XXXgit flow feature finish XXX,其中 XXX 是你要开发的特性(或要修复的Bug)的名字。我搜索到一篇很清晰的 关于 Git Flow 的讲解 ,大家一起学习。

Yep 的开发使用了 Git Flow,但作为外部开发者,你也不一定非要使用它,因为本质上 Git Flow 也只是建立分支,并以分支为基础的一套方便工具。

例如 git flow feature start XXX 以 develop 为基础,创建一个新的 feature/XXX 分支,而 git flow feature finish XXX 就将 feature/XXX 分支合并到 develop,你完全可以直接用 git 命令来实现。例如 git checkout -b XXX develop 就会以 develop 分支新建一个 XXX 分支(这里没有自动写上的 feature 前缀),当你完成你的修改后,git checkout develop 然后 git merge --no-ff XXX develop 就可以将 XXX 分支合并进 develop 了。不过,你也可以直接以 XXX 分支发 Pull Request,只需先将其git push origin XXX到 GitHub,然后在你 Fork 的项目主页点击 Compare & pull request 按钮即可。如果没有这个按钮,也可以点击 New pull request 按钮来发起,注意选择正确的分支即可(你工作的分支到 Yep 的 develop 分支)。

以上是个人对 Git 以及参与 GitHub 项目的粗浅理解,如有错漏,欢迎以 Issue 或 Pull Request 的方式指正!

欢迎转载,但请一定注明出处! https://github.com/nixzhu/dev-blog

八、开源潜规则

1、何为潜规则?

规则之前概率生效概率公开各自解读
人数很少的时候管理者的意识为何会私下处理大社区里的小圈子
判例法的意识情况的复杂性为何会另外找理由揣摩者

2、六个开源软件开发的“潜规则”

1)按部就班,循序渐进

  • 理解社区目标

  • 完成社区任务:测试补丁、复审代码、撰写文档、修正错误

  • 关注整个社区的动向,而非只关注自己开发的功能

2)博闻强识,敦善不怠

  • 在某个社区中建立声望,全面了解该项目和代码是很有必要的

  • 努力钻研项目,对项目各个部分如何与其他人协作交互有深入的理解,理解超出你擅长范围之外的知识

  • 不要只把自己的理解局限于开发者

3)粗枝大叶,自寻烦恼

代码提交完毕并不代表工作结束。如果代码被接受,还会有更改的讨论、常见的问答,以及做测试。要确保你可以准时提交,努力去理解如何在不影响社区其他成员的情况下,改进代码和补丁。

4)和谐相处,助人助己

开源社区不是自相残杀的丛林世界,我们更看重项目的价值而非个体的贡献和成功。如果你想给自己加分,让自己成为更重要的社区成员、让社区接纳你的代码,那就努力帮助别人。如果你熟悉网络部分,那就去复审网络部分,用你的专业技能让整个代码更加优雅。顶级的审查者经常和顶级的贡献者打交道。你帮助的人越多,你就越有价值。

5)八面玲珑,面面俱到

想要引进新技术,特别是比较有争议的技术,最好的办法就是让人无法拒绝它。你需要透彻地了解底层代码,考虑每个极端情况。在不影响已实现功能的前提下增加新功能。不仅仅是完成就行,还要在特性的完善上下功夫。

6)糜不有初,鲜克有终

开源社区也有许多玩玩就算的人,但是承诺了就不要轻易失信。不要就因为提交被拒就离开社区。找出原因,修正错误,然后再试一试。当你开发的时候,要和整个代码库保持一致,确保即使项目发生变化而你的补丁仍然可用。不要把你的代码留给别人修复,要自己修复,形成社区良好风气。

3、人人平等与精英治理

在开源社区存在一种现象:人人平等与精英治理。其实这背后潜在某种矛盾性。在开源社区里面,我们提倡的是人人平等,但实际上开源社区基本上是由一些Maintainer在经营治理,它不是人人都可以参与的。所以我觉得开源社区是精英治理的模式,这背后的精英,通常属于某一家公司或某几家公司。 社区里面所谓的人人平等,从发言权角度考虑是成立的。你可以表达你的意见,但并不见得你的意见会被采纳。

4、社区中的潜规则

社区里会有张罗大大小小事情的人,这种人很了不起,他是社区存在的核心或者说是社区存在的原因。可能他在社区里有一些代码大家都在用,只要开源出来放在那里,开源的项目便会持续存在。

但社区就不一定了,我们经常看到一些没有人维护的“死掉”的社区,如果社区里的人在社区里依然坚持做某件事情,其实就会使社区真正存活。所以社区是由人组成,而不是由代码组成。

开源使用规范及业界优秀实践

第一节 - Google 和 Oracle 的世纪诉讼

旷日持久的 Java 版权大战:谷歌有限责任公司诉甲骨文美国公司案(Google LLC v. Oracle America, Inc.),593 U.S. (2021),于 2021 年 4 月 5 日以 Google 的胜利告终。这起持续了 10 余年,跨越了三个审判和两个独立上诉的以计算机代码性质为焦点的著作权法案件引发业界热议,对于科技和软件行业具有重大意义。

该案的诉争对象是 Java 编程语言的部分应用程序接口(简称 API )以及大约 11,000 行源代码。这些代码最早由 Sun Microsystems 开发,在 Sun 被甲骨文公司收购后,甲骨文公司通过其附属的甲骨文美国公司对其享有著作权。Google 在其开发的 Android 操作系统早期版本中使用了上述接口及代码,但在后来发布的 Android 版本中没有继续使用上述有甲骨文及其公司享有著作权的源代码。对于 Oracle 的 API ,Google 虽承认存在使用行为,但主张其构成合理使用。

最高法院 Alsup 法官在第二次上诉裁决中引用了最高法院案件 Campbell v. Acuff-Rose Music, Inc.510 U.S.569(1994),并指出:

Truth, in literature, in science and in art, there are, and can be, few, if any, things, which in an abstract sense, are strictly new and original throughout. Every book in literature, science and art, borrows, and must necessarily borrow, and use much which was well known and used before [2]

  1. 使用的目的、性质和合理使用 [4]

它(目标代码)是否具有“变革性”以及在多大程度上具有“变革性”—— Campbell v. Acuff-Rose Music, Inc. 510 U.S. 569 (1994)

法官认为谷歌的 API 是一种“创新”,它使得开发人员只需要很少的命令就能调用预先写好的代码。这里面有谷歌创造性的劳动在里面。

版权所有者不得阻止他人“合理使用 (fair use)”受版权保护的作品合理使用的目的是鼓励创新。

来看下美国版权法对“合理使用“的定义:Copyright Law of the United States

107. Limitations on exclusive rights: Fair use

Notwithstanding the provisions of sections 106 and 106A, the fair use of a copyrighted work, including such use by reproduction in copies or phonorecords or by any other means specified by that section, for purposes such as criticism, comment, news reporting, teaching (including multiple copies for classroom use), scholarship, or research, is not an infringement of copyright. In determining whether the use made of a work in any particular case is a fair use the factors to be considered shall include— (1) the purpose and character of the use, including whether such use is of a commercial nature or is for nonprofit educational purposes; (2) the nature of the copyrighted work; (3) the amount and substantiality of the portion used in relation to the copyrighted work as a whole; and (4) the effect of the use upon the potential market for or value of the copyrighted work. The fact that a work is unpublished shall not itself bar a finding of fair use if such finding is made upon consideration of all the above factors. 如何判断合理使用呢?有两种情况:

1、6种通常场景:批评,评论,新闻报道,教学(包括多份供课堂使用),奖学金或研究报告,并不构成对版权的侵犯

2、当不在6种场景以外时,考虑以下4个维度:

(1)使用目的和性质,包括该使用是商业性质还是非 营利性教育目的;

(2)受版权保护的作品的性质;

(3)与整个受版权保护作品有关的部分的数量和实质性;

(4)使用对版权作品潜在市场或价值的影响。再看谷歌案,最高法院法官的判例如下:

(1)使用的目的和性质

  1. 受版权保护的作品的性质

    计算机程序与其他受版权保护的作品是不同的,因为它总是服务于功能性目的,合理使用对计算机程序而言是非常重要的。需要进行上下文判断,而不是断章取义(仅有片段信息是不充分的)。

    同时版权保护不能延伸到“任何想法、程序(procedure)、过程(process)、系统、操作方法、原则和发现…”。

  2. 与整个受版权保护作品有关的部分的数量和实质性

    法官认为复制的数量只占整个 API 的 0.4%,而就是因为这 0.4% 使得开发者可以帮助程序员在智能手机场景下进行“变革性”的创造。再次牵涉到“变革性”的权衡,引用判例的话说就是新作品的变革性越强,可能不利于合理使用的发现的其他因素(例如商业主义)的意义就越小。—— Campbell v. Acuff-Rose Music, Inc. 510 U.S. 569 (1994)

  3. 使用对版权作品潜在市场或价值的影响

    法官认为 Oracle 的代码的市场和谷歌的安卓代码存在很大差异,一个是桌面端的 一个是移动端的,两者在各自领域并不存在事实的冲突和竞争关系。

最终,最高法院认为谷歌的 API 代码相比甲骨文的 Java 代码具有“变革性”,为鼓励创新,不应算作侵犯版权,判决 Google 对 Java API 的使用属于合理使用,谷歌胜诉。

“Google 对于实现用户界面 API 的复制,仅采用了允许用户将其应有的才能投入新的,变革性程序中所需的一切,这就构成了对该材料的合理使用。”[3]

像 Google 与 Sun 在 Java 语言上的关系,以及开源软件、API 的内容借鉴在科技领域内并不少见。如何依托于可信的开源软件供应链思想规范使用开源,对开源软件进行端到端的流程管理,结合上一节讲到的网络安全风险、法规风险、生命周期的风险,这一节将从选择开源软件、使用开源软件、维护开源软件的生命周期、回馈开源社区四个方面进行阐述。

1.1 开源项目使用的主要方式

目前企业使用开源的场景主要有两种方式:

  1. 基于开源软件进行开发

    很多企业在开源软件的基础上进行开发,在合规的基础上构筑自己的商业产品。譬如国内的云厂商绝大部分都有基于 CNCF 基金会下的开源项目 Kubernetes 构建容器相关的云产品,同时研发了很多开源或者闭源的插件、Operator 来满足不同客户的诉求,使得这些云厂商的相同类型产品之间产生了差异性,针对不同的客户和场景形成竞争力差异。但是使用 Kubernetes 的过程中,需要持续的跟进 Kubernetes 版本的变化,也消耗了大量的精力。所以这种情况下,各个云厂商将自己开发的特性开源贡献到上游,避免和上游社区形成不同的维护分支。

  2. 调用开源软件的进程

    有一些企业开发的代码是在运行时调用其它开源项目的代码或者进程。譬如使用 Nextjs 开发页面应用的时候,会大量集成 JavaScript 的库;一些在 Linux 下开发的程序会调用 OpenSSL 的 MD5 库计算哈希值进行一些校验工作。

不管是那种场景都存在“使用的代码版本老旧、编写软件时进行开源代码片段引用”等现象以及由此带来的“网络安全、合法合规、可追溯性差”等开源合规、开源治理方面的问题。本节内容将从软件开发和维护的不同阶段对使用开源进行约束,并提出规则、建议、标准和对工具的要求。

为确保满足网络安全、合法合规、可追溯性要求,从产品研发角度规范产品开发团队合理使用开源软件代码,指导产品正确使用开源软件。

  1. 无开源代码片段引用问题

    案例:Google 凭什么要赔给 Oracle 88 亿?

    https://cloud.tencent.com/developer/article/1169428

  2. GPL 感染被动开源情况

    案例:违反 GPL 协议赔偿 50 万,国内首例!

    https://www.163.com/dy/article/GJQ7HP3G0511FQO9.html

  3. 开源使用声明及履行对外开源义务合规,无法务风险

    案例:国产红芯号称自主研发浏览器核心 结果是 Chrome 换皮

    https://tech.sina.com.cn/n/k/2018-08-16/doc-ihhvciiv6109112.shtml

  4. 满足开源软件网络安全管理要求

    案例:紧急! Log4j 漏洞风险,堪比“永恒之蓝”或将影响 70% 以上企业

    https://www.leiphone.com/category/gbsecurity/5D1Aq04tyjCDMill.html

在产品开发的每个阶段、不同方式使用开源都会带来各种问题和风险,需要我们关注和控制。

类别选型集成架构与设计开发维护
现象版本老旧协议遵从没有充分利用扩展机制片段引用、对开源原生代码进行修改社区安全补丁缺乏跟踪 版本老旧
带来的问题网络安全合法合规开源原生代码 不必要的修改带来的 网络安全、可追溯性差网络安全、合法合规、可追溯性差网络安全

第二节 - 开源选型规则实践

2.1 面向个人或家庭消费者的软件产品,使用 GPL v3 License 的开源软件会带来巨大风险。其它类型的软件产品需要仔细评估风险,同时在软件采购或合作开发时限制供应商或合作方引入该类型的 License 的开源软件

案例:Ruby用实际行动向 GPL v3 吐槽,Ruby 1.9.3 将改用 BSD 许可证发布

早期 Ruby 采用的是自由软件基金会推荐的 GPLv2 or later 许可证方式,这种许可证方式包含两层意思:[5]

  • 软件本身以 GPLv2 许可证发布

  • 当自由软件基金会修订 GPL 并发布新版 GPL 时,授权一方同意授权人以新的 GPL 条款来发布软件 (*)

由于 GPL v3 中增加了包含对硬件和软件专利等问题的一系列限制自由的条款(违反第 6 条),GPL v2 only 的代码和 GPL v3 许可证的代码不能一起重新分发。此外,自由软件基金会认为 Ruby License 是非自由软件许可证,根据 GPL v3 第 10 条的内容,GPL v3 许可证的软件不能与 Ruby 以 Ruby License 联合编译。

也就是说,Ruby 只能以两种许可证之一发布,发布联编的可执行文件要么违反 GPL v2,要么违反 GPL v3,因此再发布的结果只能以源代码的形式提供,而不允许再发布其二进制文件。又因自由软件基金会从 6.0 版开始,将 readline 库改为 GPLv3 or later,这样一来,GPL v2 only 的 Ruby 便不能发布联合编译 readline 的可执行文件了。2020 年 9 月,Ruby Changeset r29262 将 Ruby 中的 GPLv2 许可证完全删除,改换为基于 FreeBSD 许可证的 2-clause BSD 许可证。[5]

  • 个人或家庭消费者用户的产品在引入开源软件的阶段进行 License 校验,禁选 GPL V3 协议的开源软件。
场景管控策略
采购场景在采购协议中增加条款,禁止或限制供应商引入使用 GPL v3 类开源软件
开源软件中央仓库在入库流程预审环节中增加 GPL v3 类自检 check 项,提前知会产品风险,若产品要引入 GPL v3 类软件,但无法满足 GPL v3 要求,则建议不予引入
评选等级在开源软件中央仓库中,GPL v3 类软件优选等级设定较低,根据风险评估尽量限制产品选用
使用申请申请使用 GPL v3 类软件,必须结合使用场景分析 License 风险,根据风险向管理决策者提出申请后使用,同时 GPL v3 类软件评审环节需要律师参与

2.2 选择开源软件必须通过开源软件的基础安全评估

在选择开源软件,对开源软件进行评估时,必须进行基础安全的评估,根据评估结果确定是否选择。“心脏滴血”漏洞事件就是最好的例证。出现“心脏滴血”漏洞之后,OpenSSL 社区建立了完善的漏洞维护记录,挽回了其在商业领域的信誉 https://www.openssl.org/news/vulnerabilities.html

近年来,以 OpenSSL 等为代表的基础开源组件频现高危漏洞,给各国和企业造成不同程度的损失,促使国家和企业提高对开源软件基础安全评估的关注程度。美国 NSA 在《网络基础设施安全指南》技术报告中提出,定期将软件升级至供应商支持的更新版本**,**在使用前和使用过程中进行验证,以确保效率和安全。对于软件的评估包括:

  • 验证软件和配置的完整性
  • 维护正确的文件系统和引导管理
  • 维护最新的软件和操作系统

由国家保密科学技术研究所主办的《保密科学技术》杂志曾写道,现有的 CVE/CPE 体系以及 NVD 等漏洞库,已经无法满足开源软件安全治理的需求,需要创新开源软件的漏洞情报研究、共享、共治机制,合作建立开源软件漏洞情报库。[6] 风险控制措施:[7]

  • 国家层面组织开展开源软件源代码检测工程

  • 企业层面建设开源软件安全治理体系

  • 用户侧建立软件安全渗透测试机制

  • 检测机构加强对安全产品中开源组件的检测

NVD(NATIONAL VULNERABILITY DATABASE,国家漏洞数据库)

NVD 是美国政府使用安全内容自动化协议(SCAP)表示的基于标准的漏洞管理数据的存储库,可实现漏洞管理、安全测量和合规性的自动化,旨在帮助个人和公司研究漏洞管理的自动化及其他安全性和合规性目标。[8] 用户可以访问:[9]

  • 可搜索的漏洞数据库

  • 检查清单

  • 影响指标

  • 相关统计

第三节 - 集成开源软件时关注传染性,避免商业核心代码被动开源

3.1 产品集成开源软件必须满足开源 License 要求

企业管理使用开源软件需要有 IT 流程保证,避免开发人员在开发过程中随意使用开源软件。对于开发流程自动化的企业,可以在 DevOps 流程中进行检测引入的开源软件和版本是否为可以选用的版本。譬如在 nodejs 代码提交时,在代码管理平台自动检测 package.json 文件中引入软件包的变化,检查构建依赖、运行依赖的 Library 是否在容许引入的清单中。

在代码提交阶段的检查属于事后检查,需要产品经理、架构师和开发者等软件生命周期相关的参与者都在产品设计、技术架构设计阶段就考虑到使用的开源软件可能要旅行的义务。

MongoDB 一直使用 GNU AGPL(Affero General Public License)v3 的开源协议,但是 MongoDB 并没有在大量云服务厂商上赚到钱,所以 MongoDB 将协议切换为 SSPL ,即 Server Side Public License 。虽然 OSI 并不承认 SSPL 是开源许可协议,但是任何使用 MongoDB 的公司和个人也必须遵守 SSPL 对条款。如果企业的产品包含 MongoDB 并提供服务,就需要考虑 SSPL 协议带来的影响,所以在产品设计的伊始,产品经理就需要考虑开源软件的 License 遵从问题。

Elasticsearch 和 Kibana 的开源协议由之前的 Apache 2.0 切换为 Elastic 许可 + SSPL 的双重授权许可模式,对于使用 Elasticsearch 和 Kibanna 的产品也带来了重大影响,架构师要根据产品的需求、提供给客户的形态慎重选择 Elasticsearch 的组件和版本,避免带来 License 遵从的风险。架构师也可以考虑寻求其它的开源组件替代方案来解决这个问题。

所以一个软件研发的过程中,需要在流程设计上考虑到 License 遵从,在研发的每个阶段设计都要求参与者考虑到 License 遵从的风险,并且要为产品经理、架构师和开发者提供足够的支持,同时对于使用的开源软件需要通过 IT 流程机制进行控制,计划使用的开源软件需要在 IT 流程中进行申请和审批,确保参与审批的人是经过专业培训的。

常见许可证类型典型软件触发代码开源义务 前提条件开源要求和范围规避开源方式License文本链接
BSD 类 如Apache/BSD/MITTomcat,OpenSSL不涉及https://www.apache.org/licenses/LICENSE-2.0 (Apache license 2.0) https://www.openssl.org/source/license.html (Apache license v2)
MPL 类 如MPL/EPL等Firefox,Eclipse产品集成使用该软件,并对外分发或销售,产品对该软件进行了修改若无修改,则无需开源;若对其进行了修改,需将修改的部分开源使用时不做任何修改https://www.mozilla.org/en-US/MPL/2.0/ (MPL license 2.0)
LGPLHibernate,glibc产品集成使用该软件,并对外分发或销售软件本身须开源。具有传染性,与其静态链接部分的代码也必须以 LGPL 许可开源;动态链接则不被传染动态链接使用,仅开源其软件本身即可,产品代码可免受传染https://www.gnu.org/licenses/lgpl-3.0.html
GPLBusybox,linux knrnel产品集成使用该软件,并对外分发或销售软件本身须开源。具有传染性,与其有链接关系的代码都必须以 GPL 许可对外开源,即与该软件在同一进程中运行的代码都必须开源进程隔离,独立于产品进程运行,仅开源其软件本身即可,产品代码可免受传染https://busybox.net/license.html (GPL version 2) https://dri.freedesktop.org/docs/drm/process/license-rules.html#kernel-licensing (GPL version 2 only (GPL-2.0))
AGPLBerkeley DB产品集成使用该软件同 GPL同 GPLhttps://www.gnu.org/licenses/agpl-3.0.html
SSPLMongoDB产品集成使用该软件同 GPL + 其他相关运行服务仅内部使用、不对外;购买商业协议https://www.mongodb.com/licensing/server-side-public-license

3.2 开源软件选型原则和评估角度

3.2.1 开源软件选型原则
  1. 产品目标与开源软件的匹配度。业界实践认为如果需要修改开源软件的代码行数超过 20%,则不如购买更匹配功能的 “商业软件” 。避免在未来软件维护过程中产生的上有主干回合等开源技术债务引发的额外成本
  2. 开源软件的 License 不兼容产品策略,譬如云服务要使用具有 SSPL 协议的开源软件,需要考虑到成本问题。
  3. 开源软件的质量和安全是否满足产品的需求。
  4. 开源社区是否已经不再更新,或者项目是否已经 Archive
3.2.2 开源软件评估原则
  1. 开源软件的技术生态
    1. 技术架构、思路是否在业界具有先进性,是否有技术规划明确的项目目标
    2. 否有主流的供应商或者比较成熟的咨询公司
    3. 是否有比较大型的客户在使用该开源软件,有成熟应用场景和案例
  2. 开源软件的合法合规
    1. 开源软件的获取来源是否可靠,是否可以持续的获取
    2. 开源 License 是否兼容、是否存在需要关注的专利等知识产权问题
    3. 开源软件是否满足产品销售地的贸易合规
  3. 开源软件的生命周期
    1. 开源软件的版本的生命周期是否满足产品的需求
    2. 开源软件的社区是否有能力支撑
  4. 开源软件的安全问题
    1. 对开源软件进行定期对病毒扫描
    2. 通过漏洞扫描发现安全风险
    3. 开源社区对已知安全问题的修复能力、修复周期
    4. 对开源软件进行全面的安全测试,保证符合产品的需求

第四节 - 架构设计解耦规则

4.1 专有软件与开源解耦

  • 规则描述:专有软件和开源代码在架构设计上解耦、逻辑解耦(可以独立升级开源软件版本)、物理解耦(独立文件或者进程)
  1. GPL 传染性问题,造成不能在同一个进程中运行
    1. 对于传统修改 Kernel 的技术方案,可以采用 ebpf 的方式通过用户态应用来处理业务。ebpf 部分的代码可以根据 GPL 要求开源,但是实际处理业务的用户态的应用就可以隔离在 GPL 传染性之外。
  2. 安全性问题,造成影响面扩大 - log4j 案例
  3. 对于 Kernel 的修改可以采用 Patch 的方式分发,即使是商业分发,购买 Patch 的人只要不做二次分发就是合理的
  • 问题案例:当因为产品原因修改开源软件的代码时,专有的代码和开源代码相互融合,难以解耦,修复开源软件的漏洞或者随开源软件的版本进行升级将非常困难

  • 处理策略:制定基于开源开发的分层插件式的解耦策略,下列解耦的方式供参考

  1. 特性间解耦:架构机制中将策略、数据和控制分离
  2. 独立组件程序
  3. 动态库链接方式 调用
  4. 静态库链接方式 调用
  5. 形成独立的文件
  • 某产品整改过程中架构解耦的实践
  1. 如果可以解耦调用,那么解耦 —— A 包含了 B 的代码变成 A 引用B的代码(案例: kernel 模块)。这种情况下,需要引入 B 项目,需要额外申请B软件的使用说明并对外履行义务

  2. 如果解不开,而且的确是基于开源做的大量修改,那么老老实实认定这个项目是“对开源软件的修改”,而不是“专有软件对开源软件的引用”。—— A 包含了 B 的代码变成 A 就是 B。这种情况下,补丁式处理这种修改结果并且牵引更加合理的修改

4.2 分析开源软件扩展机制,优先使用内置扩展机制实现定制特性

  • 对于 Linux Kernel 的开发,使用 epbf 技术是目前最佳的选择。扩展的柏克莱封包过滤器(extented Berkeley Packet Filter,缩写 eBPF),是 类 Unix 系统上 数据链路层 的一种原始接口,提供原始链路层 封包 的收发,除此之外,如果网卡驱动支持洪泛模式,那么它可以让网卡处于此种模式,这样可以收到网络上的所有包,不管他们的目的地是不是所在 主机。参考维基百科和 eBPF 简史及 BPF、eBPF、XDP 和 Bpfilter 的区别。

img

Cilium 是基于 Kubernetes 的 Linux 容器管理平台上部署的服务,透明地提供服务间的网络和 API 连接及安全。Cilium 底层是基于 Linux 内核的新技术 eBPF,可以在 Linux 系统中动态注入强大的安全性、可见性和网络控制逻辑。 Cilium 基于 eBPF 提供了多集群路由、替代 kube-proxy 实现负载均衡、透明加密以及网络和服务安全等诸多功能。除了提供传统的网络安全之外,eBPF 的灵活性还支持应用协议和 DNS 请求/响应安全。同时,Cilium 与 Envoy 紧密集成,提供了基于 Go 的扩展框架。因为 eBPF 运行在 Linux 内核中,所以应用所有 Cilium 功能,无需对应用程序代码或容器配置进行任何更改。

这种方式为开发者提供了更多的选择,通过 ebpf 方式利用 Linux Kernel 底层的特性开发服务,并且可以在不违反 GPL 的情况下开发商业应用。当然一个架构设计的优秀开源项目会更容易拓展,Kubernetes 的架构设计可以说是经典的案例。

img

Kubernetes 的架构更容易让商业发行版的厂商基于 Operator 、插件等机制扩展功能和性能,而选择是否开源则比较从容,并且不违反开源 License 。所以在选择开源产品的时候,对于开源软件的是否有足够的扩展机制,是选择的重要理由。

4.3 遵从社区版本开发原则,对开源的修改尽量回馈社区

  • 案例:虽然 Apache 许可证(2.0 版)允许开发人员修改代码,无需将更改贡献给上游社区,但 Amazon 选择主动回馈 Lucene 和其他项目。秉承开源的贡献和收获精神,Amazon 已经向 Lucene 提出了多项重要的改进,包括:
  1. 并发更新和删除
  2. 建立自定义词语频率索引
  3. 慵懒加载无限状态变送器

借助这些改进和 Lucene 社区已经构建的丰富现有功能,Amazon 搜索团队正在稳步实现在将 Lucene 用于所有 Amazon 产品搜索的目标。它让 Amazon 得以使用 Lucene 特有的功能(例如尺寸点和查询时间关联)来提升顾客购物体验。企业为客户提供良好长期体验的最佳方式,都需要投资开源软件。

  • 社区版本开发原则
  1. 不背离社区,明确架构原则,遵从社区开发原则,对开源原生代码修改尽量回馈社区,不破坏开放和生态基础,避免与社区API接口不一致问题。

  2. 基于开源开发新特性或功能时,产品需审视并遵从开源社区架构/设计的匹配情况,可参考以下流程决定哪些新增/修改代码应该开源或私有或废弃。

第五节 - 如何引用开源项目代码的片段

5.1 将开源软件部分函数/宏或部分文件拷贝到产品专有软件代码中使用

5.1.1 什么是开源项目代码片段引用
  • 未完全引入开源软件版本的整包代码,仅将部分函数/宏或部分文件拷贝到产品专有软件代码中使用叫做片段引用。

  • 片段引用情况举例:

  1. 函数名不同,函数体相同(仅函数名不同,基本功能算法代码片段与开源完全相同) ;

  2. 整段宏定义与开源代码完全相同;

  3. 工具扫描相似度不高,但除函数内调用的接口不同外,变量定义等都与开源代码完全相同。

5.1.2 引用可能产生的问题 - 案例

2021 年 12 月,TikTok Live Studio 疑似在不遵循 GPL 许可证的情况下使用了 OBS 的源代码。而 OBS 使用的 GPLv2 开源许可证具有很强的传染性:只要该软件使用过 GPL 协议的产品,则该软件产品也必须采用 GPL 协议,且必须是开源的。但 TikTok 并没有将其直播流媒体软件 “TikTok Live Studio” 开源。

img

从 TikTok Live Studio 反编译的代码看,其安装程序似乎与 OBS 的安装程序有着巧合般的相似…...

由于违反片段引用原则,TikTok Live Studio 最终在应用市场全面下架。

  • 违反原则带来的风险
  1. 所有权方面 - 专有软件意味着 Copyright ,片段使用会导致专有软件代码混淆非企业版权的代码。对于本身就是开源的项目,则片段使用不存在此问题;

  2. 协议履行方面 - 开源协议会涉及义务履行,片段使用容易导致“不知道使用了什么协议的代码”,进而忽略其相对应的对外义务履行;

  3. 安全追溯方面 - 如果社区项目存在修复更新,片段使用的代码不容易追溯社区的修复。

5.1.3 如何判断引用及扫码工具介绍
  • 检验标准:对产品全量代码进行分析,确保所有使用的开源软件是整包使用,无片段引用情况,可借助扫描工具辅助分析。

  • 扫描工具现状:

  1. SPDX - 一组用于传达与软件包相关的组件、许可证和版权的标准。

  2. LicenseFinder - 查找项目依赖项的许可证

  3. ScanCode-toolkit- 扫描代码以获取许可证、版权和依赖项

  4. FOSSology - 扫描代码以获取许可、版权和出口控制信息

  5. License- 识别项目的许可文件

  6. License Information Document - 从源代码中识别和提取许可证文本

  7. askalono - 帮助检测许可证文本的库和命令行工具。它旨在快速、准确并支持各种许可文本。

  8. Licenseclassifier - 一个库和一组工具,可以分析文本以确定它包含什么类型的许可证

  9. OSS Attribution Builder - OSS Attribution Builder 是一个网站,可帮助团队创建软件产品中常见的归因文档(通知、“开源屏幕”、信用等)。

  10. OSS Review Toolkit - 通过扫描、下载源代码、报告任何错误和违反用户定义规则的行为以及创建第三方归因文档,对项目的源代码和依赖项进行高度自动化和可定制的开源合规性检查。

  11. fossa-cli - 任何代码库的快速、可移植和可靠的依赖分析

  12. Licensed - 一个 Ruby gem,用于缓存和验证依赖项的许可证

  13. LicensePlist - 一个命令行工具,可自动生成所有依赖项的 Plist,包括手动添加的文件(由 YAML 配置文件指定)或使用 Carthage 或 CocoaPods。

  14. dpkg-licenses - 一个命令行工具,它列出了基于 Debian 的系统(如 Ubuntu)中所有已安装软件包的许可证。

  15. FOSSID - 用于许可证和漏洞的综合商业扫描程序。知识库涵盖 78M+ 存储库和 600B+ 片段。包括详细的片段扫描以检测片段和复制/粘贴代码上的许可证,即使未明确或正确声明开源许可证。

  16. DependencyTrack - Dependency-Track 是一个智能组件分析平台,允许组织识别和降低软件供应链中的风险

  17. ScanOSS - 从开源项目的大型知识库中扫描您的代码库中的片段和抄袭。旨在与 CI/CD 和现代 IDE 集成,“从左开始”进行持续验证,而不是最后只报告一份。产品本身是完全开源的。

5.1.4 如何正确处理开源软件的片段使用
  • 如果不允许引用开源代码的片段,对于使用开源软件来说确实存在很大困难,如果必须引用,一定要遵守相应软件的 License 的义务。

  • 是否重写开源软件:

  1. 如果做不到完整引入开源软件,也没有可替代的商业软件,则需要根据实际产品需求进行开发。
  2. 在重写时不要参照其代码,否则可能会被检测出重写的代码也使用了该开源软件。重写时可以选择其它团队,没有阅读过开源软件代码的工程师进行编写,在编写的过程中在不能访问 Internet 的网络条件下进行编写。
  • 当引用一段开源软件的代码,即使做了以下的修改,也会被识别为代码片段引用
  1. 修改函数名

  2. 调整上下顺序

5.2 涉及源代码交付,对开源原生代码进行修改的代码,使用 Patch 方式管理

  • 什么是 Patch ?

    Patch 是一个文本文档,也叫补丁,包含两个不同版本的源代码树之间的变化,是通过 diff 应用程序来创建

  • Patch 的业界优秀实践 - Linux Kernel [10]

    Linux 内核的 Patch 是相对于包含内核源目录的父目录生成的。用 Patch 程序应用一个 Patch。Patch 程序读取 diff 或 patch 文件,并对其中描述的源代码树进行更改。这意味着 Patch 内部文件的路径包含生成 Patch 的内核源目录的名称(或其他一些目录名称,如“a/”和“b/”)。

  • 如何应用或恢复 Patch ?

    源代码交付场景,如涉及对开源原生代码进行修改,则修改的代码形成 Patch 文件并对其进行管理。

  1. 每次贡献/合入社区的 Patch 尽量只解决一个问题,功能单一;

  2. 通过 Patch 化合入每次修改的内容;

  3. 修改开源的 Patch 源码文件,采用开源社区代码规范要求,方便回归社区。

    注:对开源原生代码进行修改形成 Patch 文件只是一种管理形式,并不解决耦合问题,实际上这种修改方式仍是将修改的代码与开源代码耦合在一起,模糊不清。

第六节 - 开源代码依赖管理最佳实践

6.1 专有软件依赖的开源软件代码存储实践

  • 将产品专有软件代码与开源软件隔离(参见业界 Google 案例),开源软件独立目录存放。从代码目录结构区分出 open_source 目录、 vendor 目录、code 专有软件目录。

  • 检验标准:同规则描述

  • Google 开源软件管理:https://opensource.google.com/docs/thirdparty/

6.2 依赖管理最佳实践

Google 的依赖管理最佳实践 [11]

  • 版本锁定 - 将应用程序依赖项的版本限制为非常特定的版本。

  • 签名和哈希验证 - 启用哈希验证可确保依赖项不会被不同的文件替换,无论是人为攻击还是破坏工件存储库;签名验证为验证过程增加了额外的安全性。

  • 锁定文件和编译的依赖项 - 通常由安装工具自动生成,锁定文件将版本锁定、签名和哈希验证与应用程序的完整依赖树相结合。应用程序的所有依赖项,包括所有子依赖项、它们的依赖项以及向下堆栈,都包含在锁定文件中。

  • 混合私有和公共依赖项 - 在混合私有和公共依赖项时,需注意“依赖项混淆”攻击:通过将与内部项目同名项目发布到开源存储库,攻击者利用错误配置的安装程序偷偷安装他们内部包上的恶意库。

  • 删除未使用的依赖项 - 在不再使用依赖项时继续将它们与应用程序一起安装会增加依赖项足迹及这些依赖项中漏洞危害的可能性。让应用程序在本地工作,将在开发过程中安装的每个依赖项复制到应用程序的需求文件中,并对其进行部署。

  • 漏洞扫描 - 漏洞扫描工具使用锁定文件准确确定依赖的工件,并在新漏洞出现时及时通知,甚至提供建议的升级路径。

为避免“依赖混淆”攻击,可采取以下步骤:

  • 通过将依赖项包含在锁定文件中来验证依赖项的签名或哈希值

  • 将第三方依赖和内部依赖的安装分为两个不同的步骤

  • 手动或使用直通代理将需要的第三方依赖项显式镜像到私有存储库中

第七节 - 开源软件义务履行规则

7.1 开源使用声明无遗漏、易获取

  • 产品发布时,随产品附上一份文档《Open Source Software Notice》,在该文档中写明产品所使用的开源软件及其版权和 License 信息,并附上不担保声明。同时确保使用声明软件与实际使用的软件保持一致,避免遗漏,易获取。

  • Cisco 案例:Open Source License Notices for Cisco Unified Communications Manager

img

  • 根据产品中所使用的开源软件,按以下格式输出软件声明(Copyright Notice and License Texts)
  1. Software: 软件名称+软件版本号
  2. Copyright notice: 软件版权信息 (软件包中版权或说明文件/官网/代码文件头)
  3. License: 软件 License 信息(包含具体内容)

img

  • 验证《Open Source Software Notice》文档,确保其符合开源使用声明义务履行要求。

7.2 履行代码对外开源义务

案例:GitHub 伊朗等国开发者遭封禁

2019 年下半年,美国怀疑伊朗制造核弹,国际关系进一步紧张,美国加紧了对伊朗的单边制裁,其中一项制裁措施就是「贸易禁令」,禁止美国人把美国的商品、技术、服务出口给伊朗,其中也包括美国的 GitHub 代码托管平台。[12]

2019 年 7 月,一位自 2012 年以来一直使用 GitHub 的伊朗开发者在不知情的情况下被 GitHub 封禁账户,认为他在利用免费的私有库开发核武器。此前,一位克里米亚地区的俄罗斯籍开发者的账号同样遭到封禁。2022 年 3 月,微软的开源项目 JavaScript 框架 Aurelia 因项目中有两名来自伊朗的外部贡献者被 GitHub 封禁。同年 12 月,GitHub 封禁了总部位于德国的初创服务公司 Pure Labs 的所有账号,原因竟是“一名员工在回伊朗探望父母时打开了笔记本电脑”。[13] [14]

美国对包括伊朗在内的多个国家实施的制裁措施阻断了美国公司与受制裁国家中的任何人开展任何业务。GitHub 表示,GitHub.com、GitHub Enterprise Server 以及开发者上传至其中任一产品信息都需遵守贸易管制法规,包括美国出口管理条例(Export Administration Regulations, EAR)。但为了实现让全球开发者都能使用 GitHub 的目标,GitHub 采取了以下两项措施:

  • 即使 GitHub 遵守制裁,但 GitHub 上提供的公共存储库不受国际武器贸易条例(International Traffic in Arms Regulations,ITAR)的约束,即使在受制裁的国家也可以使用公共存储库。[15]
  • GitHub 已获得美国财政部下属的外国资产控制办公室(OFAC)的许可,可以为位于或居住在伊朗的开发者提供云服务。 这包括为个人和组织提供的一切免费和有偿的公共和私人服务。[15]

作为全球最大的代码托管平台,GitHub 不仅是代码的天堂,更是承载开源项目的沃土。但美国长期以来对包括伊朗在内的多个国家实施广泛的制裁,这也是为什么业内一直争论开源是否有国界的原因。

  • 对于涉及敏感国家地区销售的产品,若产品涉及履行对外开源义务,须组织审核验证“对外开源代码包”,根据团队所选择的对外开源方式(如 Written Offer)履行义务,确保无法务风险。
  1. 产品应结合自身使用场景,按照所使用的开源软件 License 要求将相应代码从产品代码中提取出来制作开源代码包;
  2. 开源内容必须为代码,若产品以二进制包形式使用开源软件,须提供其源码;
  3. 开源内容不得超出 License 要求范围,且开源内容范围必须通过审批决策;
  4. 对于 GPL/LGPL 类开源软件,必须确保开源代码能够通过编译:
    1. 书面要约(Written Offer):若产品使用了 GPL、LGPL、MPL 等具有对外开源义务的软件,必须在使用声明中附上此部分,向客户承诺履行代码开源义务。此部分直接从模板中拷贝使用;若产品不涉及强制开源义务,则使用声明文档中不得包含此部分内容;
    2. AGPL V3 开源软件被用于远程交互场景下时,修改代码后即使不分发也必须向用户提供源代码。不能采用统一的 Written Offer 模式,对使用 AGPL V3 的在线软件的开源遵从方式需改成直接开源。

7.3 如对开源软件修改,须在修改的源码文件头附上修改声明

  • 规则描述:产品若对开源软件进行了修改,需在修改的源码文件头附上修改声明,说明修改人、修改时间、修改内容。

  • 修改声明举例:

/*
==============
= GetUart 
= Origin from https://github.com/id-Software/DOOM/blob/master/sersrc/PORT.C
= Commit SHA1 95e6d43
= Edited by Carl 1999
==============
*/
void GetUart (void)
{
        char   far *system_data;
        static int ISA_uarts[] = {0x3f8,0x2f8,0x3e8,0x2e8};
        static int ISA_IRQs[] = {4,3,4,3};
        static int MCA_uarts[] = {0x03f8,0x02f8,0x3220,0x3228};
        static int MCA_IRQs[] = {4,3,3,3};
        int                p;

        if (CheckParm ("-com2"))
                comport = 2;
        else if (CheckParm ("-com3"))
                comport = 3;
        else if (CheckParm ("-com4"))
                comport = 4;
        else
                comport = 1;

        regs.h.ah = 0xc0;
        int86x( 0x15, &regs, &regs, &sregs );
        if ( regs.x.cflag )
        {
                irq = ISA_IRQs[ comport-1 ];
                uart = ISA_uarts[ comport-1 ];
                return;
        }
        system_data = ( char far *) ( ( (long) sregs.es << 16 ) + regs.x.bx );
        if ( system_data[ 5 ] & 0x02 )
        {
                irq = MCA_IRQs[ comport-1 ];
                uart = MCA_uarts[ comport-1 ];
        }
        else
        {
                irq = ISA_IRQs[ comport-1 ];
                uart = ISA_uarts[ comport-1 ];
        }

        p = CheckParm ("-port");
        if (p)
                sscanf (_argv[p+1],"0x%x",&uart);
        p = CheckParm ("-irq");
        if (p)
                sscanf (_argv[p+1],"%i",&irq);


        printf (STR_PORTLOOK" 0x%x, irq %i\n",uart,irq);
}

第八节 - 开源还是专有软件判定规则进阶

  • 法理依据:思想与表达 —— 思想没有版权、表达有版权。软件的功能是思想,功能的实现是表达;如果一个思想仅有少数的表达,那么表达的相似不做追究。

  • 开源转专有软件的难度:思想同开源项目 —— 框架类似开源项目 —— 结构体类似开源项目 —— 流程类似开源项目 —— 代码类似开源项目

  • 开源专有软件的攻防

  1. 矛:如何肉眼预估存在片段引用 如果结构体和流程相似,代码大概率类似开源项目。
  2. 盾:如何自证清白 避免陷入代码相似的争论,从源头上自证 – 功能(思想)存在差异不同,设计文档存在差异。
  • 案例:企业开源的项目能否认定为专有软件

    • 某团队将代码开源出去,同时在另外一个专有软件项目里面片段复用了同样的代码,那么是否还需要修改。如果不修改,便违背了开源专有软件隔离的要求;如果修改,自己写的代码为什么开源后就失去了控制权,还要想另一个方法再实现一遍?
  • 解答:这个问题主要出在“专有软件和开源”的提法上,这个提法事实上形成了“对立”:即非专有软件就是开源。它在绝大多数情况下是正确的,沿用利于团队实施。但从字眼上分析,“专有软件”的对立面是“第三方”,“开源”的对立面是“闭源”。回到上面的案例,这段代码既属于“专有软件”,也属于“开源”,而且当专有软件认定符合本文开头的三个原则时,则不需要整改。

  • 所有权和开源协议

  1. 所有权是企业的代码,协议解释权也属于企业 —— 可以把这段代码规定为各种开源协议,也可以规定为商业协议(参考 Oracle/Mongodb 的双协议案例)。企业代码被开源“污染”属于法务遵从的问题,不破坏所有权。
  2. 企业的 A 项目和社区 GPL 协议的 B 项目静态链接生成 C 产品,则 A 项目在 C 产品的场景下需遵循 GPL 的协议对外履行义务; 之后(不包括 B ),如果 A 项目和企业内部的专有软件 D 项目静态链接生成 E 产品,那么 A 项目在 E 产品的场景下,可以以企业专有软件进行认定,不会因为“曾经被 B 污染”而导致在 E 场景下也是 GPL 协议,更不会导致 D 项目也变成 GPL 。

第九节 - 维护与升级替换规则

9.1 产品使用开源软件须具备开源软件维护能力

产品使用开源须具备开源维护能力。对于产品核心模块的开源应用,建议参与并主导开源社区,具备社区影响力,掌握该开源软件的演进方向和发展趋势,具备开源软件维护能力,满足客户问题响应和安全漏洞修复 SLA 要求。根据自身业务特点,对开源软件进行评估确定需要投入不同的资源进行维护。

第十节 - 开源软件维护

10.1 开源软件维护总体原则

  1. 对于社区内已披露但未提供修补方案的漏洞,由产品自行消减漏洞风险;

  2. 开源软件维护方发布新版本或社区补丁质量标准与社区发布的标准一致,回合补丁须保证漏洞已被修补;

  3. 开源软件维护方发布新版本或补丁修补漏洞,应满足开源软件漏洞修补 SLO 时间;

  4. 开源软件维护方不仅要对主软件(及下层开源组件)进行维护,依赖软件(及下层开源组件)也需维护;

  5. 开源软件维护方不承接产品特性或功能需求,若有相关需求,需通过正常平台需求管道提出。

10.2 漏洞修复流程

从上游 NVD 等漏洞库定期推送漏洞信息到社区,由专家团队,定期分析这些漏洞并修复。系统会将漏洞推送给所有使用典型商业软件的产品团队,产品团队进一步分析,是否影响产品,如果影响,就会推送给维护方。维护方可能是专业的开源软件专家,进一步调整解决方案;解决方案有可能来自社区,社区有解决方案,我们是要用社区解决方案还是企业自己的解决方案?社区版本可以自己维护控制,一旦产品团队自己过多的维护干扰,后面的代码升级有可能出现漏洞。所以,尽可能用社区的解决方案,保障代码的升级。如果社区没有解决方案,我们在SLA的使用范围内,产品团队可以做一些修复,消解风险后,可以通知市场销售团队,哪些产品在哪些国家、哪些客户产生了影响,提供修复的方案给市场销售团队,和客户一起修复漏洞。

对于开源社区当接收到上报的漏洞信息时,安全团队对漏洞进行评估并完成漏洞影响描述,获得CVE(Common Vulnerabilities & Exposures,通用漏洞披露)。SIG 维护者完成补丁开发并进行验证。系统将漏洞修复方案推送给下游厂商的技术市场、市场销售团队,由市场销售团队和客户产品团队进一步分析是否影响产品,进一步调整解决方案。

img

10.3 升级版本模式要求

  • 规则1:社区同时提供新版本和补丁解决漏洞时,由开源软件维护方确定提供何种修补方案。

  • 说明:社区升级新版本,开源软件维护方就提供新版本;社区提供补丁,开源软件维护方也提供社区补丁;但当社区同时提供两种修补方案时,开源软件维护方需要与社区进行互动,选择社区推荐的修补方案并进行评估,确定提供何种修补方案。

  • 案例:Libssh 是一款采用升级版本模式维护的软件,为解决 Libssh 0.7.3 以前版本存在的 CVE-2016-0739 漏洞,社区不仅发布了 0.7.4 新版本,还发布了 CVE-2016-0739-libssh-0.5.5.patch、CVE-2016-0739-libssh-0.6.5.patch 等补丁文件,开源软件维护方根据社区建议选择新版本 0.7.4 来修补漏洞。

  • 规则2:解决漏洞的新版本须满足选型规范的要求进行引入。

  • 说明:如果社区提供的解决漏洞的新版本均不满足公司对产品的需求,且社区没有提供解决漏洞的补丁,则开源软件维护方可不提供漏洞解决方案,由产品自行消减漏洞风险。

  • 案例:为解决 fastjson 1.2.60 拒绝服务安全漏洞,某团队在社区发布修复漏洞 1.2.61 hotfix 版本的当天将其引入公司。经公司 TMG 评审发现,该版本并未经社区测试,该团队也并未评估社区安全修复建议,新版本存在不兼容 bug,导致产品测试环境宕机。

10.4 补丁回合模式要求

  • 规则1:为形成一套面向客户可见的企业开源软件版本管理机制,开源软件维护方须遵循开源软件维护版本命名和漏洞补丁命名规则,规范开源软件维护版本及补丁的名称。
  1. 开源软件维护版本命名:

    开源软件自身版本命名沿用各自社区命名,维护方后续发布的开源软件补丁版本命名如下:

    • 开源软件名 - 社区版本 - hX,代号固定为 h ,X 表示数字 1~n ,可根据需要扩展多位
    • 如 openssl - 1.1.1a - h1,表示维护方发布的 Openssl 软件 1.1.1a 版本的第一个补丁版本。
  2. 开源软件漏洞补丁命名

    开源软件漏洞补丁命名:

    • 社区发布的 CVE 补丁,需体现 CVE 名,例如 openssl-1.1.1a-CVE-1234.patch;

    • 如果涉及一个 CVE 有多个补丁,可增加编号,例如 openssl-1.1.1a-CVE-1234-001.patch;如涉及多个 CVE,可采用 fix-CVE-multiple 等标识,最终在公共配置文件里面描述详细修复内容;

    • 开源软件维护方从新版本回合的 CVE 补丁,除体现 CVE 名之外,还需增加 backport 前缀,例如 openssl-1.1.1a-backport-CVE-1234.patch;

    • 社区发布的非 CVE 补丁,简单描述补丁的功能,例如 openssl-1.1.1a-fix-xxxxx.patch;

    • 每个补丁修复一个漏洞,避免出现超大补丁。

  • 规则2:为支撑开源软件维护方跨开源软件版本维护,开源软件维护方须遵循维护分支管理规则,对各维护版本进行管理和隔离。
  1. 每个开源软件版本建立一个分支,存放开源软件社区原始包、公共补丁及公共补丁配置文件;
  2. 版本分支从 master 拉出,命名为“软件名_软件版本-stable/upstream”;

10.5 依赖软件维护要求

  • 依赖软件的漏洞按照主软件社区提供的漏洞修补方案进行修补,主软件社区未提供漏洞修补方案的,由商业产品自行消减漏洞风险。

  • 主软件社区修补依赖软件漏洞的方式:(开源软件维护方可选择任意一种社区方案进行漏洞修补)

  1. 如果主软件升级新版本,依赖软件也升级新版本,则升级主软件;
  2. 如果主软件不升级新版本,但提供补丁修补依赖软件漏洞,则提供社区补丁。
  • 案例1:开源软件 EDKII 依赖 OpenSSL 提供加解密算法能力,社区老版本 edk2-stable201908 使用的 OpenSSL 1.1.1b 社区曝出漏洞 CVE-2019-1543,CVE-2019-1552 和 CVE-2019-1563。EDKII 社区在 2019 年 11 月发布新版本 edk2-stable201911,将 OpenSSL 1.1.1b 升级到 OpenSSL 1.1.1d 以解决该漏洞,同时开源软件维护方应通过升级 EDKII 到 edk2-stable201911 来修补漏洞。

  • 案例2:开源软件 curl 依赖 kerberos 提供 ftp 通信能力,curl 7.66.0 曝出依赖的 Kerberos 有高危漏洞 CVE-2019-5481。curl 社区在 2019 年 9 月发布补丁解决该漏洞,但未同时发布新版本,开源软件维护方应通过引入社区补丁来修补漏洞。

附录

附录 A - 术语表

术语含义及解释
Proprietary Software 专有软件 或 私有软件软件生产方自己保有知识产权的软件,不包含任何第三方知识产权的软件,这种软件往往被其拥有者视为商业秘密
开源代码片段使用截取部分开源软件代码片段整合入专有软件中的行为称为片段使用开源代码。片段使用开源代码可能产生版权合规和网络安全问题
合理使用并不是所有的片段使用开源代码都是违反版权法的,各国著作权法允许个人在一定使用范围和场景内使用有版权的代码片段。这一条款称之为合理使用
开源软件中央仓库在企业中设立开源软件中央仓库,企业内开发时只能使用开源软件中央仓库中规定的开源软件项目及指定的版本;对开源项目和指定的版本设立优先级,在选用开源软件的时候,依据产品、用户、销售范围等因素选择合适的开源软件及版本;使用过程中设定申请使用流程,根据不同级别进行限定。

附录 B - License 参考

LicenseSPDXCan(Rights)Must(Obligations)Cannot(Limitations)
BSD Zero Clause License0BSDCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用None Yet. 暂无Hold Liable / Place Warranty 质量保证
Academic Free License v3.0AFL-3.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Include Original 包含原始软件 Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 State Changes 列明修改Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
GNU Affero General Public License v3.0AGPL-3.0-onlyCommercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Include Install Instructions 包含安装指南/脚本 Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 Network Use Is Distribution 网络访问也视同分发 Same License 许可证“传染性” State Changes 列明修改Hold Liable / Place Warranty 质量保证
Apache License 2.0Apache-2.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Include Copyright & License 包含版权和许可证 State Changes 列明修改Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Artistic License 2.0Artistic-2.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Include Install Instructions 包含安装指南/脚本 Include Original 包含原始软件 Include Copyright & License 包含版权和许可证 State Changes 列明修改Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
BSD 2-Clause "Simplified" LicenseBSD-2-ClauseCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证
BSD 3-Clause Clear LicenseBSD-3-Clause-ClearCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证Patent Use 专利授权 Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
BSD 3-Clause "New" or "Revised" LicenseBSD-3-ClauseCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
BSD 4-Clause "Original" or "Old" LicenseBSD-4-ClauseCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Give Credit 指明原始作者 Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Boost Software License 1.0BSL-1.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证
Creative Commons Attribution 4.0 InternationalCC-BY-4.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Give Credit 指明原始作者 Include Copyright & License 包含版权和许可证 State Changes 列明修改Patent Use 专利授权 Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Creative Commons Attribution Share Alike 4.0 InternationalCC-BY-SA-4.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证 Same License 许可证“传染性” State Changes 列明修改Patent Use 专利授权 Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Creative Commons Zero v1.0 UniversalCC0-1.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用None Yet. 暂无Patent Use 专利授权 Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
CeCILL Free Software License Agreement v2.1CECILL-2.1Commercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 Same License 许可证“传染性” State Changes 列明修改Hold Liable / Place Warranty 质量保证
Educational Community License v2.0ECL-2.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Include Copyright & License 包含版权和许可证 State Changes 列明修改Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Eclipse Public License 1.0EPL-1.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Include Install Instructions 包含安装指南/脚本 Include Original 包含原始软件 Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 Same License 许可证“传染性”Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Eclipse Public License 2.0EPL-2.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Include Install Instructions 包含安装指南/脚本 Include Original 包含原始软件 Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 Same License 许可证“传染性”Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
European Union Public License 1.1EUPL-1.1Commercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 Network Use Is Distribution 网络访问也视同分发 Same License 许可证“传染性” State Changes 列明修改Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
European Union Public License 1.2EUPL-1.2Commercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 Network Use Is Distribution 网络访问也视同分发 Same License 许可证“传染性” State Changes 列明修改Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
GNU General Public License v2.0GPL-2.0-onlyCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Original 包含原始软件 Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 Same License 许可证“传染性” State Changes 列明修改Hold Liable / Place Warranty 质量保证
GNU General Public License v3.0GPL-3.0-onlyCommercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Include Install Instructions 包含安装指南/脚本 Include Original 包含原始软件 Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 Same License 许可证“传染性” State Changes 列明修改Hold Liable / Place Warranty 质量保证
ISC LicenseISCCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证
GNU Lesser General Public License v2.1LGPL-2.1-onlyCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Original 包含原始软件 Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 Same License (library) 许可证“传染性”-动态链接可隔离 State Changes 列明修改Hold Liable / Place Warranty 质量保证
GNU Lesser General Public License v3.0LGPL-3.0-onlyCommercial Use商业使用 Distribute分发 Modify修改 Patent Use专利授权 Private Use私下使用Include Install Instructions 包含安装指南/脚本 Include Original 包含原始软件 Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 Same License (library) 许可证“传染性”-动态链接可隔离 State Changes 列明修改Hold Liable / Place Warranty 质量保证
LaTeX Project Public License v1.3cLPPL-1.3cCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 State Changes 列明修改Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
MIT LicenseMITCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证
Mozilla Public License 2.0MPL-2.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Include Original 包含原始软件 Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 Same License (file) 许可证“传染性”-仅文件Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Microsoft Public LicenseMS-PLCommercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Microsoft Reciprocal LicenseMS-RLCommercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 Same License (file) 许可证“传染性”-仅文件Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
University of Illinois/NCSA Open Source LicenseNCSACommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
SIL Open Font License 1.1OFL-1.1Commercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证 Same License 许可证“传染性”Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Open Software License 3.0OSL-3.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 Network Use Is Distribution 网络访问也视同分发 Same License 许可证“传染性” State Changes 列明修改Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
PostgreSQL LicensePostgreSQLCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证
The UnlicenseUnlicenseCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用None Yet.暂无Hold Liable / Place Warranty 质量保证
Universal Permissive License v1.0UPL-1.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证
Vim LicenseVimCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 Same License 许可证“传染性” State Changes 列明修改None Yet. 暂无
Do What The F*ck You Want To Public LicenseWTFPLCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用None Yet. 暂无None Yet. 暂无
zlib LicenseZlibCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证 State Changes 列明修改Hold Liable / Place Warranty 质量保证
Artistic License 1.0 (Perl)Artistic-1.0-PerlPrivate Use 私下使用None Yet. 暂无None Yet. 暂无
Artistic License 1.0Artistic-1.0Private Use 私下使用None Yet. 暂无None Yet. 暂无
GNU Library General Public License v2 onlyLGPL-2.0-onlyCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Original 包含原始软件 Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 Same License 许可证“传染性” State Changes 列明修改Hold Liable / Place Warranty 质量保证
Zope Public License 2.0ZPL-2.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证 State Changes 列明修改Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Zope Public License 2.1ZPL-2.1Commercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证 State Changes 列明修改Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
zlib/libpng License with Acknowledgementzlib-acknowledgementCommercial Use 商业使用 Distribute 分发 Modify 修改Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证
Common Development and Distribution License 1.1CDDL-1.1Commercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Mozilla Public License 1.1MPL-1.1Commercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Give Credit 指明原始作者 Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 State Changes 列明修改Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Common Public License 1.0CPL-1.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证
Common Development and Distribution License 1.0CDDL-1.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Patent Use 专利授权 Private Use 私下使用Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Freetype Project LicenseFTLCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证
BSD Protection LicenseBSD-ProtectionCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Give Credit 指明原始作者 Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Creative Commons Attribution 3.0 UnportedCC-BY-3.0Commercial Use 商业使用 Distribute 分发 Modify 修改Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证
Unicode Terms of UseUnicode-TOUNone Yet. 暂无None Yet. 暂无None Yet. 暂无
Apache License 1.1Apache-1.1Commercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Adobe Postscript AFM LicenseAPAFMLDistribute 分发 Modify 修改 Private Use 私下使用Include Original 包含原始软件 Include Copyright & License 包含版权和许可证 State Changes 列明修改Hold Liable / Place Warranty 质量保证
Apple Public Source License 2.0APSL-2.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 State Changes 列明修改Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Server Side Public License, v 1SSPL-1.0None Yet. 暂无None Yet. 暂无None Yet. 暂无
Imlib2 LicenseImlib2Commercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证
Open Software License 2.1OSL-2.1Commercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
BSD-3-Clause-AttributionBSD-3-Clause-AttributionCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
SGI Free Software License B v2.0SGI-B-2.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Python License 2.0Python-2.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证 State Changes 列明修改Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
FSF All Permissive LicenseFSFAPPrivate Use 私下使用None Yet.暂无None Yet.暂无
Academic Free License v2.1AFL-2.1Private Use 私下使用None Yet.暂无None Yet.暂无
Mozilla Public License 1.0MPL-1.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证 State Changes 列明修改Hold Liable / Place Warranty 质量保证
MIT +no-false-attribs licenseMITNFANone Yet.暂无None Yet.暂无None Yet.暂无
copyleft-next 0.3.0copyleft-next-0.3.0None Yet.暂无None Yet.暂无None Yet.暂无
CNRI Python LicenseCNRI-PythonPrivate Use 私下使用None Yet.暂无None Yet.暂无
Open Software License 2.0OSL-2.0Commercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Disclose Source 源代码可获取 Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
Aladdin Free Public LicenseAladdinDistribute 分发 Modify 修改Include Original 包含原始软件 Include Copyright & License 包含版权和许可证 State Changes 列明修改Commercial Use 商业使用 Hold Liable / Place Warranty 质量保证
Apple MIT LicenseAMLCommercial Use 商业使用 Distribute 分发 Modify 修改 Private Use 私下使用Include Copyright & License 包含版权和许可证Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标
bzip2 and libbzip2 License v1.0.6bzip2-1.0.6Commercial Use 商业使用 Modify 修改Include Copyright & License 包含版权和许可证 State Changes 列明修改Hold Liable / Place Warranty 质量保证 Use Trademark 使用商标

参考资料

[1]甲骨文诉谷歌 Java 侵权案

https://zh.wikipedia.org/wiki/%E7%94%B2%E9%AA%A8%E6%96%87%E8%AF%89%E8%B0%B7%E6%AD%8CJava%E4%BE%B5%E6%9D%83%E6%A1%88

[2]ORACLE AMERICA,INC. V. GOOGLE LIC

https://www.leagle.com/decision/infco20180327178

[3]所有判决被推翻,美最高法院:Java 版权世纪大案,谷歌战胜甲骨文

https://finance.sina.com.cn/tech/2021-04-06/doc-ikmyaawa7809324.shtml

[4] Google VS Oracle 90 亿美金代码悬案落锤

https://zhuanlan.zhihu.com/p/510872344

[5] Ruby用实际行动向GPLv3吐槽,Ruby 1.9.3将改用 BSD 许可证发布

https://blog.delphij.net/posts/2011/08/rubygplv3ruby-1/

[6] 国家保密局——开源软件漏洞安全风险分析 http://www.gjbmj.gov.cn/n1/2020/1127/c411033-31947310.html

[7] 开源软件风险分析及治理措施研究 http://www.gjbmj.gov.cn/n1/2020/1127/c411033-31947270.html

[8] NATIONAL VULNERABILITY DATABASE General Information https://nvd.nist.gov/general

[9] Techopedia 解释了国家漏洞数据库(NVD) https://cn.theastrologypage.com/national-vulnerability-database

[10] Applying Patches To The Linux Kernel https://www.kernel.org/doc/html/v4.18/process/applying-patches.html

[11] 谷歌的依赖管理最佳实践

https://www.jdon.com/57083

[12] 财政部禁令政策 https://home.treasury.gov/policy-issues/office-of-foreign-assets-control-sanctions-programs-and-information

[13]《GitHub 的挣扎:已获美国许可,恢复在伊朗的服务》https://www.infoq.cn/article/uss2tktbzdzls9cafk5x

[14]《我疯起来自己都害怕!GitHub 封禁自家开源项目 Aurelia 引众怒,CEO 公开道歉,但开发者们并不买账》https://baijiahao.baidu.com/s?id=1661953225202005584&wfr=spider&for=pc

[15] GitHub 和贸易管制 https://docs.github.com/cn/site-policy/other-site-policies/github-and-trade-controls

开源生态构建及业界优秀实践

一、开源项目、社区和产品

1、什么是开源-项目还是产品?

很多人认为开源就是将代码放在某个代码托管网站上,比如 GitHub、Gitee 等,把代码开放出来。但这只是一种形式,实际上我们需要理解开源——真正做开源的意义是什么?

在 2013 年前,开源是一种文化和精神,按照现在比较流行的说法:开源代表了西方自由主义精神,是一种文化的追求,或者个人诉求的表态。因此如果仅仅只是将代码开放出来,而没有将想要表达的事情表达出来,这只能说是做了形式上的开源,同时这也是开源的一个误区。

而在 2013 年后,随着 Docker 在湾区的兴起,开源越来越多地跟经济、产品以及商业模式等紧密联系在一起,这时的开源代表了自由经济的一种方式,包括产品运营方式,或者研发模式方式,这些都在发生改变。2013 年是一个非常明显的分水岭,2013 年之前的项目,比如openStack 等,但它们最终的结果正如大家所见,并未真正流行起来,而 2013 年之后的项目,比如 Docker 等,到现在近 10 年,都有被大众广泛使用,因此 openStack 虽然也是开源,但它没有真正把握住机会、做好商业模式。

开源背后的精神究竟是什么?2013 年之前是个人开发者的文化,包括个人思想、形式的表达,2013 之后是经济形式的表达,而最近这两年,不仅仅是经济形式的表达,更是政府政治意志的表达,比如国内的开放原子开源基金会,国外的包括美国的很多政府部门,出台了各种规定,包括对开源的各种限制,比如 GitHub 封过伊朗、叙利亚、俄罗斯等。开源越来越受到政府政治、地缘政治的影响,越来越不如最早的精神文化般纯粹。开源的每个阶段都有对应的特点,现阶段开源更多的是在国家层面上,认为开源需要被管理,这也是一种自由经济形式与政府的计划经济形式的碰撞,开放原子开源基金会也正是在这种情况下成立的一个开源组织。

开源不仅仅是开放了源代码或者硬件设计,或者写了一个大家可协作的文档,比如基于 CC(Creative Commons)协议的开源共享,开源的背后到底是什么?对于我来说,通过这些年的工作经验来看,我认为开源项目是一个很纯粹的产品,如果想把它做好,需要投入很大的精力。开源可能没有具体的定义,但需要大家思考:在开源背后你代表的是什么?如果个人写一个开源项目,代表想要表达对这件事情的看法和逻辑;如果公司开源了一个项目,则代表对商业的诉求;如果政府做了一个开源项目,那么代表了政府的意志;这些都是开源背后需要深入思考的问题。

2、什么是社区?

社区是一群人因为共同的兴趣和爱好,不论时间、空间、年龄、性别、国际、种族等等聚集在一起形成的一种聚集形态。当然可以给这种形态设计一个门槛,签署一些合同或者文件,或者其它的任何形式的仪式。在国外,可能称之为“club”。

在 2020 年,有几个以前一起做研究生的朋友,都是技术背景出身,因疫情原因封控在家,大家一块视频“云喝酒”,慢慢地形成了一个小的 community,我们叫做“云原生喝酒 SIG”。在这个SIG里面的成员,基本都是有技术背景,然后喜欢喝点小酒,啤酒或者威士忌,因为共同的兴趣聚集在一起,慢慢形成一个非正式的组织,不需要签字/文件。

但我们经常性会看见很多公司会说:“XXX 公司签了 CLA,加入了 XXX 社区。”如果有签署的门槛,签了某个文件才能加入某个社区,那这个社区其实不是 open source 的社区,而是叫做“行业协会”或者“组织”,那就涉及备案、查询以及一些复杂的法律问题。因此在开源的社区里,只要大家在使用这个工具,或者一些想法的交流,甚至只是尝试下载使用了,那也是社区的一部分,而不是说一定要签 CLA,才是社区的一部分。

3、开源生态在 2 B和 2C 之间的过渡

开源对商业有什么帮助?

1)开源可以形成事实标准,会产生隐形绑定

很多公司经常会讨论为什么要做开源?开源有时是一种事实标准,只要有标准就相当于绑定了客户(因为商业模式也是一种垄断),形成了标准就形成了商业利益。

2)开源会形成生态,对商业市场产生支撑

比如 Docker、kubernetes 就是生态,对商业市场产生支撑,无论哪个做云服务的厂商,都有在做 kubernetes 以及相关的各种定期服务。

3)开源是产品口碑的双刃剑-马太效应

开源做的越好,对产品的口碑越好,开源才会越做越好,这时一个向上积累的过程。如果在一开始口碑就做差了,后面就算产品做好了,也会形成越做越差的效应,这就是马太效应。因此一旦开始开源,一定要谨慎选择,因为如果开源没有做好,会影响到产品,从而影响到产品的销售。

To C 商业模型的开源项目:目前很少有项目对 To C 在商业上有特别大的帮助,主要还是注重做生态。

To B 商业模型的开源项目:开源项目主要是针对商业合作伙伴,即商业的上、下游,这时伙伴是最关键部分。

如果没有形成社区就想做一个商业生态,希望很多人都来使用这个产品,这是不现实的,更建议直接销售这个产品,将售前、售后队伍壮大,这种方式会比做“跨过社区做生态”这件事更加能落地。因此决定开源的公司 / 上游的公司,优先考虑一个问题:该项目是否可以形成一个生态?形成商业生态的基本原则是该开源项目有很多人都在使用,比如 Docker,任何一个做前端或者后端的人都可能会用到 Docker,Docker 拥有非常广泛的群体,在社区形成之后才慢慢开始做商业,到现在 Docker 还在盈利中。

二、金字塔模型和沙漏模型

1、开源之战略-金字塔模型

在公司负责开源,或者是商业开源运营者,或者产品设计者,都会遇到投资人的发问:“你为何要做开源?开源给你的商业利益带来什么好处?”尤其是大公司,面临的挑战可能就更多,涉及的人员更多,小公司可能一两个老板就能直接拍板,因此如何说服投资人来做开源呢? 主要分为以下几个步骤:

1)制定战略

战略是企业开源的灵魂,没有灵魂的开源项目不会获得成功。

“将开源作为企业的战略,开源给企业带来的价值是什么?”需要将这个事情向领导层解释清楚,如果公司的领导层,比如董事会等,没有开源的战略意识,就算是做了一个开源项目,那么这个项目在公司里也做不大,因为没有战略就没有战略投资,没有战略投资就无法将该项目做长。如果没解释清楚,当跟公司建议做 marketing 宣传时,领导层会疑惑做了这个宣传后会带来多少订单,但这其实跟市场宣传没有直接逻辑关系,为公司商业项目来说,将资金投入到开源中,包括社区、生态建设等,是无法获得直接利益回报。 因此想在一个公司里将开源这件事做好,那么一定要将开源变成公司的战略,灌输到管理层,开源项目才有机会成功。

2)设计行业标准或事实标准

如果公司都是开源的,比如 RedHat 模式,全部以开源为核心展开的服务,就不用再考虑金字塔模型了。

但如果公司是做传统生意,我们需要建立行业标准或事实标准,根据项目的具体情况来说服管理层。

3)设计开源项目

一定要将开源项目当作产品来设计,关注开发者需求而不是追求项目的成就感。如果仅仅只是开放出去,开源项目很有可能活不长久,目前国内传统的几家大厂,每年开源的项目加起来至少两三百,但目前依旧活跃的项目并不多,因此开源项目需要设计。

如何设计开源项目? ① 商业目标:将开源项目当作产品,思考商业目标是什么。 ② 用户体验:用户体验怎么样?从用户出发,操作易上手是最基本的要求。

4)建设生态

这是商业的载体,壮大用户群体、活跃开源社区、让合作伙伴使用等,让整个生态生机勃勃,健康发展。

2、开源之产品-沙漏模型

沙漏模型最核心的点在于这个图中最细处,即开源项目,也可看做产品,把握好这个最细处,整个过程就不容易失控,而且需要清楚知道面向的受众是谁?很多情况下大家以为面对的是普通开发者,然而不是,从商业角度上看,项目要面对的是下游的商业合作伙伴的开发者,比如前两年我做欧拉运营,面对的不是使用欧拉的普通开发者,而是使用欧拉做商业发行版的厂商开发者,比如麒麟,只有下游的商业合作伙伴获利,才会在我们的上游投入人力,一起将这个开源项目做好,形成一个良好的循环。

在形成循环之后,核心是控制中间产品功能的设计,需要松弛有度,卡的太紧其他人无法参与,卡的太松所有人都来了容易乱套。比如 Cloud Foundry,在 2011 年的时候,国内的几家大外企公司员工基本上很多人都有参与,到现在成立了基金会,也有开放治理,但参与成员并不能真正像 Cloud Foundry 一样贡献代码,这种就是卡的太紧情况。

3、沙漏模型成功案例-Kubenetes

Kubenetes 的核心产品特性,比如 CSI,这些接口的标准都被 Google 所控制,其他公司一般进不去,如果想要在里面推广一些事情,那就得和Google 先打好关系,这也说明 Google 有技术能力以及社区影响力,能牢牢把控住 Kubenetes。Kubenetes 的下游商业伙伴包括国内外几大厂商,这些厂商会将自己的特性往上游推,在上游投入人力,因此形成一个良好的循环,还能够通过 CNCF 的稳定治理给所有人一个可以发言的机会。

4、沙漏模型失败案例-Docker

Docker 拒绝改变,拒绝别人给它的意见,因此 Docker 逐渐在走下坡路,最后还被拆分,虽然拆分以后据说今年又挣钱了,但这只能说明 Docker 的生态做的不错,而在社区把控这一块,Docker 卡的非常紧,非常不利于开源,这也是一个典型案例。

5、沙漏模型失败案例-OpenStack

OpenStack 失败的点在于无法把控中间处,没有一到两家具有非常强技术实力的公司把控项目,造成了 OpenStack 里项目满天飞,各个项目、各路人马互相厮杀,也因此导致 OpenStack 开始越来越散、越来越乱,尤其在Docker 的冲击之下,OpenStack 逐渐停了,连基金会都改名了。而捐到CNCF 里的项目虽然也很多很乱,但没有影响到生态的发展。

国外做 OpenStack 的厂商可能不多,但国内还是有很多做 OpenStack 的厂,在小的范围、小的模式下,有些厂依旧活跃着,这也说明它的商业在某些程度上还是挺成功。

三、同心圆模型

1、企业开源之生态-生态伙伴同心圆模型

同心圆模型是指,当我们在企业内做开源时,由近及远,谁是我们可以合作的人?尤其在一些大型公司内,做一个开源项目不是一个团队的事,这个项目公司内部很多团队都要参与,因此需要平衡公司内的利益、公司外的利益,包括对产品设计要有想法、竞争力,也包括说服各个 BG 的老板,这些都需要投入很多精力,如果能将公司内部的这些力量整合在一起,形成核心开发者圈子,这个项目基本就成功了 80%。

第二就是是否拥有忠实的追随者?从商业角度来看,追随者是判断是否能说服公司上下游企业的开发者的关键,比如 openEuler,需要维护的追随者是麒麟、统信。

圈再往外就是当真正投入到开源社区里,是否能形成一些更多的个人用户,俗称散户。如果文章写得足够好、功能特性足够吸引人,那确实会有很多散户被吸纳进来。比如 TKEstack 中的一个特性,是针对 GPU 的虚拟化混合部署的方案,这是互联网公司才有的特性,因为互联网公司会购买很多卡,只要英伟达开始出售就会购买 20~30 块来使用,因此形成一种易购的环境,为了将这些易购的卡发挥最大的作用,需要将它们平衡在一起,形成一个调度管理,这是当时 TKEstack 主打的功能,后面有听说一个房屋租赁公司,内部就有在使用 TKEstack,这家公司跟社区无联系,也与华为和腾讯没有商业来往,但正是因为 TKEstack 符合它的需求,才开始内部使用。因此产品做的好有特点,也能够吸引很多散户。

最难做的是什么呢?是最外边这一圈的竞争对手。很少能有两家公司在商业上有非常明显的竞争关系,却能合作做同一个开源项目,一般情况下由中立的基金会从中协调、平衡。在基金会里,所有人可以吵架,但都需要有理有据、合情合理,不能无差别性攻击,然后形成统一的观点之后,不允许私下乱做一些小动作,这些规则不是一开始就有,而是基金会从中调解,这同时也是基金会的价值。

2、企业开源-开源就像投资

这个就是前面所说的金字塔模型理论,即一定要有投资,开源就像是做投资,一定是企业老板有投资才能做,比如员工全职在公司做开源,这些员工的工资、奖金等,都来源于投资,没有投资,开源项目不可能做得特别成功或者特别大,当然也有些因为个人兴趣做好的开源项目,可这种情况非常少。

3、企业开源之案例-TKEStack(开源就像创业)

做开源好比创业,需要天时、地利、人和同时具备,三者缺一不可。

1)天时在正确的时间做正确的事情 – Kubernetes 已经成为现在基础架构中的主流选择,这时候开源 TKEStack 并不需要更多的精力去教育市场。 把握技术发展趋势,顺势而为 – TKEStack 的整个管理是 Kubernetes On Kubernetes 的方式,一切功能都做成插件,顺应 Kubernetes 的大潮流而设计开发。

2)人和开源最重要的就是生态,没有人参与的开源项目不算开源项目 – 内部集合了 TEG 数据平台部、企业 IT 部和 CSIG 云产品部容器产品中心,同时得到了 TEG 研发管理部和运营管理部的大力支持。

找到项目所属的社区,善于利用社区力量,构建核心的维护团队 – 国内已经有丰富的 Kubernetes 社区,这是发展 TKEStack 的良好土壤。

让开发者觉得好用,并不需要满足所有人的需求 – 没有完美的产品,所以要锁定自己的目标用户。

3)地利尽量利用本地社区建立核心团队,在身边的人开始发展社区用户和生态 – 公司内有机会使用 TKEStack 的团队是建立社区的目标。

选择项目的范围,利用自身影响力的范围划定首要的区域 – 不盲目扩展项目的范围。

四、openEuler 实践

1、通过 SIG 践行商业伙伴之路

SIG 成为运营的最小单位,但是也容易造成社区割据的局面,不同的商业伙伴在其中相互影响;需要有社区的核心来平衡各方的利益,带领社区前进。

Special Interest Group(SIG)作为 openEuler 运营的最小单位,如果每个 SIG 都非常活跃,社区很可能就会被毁了,这里同时有一个新问题:是否要无限制成立 SIG?一个 SIG 从成立,到运营好,到活跃起来真正成为社区中前进的动力,这个过程需要很长时间进行磨合。

因为成立了很多 SIG,所以成立的过程中相对没有那么多苛刻的要求,比如考试。社区成立 SIG 逐渐转变成不同的商业合作伙伴需要成立各种各样的SIG,这里就有商业导向的问题,也因此很容易形成割据的局面,但同时能发现运作 SIG 这件事是好的,比如麒麟与统信,两者在操作系统这个市场上是敌对状态,但这两个公司还共同维护了一个 SIG,而且维护的还不错。

而社区中总有一些令人惊喜的人和事存在,比如中科院软件所,它在整个操作系统,包括开源领域的投入是非常有价值的,他们在 openEuler 里面做了很多踏踏实实的工作,很多事情都是软件所在默默无闻的干。如果大家都能以软件所那种心态来做开源,那么这个社区会做的很好。同时因为公司有各自的商业利益,这需要有人来进行平衡,因此需要考量社区运营者,包括核心团队,以及商业领袖是否能进行周旋的能力。

第二个问题:要不要把 marketing 行为与社区生态建设进行绑定?现在有个趋势,大家要成立一个社区,就先举办一个大会,请几个院士过来进行宣讲,举办大会已经变成比拼“院士”,这次请4个院士,下次请 8 个院士,再下下次不请院士大会就无法举办了!这个现象非常的不好,其实 marketing 与社区生态是相辅相成的,只要还有举办大会的资金,那开发者大会就可以举办,但不应该把举办这个大会变成一种商业竞争的方式,比如前面所述的比拼“院士”的会,有时不仅要拼“院士”,还要拼“领导”,不仅公司的领导,还有政府的领导...正常办大会应该如此:做社区面对的是开发者,那么举办大会就请重要的合作伙伴开发者;如果是商业社区,那么商业体系更成熟,可以请客户、供应商等;如果面临普遍推广,那就普遍进行邀请、撒网即可。

openEluer 里还有一点做的不错的地方:基础设施。因为 GitHub 上很多基础设施没法用,所以不得已自己做了很多基础设施,比如会议程序(小程序)、会议系统等,能够帮助开发者真正聚集在一起。如果你想要做好一个操作系统的社区,你的基础构建能力非常关键。

2、找到合适的人是这个工作的关键之一

运营包括几种方式:

1)平台运营

比如 CSDN、infoQ、开源社等,这些不做具体的项目,因此不需要技术背景,只要是传统的 marketing 出身的人,或者有从事客户关系维护等,都是可以来做平台运营。

2)技术社区运营

需要有非#### 常强的技术背景,如果不懂技术,但又想做这个社区的运营,那么可以进行学习,没有人生来什么都懂,都是通过后天学习获得。因此做这个社区运营最核心的一点就是摇动技术,至少其他人说了你能够听明白。

做好运营也需要有平和的心态。比如做一场 meetup,涉及到活动议程的设计,该请什么人来进行演讲比较合适,并且有设计演讲内容的能力,能够跟讲者达成一致以及平衡;协调大家的时间等,这些事情都非常琐碎且繁多,因此需要有一个平和的心态,将事情做好。

做运营可能有时候不仅仅是一个运营,还可能是个多方面小能手。比如欧拉早期运营,还需要做一些售前售后的工作,面见客户与客户沟通,了解客户的需求,甚至有些项目需要进行售后的事情,因此需要像一个项目经理一样,从前到后的所有事情一件件搞定,这需要非常多面的素质才能将事情做好。

开源合规及其风险管理

前言

1、开源合规及其风险管理的目的与意义

目的与意义:

  • 了解开源与许可协议、专利
  • 了解不同场景下开源的合法合规要求,避免开源代码因不符合相关要求在对外提供后而引发的法务和知识产权方面的影响
  • 了解合法合规工具,掌握合法合规提升效率的方法

2、开源合法合规的必要性

1)外部压力

  • 开源软件维权人的积极维权
  • 开源社区规范的倒逼
  • 开源爱好者的自媒体监督

2)内部压力

  • 内部流程规范的要求和追责机制

一、开源软件合规风险

1、开源软件三大组成要素

1)开源软件定义

开源软件是一种源代码免费向公众开放的软件,任何团体或个人都可以在其 License 的规定下对其进行使用、复制、传播及修改,并可以将该修改形成的软件的衍生版本再发布。

—— 来源于 OSI 开源软件定义

2)运作机制

开源软件三大组成要素:License + 社区模式 + 商业模式;

  • License 是游戏规则,不遵守将承担法律后果
  • 社区是组织方式,其发展的核心学问所在,主要特征:子项目充分竞争、充分的对等评审、用户充分参与、源代码发布等
  • 商业模式是本质,主要包括:捐赠、技术服务、广告、增值产品、双重授权、软硬件结合等

比如 Open-Core 这类的商业模式,将企业版中的部分功能开源,从而吸引用户进来社区,当用户数量足够多,能够为它的其他收费功能进行付费时,企业也因此获得收益。也有些企业主要是提供技术服务,比如基础设施维护;另外有些开源软件中会植入广告,收取一定费用等。

2、开源软件主要合规风险

当你听到“开源软件”一词时,你是否认为它与共享软件、免费软件或共有领域软件之类一样,是免费使用的?以及使用开源软件不会具备对应的法律风险?

使用开源软件就是有可能触犯会到它对应的一个法律风险!总体来说,开源软件的合规风险主要分为三大类:开源知识产权风险、数据安全和隐私风险和出口管制风险。其中开源知识产权风险又分为三类:版权、专利和商标风险。

1)版权侵权风险

不遵守开源许可证导致的版权侵权,比如未按 License 要求保留版权声明、许可证文本等。

软件版权其实具备很多对应的一个权利,包括署名权、发表权、保护作品完整权、修改权、复制权和发行权等这些权利。总体来说,不管是开源软件还是闭源(专有)软件,软件的程序及相应的文档都受版权法保护,且版权保护不需要履行注册手续,自产生之时就自动获得版权。

对比闭源软件和开源软件的一些特性,就闭源软件来说,它的版权所有者,通过 ”软件许可协议“,将自己的代码许可给对应的用户,而开源软件的版权所有者,通过 ”开源许可证“ 将自己的代码许可给用户。除此之外,两者在具备版权保护这一方面,不论是闭源还是开源软件,都是具备对应的版权法,即具备版权保护,但在是否提供源代码方面,开源软件代码就是公开提供所有的源代码,闭源软件就需要具体去看对应的所有者和用户之前的合同协议是否需要提供相应源代码。在 “可复制、可修改和可自由发布” 这三大特性方面,闭源软件保留改权利,不允许用户自由复制、修改和分发,然而开源软件是可以自由复制、使用、修改和分发。

开源软件的版权风险分为两大类:

① 违反开源许可证

违反开源许可证主要是指开源软件的使用者,没有按照对应开源许可证的规定去使用开源软件,从而导致版权侵权,之前有一个案例:在 2007 年,Linux 社区成员指责华硕公司没有用遵守 GPL 许可证的规定,华硕公司公布其云顶 Linux 操作系统的 Eee PC 的完整源代码,包括 asus_acpi 组件和所有核心数据,对于希望完全掌控软件的企业而言,将全部源代码开源显然是不可接受的,因此,使用开源软件的企业有必要了解开源软件的法律风险。

② 开源软件存在版权瑕疵

开源软件存在版权瑕疵是指贡献者将不具备版权的代码贡献到开源社区,使得开源软件本身存在版权瑕疵,例如:某一个开源软件贡献者在贡献代码时,把某个公司的 Java 代码,或者说不具有版权的代码贡献到开源软件 a 中,在该情况下开源软件 a 就存在版权瑕疵,用户在使用开源软件a时,可能会触犯到版权,这一点值得注意。

2)专利侵权风险

开源软件侵犯第三方专利导致的专利侵权风险(如 GPL2.0 序言所述:“自由软件还持续受到软件专利的威胁”)

大多数情况下,开源软件中的贡献者协议或者 CLA 里一般不会有太多的定义来描述专利条例,因此在 GitHub / Gitee 上使用开源软件时存在一定的专利侵权风险。

专利风险分为:

① 外部战略风险

外部风险是指不受开源软件许可证约束的乙方针对开源软件的使用者发起的专利请求,相关案例如下:微软公司在 2009 年 2 月起诉导航设备制造公司 TomTom 侵犯其多项专利,该多项专利中有两项涉及 FAT 文件系统,包括 TomTom 产品在内的 Linux 内核都在使用该文件系统,该案也是微软公司第一次针对 Linux 发起专利诉讼,同年 3 月,TomTom 同意向微软支付一笔专利许可费,从而迅速与微软达成和解。

② 内部专利风险

内部风险是开源软件的贡献者针对开源软件使用者发起的专利请求。

3)商标侵权风险

大部分开源许可证不包括商标授权,因此随意使用未经授权的商标会产生侵权风险。

商标和项目有些情况下是分离的,比如我们将某个项目捐赠给某个基金会,但商标我们不一定捐赠给这个基金会,也就是说我们的源代码和商标是分离的,如果在公开场合对商标进行传播,则需要对商标进行授权。如果想要主导一个开源社区,需要注册几类跟IT相关的商标,比如第 9 类、第 38 类、第 41 类、第 42 类等类别的商标。

商标法不同于旨在激励独创性作品和创造性发明的版权法和专利法,商标法的目的是通过保护产品或服务的来源,从而保护生产经营商。开源软件的用户有权在原来的代码基础上开发新的产品,所以开源项目的衍生产品是无法使用与原来项目同样的商标。对于大部分开源许可证的授权,都有对应的版权授权,部分有专利授权,但是很少有开源许可证有对应的商标授权,因此企业在使用开源软件的时候,一定不要随意使用开源软件的商标。

例举 Apache 软件基金会对 Apache 软件商标使用的一个详细规定:

  • 可以使用的情况有:描述作品来源、复制 NOTICE 文件时保留的商业性标识、书籍或杂志上等学术用途;
  • 不可以使用的情况有:软件产品的品牌中、域名中、会议或活动的名称中。

4)商业秘密风险

商业秘密被公开的风险,比如使用 GPL 的一些开源软件,可能会导致传染,让部门/公司内一些产品的核心软件也必须依照该许可证进行开源,从而导致商业秘密被泄露。

  • 因不当使用开源软件而导致产品核心软件代码开源
  • 未经授权,将第三方非公开代码开源

3、开源不等于免费,开源软件随意使用存在法律风险

1)履行开源义务

开源软件使用者除了享有使用的权利,还必须按照 License 规定履行相应的开源义务,否则即违反了开源 License。

开源义务包括

① 使用声明义务

在对外分发产品时,附上声明文档,注明产品所使用的开源软件名称、版权、License 内容等信息。

② 代码开源义务

将一定范围内的代码对公众开放,开源范围视具体 License 的要求和产品具体使用方式而定。

2)案例

某公司内研发员工发现内部某款产品是基于源项目 xx 开发,该项目以 MIT License 发布,但该产品在使用时删除了部分代码文件中 License 声明信息,且在发布时也未另外声明,此行为已经违反了该软件的 License 的使用声明要求。

解析: MIT、BSD 这类开源软件 License 要求较为宽松,使用者可以任意使用,修改代码(甚至软件名称),分发等,但其同时要求使用者履行使用声明义务,即保留原软件的版权与 License 声明信息(或者在单独文件中声明),该产品的行为直接违反了履行使用声明义务的要求。

启示: 由于该产品仅在公司内部使用,不会对外暴露,因此其行为引发外界开源诉讼风险较小,但对于对外商用发布的产品,必须严格按照 License 要求履行开源义务,否则可能引发开源诉讼导致赔款甚至禁售风险。

二、开源许可证及其风险管理

1、开源许可证本质

1)在中国大陆法系国家,开源软件许可证毫无争议的是许可人与被许可人之间的合作,开源许可证是个格式合同,不允许更改;在美国法下,它可能是合同,也有可能是版权;

2)开源许可证规定了许可人(软件开发者)和被许可人(用户)的权利和义务,可能涉及版权、专利、商标、担保等一系列权利义务的设置,正是这些权利和义务,决定了权利人是否将源代码真正地向社会公众开放,从而可以实现是否是开源软件的判断,即初始作者有权选择某个许可证(比如许可证 a)将初始软件发布,对应的中间分发者如果想要再次修改,然后再分发这个软件,那中间分发者需要按照许可证a的要求,梳理需要遵循的义务,再去发布软件,且选择的许可证必须满足许可证a的条件;

3)被许可人在违反许可证设定的义务时构成合同违约,同时,根究具体情况还可能构成著作权侵权,我国合同法第 122 条规定,在违约与侵权构成责任竞合时,当事人需择一地主张权利,涉及采取补救措施、赔偿损失、定金违约金等法律救济形式。

2、许可证规定内容

每个许可证具备的特性都可能不一样,其中 1~5 项为通用属性:

1)编写者:许可证的作者有修改许可证,发布许可证新版本的权利。

2)版本号:开源许可证都应具备版本号,版本号不同,内容有可能不同。

3)术语定义:定义关键概念,比如 "modified"、"derived"、"source code"。

4)版权规定:版权许可条款-明确用户在版权方面的权利;重新发布的规定-规定用户使用、复制和发布的要求。

5)免责条款:免除许可证颁发者和贡献者的责任。

6)专利规定:明确用户在专利方面的权利;专利报复条款。

7)商标规定:明确声明不能使用商标。

8)其他条款:附加责任、新版本选择、地区限制、违约责任规定等

3、开源软件分发场景判断

首先,我们要先判断我们的开源软件的应用场景属于自用还是分发,如果应用场景属于自用,那么就可以忽略开源许可证的规定与要求。

比如,一个公司并没有将开源代码分发给不同主题下的第三方,而是在公司内部同一个主体下进行开源代码的分发,或者仅仅是一个人在自己使用开源软件的这种请款,那该应用场景就属于自用,则可以忽略对应开源许可证的一些要求。

再比如说,一个甲公司把代码分发给第三方,构成了分发条件,在这种情况下就需要遵循对应许可证的规定。

还有一种情况,SaaS 服务就是云服务方面,除了 AGPL、SSPL 这类许可证针对云服务有一个明确的规定外,大部分许可证对其分发没有一个明确的规定。

针对金融和分发,举一个实例,也是前段时间发生的一个状况:某个银行,用 Itext(AGPL 许可证)创建转账发票(PDF),Itext 公司给其发了一封律师函,认为该银行的使用场景存在违规情况,在这种情况下,需要去判断使用场景属于自用还是分发,如果属于自用,那么可以忽略对应许可证的规定,如果是分化,则需深层次判断是否需要遵循对应许可证的规定,那以下哪种场景涉及分发呢?

1)银行使用内部系统创建所有发票,并将它们储存在服务器上,想要查看、打印发票的人可以上网从该服务器获取打印发票;

2)每当用户在系统中查看、打印发票时,都会触发即时创建 PDF 的流程。

答案是第一种情况下属于自用,第二种场景属于分发。首先说说第二种场景,用户在系统中每当想要查看打印发票时,都会即时触发对应代码,这种情况下就涉及到触发对应分发场景,那第一种情况为何不属于分发?其中一个关键词是银行使用内部系统,创建所有发票,所以银行是使用内部系统去运行 Itext,创建转账发票,在整个创建过程中,并没有第三方的一个用户接触到流程,因此第一种情况下属于内部使用,可以忽略AGPL 修正的规定。

4、自由开源软件组件

1)常见的使用情境

① 合并(Incorporation)

开发人员可能会复制部分的自由开源软件,到你的软件产品之中。相关的字词包括:

  • 整合 (Integrating)
  • 融合 (Merging)
  • 贴上 (Pasting)
  • 改用 (Adapting)
  • 嵌入 (Inserting)
② 链结(Linking)

开发人员可能会链结或加入自由开源软件许可组件,与你的软件产品一起运作。相关的字词包括:

  • 静态/动态键结 (Static/Dynamic Linking)
  • 配对 (Pairing)
  • 贴上结合 (Combining)
  • 利用 (Utilizing)
  • 打包 (Packaging)
  • 建立相依关系 (Creating interdependency)
③ 修改(Modification)

开发人员可能会对自由开源软件组件进行变动,包括:

  • 增加/注入新的程序代码到自由开源软件组件里
  • 对自由开源软件组件进行修正、优化,或更改
  • 删除或移除程序代码
④ 转变 (Translation)

开发者可能会转化程序代码的状态,包括:

  • 将中文翻译成英文
  • 将 C++ 转变为Java
  • 编译成二进位代码
⑤ 开发工具

开发工具可能会在幕後执行某些操作行为。例如,开发工具可能会将其自身的部分程序代码注入至输出成果。

2)自由开源软件组件如何被发行?

① 谁会收受到这些软件?
  • 顾客/合作伙伴
  • 社区项目
  • 在商业团体范围内的另一个法人(这可能会被视为发行)
② 传递的形式是什么?
  • 以程序源代码传递
  • 以二进位代码传递
  • 预载到硬体里

5、开源许可证大家庭

目前开源许可证超过 2,700 多种,根据其互惠性,即常听到的传染性(为何会用到互惠性这个词?传染性相对会有些污名化,是开源的特性,传染性对于大家来说会更好理解,但开源许可证本质上是希望自由公开使用开源软件,因此选择更积极的褒义词去形容开源许可证的特性)。许可证的互惠性,主要是关于许可证对于分发衍生软件的限制,比如许可证 a 和其他模块以某种方式组合在一起,构成衍生作品,该衍生作品也必须遵守对应许可证 a,那么就可以理解为许可证 a 是具有互惠性的。根据互惠性的强弱,可进行如下分类:

类别许可证
Affero General Public License(强互惠型)GNU Affero General Public License v3 or later
Reciprocal(互惠型)GNU General Public License(GPL) 2.0 or 3.0 、Sun GPL with Classpath Exception v2.0;
Weak Reciprocal(弱互惠型)Common Development and Distribution License(CDDL)、Eclipse Pubic License、GNU Lesser General Public License(LGPL) 2.1 or 3.0 、Mozilla;
Permissive(宽松型)Apache 2.0、Artistic License、BSD License 2.0(2-clause Simplified,3-clause,new,or Revised)、MIT License

开源许可证可按 “源代码再发布时的要求” 分类,按照软件再发布时对提供源代码的要求,互惠性越强,商业友好性越差,版权侵权风险越大。

1)宽松型许可证

宽松型许可证(Permissive License)是最基本的类型,用户可以修改代码后闭源。它有三个基本特点

  • 用户使用代码没有限制;
  • 不保证代码质量,用户自担风险;
  • 用户必须披露原始作者。

Apache 许可证是注明的非营利开源组织 Apache 软件基金会采用的许可证。该许可证鼓励代码共享和尊重原作者的著作权,允许代码修改和再发布(作为开源或商业软件),同时该许可证还为用户提供专利许可。

如果去分发 Apache 2.0 的一个开源软件,则需要满足以下 4 个条件

  • 没有修改过的文件,必须保持许可证不变。
  • 凡是修改过的文件,必须向用户说明该文件修改过。
  • 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议、商标、专利声明和其他原来作者规定需要包含的说明。
  • 如果再发布的产品中包含一个 Notice 文件,则在 Notice 文件中需要带有Apache 2.0 许可证,你可以在 Notice 中增加自己的许可,但不可以表现为对Apache 2.0 许可证构成更改。

2)弱互惠型许可证

如果一个软件包含弱互惠型开源许可证下的部分代码,完全发布时某些部分必须使用该许可证,其他部分可在其他协议下发布,典型的弱互惠型许可证主要有 LGPL、MPL 和 EPL。

下面主要介绍 LGPL(GNU Lesser General Public License,2.1、3.0,以下分别称“LGPL 2.1" 与 "LGPL 3.0”)

  • LGPL 许可证是 GPL 的一个为主要为类库使用设计的开源协议,和 GPL 许可证要求任何使用/修改/衍生之 GPL 的软件必须采用 GPL 许可证不同,LGPL 许可证允许商业软件通过类库引用的方式使用 LGPL 类库而不需要公开商业软件的源代码,这使得采用 LGPL 许可证的开源代码可以被商业软件作为类库引用并发布和销售。
  • LGPL 2.1 再发布需要满足的条件:如果修改 LGPL2.1 的代码或者衍生,则所有修改的代码,涉及修改部分的额外代码和衍生的代码都必须使用 LGPL 2.1。
  • 相比于 LGPL 2.1,LGPL 3.0 不仅要求用户公布修改的源代码,还要求公布相关硬件,如安装环境代码等;同时,LGPL 3.0 明确了专利许可。

3)互惠型许可证

互惠型开源许可证明确要求,如果一个软件包含该协议下部分代码,完全发布时必须作为整体适用该协议。GPL(GNU General Public License,2.0、3.0,以下分别称“GPL 2.0" 与 "GPL 3.0”)最初由自由软件基金会(Free Software Foundation)Richard Stallman 为 GNU 项目所填写,GPL 2.0 给予任何人自由复制、修改和发布 GPL 2.0 代码的权利。

GPL 2.0 再发布需要满足的条件:

  • 所有以 GPL 2.0 发布的源代码的衍生,也必须按照GPL 2.0发布;
  • 不论以何种形式发布,都必须同时附上源代码。
  • 确保软件自始至终都以开放源代码形式发布,保护开发成果不被窃取用作商业发售。

GPL 3.0 与 GPL 2.0 类似,区别在于:GPL 3.0 不仅要求用户根据许可证要求公布修改的源代码,还要求公布相关硬件,如安装环境代码等;GPL 3.0 明确了专利许可。

AGPL 3.0 基于 GPL 增加了规定在使用开源软件提供云服务时也必须提供源代码。所以如果使用 AGPL 许可证的一个开源软件的时候,需要关注到使用场景。

4)不同 License 约束内容的区别

以下 10 种 License 覆盖了开源软件中 90% 以上的代码,采用这些 License 的开源软件在业界应用也最为广泛;其中 GPL V2 对于开发者和二次开发者的义务要求最多,使用时应加以关注。(建议使用相对宽松型的 License)

6、互惠性与聚合体

谈到了互惠性,大家可能也会怀疑,互惠性是完全不能隔离掉的吗?其实也是有一些隔离措施,其中比较关键的一个定义就是聚合体,那聚合体是由多个独立的程序组合而成的共同体。GPL 允许你制作和发布一个聚合体,即使其他软件的许可证,不是自由开源许可证,不是 GPL 兼容的许可证或闭源分发也可以。唯一的条件是你不能禁止用户行使每个独立程序许可证所允许的权利。

如何去区分,到底是两个独立的程序组成的聚合体,还是一个程序的一个两部分呢?这本质上是个法律问题,会根据不同国家、不同地域的法律规定产生变化,但又无法脱离技术。从技术方面来看,独立程序的标准,既依赖于通信机制,也依赖于通信语义(交换了什么样的信息)。

进程间通信的方式有很多,比如:消息传递、同步、共享内存、远程过程调用、Socket 通信等。如果两个模块都包含在一个可执行文件中,或者两个模块运行时共享内存,那它们一定是同一个程序。反过来,管道、socket 通信和命令行参数通常都是两个独立程序的一个通信机制。但是如果两方的通信语义非常密切,共享内部数据结构,那它们也会被认为是一个大程序的两个组合部分。

应用程序一般由三个部分组成:私有代码;开源代码;第三方组件。

针对开源代码的引用方式,一般包括以下九种,其中前 4 种是比较常见的引用方式:

1)动态链接(Dynamically linked) 一种是 Lib 包含了函数所在的 DLL 文件和文件中函数位置的信息 (入口),代码由运行时加载在进程空间中的 DLL 提供,称为动态链接库(dynamic link library)。

2)静态链接(Statically linked) 一种是 Lib 包含函数代码本身,在编译时直接将代码加入程序当中,称为静态链接库 static link library。(所以无论是动态链接库还是静态链接库,都会有 lib 文件)。

3)源码引用(Source Code): 源代码,例如 .java 或 .cpp文件。与构建,二进制文件或发行版一起打包组件的源代码。

4)单独(聚合体)(Separate Work): 适用于松散集成的组件,应用程序具有其自己的可执行文件,而组件与应用程序之间没有链接。

5)汇总(Merely Aggregated): 适用于您的项目不使用或以任何方式依赖的组件。

6)标准实现(Implementation of Standard): 适用于根据标准实施的情况,例如,项目随附的 Java 规范请求。

7)前提条件(Prerequisite): 适用于您的发行版中未提供但必需的组件。例如预先准备好 JDK 的支撑。

8)开发工具/排除(Dev. Tool / Excluded): 组件将不包含在已发布的项目中,例加,内部用于构建,开发或测试的组件。例处单元测试,IDE 文件或编译器。

9)未指明的/不确定(Unspecified): 尚未确定此组件用法,您可以使用 "未指定" 来表示您需要调查此组件的使用情况。

针对以上九种引用方式,对应每一个许可证的风险都是不同的,其中风险限定的范围为,开源软件许可证侵犯版权的风险与企业核心代码被污染的风险。就互惠型许可证举例:针对这九种引用方式,分了两种使用场景:

  • 第一种场景是商业分发项目,主要指的是把整个代码打包,然后整个通过实体分发给用户;
  • 第二种场景是 SaaS 项目,即云服务;

整体来说,针对互惠型的许可证,商业分发项目包括动态链接、静态链接、源码引用,使用这些引用方式都是具备很高的风险,但是对于 SaaS 项目来说,这三种引用方式的风险相对来说低很多,因为互惠型的许可证,比如说 GPL 它没有针对云服务做对应的规定,但是值得注意的是,互惠型许可证的一个引用方式:前提条件,对于商业分发项目这种场景,具备一定风险。

7、开源许可证的兼容性

兼容性定义:适用不同许可证的两个开源程序合并成一个较大的程序,或者把其中之一的代码合并入另一个时,如果各个许可证的限制或条件没有冲突,允许该种合并,我们就可以说这些许可证是兼容的。

如果是许可证 a 的代码和许可证b的代码,他们组合成一个作品,如果组合作品是以许可证 a 发布,那就可以说许可证 a 兼容 b;如果组合作品是以许可证 b 发布,那就可以说许可证 b 是兼容 a;如果组合作品可以许可证 c 发布的话,我们就可以说许可证 c 是兼容 a 和 b 的,那这个相对来说比较抽象。

以喝饮料来举个形象的例子:A 许可证要求你喝碳酸饮料,B 许可证要求你喝可乐,C 要求你喝 2L 可乐, ABC 这三种许可证它的要求逐渐严格,当你履行了喝可乐的这个动作时,同时也满足 A 许可证要求喝碳酸饮料这个要求,所以可以说 B 是兼容 A 的,C 的要求会更为严格,必须喝 2L 可乐,那这种情况下就可以说 C 是兼容 A 和 B 的;如果 D 许可证要求你吃汉堡,那这种情况下, D 和 A、B、C 都是不兼容的。

因此需要查看双方的许可证协议中是否包含一个条款,允许你将协议升级到稍后的版本,例如,LGPL v2.1 和 GPL v3 是不兼容的,但如果两方的许可证协议中都包含“可以升级到更高版本”的条款,那么 LGPL v2.1 就可以升级到 LGPL v3,LGPL v3 和 GPLv3、AGPL v3 是兼容的。

许可证的兼容性列表可以分为以下两种情况

1)合并/修改代码:从要组合的代码中取出整体/部分代码,修改或不修改都可以,然后把它添加到你的代码中构成一个作品。

2)使用库:没有直接复制代码,在编译或运行时通过链接、导入或其他典型的机制(例如静态与动态链接)把要组合的开源代码绑定在一起。

三、开源许可证与知识产权风险示例

1、开源软件许可证与知识产权风险

1)场景一:若企业作为使用人使用开源软件(Apache 和 BSD 等许可证无风险)

许可证类型GPL v2GPL v3MPL 2.0EPL 1.0APACHE v2BSD/ISC
软件传染性(开源)强传染强传染修改部分传染修改部分传染
给所有下游用户的专利许可无规定(默认有)
能否起诉其他用户专利侵权可以不可以可以,但软件许可终止可以,但专利许可终止可以,但专利许可终止

2)场景二:若企业作为贡献人贡献开源代码(MPL/EPL/Apache的专利许可仅限于贡献部分)

许可证类型GPL v2GPL v3MPL 2.0EPL 1.0APACHE v2BSD/ISC
软件传染性(开源)强传染强传染修改部分传染修改部分传染
给所有下游用户的专利许可无规定(默认整个软件)整个软件贡献部分贡献部分主动贡献部分(含贡献者关联公司专利)无规定(默认主动贡献代码有)
能否起诉其他用户专利侵权默认有许可,不可已许可,不可已许可,不可可以,但专利许可终止已许可,不可

2、许可证遵从义务引发的诉讼

许可证遵从义务引发的诉讼主要指以违反许可证义务的版权诉讼为主,由维权个人/组织发起,原告胜诉率极高,后果含开源、赔款、禁令(和解:开源/赔偿),主要集中在欧美,以美国和德国为主,但近些年来国内的诉讼也越来越多。

1)美国发起诉讼的部分案例

  • 2007 年,SFLC 代理 busybox 分别起诉 Xterasys Corporation,High-Gain Antennas,verizon,Monsoon Multimedia,每诉均要求禁令,后均和解
  • 2008 年, SFLC 代理 FSF 起诉思科,后和解
  • 2009 年, SFC 代理 busybox 起诉三星、百思买等 14 家公司,法院首次下达开源软件禁令
  • 2013 年, XimpleWare 起诉 Versata 等 12 家公司,后赔偿和解
  • 2009-2014 年,多家公司收到来 SFLC/SFC 的警告函,包括三星(三星 2013 年再次对 SFC 捐款和解),均私下和解。
  • 2016年,Artifex Software vs. Hancom,后赔偿和解。

2)欧盟发起诉讼的部分案例:除了 2007 年的 Iliad 案在法国,其他均发生在德国。

  • 2004年,Welte 起诉 SiteCom,被告败诉,法院首次颁发开源软件禁令
  • 2006年,Welte 起诉 Versatel,被告败诉
  • 2006年,Welte 起诉 D-Link,被告败诉。赔偿 2000 余欧及诉讼费用,并披露销量以及上下游名单
  • 2007年,Welte 起诉 Skype, 被告败诉
  • 2007年,Welte 起诉 lliad, 被告败诉
  • 2013年,Welte 起诉 Fantec,被告败诉,赔偿 8000 余欧及诉讼费用,并披露销量及上下游名单
  • 2015年,Mchardy 起诉某厂商,法院发临时禁令 期间,上百家公司收到来自 Welte 和 Mchardy 的违反开源许可证义务的警告函,绝大部分和解。
  • 2016,Mchardy 起诉德国某运营商,申请禁令,后原告撤诉
  • 2016,Linux 权利人起诉 Vmware,后原告败诉
  • 2016,某软件商 vs. 德国某大学,申请禁令,原告胜诉
  • 2017,Mchardy 起诉 Gerniatech,申请禁令,后原告撤诉

3、许可证遵从义务引发的非诉问题示例

1)ONAP 发布代码前会例行扫描检视,发现因许可证冲突导致无法使用的代码多次要求运营商贡献方重写或删除。

2)企业某对外开源项目中使用并修改了 Apache License 代码,但在该文件包中无修改标记且遗漏许可证文本,被权利人发现在社媒公开投诉。

3)企业某对外开源项目中误将开源无修改软件的版权声明误替换为企业版权声明,代码开放 3 分钟后即被开源爱好者发现并在网络公开。

4、开源软件专利侵权风险——业界部分诉讼

1)相比商业软件:诉讼较少——本身的特性(免费许可与不诉义务)、社区环境

2)版权权人起诉少:以下诉讼除了最后一起均为第三方起诉开源软件用户

3)OIN,FSF 等:常协助被告搜集无效证据、号召联合抵制、促成低成本和解或无效原告专利

起诉时间原告被告起诉法院涉案开源软件结果
2006 年FirestaRedhat东德克萨斯地区法院Hibernate 3.0 软件,Jboss 开源中间件的一部分,许可证 LGPL v2.1和解,内容保密
2007 年IP Innovation L.L.C. Technology Licensing Corporation, patent trollRedhat, Novell德州东区法院Linux 系统,许可证 GPL v2原告败诉。专利被无效。被告寻求 OIN 支持寻找无效证据
2007 年NetApp (被告的竞争对手)SUN德州东区法院ZFS, Sun 为 solaris 操作系统开发的文件系统,许可证 CDDL和解,内容保密
2008 年微软 (首次诉讼攻击 Linux)(分蛋糕)TomTom, 导航设备制造商华盛顿西区法院,原告同时申请 ITC 调查基于 Linux 的车载计算机系统和导航系统产品,GPL v2和解,内容保密,被告寻求 OIN 等支持
2008 年Trend Micro (被告的竞争对手)Barracuda,07 年初加入 OIN加州北区法院。同时申请 ITC 调查Clam AV, 一款类 Unix 上使用的开源的反病毒软件,许可证GPL v2和解,内容保密。被告寻求多个社区支持,专利被 ITC专家认定无效。
2009 年Software tree, patent trollRedhat, HP, Dell, Genuintec 后三都是 Redhat 集成产品的销售者东德克萨斯地区法院JBoss 开源中间件,许可证 LGPL v2和解,内容保密
2009 年Acacia 的子公司Redhat, HP, Dell, Genuintec 后三都是 Redhat 集成产品的销售者东德克萨斯地区法院JBoss 开源中间件,许可证 LGPL v2和解,内容保密
2010 年OracleGoogle加州北区法院Android 操作系统 许可证 Apache v2.1审理中
2013 年XimpleWare(被告竞争对手)Versata 等 12 家公司加州北区法院一款编码规则软件, GPL v2和解

5、软件本身版权风险

1)版权风险:代码开发时因未经授权使用开源代码引发

2)诉讼/纠纷示例:

  • Oracle vs. Google , Android API 接口 + 9 行代码 (争议金额:90亿)

  • Elasticsearch Inc. vs. Floragunn GmbH and certain GitHub users,X-Pack source code in content hosted on GitHub

    专利涉及知识产权本身的风险,不仅要看最后官司的结果,更要看这中间带来的对企业品牌声誉的影响,而且中间所付出的各种诉讼的费用以及相应的人力成本都是非常巨大的。所以说我们的建议就是使用开源参与开源之前就能够有专业的团队和专家开发者,大家能够懂开源合规是什么,尽可能地在自身的能力范围内做到开源合规,这是非常重要的,可以给公司将来的风险能够降低到最低。

四、企业开源合规风险防控

1、企业使用开源合规流程

企业使用开源合规流程主要包含三大环节:

1)开源组件引入代码仓

识别和审计主要指的是去扫描并审计源码,这个源码就包括自由软件、第三方专业软件和开源软件,确认代码来源和许可证。处理问题主要指的是需要根据公司的开源政策和合规的红线,去处理审计中出现的问题,比如可能发现某些开源软件具备互惠性比较高的许可证,在这种情况下就需要去注意其使用场景。

① 识别(辨识)

辨识自由开源软件组件;

步骤:

  • 来自工程师的输入要求
  • 扫描软件
  • 对开源软件的发现执行尽职调查 (Due Diligence)
  • 将人工辨识之新组件信息加到知识库

成果:

  • 对该自由开源软件的合规纪录被建立或更新、
  • 依自由开源软件政策所订,穷尽或限定范围内,对源代码审核之稽核将被要求。
② 审计(稽核)

辨识自由开源软件许可证;

步骤:

  • 供稽核之程序源代码被辨识
  • 源代码或已使用软件工具进行扫描
  • 稽核或扫描的「成果 (Hits)」被审核及验证,而得作为该程序代码适宜的来源信息
  • 稽核或扫描依该软件的开发与释出周期而被反覆操作

成果:

  • 稽核报告能用以辨识、程序源代码的原始出处及其许可证
  • 有待处理的疑虑
③ 处理问题

处理审计过程辨识出的所有疑虑;

步骤:

  • 提供反馈予相应的工程师,以处理在稽核报告里,与你的自由开源软件政策冲突的疑虑
  • 该工程师继续就相关的程序源代码实施自由开源软件审核

成果:

  • 对报告里每一个被标记的文档作处理,及对任何标记许可冲突的状况作处理

2)从代码仓引入产品

审核、审批主要指的是审核并批准的合规记录,也包括流程记录环节,保存公司内部每个产品每次发版时经过批准的开源组件清单。准备声明,因为开源许可证会有需要声明的义务,包括对您开发软件的版权所属、通知说明之类的。

① 审核

审核已处理之疑虑以确认其与你的自由开源软件政策相合;

步骤:

  • 於审核工作人员里,应包含适切对应的管理阶层
  • 依你的自由开源软件政策为参据来实施审核

成果:

  • 确保在稽核报告里的软件与自由开源软件政策相合
  • 准备往下一个步骤前(例如:核可前),保存稽核报告的发现,并标注已处理的疑虑
② 批准(核可)

自由开源软件组件经批准认同合规纪录:

  • 根据上一个步骤的软件稽核及审核结果,软件可能被核可或可能不被核可使用;
  • 核可时,必须注明被核可的自由开源软件版本、被核可组件的使用模式,以及其他依自由开源软件许可证应施行的义务性要求;
  • 核可须对应到适宜的行政管理阶层来进行。
③ 留存记录

保存每个产品每个版本经过批准的开源软件清单:

  • 当一个自由开源软件组件被核可在产品中使用时,其应被加入该产品的软件清单;
  • 该项核可及核可的条件,必须被登记纪录在可追踪系统里;
  • 若新版本的自由开源软件组件或新的使用模式被提出时,该追踪系统必须清楚显示这需要一个新的核可。
④ 声明

为发行产品中任一自由开源软件备妥适宜的声明:

  • 藉由完整著作权及署名声明之提供,来承认自由开源软件的使用;
  • 通知产品的终端使用者,如何获得自由开源软件程序源代码的复制件(当此要求适用时,例如 GPL 及 LGPL 即为此种状况);
  • 应需求复制产品里自由开源软件程序代码之全部许可证协议文件。

3)产品发布

发布声明及源码、发布后的验证、准备待发布的开源声明。

在发行环节,需要发行源码和声明,并且需要把索取源代码的说明文件也分发出去,如果后续用户想要索取源码,我们也需要把对应的索取渠道告知给用户。

① 发行前的验证

验证发行的软件已经过审核及核可

步骤:

  • 验证预计发行的自由开源软件套件已经过辨识及核可
  • 验证已经过审核的程序源代码与贩售产品里相对应的二进位代码是符合的
  • 确保已被审核的源代码符合相对应的产品执行文档
  • 验证所有相应的声明已被列入,以告知终端使用者其索取已被辨识之自由开源软件程序源代码的权利
  • 确保所有相应的声明已被纳入好让终端用户知道他们能获取相关自由开源软件的权益
  • 验证合规于其他已被辨识的义务性要求

成果:

  • 使发行的套件仅会包含已经过审核及核可的软件
  • 「供发行的合规稽证 (Artifacts)」(依 OpenChain 规范书所定义),包括被列入发行套件或其他投递模式所相应的声明文档
② 相应程序源代码的发行

依据要求提供相应的程序源代码

步骤:

  • 提供伴随任何相关联建置工具以及文件的对应程序源代码(例如,上传到发行网站上或列入发行套件里)
  • 此相应程序源代码应被辨识与标记,以和其产品及版本别对应

成果:

  • 提供相对应程序源代码的义务性规则被满足
③ 最后验证

确认合规於许可证的义务性规定

步骤:

  • 验证相对应的程序源代码(若有的话)已经被正确地上传或发行
  • 确保其他许可证有被遵守
  • 验证上传或发行的程序源代码与经核可的版本是相对应的
  • 所需声明已被适当地发布与提供验证
  • 验证其他被辨识出的义务性要求已达到;

成果:

  • 验证供发行的合规稽证 (Artifacts) 已被适切地提供

2、企业贡献开源项目的合法合规要求

企业参与外部已存在的开源项目,向其贡献代码,在代码开源前,我们需要考虑哪些合法合规要求?

1) 了解并签署贡献者协议或开发者原创声明(视社区要求而定):了解贡献者协议/原创声明中对企业(贡献者)的约束。

2) 明确开源文件来源,确保可开源:明确贡献内容中所有代码、文档等文件的来源及版权,确保拥有将贡献内容提交至社区的合法授权。

3) 识别清理 License 冲突:识别贡献内容中所包含的所有开源 License,整改确保与项目 License 不冲突。

4) 履行开源义务:根据贡献内容中包含的开源 License,履行相应开源义务。

3、企业自发(发布)开源合规流程

如果企业想要自发或者说发布一个开源项目,它的合规流程应该是怎么样的?那企业在对外发布开源项目时,应调查清楚开源项目包含哪些第三方组件,确定开源项目组件信息,包括组件的来源、出处等。

企业自发(发布)开源合规流程也分为三个环节:

1)确认:披露和发现。

确认企业在这个开源项目中使用了哪些第三方开源软件组件和片段。在这个环节,需要输入项目的源码,输出软件物料清单(SBOM),突出显示开源软件的组件和片段,其来源和许可证。

2)批准:审查和批准。

批准开源软件的预期用途。在这个环节需要去输入第一个环节输出的SBOM和架构,输出产品或者服务发布时应遵守的义务汇编,探寻开源许可证的风险及声明义务,梳理清晰。

3)通知:遵循 OSS 许可证。

通知部署的开源软件所有许可义务,当在第二环节准备好的需要遵守的义务和责任之后,那在第三个环节需要准备材料,把材料发布出去,包含所有通知的源代码(书面通知、版权、许可文本和归属)。

4、业界开源项目的法务合规保障机制

当前开源社区对于合规保障较弱,而公众对于一般开源社区也较为宽容,发现问题及时整改解决即可,但由单个企业主导发布的开源项目,则容易被公众或竞争对手针对,因此要有更严格的保障:

1)项目发布前培训

项目发布前,对项目负责人进行培训,告知相关法务注意事项,如代码成份分析、合法性检查、License 兼容性整改、贡献者协议要求等,但没有强制审查检验机制。

2)项目负责人组织合规整改

项目负责人组织清理与项目 License 不兼容的代码,通过人工审查 + Maven 插件工具 + 其他扫描工具(项目负责人自行决定) 进行识别清理,但没有强制在项目发布前要求完全清理,可能会在发布后持续进行。对于删除原有 Copyright、存在不兼容 License 等行为可能难以被发现,主要靠发布后用户/贡献者持续发现推动解决。

3)签署贡献者协议

项目发布后,要求每个贡献者签署贡献者协议,约定贡献代码版权归属(一般归贡献者),若含有专利,则贡献者必须确保该专利是被授权给所有用户使用,但即使存在问题,也可能难以第一时间发现,主要靠自觉。

4)Committer 持续审视

Committer 负责审视贡献代码,识别和解决合规问题,依赖个人能力,主要还是靠贡献者自觉。

5)问题发现解决

社区中的合规问题一般通过 “用户/贡献者反馈 —— Committer 组织整改” 方式解决,若发现抄袭、修改版权等行为,Committer 会组织进行整改,而相应贡献者也会遭到社区谴责,可能影响其后续的贡献。

5、开源前需要考虑的合法合规事项

企业原创或主导、由企业主动对外开放、以开源社区形式运作的开源项目,在项目开源前,我们需要考虑哪些合法合规要求?

怎么做?具体步骤如下:

  • 项目成员岗前合规培训
  • 基于商业诉求,明确项目License,贡献者协议等法务文档
  • 持续扫描识别License风险,及时清零
  • 发布前合规检查,确保风险清零
  • 社区运营过程中持续扫描识别并解决合规问题

1)制定并配置项目法务文档

明确项目 License,贡献者协议、企业权利声明等文档;

① 选择 License

License:规定了该项目所有用户所享有的权利及必须履行的义务,开源项目的业务团队根据自身业务目的,与企业的法务部共同明确项目 License。

如果限制少,更多地选择宽松的许可证,比如 BSD 和 Apache 许可证,如果需要代码对外开源,或者履行更多地开源义务,可以选择比较严格一点的许可证,比如 GPL 或者 MPL许可证。

② 案例-选择 License

业务诉求:

  • 代码开放,提供版权和专利免费许可,无强迫用户回馈诉求
  • 鼓励使用,无限制分裂诉求
  • 优先使用中文许可证

代码扫描结果: 除了 BSD 代码外,无其他第三方许可证的代码,故所选许可证与BSD兼容即可

推荐: 国产木兰宽松许可证

③ 示例:license 惹争议事件

Facebook Patents License 惹争议

  • Facebook React( FB+PL 许可)
  • BSD-3 Clause:商业友好,无强制开源义务,仅需履行声明义务即可
  • Facebook Patents License:“Facebook 保护主义” 条款,若使用者对 Facebook 发起专利诉讼,即使该专利与 React 无关,React 对该使用者的授权也会被终止

2017 年 7 月,Apache 基金会主管兼法律事务副主席 Chris Mattmann 正式发表声明称:Facebook BSD+Patents License (FB+PL)已经正式被列入 “Category X” 列表,因此 Apache 项目中将不能够包含或依赖于 Facebook Patents License 的代码;而已经发布的代码,涉及 FB+PL 许可证的,需要在 8 月 31 号前完成替换。

Facebook BSD+Patents License 持续被众多开发者诟病声讨,2017 年 9 月,Facebook 表示后续将 React 等采用 FB+PL 许可的项目,改为 MIT 许可。

解析: Facebook BSD+Patents 许可证增加了对 Facebook 的专利保护条款,即如果用户使用了该软件,那么就不得针对 Facebook 或其任何附属公司的任何产品或服务发起专利诉讼,否则 Facebook 针对该软件授予的专利许可将自动终止,导致用户承担的专利不诉范围远远超出了其使用的 React 本身。

启示: 某些开源项目表面声明的 License 看似宽松,但可能潜藏风险,产品在引入开源软件时应获取其完整的 License 。若无法确定 License 风险, 可先向法务部咨询,评估风险后再决定引入。

④ 代码原创声明 & 贡献者协议

代码原创声明:面向企业内部,所有参与开源代码编写的员工需签署。主要内容包括:

  • 承诺个人开发的代码都为个人原创,若包含第三方知识产权的内容,或是公司专利,须如实向公司反馈,在获得批准后才能合入开源代码。
  • 若由于个人原因(如提供虚假信息,隐瞒信息等)导致项目开源后公司遭受侵权诉讼等损失,个人须承担相应责任,代码开发者对自己的代码负责。

贡献者协议:面向公司外部,所有参与社区代码贡献的贡献者必须签署。主要内容包括不限于:

a、贡献者所享有的权力

  • 如是否享有贡献代码的版权,社区内部的发言权等

b、贡献者所需承担的责任和义务:

  • 贡献者必须确保贡献内容有充分地授权,能够以项目 License 开源,或贡献内容 License 与项目 License 相兼容。
  • 若贡献内容包含第三方知识产权内容,须获取相应的授权,并在贡献时明确声明。
  • 贡献者承诺其贡献的内容属于原创,或者拥有其贡献内容的合法授权。
⑤ 版权声明及免责声明

企业权利声明及免责声明:针对企业享有版权的内容,须附上企业的权利声明与免责声明,以保护企业权利。

声明包括企业原创文件和非企业原创文件两类

a、企业原创文件:在文件头附上企业的版权信息与免责声明

  • 企业版权信息,年份为代码新增年份,邮箱可以是项目运营统一邮箱,或该文件开发者邮箱,以便其他开发者或用户通过该邮箱进行提问或沟通;
  • License 及免责声明。

b、非企业原创文件:企业在其基础上进行了修改,则在文件头附上企业的版权信息,免责声明一般在原文件 License 中会有声明,无需额外添加;

  • 保留原文件中的声明,不得更改或删除;
  • 企业修改年份,可只写年份,也可写具体日期;
  • 简要说明修改内容;
  • 企业版权信息,邮箱同上文(可以是项目运营统一邮箱,或该文件 owner 邮箱)。

⑥ 案例-某编译器误改版权事件
  • 某编译器版权声明修改遭热议:某编译器开源前,使用版权信息生成脚本对自研代码文件生成企业版权信息;
  • 脚本运行范围误将 third_party 目录也覆盖在内,导致其中的文件版权也被修改;
  • 上网当天即被网友发现,在网络上引发热议,该项目于当天紧急整改后再次上线。

2)识别项目所有文件来源

识别项目中其他开源软件及其 License:明确项目所有代码来源,区分企业代码,开源代码,确保持续可追溯;

① 开源代码可能产生的风险

涉及第三方知识产权的开源代码可能产生以下三种风险:

  • 开源代码包含第三方非公开信息,引发商业秘密纠纷;
  • 开源代码本身侵权第三方知识产权,可能被潜在的权利人起诉和要求赔偿,甚至禁止该代码的使用;
  • 未经授权使用开源软件相关的商标、标志,且不属于合理使用。
② 使用扫描工具确保可开源

通过某工具扫描项目全量文件(代码文件及二进制文件),明确所有文件来源,确保:

  • 开源代码包中的代码原则上必须由企业原创代码构成,不得包含来源不明的代码或二进制包,也不得包含未获得相应授权的第三方代码以及版权标识、包括但不限于免费代码、开源代码或商业代码,若需要随项目一起发布,则须获得相应版权方许可。
  • 开源代码包中不得包含未经授权批准的第三方商标和非公开信息等,尤其避免包含第三方特有特性代码,未经授权批准的第三方公司商标、标识、公司名、人名等敏感信息。
  • 若开源内容中包含企业专利,必须经过业务团队与法务部审核批准后方可开源。
  • 禁止在企业原创代码文件中嵌入其他开源软件代码片段。

3)识别清理 License 冲突

清理与项目 License 冲突/不兼容的开源软件

  • 清理与项目 License 冲突的开源软件;
  • 在项目代码中标识项目License与企业版权信息;
① 检查与项目许可证是否兼容

不同开源 License 所规定的权利与义务不同,相互之间可能不能兼容,项目在发布前必须检查项目引入的所有开源软件 License,确保其与项目许可证相兼容

常见 License 兼容关系,具体兼容关系可咨询对应法务;不兼容的 License 不可以出现代码混同,比如将部分代码加入到另一部分代码中。

  • 通过 FOSSID 等工具扫描识别项目中所包含的所有开源软件 License。
  • 判断这些 License 与项目 License 是否冲突,涉及具体冲突判断可向开源律师求助。
  • 对 License 冲突进行整改清理。
② 对于冲突 License整改

对于冲突 License 整改的两种方式:

  • 采用其他不冲突的开源软件替代;
  • 自研重写替代:重写时应采取 clean room 方式,重写人员不得直接接触参考开源代码,更不得直接在参考代码基础上进行修改,只可以在了解参考代码的功能后独立写出实现代码,否则重写可能失败,无法规避非兼容许可证。

4)遵从开源License,履行相应义务

  • 基于已识别到的开源软软件清单,分析各 License 风险,剔除权利不明或义务难以履行的开源软件;
  • 履行开源软件义务(主要为声明义务);
① 声明义务

若项目中集成了其他开源软件,项目在发布时也须遵从相应开源 License,履行开源义务,否则也会导致侵权风险。由于开源项目代码天然开放,因此开源项目主要涉及的是声明义务:

  • 明确项目中所包含的所有非企业原创的开源软件(第三方开源软件)。
  • 在项目根目录下添加“第三方开源软件使用声明” 文档,记录所使用的所有第三方开源软件的版权和许可证文本。
  • 保留所有第三方开源软件文件中的版权及 License 声明,若企业在其基础上进行了修改,可在原文件声明内容的基础上增加企业的版权声明(针对修改部分),但不可删除原有第三方声明。

5)管控后续合入代码,符合 License 要求

  • 与贡献者签署贡献者协议,明确贡献代码版权归属,约束贡献者代码符合项目License 要求;
  • 贡献代码审核,定期识别合规问题,及时整改。
① 持续风险识别

对于社区后续合入的代码,包括企业或其他贡献者贡献的代码,需要持续进行风险识别,避免引入与项目 License 冲突的代码:

a、从法务角度

  • 在社区运作规则中明确代码贡献合规要求,贡献者必须签署或同意《贡献者协议》,方能提交代码。

b、从运作机制角度

  • 设立代码合入门禁,合入前必须通过门禁扫描,识别并确认无风险后方可合入。
  • 定期对项目进行整体扫描,识别并及时处理发现的风险。

开源安全及其风险管理

一、开源安全为何这么重要?

1、开源项目数量爆发式增长

现在使用开源的人越来越多,开源软件越来越多,开源生态发展越来越迅速,开源成为构建企业信息技术重要底座,是数字基础设施的存在。从全球来看,开源项目数量呈现爆发式增长,截至 2020 年 GitHub 托管仓库已超过 2 亿个,2020 年新增仓库 6,000 万个;另外 2021 年 Gitee 平台上开源项目与 2020 年相比增长比例为 33%,达到了 2,000万,由此可知,开源项目的数量增长极为迅猛。

2、企业逐渐重视对外开源贡献

从开源贡献角度,根据往年的数据,企业逐渐重视开源贡献,根据 OSCI 公布的 2022年 4 月的全球开源厂商 GitHub 开源贡献排名,华为、腾讯、阿里分别位列 12、14、16 位。

开源厂商活跃开发人数参与社区数量
华为5471,473
腾讯4651,642
阿里3811,130

3、企业开源软件应用比例逐年提升

根据 BlackDuck《2022 开源安全与风险分析报告》显示,2021 年全球企业应用开源软件的比例已经达到 78%,与 2018 年相比增加 30%,且四年来开源软件持续增加。

根据中国信通院调查显示,2021 年我国已经使用开源技术的企业占比为 88.2%,暂未计划使用开源技术的企业占比为 2.1%。现在写代码的企业基本上已经消失了,大家都习惯使用开源软件或开源组件这种形式。

4、开源安全现状

1)开源软件漏洞数逐年增加,安全形势日益严峻

来源:https://www.synopsys.com/content/dam/synopsys/sig-assets/reports/rep-ossra-2022.pdf

近年来,大约有 78% 的开源软件已应用在企业中,其中大约 81% 的开源软件至少含有一个安全漏洞,而在近两年,超过 88% 的开源项目未被维护,再往前统计,近四年间,超过 85% 的开源项目未被维护,当然也会存在一些开源项目没有 license,或者 有 license 冲突的情况,因此对整个企业用户来说,使用开源软件本质上降低可开发的成本,也就是减少了开源里常说的 “重复造轮子” 的工作量,但实际上开源软件在安全方面存在较大风险:首先社区的贡献者不一定有安全的意识,很多人考虑的是如何实现功能;其次就是并不是每一个 PR 的合入,都会有安全专家进行审视。

2)NVD 公布的漏洞中开源漏洞比例较高

数据来源于 NVD(国家漏洞库):

  • 业界 NVD(美国国家漏洞库)公布了 54,256 个漏洞;
  • 约 88% 的网络问题来源于非自研软件,外部客户对非自研软件的网络安全高度重视;
  • 开源漏洞在第三方中占 66%,由于开源软件漏洞任何人都可见,更容易被针对性攻击。

3)漏洞管理以及未公开漏洞发掘存在较大挑战

① 漏洞管理:

上千款开源软件中已知漏洞的管理是个大工程,攻击者常用的手段是使用未修复的已知漏洞及其变种来攻击目标。

  • 全量漏洞感知能力、应急响应能力和危机应对能力
  • 无 CVE(Common Vulnerabilities and Exposures 通用漏洞披露)警示的漏洞修复,例如开源社区当做 bug 或无意修复的漏洞,无 CVE 警示
  • 协议类、架构类漏洞修复成本高。越早发现漏洞,成本越低。
② 未公开漏洞:

攻击者很可能使用开源软件的未公开漏洞(0-day)攻击,如何减少 0-day 漏洞攻击影响是业界难题。

  • 每年数十例 0-day 攻击被发现,近年有上升势态。0-day 攻击的防范一直是业界挑战,需要在漏洞发现和韧性架构等方面综合投入。

4)基础软件面临的安全影响

① OS 相关

2020 年 12 月 8 日 CentOS 策略变更,基础软件安全问题凸显

  • 原本 CentOS 是RHEL 的“复制”,具备完整的可商用能力
  • 后续 CentOS 版本不再适合商用生产部署,行业客户及 OSV 业务连续性面临风险

“CentOS 停服”导致整个产业链需要重新选择操作系统技术路线

  • 不再提供补丁更新,现有业务随时面临宕机和安全风险,无法及时恢复
  • 不再支持新的软硬件,新部署硬件只能采购付费 RHEL

前车之鉴: Win XP 停服,高危漏洞不再修复,导致勒索病毒侵蚀了全球数十万台电脑,100 多个国家受到病毒影响。

② DB 相关

MySQL 5.7 版本计划 2023 年 10 月 EOX,漏洞不再修复,现网存量 5.7 及之前版本的安全保障成为难题。

二、开源安全已经成为企业全球化挑战

众所周知,开源是全球化的产物,一旦出现安全问题,其影响范围将波及全世界。

1、开源安全分类梳理

1)开源安全风险成为开源首要关注的风险点

根据 BlackDuck《2022 开源安全与风险分析报告》显示,87% 的代码库至少含有一个漏洞,漏洞含有比例逐年增高(近 4 年),49% 的已审核代码库包含高风险漏洞。

2)开源安全风险分类

① 开源漏洞风险

开源漏洞风险是指开源软件、硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。近些年以 Apache Log4j 等一系列开源漏洞爆发,导致全球范围内安全攻击事件频发,因受影响的信息系统遍布全球基础设施,轻则影响网络,重则影响国家基础设施安全,影响人们衣食住行正常运转。

案例一:Apache Log4j2 漏洞影响全球 70% 的网络系统

Apache Log4j2 于 2021 年 12 月爆发漏洞,该漏洞编号为 CVE-2021-44228,CVSS 评分为 10.0分(最高分),划分为严重漏洞,这意味着利用 Log4j 漏洞能完全攻破系统,典型的结果是攻击者完全控制一个系统,包括操作系统层的管理或者“根”权限。

根据统计 Java 现存日志框架在 Github 上的关注量来看:Log4j2 的关注量排名第三,Apache Log4j2 漏洞影响全球 70% 的网络系统;

该漏洞影响 log4j-core JAR 文件,Log4j2 对每条日志通过消息工厂 (MessageFactory) 创建消息 (Message) 对象,然后创建处理事件 (event),将消息 (MessageFactory) 加入到处理事件 (event) 中对消息进行处理。在消息处理过程中,log4j2 的 format 方法 (函数) 会判断组件是否启用了 lookup 方法,如果开启了,log4j2 组件就会读取日志消息中的 ${} 关键词,然后将 ${} 关键词中的内容传递给 lookup 方法。最终 lookup 方法会调用 JndiLookup 中 Lookup 方法;从远程拉取攻击 Payload;造成远程代码执行漏洞。

漏洞根因:在 Apache Log4j 2.0-2.14.1 版本中(不含 2.12.2),JNDI 功能可能在配置文件、日志信息和一些参数中可能存在对 LDAP 和其他 JNDI 协议保护不足的问题。攻击者如果可以控制日志信息或参数则可能导致通过 LDAP 服务器执行任意代码。

漏洞原理(JNDI 注入):JNDI 支持远程下载 class 文件来加载对象, Log4j 在使用 JNDI 时对远程地址和 class 未做限制,当程序使用 log4j 打印用户输入的时候,攻击者便可以利用此漏洞给服务端植入任意代码进行攻击。

在漏洞爆发之后,中、美两国都做了一些响应,我国工信部做了具体的发文,美国政府也做出具体指示。

彭博社)——据一位白宫政府官员称,白宫要求主要软件公司和开发商与他们合作,以提高开源软件的安全性。源于流行的开源 Apache 软件中的一个漏洞被披露,网络安全官员将其描述为近期最严重的漏洞之一。

该官员说,在周四的一封信中,国家安全顾问杰克-沙利文邀请软件行业的主要参与者讨论提高开源软件安全性的举措。这项工作 2022 年 1 月份由负责网络与新技术的副国家安全顾问 Anne Neuberger 主持为期一天的讨论开始。

启示:识别产品中正在使用关键的开源项目;大规模使用开源软件的公司对开源软件要谨慎选择、持续维护。勿在浮沙筑高台。

a、开源软件安全问题需要高度重视

  • 开源软件应用广泛且不可避免
  • 很多场景缺乏软件的安全责任主体

b、基础软件安全可信更刻不容缓

  • 相比应用软件,OS、DB 等基础软件安全影响更大
  • OS、DB 软件更新周期长,安全任务要求高

c、开源软件安全风险需要从多方面分析

  • 社区、代码管理、开发团队
  • 标准、规范、政策
  • 安全可信标准
② 开源后门植入风险

这类攻击是将恶意代码直接注入到开源项目的存储库中,攻击方式包括:

  • 从项目维护人员那里窃取凭证;
  • 在公共存储库中发布项目新版本;
  • 向包含恶意代码的项目中提供 pull requests;
  • 篡改开源开发人员工具,将恶意代码注入下游应用程序。这类攻击方法一般是在上游“设置陷阱”,然后通过供应链将漏洞植入到数千家企业的代码库中,向下游发起攻击。SolarWinds 后门攻击事件和美国明尼苏达大学 (UMN) 为开源 Linux 项目提交后门代码,为典型开源后门植入类事件,此类风险为被动开源安全风险,后门植入隐蔽且不自知,可造成个人、企业和国家通过开源后门植入代码被监控,严重威胁信息安全。

案例二:SolarWinds 后门攻击事件波及全球重要科技发达地区的敏感机构

  • 事件时间线:2020 年 12 月 13 日,美国网络安全公司 FireEye 发布分析报告称,SolarWinds 旗下的 Orion 基础设施管理平台的发布环境遭到黑客组织入侵;
  • 影响分析:在全球多个地区检测到攻击活动,主要针对北美、欧洲、亚洲和中东的一些政府、咨询、技术公司。
  • 攻击手段:黑客对文件 SolarWinds.Orion.Core.BusinessLayer.dll 的源码进行篡改添加了后门代码,该文件具有合法数字签名会伴随软件更新下发。后门代码伪装成 Orion OIP 协议的流量进行通信,将其恶意行为融合到 SolarWinds 合法行为中。
③ 开源隐私信息泄露风险

这类风险是指个人、组织或企业对外开源项目、贡献代码时无意或有意将未经隐私信息清洗的代码,公开到托管平台上去,导致涉及个人或企业隐私的信息被迫公开。此风险涉及信息类型众多,严重威胁个人财产和隐私安全。

案例三:某连锁酒店信息泄露波及上亿条信息

  • 事件时间线:2018 年,某连锁酒店用户数据在暗网公开售卖,数据涵盖大量敏感涉密信息;
  • 事件影响:涉及酒店 10 余家。据统计,此次泄露的数据数量总计达 5 亿条,其中,酒店官网注册资料信息共 53 GB,约 1.23 亿条记录;入住登记身份信息共 22.3 GB,约 1.3 亿条;酒店开房记录共 66.2 GB,约 2.4 亿条;
  • 利用手段:据分析此次事件源于内部人员在 Github 上传一个开源项目,该项目源码中包含酒店的服务器及数据库 IP 地址,路径、用户名和密码及网站密钥等机密信息,这些隐私信息被黑客利用导致大量数据泄露。

三、业界开源安全实践洞察

1、开源社区安全

主流社区安全能力建设从突破单点安全技术,逐步发展到打造安全基础设施、供应链安全、整体安全架构的系统化防护体系

1)业界主流社区从单点安全特性逐步向整体安全架构、供应链安全和安全基础设施等系统化建设方向发展。

2)案例:Google 在发布 AOSP 开源项目的时候,更多的使用的是传统的 Linux 安全能力。随着对安全的认知及安全观加强之后,开始创造一些原创的安全能力。

  • Linux:项目诞生(1991)--- 支持 SELinux(2003)--- Syzkaller Fuzz 关键(2016)---- KSPP 安全项目(2017)--- 任命供应链(2020)--- Sigstore 签名服务(2021)
  • ASOP:项目诞生(2008) --- 漏洞致谢(2009)--- 支持SEAndroid(2014)---- 原生支持 Fuzzing(2017)--- 奖励开源软件安全研究(2019)
分类openEuler 等社区可借鉴点
安全架构单点安全技术---- 整体安全架构
供应链安全自身安全----上下游供应链安全
安全基础设施(漏洞挖掘)单个漏洞奖励 ----漏洞挖掘等基础设施
安全基础设施(安全开发)单一构建工具支持 ----安全开发基础设施支持

3)围绕开源件健康度和依赖度评估、漏洞感知与修复等系统化建设,是供应链安全发展的重点。

① 开源软件存在的安全薄弱点:

  • 缺少安全 Metadata(缺乏文档、LICENSE、反馈渠道、维护状况等)
  • 未做到默认安全(使用不安全的加密算法、协议、设计等)
  • 软件依赖链不明确(较难获知依赖链的安全状况)

② 开源软件漏洞风险:

  • 漏洞库信息缺乏(具体版本漏洞信息不准确)
  • 代码质量参差,存在漏洞风险(潜在漏洞数量多)

③ Google 安全实践:

  • 2020 年布局 OpenSSF 社区,构建开源社区安全能力量化评估体系
  • 2021 年发布 OSI(Open Source Insights),建立开源软件依赖链信息库
  • 2021 年发布 OSV(Open Source Vulnerabilities),建立开源软件漏洞信息库,支持开源版本漏洞查询
  • 发布 OSS-Fuzz 平台及 Patch 奖励项目,提供 Fuzz 算力和修复资源,增强开源软件漏洞挖掘力量

2、开源选型一

Google 布局 OpenSSF 社区,制定开源软件安全评估体系,推动开源项目安全状况改善

对社区安全有评分,对社区的活跃度也有评分,从开源软件的角度,评分越高,也就意味着即使有一些开源软件漏洞,也会很快被软件开发者发现并修复。通过这些度量,可以让开发者或者开源软件使用方能理解这个社区是不是舍得被信赖,是不是一个可信的开源软件提供商,或者在选型时可以有的放矢地解决一些选型问题。

1)Security Scorecards 项目:

  • 对开源项目的安全情况进行自动分析;
  • 推动改善关键项目的安全情况;
NameDescription
Binary-ArtifactsIs the project free of checked-in binaries?
Branch-ProtectionDoes the project use Branch Protection?
CI-TestsDoes the project run tests in CI, e.g. GitHub Actions, Prow?
CII-Best-PracticesDoes the project have a CII Best Practices Badge?
Code-ReviewCII-Best-Practices
ContributorsDoes the project have contributors from at least two different organizations?
Dependency-Update-ToolDoes the project use tools to help update its dependencies?
FuzzingDoes the project use fuzzing tools, e.g. OSS-Fuzz?
MaintainedIs the project maintained?
Pinned-DependenciesDoes the project declare and pin dependencies?
PackagingDoes the project build and publish official packages from CI/CD, e.g. GitHub Publishing ?
SASTDoes the project use static code analysis tools, e.g. CodeQL, SonarCloud?
Security-PolicyDoes the project contain a security policy?
Signed-ReleasesDoes the project cryptographically sign releases?
Token-PermissionsDoes the project declare GitHub workflow tokens as read-only?
VulnerabilitiesDoes the project have unfixed vulnerabilities? Uses the OSV service.

2)Criticality Score 项目:

  • 制定社区打分标准;
  • 筛选开源世界的关键项目列表;
  • 推动关键项目的安全改进;
ParameterWeightMax thresholdDescription
created_since1120Time since the project was created (in months)
updated_since-1120Time since the project was last updated (in months)
contributor_count25,000Count of project contributors (with commits)
org_count110Count of distinct organizations that contributors belong to
commit_frequency11,000The average number of commits per week in the last year
recent_releases_count0.526Number of releases in the last year
closed_issues_count0.55,000Number of issues closed in the last 90 days
updated_issues_count0.55,000Number of issues updated in the last 90 days
comment_frequency115The average number of comments per issue in the last 90 days
dependents_count0.5500,000Number of project mentions in the commit messages

3、开源选型二

OSI 项目提供统一的软件及依赖分析工具,结合高质量的数据,更好的洞察软件的健康度

1)2021 年 6 月,Google 发布 OSI(Open Source Insights)开源软件资产库,应对开源安全及合规挑战。其信息包括:安全建议、合规信息、软件依赖关系、安全及修复建议、OSSF Scorecard 等,软件组合分析能力需要积累的数据资产。

2)目前涵盖的开源资产:1.73M 的 NPM Packages;678k 的 Go Modules;418k 的 Maven Artifacts;68k 的 Cargo Creats; NuGet、PyPI 的数据资产待发布。

3)借鉴:持续优化开源软件组合分析工具,构建漏洞精准定位和开源软件依赖解析能力,可视化开源软件的健康度

4、漏洞挖掘

Google 构建并开放 OSS-Fuzz 平台、Github 收购集成 CodeQL 等静态开源漏扫工具,赋能开源软件仓漏洞发掘

1)Google 开放大规模 Fuzz 平台,助力开源仓持续 Fuzz,发掘和验证漏洞:

  • 开放 OSS-Fuzz平台,将内部构建的 ClusterFuzz 能力开放给开源社区
  • 到 2021 年已被 500 个开源项目使用
  • 为开源软件提供集群服务器,以及自动化跟踪闭环的能力

2)Github 集成静态开源漏扫工具,赋能开源仓安全扫描、漏洞变种分析:

  • Github 收购 CodeQL 工具,免费开放给开源代码仓使用,使用 codebase 查询语句进行变种分析,消除同一类型漏洞
  • Github 集成 sonarcloud 等静态安全工具,助力开源仓持续集成安全扫描

3)借鉴:构建自己的开源软件集群Fuzz平台、优化静态安全扫描工具,提升挖掘开源软件漏洞的能力,减小开源漏洞攻击风险。

5、开源漏洞管理

Google 提供漏洞修复奖励加速开源软件漏洞修复;构建并开放开源软件漏洞数据库 OSV,帮助开源软件使用者确认其版本是否存在漏洞

1)Google 提供漏洞修复奖励计划:

  • 鼓励开源软件维护者修复其维护的开源项目中的漏洞
  • 吸引第三方人员帮助修复开源软件漏洞
  • 通过Fuzz对修复补丁进行验证

2)Google 构建并开放开源软件漏洞数据库:

  • 提供 API 给开源软件使用者查询使用版本是否存在漏洞
  • 确认开源软件漏洞的引入和修复 commit 信息
  • 从多个源获取漏洞信息,包括 Google 自己的 OSS-Fuzz
  • 目前,还没有将漏洞关联到 CVE 信息

6、开源供应链危机应对

面向全生命周期,采用工具+管理+安全增强特性等多方式组合看护供应链安全

整个研发流程之外,还有很多问题,比如,有一些恶意的开发者往社区投毒,近几年供应链安全投毒的安全事件逐渐增多,部分事件如 SolarWinds 影响巨大。

1)案例 1:明尼苏达大学 Linux 内核投毒。

美国大学教授 “故意” 向 Linux 提交含 Bug 代码,内核管理员 “封杀” 明尼苏达大学。 他通过 Linux Curl 做安全实验,通过机器生成一些不安全的代码和函数,然后不停地提交给社区,这些不安全地代码和函数如果不通过某些自动化工具,很难被识别。如果是面对一些不负责任或者安全意识不高或者相应专业能力不强的审核人员审核,很容易通过。当时很多新闻报道,最终虽然没有产生严重的后果,因为这个代码马上被发现退回。 启示:如果不使用自动化工具或者使用更好的安全方法,面对所谓的投毒的恶意代码提交者,很难防范这个风险。

2)案例 2:SolarWinds Orion 攻击事件

攻击者篡改 SolarWinds 更新包代码将恶意代码插入 DLL 组件(SolarWinds.Orion.Core.BusinessLayer.dll),该恶意动态链接库是攻击者主要篡改代码部分,具备执行各类攻击插件以及进行 HTTP后门通信等功能。

因直接攻击代码仓库,且代码写得高度整洁,被正常构建具备合法的数字签名证书。 带有后门的更新包在官网上架: 更新包名称为:CORE-2019.4.5220.20574-SolarWinds-Core-v2019.4.5220-Hotfix5.msp。 该更新包具有 SolarWinds 合法的数字签名证书客户基于信任精神从官网下载和安装该恶意更新包。

HTTP 后门代码通过域名生成算法 (DGA),构造和解析 avsvmcloud.com 的子域,观察到的部分恶意域名。

  • 一旦通过对这些 DGA 域名(CNAME)进行解析,并成功检索到对应的域名,其会使用这些对应的域名进行 C2 通信;
  • 进行 C2 通信过程中,攻击者会根据攻击目标,从而发放不同的控制命令,从而执行对应的恶意代码功能。该后门代码会接收制定指令,指令包括收集系统信息、运行指定任务、写删读文件等等,通过写文件可以执行其他功能模块程序。

3)案例 3:SolarWinds Orion 攻击事件

  • XCode 官网下载慢,使攻击者有可乘之机,提供无 Hash 校验码 (Xcode 6.4 版本) 恶意下载源。
  • MacOS 上存在允许任何来源安装的选项。低版本 Gatekeeper 恶意软件检测机制可被绕过。

7、开源软件安全管理热点问题

总结:当前开源软件热门的安全管理事件,都是因为安全流程的疏忽,或者是没有使用相应的安全自动化工具,或者过多的让低技能甚至是不负责的代码审核者去审核这些代码而导致的各种安全问题,这些安全问题最终会因为开源软件的依赖和组件漏洞的关联导致广泛传播,造成企业和个人的一些资产和信息的损失。

1)开源软件漏洞由 POC 披露到 NVD 首次公开时间长达 11 年

  • CVE-2009-4067 Linux 内核 USB缓冲区溢出漏洞 2)最主要的缺陷类型为:跨站脚本、内嵌的恶意代码、资源耗尽、信息暴露等

3)软件代码/制品仓中安全风险态势严峻:

  • Maven (Java) 数据量达 650 万+,Nuget (.NET) 累计下载 930亿+,Rubygems(Ruby)累计下载 712 亿+,PyPI (Python) 用户 49万+,其余还有 Composor (PHP)、npm (JavaScript) 等。
  • 2020 年新增漏洞数为 3,426,环比去年增长 40%;近 3 年增长速度呈上升趋势,2020 年新增漏洞数是 2015 年的 4.48 倍。
  • 对 Maven、NPM、PyPI 等仓库的删除、投毒攻击持续发生 4)组件漏洞存在广泛的依赖层级传播

四、企业修复开源软件漏洞实践

1、开源生态中与开源安全相关的组织

实际上整个开源生态是以用户为中心,整个开源社区的安全需求的反馈大部分来自于用户。

其次就是开源基金会,比如 openSSF,很多大型的社区,都会成立一个安全委员会,来构建一些安全的基础设施、标准及流程,包括上报漏洞、披露漏洞、解决漏洞等的标准化流程。

社区的开发者为开源软件安全提供主要贡献,因此开发者们需要社区提供一些安全设计及编码规范。

另外就是软件的提供商或发行商,比如 SUV,将开源的成果、项目进行包装,然后提供给用户。

最后就是政府机构,为开源安全提供一些政策和协调,比如社区的贡献者发现一个漏洞之后,首先应该通过什么方式上报?先上报给社区的安全委员会还是先上报给政府?原则上是需要上报给社区里类似安全委员会这样的组织,然后安全委员会根据原有的流程上报给对应的用户。

2、企业如何修复开源软件漏洞?

  • 开源软件漏洞通过问题单跟踪处理,根据漏洞的风险等级,产品会按照漏洞相应SLA要求进行修复。在研发阶段,高风险开源软件漏洞必须在产品版本发布前修复;中低风险漏洞经过实际风险评估后,可以遗留到下个补丁或版本修复,但是修复时间必须符合企业漏洞相应 SLA 要求;
  • 产品 GA 以后,所有开源软件漏洞都必须按照企业漏洞相应 SLA 要求修复。

3、建立从开源漏洞发现到用户升级的漏洞 E2E 处理流程机制

主要分为三个部分:上游的供应商、下游的用户以及中间的企业。供应商发现漏洞之后,会通知到企业;其次公司这边也会通过产品测试发现一些漏洞;再就是外部渠道上报的一些漏洞,比如通过漏洞奖励计划收上来的漏洞;再有就是用户在使用过程中受到攻击,运维人员也会将这些漏洞反馈给企业。从这些渠道里收集到的漏洞,会在企业内部进行评审和备案,收集漏洞之后,建立相应数据库来维护这些漏洞,比如哪个软件的哪个开源软件的哪个版本有什么样的漏洞,我们称之为为“漏洞 item化”。在维护产品的开源软件时,需要通知涉及的研发团队,由他们来制定漏洞处理方案,再同步到用户做漏洞的闭环处理。

4、openEuler 社区漏洞处理能力建设实践

1)openEuler 社区漏洞处理流程

参照业界漏洞管理最佳实践:CVSS、CPE、CVRF 、ISO/IEC 29147和 ISO/IEC 30111 制定 openEuler 社区漏洞处理流程

社区里的安全委员会都是由相关安全专家来进行组织运作,首先可以通过邮箱给安全团队上报漏洞,安全团队接收漏洞之后,对漏洞进行评估打分,分成高中低的级别,同时对漏洞进行补丁开发、补丁验证,在 NVD 获得 CVE 之后,可以选择受限披露。如果漏洞在下游厂商或用户,在还未打上补丁之前就对外进行公布,这种行为存在很大风险,黑客很容易通过漏洞进行攻击,因此做受限披露,通知下游的厂商用户做补丁的修复或规避,最后会发布正式的安全通告,对应到 CVE。

2)openEuler 社区漏洞处理机制

① 漏洞感知
  • Vtopia 漏洞感知系统
  • 加密邮件上报 (openeuler-security@openeuler.org)
  • 漏洞奖励计划
② 漏洞分析、评估和验证
  • 漏洞原理分析
  • 漏洞严重等级评估(Critical /High /Medium /Low)
  • 漏洞验证和重现
③ 漏洞修复
  • 漏洞修复
  • 私有披露(distirbutors-announce@openeuler.org)
  • 漏洞修复验证测试
④ 漏洞披露
  • 网页版 SA
  • 网页版 CVE
  • CVRF 格式 SA
  • 绿盟漏洞漏扫系统
  • 订阅邮件推送 (sa-announce@openeuler.org)

3)openEuler 社区漏洞处理流水线

主要流程:

  • 软件包及版本信息同步到 vtopia
  • 漏洞推送到 openEuler 社区建单跟踪
  • 漏洞解决进展监控
  • 漏洞修复与发布

4)openEuler 社区漏洞管理 CVE-Manager

① 漏洞提单

② 漏洞分析提醒

③ 漏洞分析结果检查

④ PR 关联检查

a、人工提单,信息补全

  • 人工创建 CVE,只需要填 CVE 编号和软件名称,可通过 /get-cve 补全 CVE 信息。

b、补丁辅助查找

5)openEuler 社区漏洞发布平台

① 安全公告:补丁维度

② CVE 公告:漏洞维度

③ CVRF 格式 SA:机器可读的 SA

6)openEuler 社区漏洞看板

① 漏洞感知详情

② 漏洞修复 SLO 达成率 Top20 软件

③ 漏洞修复详情

7)openEuler 社区漏洞奖励计划方案

openEuler 通过漏洞盒子平台对 iSulad/A-Tune 开展奖励计划

  • 厂商提供奖金:华为
  • 第三方众测平台运营奖励计划:漏洞盒子
  • 开源社区接收和处理漏洞:openEuler 社区
  • 由华为提供资金,第三方众测平台公开发布开源社区奖励计划。
  • 安全研究者邮件提交漏洞给社区。
  • 社区通过邮件与安全研究者沟通最终确认漏洞等级,漏洞奖金。
  • 社区将将该漏洞标题,漏洞等级,漏洞奖金,提交者邮箱等信息邮件回复漏洞盒子。平台方将核对确认后,分配专属客户联系安全研究者,沟通奖金事宜,及协议签订。如无平台账号,引导其在漏洞盒子注册账号,用以发放奖励。
  • 社区发布补丁公告,通知漏洞盒子与安全研究者后,漏洞盒子发放奖励到该安全研究者平台账号。安全研究者随时可以在平台发起提现操作。提现申请需要在漏洞盒子平台绑定银行卡等信息。
  • 漏洞盒子财务部每月 10 号打款,并完成相应个税缴纳工作。

由三方平台负责奖励计划的运营和支付,社区负责漏洞处理和奖金评定,社区不保存白帽子信息,无隐私泄露风险。

五、全球开源安全防范措施愈加严格,我国尚处于探索阶段

1、全国开源安全发展较早,多层面合力应对开源安全威胁

1)开源安全防范政策层层加码

多国实施开源漏洞悬赏计划提高开源项目安全性:

  • 欧盟 “FOSSA项目”(2015 年):定期提供悬赏奖金,支持常用开源软件漏洞挖掘奖励;
  • 美国“开源软件代码测试计划”(2006 年):针对大量开源软件进行安全隐患的筛查和加固,截至 2017 年 2 月,累计检测各种开源软件 7,000 多个,发现大量安全缺陷;
  • 英国 “开放代码的安全注意事项指南”:英国政府认为开源可以在协作开发中创建更好的代码,并提高与用户的接触,但同时以要遵循指南中注意事项保障开源代码安全。

2)开源安全组织探索开源社区安全保障

2020 年 8 月 Linux 基金会成立开源安全基金会(OpenSSF):

  • 设立一个理事会 (Governing Board),一个技术咨询委员会 Technical Advisory Council);
  • 截至 2022 年 4 月,该基金会共拥有 74 位会员,包括 25 位付费会员 41 位普通会员和 8 位协会会员。目前基金会共托管 2 个主要开源项目,并形成 5 个工作组推进开源安全治理;
  • 开源安全基金会 (OpenSSF) 最佳实践徽章提供为开源软件提供安全证明。徽章的使用者可以快速评估哪些开源项目遵循最佳实践,因此更有可能生产出更高质量的安全软件。

3)开源社区构建安全开发衡量标准

  • Alpha-Omega 项目:通过直接参与软件安全专家和自动化安全测试来改善开源软件 (OSS) 的安全状况;
  • Siastore;
  • SLSA。

4)头部科技公司开源安全防范体系建立较早

对内成立开源管理办公室 (OSPO) 管理企业:

  • 在 2,700 名研究参与者中,超过一半 (52%) 拥有正式或非正式开源项目办公室,或者他们的公司计划创建一个计划;
  • 对外积极推动开源安全生态发展:微软、谷歌.….…
  • 头部科技公司致力于开源重要领域安全类开源项目:微软、谷歌、IBM......

2、我国政府、企业和个人三管齐下应对开源安全风险

1)多政策提及开源安全防范要求

《关于规范金融业开源技术应用与发展的意见》:

  • 2021年10月20日,人民银行办公厅、中央网信办秘书局、工业和信息化部办公厅、银保监会办公厅、证监会办公厅联合发布;
  • 意见提及坚持安全可控。金融机构应当把保障信息系统安全作为使用开源技术的底线,认真开展事前技术评估和安全评估,堵塞安全漏洞,切实保证技术可持续和供应链安全,提升信息系统业务连续性水平;
  • 意见支持金融机构制定应急处署预案,应对开源技术潜在漏洞后门及闭源停服等突发情况。

《十四五”软件和信息技术服务业发展规划》:

  • 2021年11月30日,工业和信息化部印发;
  • 规划提出在发展开源生态的同时需要开展开源治理工作,对知识产权进行托管,建立开源软件知识产权基金等,开源安全治理部分尚未单独说明;
  • 在开源安全层面,建设国家和行业级别开源社区的安全审查体系,保证各行业广泛使用的重要开源产品及技术服务的安全性;以国家规育制度和行业自律公约等形式规范开源软件的治理工作,推动公正的中立第三方代码托管平台,保证开源服务的安全和可信的运行态的服务试用。

2)开源安全组织处于探索阶段

开放原子开源基金会关注开源项目安全漏洞治理:

  • 开放原子开源基金会openX研究工作组下设的目标是构建一个公益性的开源研究机构汇聚领先开源人才和智力;同时以一个开放、透明的社区的形式,以跨学科的视角,将 “开源开发”、“开源治理”、“开源运营” 等研究融为一体,持续输出 “方法”、“技术”、“工具”、“规范” 等前沿知识性成果;
  • 下设开源项目安全漏洞治理子工作组通过专题小组的研究和产出,帮助更多的企业和组织提升安全漏洞治理的能力,提升企业和组织的生产力和竞争力,为企业和及其开源项目保驾护航。

中国信息通信研究院创建 “可信开源” 品牌,探寻开源安全标准化工作:

  • 标准制定方面形成包括企业级开源治理、开源供应链、开源工具、开源项目和社区在内的可信开源治理体系,为企业规范开源治理,降低开源风险提供参考;
  • 白皮书撰写方面,继续深入产业研究,正在编写包括《开源生态白皮书》在内的多本开源领域白皮书, 树立行业标杆;
  • 社区建设方面,继续扩大金融行业开源技术应用社区规模,吸纳50余家金融成员探讨金融行业开源痛点问题;
  • 公共服务方面,建成综合性开源治理平台,为企业和个人提供开源风险检测和开源生态监测公共服务。

3)开源社区安全开发意识有待加强

国内部分活跃度高的开源社区陆续设立开源安全漏洞治理组保障社区安全治理:

  • MindSpore 社区建立单独漏洞管理团队,协调漏洞从接收到披露的整个过程,包括:漏洞收集、漏洞跟踪处置、负责任的披露;
  • Open Harmony 社区建立安全问题响应组,发布安全问题处理和发布流程,通过安全漏洞例行;扫描、内部上报和外部上报等方式及时发现开源安全问题,安全问题分发员完成对新问题的确认,修复负责人将组织修复团队,并会根据问题的严重性,开发需要的时间和发布经理反馈的版本计划,综合自己最佳的判断来制定问题的修复计划;
  • FATE 设立安全响应委员会/安全专委会。

4)金融与出海企业开源安全防范体系落地较早

  • 涉及海外业务企业,关注开源安全隐患颗粒度细分至代码片段级别;
  • 涉及海外业务企业,追求快速漏洞相应速度。

六、开源安全防范需兼顾上游开源社区与下游开源用户

1、开源社区需建立安全开发规范

1)对社区运营的开源软件提供安全开发规范指引;

2)进行开发过程全流程安全扫描与识别;

3)开源软件运营安全需持续关注。

2、用户企业需建立开源安全问题修复措施

1)安全漏洞和后门植入需按照轻重缓急应修尽修

a、漏洞评估与解读首先为用户企业提供漏洞全貌。 b、收影响组件分析为用户企业梳理漏洞修复优先级:

  • 通常单个组件漏洞职责单一的,这类漏洞较易处理;
  • 单个组件是框架类的处理起来比较麻烦;
  • 单个组件升级后相应关联组件或底层中间件需同步升级,处理中比较麻烦甚至可能需要修改程序代码;
  • 单个组件有漏洞,但相关程序代码未涉及的情况较易处理;
  • 单个组件含有另外一个组件,但未使用另外一个组件功能的较易处理。 c、修复方案制定应结合用户企业实际情况实施。

2)隐私信息泄露防范需做好出口管理

  • 开源运营方应对开源软件产品及服务建立隐私信息安全监控防护机制;
  • 在使用开源代码时,开发者应注意各类语言的开发习惯;
  • 对于贡献开源技术的企业贡献者,也应遵循保护核心代码、隐私信息保密。

七、开源安全发展展望

1、国家层面

1)建议国家和行业监管部门继续完善和制定开源安全相关的政策,建立长效工作机制,搭建国家级/行业级开源安全风险分析和威胁情报收集平台。具备系统化、规模化的软件源代码缺陷和后门分析、漏洞分析、开源软件成分、风险分析及情报收集等能力,及时发现和处置开源软件安全风险;

2)对已知开源成分及依赖链条漏洞威胁情报的实时监控跟踪机制,搜集多维度多渠道的开源威胁情报;

3)针对企业、机构已有的开源成分清单和图谱,在第一时间内将有效的开源威胁情报同步给相关责任人。

2、组织层面

1)建立开源软件安全标准化体系,尤其需要强化开源组件、安全开发和事件外置等方面的标准化工作;

2)立足新形势、新趋势,重点围绕网络安全法、数据安全法、关键信息基础设施安全保护条例等法律法规要求的落地实施,统筹规划国家开源软件安全标准体系,用于指导开源软件安全标准的制定和相关标准的修订工作;

3)建议强化开源软件安全标准的应用实践工作:

  • 选取典型的开源软件安全保护场景,开展标准适用性和实施效果评价;
  • 是完善开源软件安全标准研究、宣贯和应用推广机制,和企业、高校、科研院所建立“产学研用”的一体化联盟,共同攻关开源软件安全标准化难点。

3、 个人和企业层面

1)合力共建开源创新生态环境,同时通过学习借鉴国外更完善的基金会运行模式、组织机制和法律制度,了解开源生态运作机制,定期开展开源安全风险意识培训,不断提高自身开源代码安全开发能力;

2)积极配合国家监管部门、研究机构、标准组织等出台开源软件安全相关的政策、标准,共同打造安全可信的开源生态环境。

开源生命周期管理

​ 开源软件的生命周期管理,从本质上来说,和开源软件使用规范中,所陈述的开源软件供应链管理有一定的区别。开源软件供应链管理更多讲述的是开源软件本身的引入、使用以及维护,这是开源软件本身端到端的流程。

​ 但是开源软件的生命周期管理,跳出了开源软件本身的角度看问题。众所周知,开源软件使用是集成在产品代码当中,开源软件跟产品息息相关,产品的生命周期问题会导致开源软件的生命周期问题,所以这门课程阐述的是:如何从产品角度看开源软件的生命周期管理。

一、软件工程课程框架

在企业做产品管理阶段遇到复杂的软件工程场景下,如何做好开源的管理?

​ 单看开源软件的一些风险,比如安全、合规等,只要有开源的基础意识,包括开源管理能力、工具等,通过组织就能解决该问题,或者消减风险;但如果产品具有各个不同的模块,甚至不同的组件,由厂商整体打包后向客户分发产品或提供服务,尤其在制造业或金融业,具有成套硬件和软件,包括由云服务仪器提供的这类产品,以上这种情况中产生的开源安全和合规问题,会不可避免受到不同部件的限制,比如硬件从生产到交付客户使用,但最后却无法工作,或者过时——已经走出生命周期的过程了;硬件的使用周期很长,一台电脑可能十年都不换,但运行在电脑内的操作系统,比如 Windows 7 却早已退出其生命周期的时间,由此可见,软件的生命周期比硬件的生命周期时间要短的多;而建立在操作系统之上的应用软件(Office、微信等),在新版本覆盖掉旧版本后,那么有个问题就产生了:上层软件平台、软件组件都是如何修复的呢?软件平台和软件应用,对软件维护的要求,包括运行时间的要求、投入的人力资源都不一样(因为生命周期不一样)。因此如何协同处理相关安全漏洞问题以及合规问题,就是开展全生命周期需要解决的问题。

​ 在现代化的软件开发过程中,怎样通过软件的配置管理,统一化管理开源、产品组件平台等,用相应的软件开发工程体系(比如构建工程、测试工程、发布工程)解决问题,就是开源的生命周期管理。

1、现代化软件开发生命周期管理

从生命周期角度,探讨如何持续构建高安全产品的研发能力

① Why:从客户问题、产业现状、企业竞争力三个视角看生命周期面临的挑战,转变对生命周期的意识。

② What:优选解决优生问题,生命周期解决死的问题。从合同/产品/单板/软件版本/平台/工具/开源软件各层识别挑战。

③ How:以某产品实际面临问题为实战,探讨如何做生命周期管理,谁来做,怎么做?

2、配置管理

了解配置管理的 why、what、how。

① Why:配置管理对于产品的意义?

② What:配置管理存在的问题是什么,产生的原因是什么?

③ How:解决这些问题的方法是什么?

3、构建工程

1)了解构建工具的管理要求、业界高阶构建工具的主要功能与优劣、构建环境封闭的要求

2)实战演练:通过对 demo 系统的实操加深理解

二、认识软件版本生命周期所面临的挑战

1、发现身边的安全隐患

​ 在软件开发过程中,不论是使用 Bugzilla,还是使用开源社区内的 issue、PR 来进行漏洞跟踪,总之每天都会收到软件内爆发的漏洞,然后再给漏洞打上补丁,这已经是一个常规操作。如果只是构建单一的软件,那每天可能只有 1~2 个漏洞,但对于产品来说,产品里会有各种各样组合性软件,一天收到几百个漏洞单是件很正常的事情。如果你是项目经理,或者软件开发经理,明天产品发布,突然收到 100 个漏洞单,在这种情况下,你会怎么处理?

  • 先发布?
  • 发布之后怎么解决或者是需不需要解决?
  • 客户是否认可?

​ 如果只是站在我们自己的角度上看待这个问题,可能第一时间就想把这 100 个漏洞找出来,一个个打上补丁。理论上需要这样做,因为漏洞第一时间肯定是要响应,但是否考虑过一个问题:这个 100 个软件时分布在哪些组件/应用软件里?可能这个 APP 有 50 个开源软件有漏洞,另外 50 个可能在操作系统里,比如安卓服务里有20 个漏洞,手机里统一安装这种服务,交付客户之后,还是有 20 个漏洞,甚至可能不在安卓系统里,而是在硬件里。因此这 100 个漏洞修复,如何满足第一时间、安全应急、是否可修复以及是否能落地等要求,就需要通过生命周期管理和软件工程来解决。

2、客户需要的是持续、系统的安全

序号产品代码质量问题从安全视角重新理解
1来源可靠用的是真的
2编码安全规范:1. 敏感信息(比如公网 IP);2. 危险函数和调用;所有代码需要代码级安全
31. 片段使用;2. 老软件;3. 一个开源软件多版本;4. 多平台产生多副本;5. 多平台自身副本;扩大了攻击面
4组件生命周期覆盖软件版本生命周期持续有人维护
5所有公开开源软件漏洞都在代码层面修复真的改了
6现网升级现网及时补洞

结合多年与客户交流总结的软件工程问题,发现客户更关心的一些方面在于:

​ 首先就是产品代码质量问题,包含是否容易产生漏洞?来源是否可靠?使用的软件是从官网下载还是第三方下载?是否被别人做了后门等问题。

​ 其次,代码是否遵循编码规范问题,有些企业聘用一些员工,这些员工可能有编码经验,但这并不代表这个员工的编码水平很高/代码写得好,因此很多公司相应会有些编码规范,以降低代码里的安全问题,并且要求开发者写代码时需遵守这些规范,比如不能有魔鬼数字、写代码要空行空格、变量需写清楚具体含义等。

再次就是一些会扩大攻击面的问题:

1)片段使用:当我们引用其他人写的软件的一些片段,这看似稀疏平常的事情,但我们不知道是,拷贝的这份代码里面可能有个很大的漏洞,而因为我们没有这个软件的具体版本信息及来源信息,导致在做代码检查时,并未能察觉出这个漏洞。

2)老软件:不论是开源软件,还是自己写的软件,所有软件更新迭代的速度都非常快,基本至少三个月就会更新一个版本,新版本一定会修补之前老版本的漏洞或者安全问题,如果一直使用老软件版本,会使得漏洞/安全问题像滚雪球一样越滚越大,直到无法修复。

3)一个开源软件多版本:比如使用一个开源软件,不仅使用一个版本,还可能使用多个版本——可能是因为这个版本有兼容性问题,为了快点上线,顾不及兼容性问题,所以使用多个版本,总之能运行就可以。而这样会导致什么问题呢?每个版本都有各自不同的许可证,有各自不同的安全问题和漏洞,如果不做版本的归一,而是放任自由多版本,鱼龙混杂,当这个多版本软件经过 4~5 年的售卖,雪球越滚越大,最后导致信息无法跟踪,不清楚这个版本由谁引入,又是谁对这个版本负责,软件管理成了另一大难题。

4)多组件产生多副本:比如一个片段引用,a 组件引用了,b 组件也引用了,那 a、b 组件如何协同修复片段漏洞?所以即使能识别片段代码内有漏洞风险,但因为片段集成的地方太多,也会导致最后完全无法跟踪漏洞并进行修复;

5)多组件产生多副本:片段本身有很多副本,片段集成之后的软件也不可能是单一的代码段,还可能集成了其他软件(一代软件),如果主软件有一个版本,一代软件有多个版本,一代软件的一代软件又有多个副本,最后形成软件灾难,变成难以维护的软件垃圾,无法用手段来进行管理,这时就很容易受到攻击。

​ 这些也是在软件开发过程中会面临的很现实的问题:不论软件如何开发,越开发攻击面越大。因此站在开发者,或者企业的供给侧角度来看问题,需要做好以下这些方面:

​ ① 用的软件是真的、可靠的,代码是安全的,尽量避免扩大黑客的攻击面,保障系统整体上是安全的;

​ ② 但这样还不够,客户看到的可能不是这些问题,客户更希望拿到的产品,从生产到发布再到最后生命周期 结束退出应用,整个过程都是有人持续维护,也不是单一的组件问题,而是整体一套系统;

​ ③ 及时跟踪开源软件漏洞,确保漏洞真的被修改,而且是改的很完全;

​ ④ 以及环节出现漏洞时,应有一个能够及时响应的机制,快速定位到漏洞,在客户发生之前解决问题。

3、产业现状:开源社区既是创新沃土,又易被黑客利用

​ 开源软件缩短了产品上市时间、提升了创新能力,大家能用很少的人力、资源以及时间,把新技术移植到产品中,使产品获得收益的时间越来越快,收益越来越多,但也因为开源中的代码是透明且易获取,当我们在研究代码如何编写以及使用时,黑客同时也在研究如何攻破,因此开源社区和开源软件都具有两面性:既是创新沃土,又易被黑客利用。

​ 根据统计,整个信息行业大约有80%的代码都使用了开源软件,一旦爆发漏洞,像 OpenSSL 这种高危漏洞,系统就很容易被攻破。所以开源软件的安全观需要上升到整个产品的安全观,这也是开源软件的生命周期管理会上升到产品的生命周期管理这个维度的原因。

1)开源社区是创新沃土,广泛应用于产品

​ 在云计算领域,大约 80% 甚至 90% 的软件都是开源软件,由此可见,基于云计算构建的金融业、制造业、科技行业等,所有的服务已经被开源软件所包围,一旦开源软件被大量引入系统之后,经过长期的开发,开源的硬件、软件、操作系统、组件以及 APP 等技术栈都会被开源软件所取代,这种情况下,不得不从整个生命周期和整个软件栈的角度来看软件的风险。

2)开源的漏洞易被黑客利用,漏洞一旦公开必须快速在产品修复

​ 很多开源社区非常健康、欣欣向荣,一旦出现漏洞立马有人进行修复,同样也有些开源社区——技术不错、idea也很好,但这个开源软件的维护者/贡献者人数特别少,寥寥无几,在这样的社区里提的问题,可能需要等上一个星期甚至一个月,才会有人答复,当爆发严重的漏洞时,若无人及时修复,有些黑客可能就会利用这个漏洞来做些事情,因此如果使用该社区的技术,可能需要长一个心眼。

​ 当年 OpenSSL 这个心脏滴血漏洞还未爆发时,根据之前的一些统计数据,大约 70% 的 CC 认证功能及系统、80% 的网络加密传输系统等都在使用 OpenSSL 这个软件,如此大的使用率让大家都认为该社区非常安全健康,开发者的维护应该很积极,而事实上,在这个心脏滴血漏洞爆发前夜,社区的维护者,包括项目负责人,因为没有资金支持运作,正在讨论这个社区是否还能继续下去、是否需要解散的问题,导致社区爆发漏洞之后,长时间无人修复,仅能依赖于企业自发的维护、拯救使用 OpenSSL 的系统,最后大量用户信息被泄露,产生了巨大的经济损失,为业界敲响了警钟。

​ 而大家对这事的认知仅仅停留在:单一把 OpenSSL 这个软件录入修复,软件有漏洞,修复就安全了,然而到 2021 年,Log4j 同样爆发安全漏洞时,造成的影响远不止 OpenSSL 爆发时只是单一修复系统的问题,这个 Log4j 从爆发到现在 2022 年,它的影响仍然没有消去,现在还有很多云服务在扫描,管理员连 Log4j 的漏洞在哪都没有找到,这是什么原因呢?因为云服务在大规模使用开源软件之后,经过日积月累的开发,整个软件栈,不论是犄角旮旯,还是肉眼可见的能接触到的应用,都被开源软件占据,这个漏洞的影响方面就不止原来的那一小块部分,它会贯穿整个产品的生命周期。

4、企业竞争力与现代软件开发的核心矛盾

1)分与合的矛盾

问题:把所有的安全、合规问题都解决了,但同时需要花大量的精力、时间和人力去维护、修复,也因此没有时间、人力去做竞争力,那这个问题怎么解决呢?这就是现代软件开发当中的一个核心的矛盾——分与合的矛盾。

① 竞争力

​ 企业内部使用开源软件为何能具备竞争力?

​ 开源软件可以改变交付方式。以前大家做软件开发,需要自己一段一段进行编码,而现在只需要集成某些能力强的开源软件,就能包含这一块的特性功能,比如 k8s、OpenStack,这是一个全功能的开发软件,围绕操作系统或者镜像管理,包括容器管理等这部分的事情都不再需要我们去操心,他们都能帮我们解决,这时我们组件的交付方式变成黑盒模式——不需要关心里面的内容,只需要关心是否实现这个功能,能用接口调用出来,那么就可以交付了。

​ 因此企业内部分工,以组件方式交付产品,能大幅提升产品线质量/效率/竞争力。

② 挑战

​ 正因为是黑盒,我们不知道内部究竟有些什么,所以可能产生以下一些挑战:

  • 不归一:老组件一直在网使用,导致单产品同时使用一款软件的不同版本
  • 版本老:考虑到稳定性因素,部件年老龄化,采用延长维保覆盖产品生命周期
  • 多副本:基于开源修改,片段代码散落在自研代码中 这就是企业竞争力与现代软件开发的核心矛盾之一。

2)稳定与升级的矛盾

① 竞争力

​ 发布产品前,需要保证产品能够稳定、可靠地运行,尤其在一些国计民生行业,比如电信、能源、交通等行业,稳定性和可靠性可能是这些企业赖以生存的竞争力。

​ 修复漏洞可能有几种方法,要么将软件的版本进行升级,从头开始升级,操作系统到应用,甚至硬件的漏洞也进行修复,全部升级下来,就会产生一个问题——升级可能需要跨部门协作,比如硬件部门、软件部门、操作系统部门、开发部门等都得协调,那效率如何进行保证?如果效率不能进行保证,就会选择不升级而只是打补丁,还是用着原来稳定的版本,把这个漏洞继续留着,后面再去解决。如果从头进行升级,同时考虑到兼容性问题,那这个成本会变得非常高,站在生命周期角度考虑,产品经理一定会犯难:升级还是不升级?如果不升级,老版本稳定,不一定会被攻破,而一升级整个架构可能都会改变。

​ 因此当我们频繁地修复漏洞、升级组件、升级软件等,甚至解决不了某些漏洞时选择绕开,这些问题都会给整个系统带来很大的不确定性,从而影响软件的稳定性和可靠性。这也是为何现在很多客户或者软件企业,都不愿意升级那些老旧组件、不愿意升级产品。

② 挑战:升级新版本才能规避漏洞

​ 那怎么办?是否可以不升级,承担风险即可?实际上是不行的,如果不升级或者部分升级,那么这个漏洞就会像滚雪球一样,越滚越大就会出现前面所述情况:整套系统可能会出现,开源版本大概十多个,OpenSSL 的版本也有十多个,有些团队认为升级很简单,比如 OpenSSL 升级到 2.0,但有些团队,人力资源比较少,或者为了稳定不进行升级,在日积月累中,整套系统就会遍布开源的版本,未来黑客拿到开源软件的漏洞清单,因为整套系统里面所有开源软件版本都有,只要在任何开源软件随便找一个漏洞,就能攻破,这就是前面所述:一旦不从生命周期端到端考虑产品的漏洞修复,就会导致攻击面会被扩大。

建议:竞争力跟产品安全、产品合规是一个严峻的挑战。要解决攻击面变大的问题,需要从生命周期的端到端看问题。

例如,某个公司,当产品出现问题时,应该如何解决呢?

​ 第一层,现网上发生了一个漏洞,需要及时修补。

​ 第二层需要审视合同,在与很多企业进行沟通时发现,他们只会跟客户说:“把这个 APP 的问题解决掉就可以了,其他事情不解决。”这说明行业基本就是这样一个共识,或者说是潜规则,但在合同里没有表明清楚,合同里写的是需要对这个系统的所有安全问题进行负责,那客户就会站出来说,“你只是把这个 APP 的问题解决了,并没有解决操作系统的问题,那下次安装 APP 又会出现这个问题。” 而合同内约束的是某某漏洞解决的责任。

​ 第三层,如果漏洞解决责任是一揽子工程,不仅包括 APP,还包括操作系统,甚至包括硬件,这时就不能简单去看现网的问题,还需要回到整个产品的配置中去,看 SBOM,看信息树,到底产品里挂接了多少个平台、组件、硬件,而这些硬件平台组件又分别是哪些部门在管理,他们的漏洞一级响应、合规一级响应以及相应的问题处置方案是什么,配置内包含的内容越多,攻击面越大。

​ 第四层,再回头看各个组件漏洞如何修复,开始的软件漏洞如何修复,自研代码如何修复,整个代码修复完之后,甚至硬件问题修复完成之后,统一再上线到现网里提供给客户使用。

​ 这就是端到端解决问题的一个思路。

​ 整个过程如果没有自动化跟踪机制,或者成熟的软件开发流程,是无法 cover 所有的事情,或者自动化程度不高,也会导致产品修复、产品开发,不能按照合同约定及时提交给客户,而有些维保人员或销售人员,会因此搪塞客户:“这个不修复也没事,出现问题的概率很低,修复还可能影响你的网络,要不咱就不修复了。”从此而埋下了一个隐患,久而久之,若爆发出来则不可收拾。

- 生命周期内持续有人维护

​ 要修复一个漏洞,安全部门观察到某个开源软件包含了一个漏洞,请产品去修复这个漏洞,安全响应部门已经将所有的漏洞,包括它的行为都已经归档,但是产品在过程中是否修复了呢?产品修复肯定是在新版本的软件包里修复的,或者是给一个新版本的补丁,从企业内部来说有可能产品确实是修复了,但是到客户,到销售部门,到维护团队,整个修复的流程是否真的都做到了?因为涉及到中间的环节太多,如果没有一个跟踪机制,这个修复流程实际上是不清楚的。

-所有代码需要代码级安全

​ 代码级安全不仅仅指在企业内研发阶段需保证代码级安全,也包括客户提的二进制代码,所有的程序都要做到代码级安全。假如说有些产品因为某种原因不停迭代,新版本和老版本都在老的硬件上,因为需要兼容老的硬件,所以某些软件不能升级,这种就是一个新的兼容性挑战。

5、开源安全之殇

开源软件升级的事情,怎么会威胁公司的生存?

案例:ONUS 是越南的一家金融科技公司

​ 2021 年 12 月 9 日,由 Log4j 引起 Log4Shell 0day 漏洞的执行程序在 GitHub 上公开。这个事件和心脏滴血事件类似,看上去 Log4j 社区一直有人维护,社区内也有很多人在贡献,但在 JDBC 上做的一个链接/模块长期无人维护,当这个点被黑客发现并且利用,他们在各种试验之后,证明可用来攻击其他系统,因此就爆发了 Log4j 事件,而在这事件出来之后,大家第一反应就是等,等社区出补丁、“work-around” 的解决方案,然而等到后面,才发现这个问题非常底层,短时间内没办法解决,虽出了一系列方案,但也解决不了根本问题,等到最后企业开始真正去解决这个漏洞时,发现应用软件、中间件等都被攻击了,而中间应用软件修复好之后,服务器、服务器软件、云也都被攻击了,因为服务器的应用范围非常广,很多系统都拿它来记录日志、遥测信息,这时就不仅仅是一家公司的问题了,大家都把自己的系统托管在云服务厂商上,云服务厂商与硬件厂商一起运营云服务,当其中一个应用出问题,导致整个基础设施都出现问题,因此需要整个上下游都需要修复这个漏洞,系统才会变得安全。

​ 然而很不幸,ONUS 成了黑客们的攻击目标。在 12 月 11 日至 13 日期间,黑客成功地利用了 Cyclos 服务器上的 Log4Shell 漏洞,200 多万条客户信息被出售,并被黑客勒索 500 万美元。

​ 在 Log4j 漏洞爆出来之后,这家金融公司第一时间知道这个漏洞并进行修复应用及相应的算法。但是很不幸的是,没有进行端到端的生命周期管理模式,以及还应用很多从外部采购的第三方平台,包括服务器的软件。

​ 从这个案例看来,即使修复了上层应用的风险和漏洞,但仍然会暴露底层软件,包括操作系统、云服务问题。对漏洞修复、开源软件升级、生命周期配套已经威胁到公司利益!不改不行,不说不行!

三、探讨如何持续构建高安全产品的研发能力

1、管生

建立软件BOM(SBOM),全流程产品视角管控

​ 如何持续看护整个生命周期的产品安全和漏洞问题,实际上软件开发需要经历几个阶段,从整个产品的研发阶段,包括规划、开发、质量测试、生命周期的发布,到最后的维护,整个生命周期都会建立一个追溯机制。

​ 从社区开始,有不同的开发者进入社区,优先于企业发现社区里的各种漏洞、洞察可能存在的风险,一旦发现风险,就会拿到专家组里进行评审,比如这个 Log4shell 漏洞会不会影响公司的产品,比如云计算的产品,还是计算的产品,还是无线的产品?专家组会对这个问题的严重程度进行分类,通过评估标准,把相应漏洞挂接到软件库里,这个软件库有系统,这个系统会将所有产品及产品所使用组件、组件下使用的开源软件,包括开源软件的漏洞,通过树状的方式全部记录下来,这是典型的 SBOM 的一个应用场景。

​ 产品使用需要遵守研发申请的过程,先提出申请:我需要用这个软件实体库内的某一个开源软件。那么就需要做各种合规的、安全的审核,审核通过之后,才会被调入到产品的配置库内,和产品一起进行构建。

​ 产品构建之后会进行扫描,因为在使用开源软件过程中,可能会对其进行裁剪或者增强,这个过程可能会引入新的问题,所以需要再次扫描排除问题,没有任何问题之后才会将整个产品进行发布,然而产品发布并不是整个过程的终点,还需依据合同对产品进行维护,在社区内排查漏洞并进行修复。

​ 有这样一个追溯机制,任何一个漏洞到底影响了哪一个组件或者产品,都可以被快速定位出来,一旦被定位,就能给出建议,比如云计算里的某个产品,server 出问题了,可能会影响到产品的安全,那么我们会对产品进行扫描,确定这个漏洞会影响的范围,比如只会影响 1.0~1.1 版本,我们马上会有相应的应急方案,对这个软件的漏洞,要么打补丁,要么进行升级,会产生兼容性问题,升级的版本与操作系统不兼容,所有东西都会通过内部研发的机制,先进行兼容性测试,比如 a 版本和 b 版本,都能修复漏洞,通过内部的兼容性测试,可以知道修复 b 版本既可以保证兼容性,又可以保证能修复漏洞,那我们就会优先去选用 b 版本解决这个漏洞。

​ 通过这样一套机制,能保证交付到客户的这些软件,它的解决的方案,包括产品,能够从端到端的视角,把所有漏洞犄角旮旯的这些问题都能找出来,进行妥善处理。

2、开源软件技术组织和产品线的矩阵管理

​ 产品安全管理过程中需要有一个专家机制做技术上的评判,这个专家机制,不是按照产品来进行划分,而是按照技术来划分,比如大数据的技术,云计算里面可能用到的大数据、AI、知识图谱,还有各种各样的技术,通过技术去划分开源软件,每个技术都有一类专家进行看护,可以看到库里面的哪些软件是漏洞少的,引入的新软件里面有多少漏洞,新的漏洞多的版本,我们及时将其剔除,因此在华为的软件库里,安全组件占比是最多的,在特殊场景下需要带漏洞的软件是极少的,只有在某些特定的场景下,允许其进入华为的软件库里使用。这就是华为公司在使用开源软件提交产品的竞争力所在。

​ 看护的目的是什么?在这以增长率表示。图内的增长率是指:当我们使用开源软件时,符合我们要求的版本有多少。一开始建立时定的要求比较低,因此满足我们要求的版本就比较多,相应增长率就比较高,后面增长率会稳定在某一水平,也代表我们的标准日益趋同,标准逐渐统一,即每月审核通过的软件/能用在产品内的软件会固定在一个数量,以保证整个研发体系的风险可溯、可控。

​ 除了技术组织看护之外,还有产品线的各种组织来看护,因为在技术看护下来之后,还需要针对各个不同产品的特征来进行看护,比如将某个产品交付给山东的客户,是以公有云方式进行交付,交付给陕西的客户,是以私有云的方式进行交付,那么应用场景就不一样,从 license 来看,如果是 GPL,线下交付给客户的方式,属于分发,风险则会更大,如果以云服务的方式交付,那么风险就很小,通过技术组织的看护,可以将风险进一步降低,保障效率的同时,又能保障风险被快速处置,这个就是通过组织的矩阵管理进一步细化的方式。

​ 成立软件选型专家组织,集中把控软件选型:在做优选的时候,要有相应的开源软件的一些技术组织,对开源软件来进行管控。比如说对软件的分类,专家对软件进行分类,按照分类,专家评估,评估报告会影响产品引入开源软件的优先级。在产品线的团队里,应该也有相应的专家能对产品做分层的管理,把产品线的开源软件的优选管控起来,只有这样形成一个矩阵化的管理,才有相应的保障。

3、管死:生命周期

挑战:层层嵌套带来的配套复杂性

生命周期管理模型:

① 合同;② 产品;③ 主要硬件;④ 其他硬件;⑤ 软件版本;⑥ 平台版本;⑦ 硬件配套软件;⑧ 构建工具;⑨ 开源软件;

​ 从合同开始,产品包含有很多很多内容,可能有整机,可能有内部的硬件,包括主控板等硬件,还有软件,软件分平台类的软件,应用类的软件,针对芯片的某些驱动,构建工具的软件,这些都需要有生命周期的规划。本软件的生命周期一定要包含上层软件的生命周期,也就是说平台软件也好,芯片软件也好,驱动也好,它的生命周期一定要包含上层应用的生命周期。

​ 在一个现代化的软件开发流程中,企业要开发一款产品,包含各种交付件,硬件、软件、平台、应用等等,都是需要软件的看护,硬件的生命周期往往很长,差不多 5~10 年,软件就逐渐缩短,比如基础软件可能远一点,比如操作系统 openeEuler,比如 Ubuntu,大概有 3~4 年的生命周期,但是存在在操作系统上的平台,比如云平台或者一些开源软件平台,可能只有 1~2 年的生命周期,再在上面构建 APP 应用系统,比如 OpenSSL、Log 4j,这种软件可能一两个月都在升级版本,无时不刻会有漏洞出来,因此越是底层的软件或硬件,越要 cover 处上层应用的安全风险,不能上面的应用还在用着,下层的平台或者操作系统就已经停止支持。这个风险就是 APP 不论怎么修复,上面的应用,一旦操作系统出现问题之后,交付给客户的整套产品都会出现问题,而且没法通过 APP 的支持人员来解决。这就是为什么要层嵌套,特别是现代软件开发过程中层嵌套的产品,如果不对生命周期进行管理,一定会造成即使知道漏洞要修复,也修复不了的问题,因为平台无人看护,资源撤了,人也离开,最后导致落地困难。

​ 如果想要解决这个问题,就要考虑一个思路,不仅要考虑如何开发产品,还需要再开发之前就考虑清晰,需要支持这个产品多长时间?如何在支持时间内保障交付在各个客户收集的各个部件,其安全风险都能够被 cover?这个设计一定要在产品开发之前就设计好,且设计完之后,在合同层面告知客户,比如这个版本只能维护四年,用到的开源平台,比如 Red Hat 的版本就只有 5 年,如果 5 年之后,可以新签订合同进行维护,也可以提供新产品,继续提供 4 年或 5 年的维护周期,一定要让客户知道产品的生命周期是有期限的,知识能力是设计出来的,这时生命周期设计,也是交付给客户,让客户更安心地在这个生命周期时间内,享受企业带给客户维保的承诺。

4、产品各层级生命周期可维护

​ 比如产品里集成的 openSSL,12 个月内每个月都发布一个开源软件发行版,每个版本对应的软件版本都需要进行看护,逐层分解:产品软件下又分平台软件,平台软件可能有 4 个版本,每个版本支撑产品软件的时间得进行确定,平台软件定义好之后,开源的操作系统能支撑平台软件的时间、人力等也要进行计算。整个过程就如计算客户的合同,每层进行细分,投入的人力、资源等在内部逐一签订契约,以保证所有生命周期管理的项目能逐一执行下去。

​ 制定产品生命周期的时候,需要注意生命周期可维护。产品硬件,软件它都有生命周期的模型的约束,产品是要不断迭代演进的,如果某一个产品版本一直用下去,肯定会出现网络安全问题的。硬件也是有生命周期的,因为硬件很难去被替换,所以我们在硬件设计的时候要预留相应的空间,使得我们的软件能够进行升级,不能因为硬件而不允许升级,相应的产品的软件平台,工具、芯片、软件,同时能够保证升级,不会被上一层和下一层的软件生命周期所约束。

通过硬件/软件配套管理,避免生命周期失控,执行 EOX 管理

1)合同界面:产品、硬件、软件生命周期模型有约束;

2)产品:代内、代际皆可持续演进,更换硬件设备做到最少;

3)单板:有 EOS;

4)产品软件与 EOS 硬件配套策略:如果现网要升级新软件,则需替换 EOS 硬件;

5)产品软件:内部各组件以及与硬件、产品有配套机制;

6)内部组件:按大特性版本做 EOX 管理,EOM(停止配套)严格执行,确定好 EOM 到 EOS 时间,用补丁方式升级;

7)开源软件:开源软件生命周期无法覆盖的,产品/平台在 GA 与 EOFS 之间要升级;开源软件版本 EOS 前,责任 owner 提供缺陷修复(含安全漏洞)服务

–– 组件级小软件:增加 EOS 点,采取社区维护+企业维护模式,拉长 EOS 点 (最少 1 年)

–– 系统级大软件:确定生命周期 GA-EOM、EOM-EOS 时间

8)构建工具:自研类遵循平台生命周期管理要求;开源类遵循开源软件生命周期管理要求;

9)硬件配套软件:硬件配套软件执行单独的生命周期,与硬件生命周期管理对齐。

四、小结

1、生命周期管理长效机制总体策略

对外:完善供应商、企业、客户三个对象的生命周期规则,确保产业链生命周期不脱节;

对内:完善各对象的配套关系,建立完整的产品树,确保生命周期风险可视 & 可控。

1)客户合同界面:规范客户合同界面对产品/硬件/软件生命周期管理的约束。

2)产品:各个组件+硬件

① 产品:断代模式下,明确并加快产品断代。比如之前有个开源软件 python 软件,官方在 2020 年停止对其进行维护,我们如果大规模使用了这个软件怎么办呢?我们只能通过跟客户沟通——因为产生了重大的不可预知的变更,我们的这个版本只能维护到 2020 年,希望客户能够理解,我们需要在 2020 年升级到下一个版本,这个版本里使用更新的可维护的组件。如果社区已经不维护了,还强硬跟客户解释我们可以一直维护下去,这种做法是欺骗客户,是不可取的行为。

② 硬件:执行单独的单板/部件的生命周期管理,以及与产品软件的配套关系管理。硬件也会产生漏洞,比如之前报道出来的关于 Intel 的 CPU,爆发的幽灵漏洞,正是因为硬件设计本身的问题所造成的。

③ 产品软件:单产品软件、内部组件、开源软件、硬件配套软件、工具软件;很多人往往会忽视工具软件,认为工具软件只是在公司产品内部使用,关系不大,但往往工具软件会生成一些配置文件,或生成代码嵌入到产品内,如果不进行管理,这些自动生成的代码就管理不到,产生的风险也因此无法识别。

3)供应商合同界面:规范供应商合同界面对三方件的生命周期管理约束。

​ 随着产品越做越大,产生的事情越来越多,不太可能仅靠人工就能进行管理,需要依靠工具、自动化系统,比如信息树、漏洞跟踪系统等,将信息可视化,一旦遇到风险,能进行自动预警、自动分发任务,从而在相应团队里进行修复。因此所有的这些东西都由数字化平台承载,进行统一风险管理。

2、生命周期优化必须解开两个扣

产品必有死期,合同必有约束

​ 生命周期的管理总结:产品它必有死期,产品无限制的固定的维护下去,一定有死亡或者是退出生命周期的一天,即软件和硬件需要不停迭代,只有迭代才能保证软件中的安全、合规问题能够被解决掉。

​ 跟客户谈合同的时候,合同也应有约束,合同不能无限制,对某一个老的硬件或产品一直维护是不切实际的,总有一天会有大量的安全问题,产品不可用,以及对商业造成损害。在研发的角度上,持续产品的研发能力,保证所有的东西都是可以维护,易于升级。

企业开源的战略和战术

硬件厂商自底向上穿透接口标准,扩展商业新场景

云厂商以流量为基础,加速培育与收割

开源流量红利

  • 本质:开发者的技术习惯和投入时间

  • 来源:人数红利、技能红利、创新红利

从被动接到主动引

  • 服务化
    • AWS 服务化大量开源项目
    • 逻辑:商业领先者打法,利用用户量的惯性效应
    • 案例:
  • 定规范
    • Azure 在技术曲线出现拐点时制定标准
    • 逻辑:工具链(VSCode/Github)优势打法。终结碎片化发展,用标准锁流量
    • 案例:ONNX vs TF,OSM vs Istio
  • 圈应用
    • Goole对应用开发技术加强管控
    • 逻辑:垂直领域(云原生/AI框架)优势打法,开放底座,用上层框架锁应用
    • 案例:效仿GMS,Istio和Knative不开放治理

主流 IT 厂商对开源软件的态度从对抗,到合作,以至于依赖

开源三次浪潮

  • 技术极客打破商业垄断(基础软件、中间件:UNIX、虚拟化、数据库)---商业公司对抗、攻击、市场PK
    • 案例:
  • 商业引导构建事实标准(基础资源管理调度,移动,大数据:Cloud OS、PaaS、Android、Hadoop)---兼容、合作、主动运行
  • Startup、云服务厂商以商业目的建生态(Cloud native技术:Devops tools、AI、电信云)---基于开源构建

谷歌在开源+闭源支撑生态发展和控制基础上,实现生态价值闭环

Intel将开源社区作为重要的产业控制点

  • 背景及策略

    Intel作为最大的开源软件社区推手,在各层级重点参与50+开源社区,在长周期维度进行有秩序的生态建设,通过芯片进行商业变现。

  • 英特尔将开源进行到底!

微软对待开源态度由抗拒、尝试、走向接纳,现在将开源视为核心业务发展转型关键,从软件到服务

  • 2001年,微软前任首席执行官Steve Ballmer在访谈时提到:“从知识产权保护角度看,Linux就是癌症而无可救药!”
  • 2008年,微软创始人Bill Gates对微软高层表态:“微软需要支持开源软件。”
  • 2013年,MS Open Tech首席执行官表示:“我们相信开放将为微软的客户、开源社区,以及我们的业务带来更大的机会。”
  • 微软现任首席执行官Satva Nadella在公开会议提出:“微软爱Linux!

微软围绕 Azure,通过持续投资和并购,布局开源

  • 2020年1月份,为了加强Azure在教育领域的支撑能力,微软收购了数据感知管理软件企业BrightBytes;
  • 为了让Azure在电信行业更具吸引力,微软之后又收购了Metaswitch,来支持5G以及云原生应用场景;
  • 为了增强Azure 在IoT方面的安全能力,微软在6月份宣布,收购IoT安全专家CyberX;
  • 为了让数据管理更智能,微软在6月份收购了行业数据模型供应商ADRM;
  • 除了围绕Azure层面的并购,微软在拥抱开源方面,也在跑马圈地。3月份,微软收购了npm,这次收购有点特别,微软并不直接插手,而是由之前收购来的GitHub“操刀”。收购 npm,让微软自此拥有了世界最强大的软件包管理器。可以预测,npm和GitHub形成合力后,开源领域再无其他,微软将成为开源领域实力最雄厚的“富爸爸”。

收购Github,通过 OSPD 运作,实现4年2000到25000工程师Github开源参与

OSPD 负责微软开源规则制定和Github体验管理

  • 案例:https://blog.csdn.net/kaiyuanshe/article/details/111399082

亚马逊:从开源业务收割者到新领域贡献者

  • 亚马逊云科技将持续创新,贡献更多的优秀开源项目 https://zhuanlan.zhihu.com/p/415654854

开源与商业模式

企业开源赋能课程系列直播:开源项目社区如何走向商业化**

课程及讲师介绍

直播回放

一、开源雨林

1、开源雨林以用户为中心的开源生态,聚焦于行业用户

     帮助行业用户了解开源,更好地使用开源,用户逐步升级,能够贡献开源。开源雨林通过团队合作、机制合作、项目合作的方式,与行业用户一起,建立企业用户自己的开源能力中心,携手共同引领开源。开源雨林的愿景与使命就是以源汇智,创见未来。

2、开源软件赋能计划为企业级用户保驾护航

1)开源通识

     开源治理,知识产权,社区运营等;

2)开源使用

     开源软件选型,漏洞管理,开源合规等;

3)开源贡献

     代码贡献、项目捐赠、社区赞助;

3、开源雨林课程开发与推广

1)目标

     i. 联合第三方机构开展赋能计划改善国内开源环境,构建企业用户的开源生态阵地。
     ii. 覆盖中国从 TOP 500 到中小企业开源需求的课程 开发 & 赋能,咨询,联创。

2)进展

     i. 当前已覆盖包括中国人民银行、中国工商银行、中国农业银行等在内的 15 家中国 TOP 500 企业课程赋能;

     ii. 开源雨林已联合华为 EBG、信通院完成独立课程的开发与赋能。

3)系列课程(11 门)

    《开源文化与认知》

    《开源使用规范及业界优秀实践》

    《开源生态构建及业界优秀实践》

    《开源安全及其风险管理》

    《开源合规及其风险管理》

    《开源生命周期管理》

    《社区规则和潜规则》

    《开源社区与商业模式》

    《企业开源的战略和战术》

    《开源使用优秀实践分享》

    《开源生态优秀实践分享》

二、开源生态

1、以用户为中心的开源生态

用户是生态要素的消费者,也是生产者;是开源生态发展的引擎

1)互联网/云服务/ICT Vendor:推动开源,繁荣生态,影响技术;

2)新创企业生态:新创企业经过商业化之后,提供更多创新场景、高价值应用以及服 3)同时有许多投资机构做商业助推,

4)开源工具链协助进行运营与管理,

5)政府也会提供很多公共政策来进行扶持与引导;

6)高校、科研机构:技术创新、人才培养;

7)开源组织:治理架构、技术生态、事实标准、标准联盟;

8)媒体平台:营销、宣传、推广平台;

这就是整个以用户为中心的开源生态。

2、开源软件价值链

用户、开源厂商、开源社区、基金会、开发者、投资机构六者之间进行相互的价值传递。

三、开源项目社区

1、社区>代码

    如果有个好的想法,但是初代代码写的一般,还有优化空间,两者结合就有可能会发展成很好的社区,其他的组合就不一定会有这样的效果。(Good ideas & bad code build communities,the other three combinations do not.---Stefano Mazzochi,s.apache.org/badcode)

    为何这么说呢?比如 Linux 社区最初的作者 Linus Torvald,写了一套开源的 Linux 操作系统,这时一个非常棒的主意,且非常创新,当时并没有这样类似的系统,但写的代码由很多优化空间,因此就开放了他的代码,将代码开源,要求很多人来帮忙做进一步优化,在不断优化之后,社区越来越壮大,时至今日,成为全球领先的开源操作系统。

    相反地,如果有一个很棒的主意,但仅有个人或者少数几个人主导并认为其代码已经非常完美,不需要其他人参与,那么这个项目有可能变成几千万个开源项目的其 中一个,孤芳自赏。

    第三种情况,代码写的很不错,或者个人能力很强,但只是重新发明轮胎,把其他人类似的项目/场景挪用过来,直接进行优化,而不是贡献到上游。这种情况,也很难形成社区。因为高手如果要做贡献,为何不到原来的上游做贡献就好呢?为什么要参加一个 "me too" 的项目,或者重新发明的轮胎的项目呢?这样也不会形成一个好的社区。

    因此 "社区重于代码" 就是一个很好的创意,加上一般的代码,呼朋引伴一起不断优化代码,形成优质的开源项目社区,这就是社区重于代码的含义。

2、当社区遇见企业

    如上所述,Linux 从个人项目逐渐优化而形成自然状态下的社区,大家有意识地组织起来,社区越来越壮大,最后可能会变成一个开源基金会(比如 Linux 基金会),或者成为一个新创企业,比如 Red Hat (红帽)。

    另一种情况,不是由草根、个人或者少数人发起的开源社区,而是由商业来进行主导,业内也有很多成功的项目,比如 Google、Android 等,是自上而下的培育社区,精心运营。基本上由商业组织,尝试不断融入、扩大影响力,甚至主要这样一个开源项目。

3、成功的开源模式

    成功的开源基金会的开源项目的开发者数量及日均代码提交数量远远大于单一厂商主导的项目,如 MySQL(Oracle)等,其投入跟产出的回报可能会差到5倍。

    在 2010 年 Henrik Ingo 的研究报告中介绍了开源基金会所运营的项目,所创造的市场、客户群以及代码贡献者数量都远远大于单一公司主导的小型或中型社区,相应其市场潜力规模也更大。

4、主流基金会

5、ASF vs. LF

在此主要聚焦于两种不同类型的基金会:Apache基金会、Linux基金会。两者的税务结构,说明它们都是非盈利机构,不会给股东进行分红,但是Linux基金会是非盈利的商业协会,除了接受资金的捐赠之外,还可以经营项目,可以举办会议或者是办咨询、认证培训等。参与模式中Linux基金会是企业参与,每年都需缴会员费,根据金额决定会员资格跟级别,而Apache基金会是个人参与,资金来源是企业每年给的赞助费,而非会员费,因此两者之间的年营收,目前是 10 倍上的差距。

基金会ApacheLinux
税务结构501(c)(3)501(c)(6)
资助形式捐赠会员
雇员很少较多
参与模式个人企业
运作范围项目项目+会议+咨询+培训
年收入 (2021)US$1.5MUS$100M+
项目范围大数据、数据库、Web、云服务、AIOS、云计算、网络
项目个数300+600+
允许相似项目
社区导向纯技术,真正的开源社区 ->项目多,生态好技术+商业 ->组织化运作
公司话语权公司利益
项目决定权项目自治董事会+项目

6、ASF-全球最大的开源基金会

1)使命

为公众利益而提供软件

2)300+ 顶级项目

大数据、人工智能、机器学习、物联网,流媒体、云管理、Mobile…

3)下载/使用的领头羊:中国

中国是全世界下载与使用 Apache 基金会软件项目最多的国家,可见 Apache项目非常受中国很多企业的欢迎。

7、Apache 孵化器

1)孵化器现状

一个项目要进入 Apache 软件基金会需要经过孵化期(大部分项目都需要),目前有 30 几个孵化项目,这些孵化项目由企业或社区捐赠给 Apache 软件基金会进入孵化器,孵化期一般约 1~2年。

2)为何需要孵化?

是为了学习 Apache 的治理原则、融入国际顶级基金会的文化、政策等,好比凤凰浴火重生,在孵化期借机发展壮大自身社区,同时培育项目的独立性与多元性,厘清项目的许可证及知识产权。

3)源自中国的 Apache 项目(31)

2015年,Apache 软件基金会在中国举办的 Apache 中国路演,当时只有少数一两个源自中国的项目(来自于 eBay 中国研究院,如 Apache Kylin)。而 7 年后的今天,已经有 31 个项目由中国发起,其中已经毕业,成为顶级项目一共有 19 个,正在孵化的有 12 个项目。今年年底是毕业的旺季,再过一段时间,已经毕业的项目会更多。短短七年,数量翻了十倍不止,说明 Apache 软件基金会非常适合中国的企业把项目捐赠出去并进行项目社区发展。

4)案例:Apache ShardingSphere (SphereEx)

京东数科将 ShardingSphere 项目捐赠到 Apache 软件基金会,项目负责人张亮与潘娟成功地带领该项目从孵化项目毕业成为顶级项目之后,成立了开源商业公司-SphereEx。该项目在加入孵化器之前,在 GitHub 上的表现(关注度、issue、PR、贡献者、提交者等数据)与加入之后的数据对比如下表,由此可见其增长幅度非常巨大。因此可以发现,一个开源项目捐赠到国际顶级的软件基金会之后,在社区发展、社区治理以及项目的健康度,都会大幅增长,从而有更好机会走向开源商业化。

内容加入 Apache 孵化器之前 (2016.01.17-2018.11.09)当前 (2018.11.10-2022.11.30)
Stars5k+17.7k
Issues9488,350
Pull Requests49114,048
Contributors37465

四、开源商业化

之前我们看到了开源项目社区的自然发展过程,现在来看一看由企业精心主导的开源项目社区发展又是什么样的路径。我们先看全球领头羊企业如何推动开源项目社区的发展,其次再看由成功的开源项目社区转变为开源新创企业的路径和商业模式。二者殊途同归,相辅相成。

1、全球开源大潮

1)开发者

① 全球 83M+ 开发者

② 80%+ 贡献者在美国之外

③ 用户最多前十名的国家(全球):美国、中国、印度、英国、巴西、德国、俄罗斯、加拿大、日本、法国

2)企业

全球财富 100 强中 90% 的企业都在使用开源,其中 50% 的私人企业参与开源贡献。

3)GitHub Top 1,000 开源项目

参与开源贡献的组织超过了六成

① 开源协议:MIT License(46.2%), Apache License v2 (18%),GPL v3(2.8%)

② 编程语言方面:JavaScript(33%)远超 Python、Java、Go、TypeScript 位列第一

③ 组织 61.73%,个人 38.27%

2、国际开源领头羊企业

1)国际开源领头羊企业的实践

① Google:实现生态价值闭环

i. 开源生态底座(比如 Android),闭源核心能力(比如 Google Mobile Service: GMS),自营基础设施服务(比如 Google Computing Platform: GCP),自营消费级硬件(比如手机)与服务(比如 YouTube、Gmail、广告等),第三方服务、硬件与合作伙伴

ii. Android 形成生态粘性后,透过 GMS 认证 进行价值变现和管控

② Intel:将开源社区作为重要的产业控制点

i. 内核、OS、虚拟化;基础软件;水平应用

③ Microsoft:抗拒 -> 尝试 -> 接纳 -> 转型

微软从抗拒到尝试到接纳最后转型拥抱开源的各个阶段的重大举措值得了解。开源不只是由下而上的工程,更是一把手工程,希望更多的中国企业可以参考这些案例,进行一些思考,把开源当作公司战略转型的重要举措。

i. 成立微软开放技术子公司(2012-2015);开源管理办公室 (OSPO: 2014)

ii. VS Code 开源 (2015);收购 GitHub(2018)

④ Amazon:从开源变现者到新领域贡献者

i. AWS 将许多广受用户采用的第三方解决方案予以云服务化,并提供一些增值服务,如计费、监控,以及最后一里的工具,文档等来优化易用性及用户体验。如此吸引了大量的中小企业与部门级客户

ii. 如此作为引起了众多开源项目社区以及对应的第三方解决方案提供商:如 mongoDB(10gen), Cassandra(Datastax), Spark(Databricks),ElasticSearch(Elastic)等的不满,从而采取各种不同的竞争手段与其对抗(详见后续章节展开说明)

iii. AWS 自身不断精进优化,也推出了自己的开源解决方案,如 Amazon SageMaker Neo 来支持广泛的框架和算法(如 TensorFlow,MXNet,PyTorch 等)以及多样化的硬件架构(Intel、NVidia、ARM、Cadence 等)

2)Google 如何做开源?

① 2004 成立 OSPO(开源管理办公室)

i. 服务 7.2 万员工,开源项目约 2,000~4,000

ii. 15 名成员:律师, 推广团队, 工程团队 (开发自动化合规性检查工具,支持其它开发团队);跟踪公司范围内所使用开源项目状况,包括构建的合规性、代码引入和发布的时间等;

iii. 鼓励公司所有员工,在他们主要的开源工作(图形设计师、技术作者、营销人员或开发者)之外,要去花 20% 的时间去参与到公司其他的项目中去。促进团队交叉合作,帮助理解并改进公司层面上的全局项目。

② 坚持三个原则

i. 帮助其员工使用开源项目(工程师入职第一周就学习 Apache Way)

ii. 发布开源项目到开源社区

iii. 支持与拓展全球开源生态(如 GSoC,TODo Group…)

③ 相关治理与政策

i. 发布一款新的开源项目遵循那些流程

ii. 如何为其它开源项目提交补丁

iii. 如何管理引入第三方的开源项目以及如何使用

iv. 为何仅使用某些特定的许可协议的项目

v. 为何所有接受到的补丁都遵循许可协议

④ Kubernetes:GitHub #1 开源项目

Kubernetes 能成为 GitHub 最受欢迎的项目就是因为 Google 精心主导该项目社区开源的结果。

3)Twitter 的开源之旅**

① 自第一天起开源

成立于 2006 年,号称 “”,拥有 4,000 员工,3亿+ 活跃用户,5亿+ 推特/天,其中 80% 为移动用户。

② 开源办公室(OSO)

速度及最少的官僚、开源流程令人愉快、有效率地保护公司、为关键项目建立社区、培训/文化至为关键、为工程师服务

③ Twitter 学到的教训

i. 在许多项目里做出重大贡献

  ​ 如 Apache MesosApache ParquetBootstrapTWEMCACHE 等项目

ii. 在其中学到的教训

   a.贡献带来的影响:      贡献他人,成就自身,企业在做贡献或者共建开源项目时,对自身企业品牌、技术或用户的影响非常大)    b.社区不会凭空诞生:      社区需要精心耕耘,参与、贡献和引领    c.开源办公室成为生态核心:      开源流程令人愉快,为工程师服务

3、国际开源商业化

1)开源软件商业模式**

开源有多种商业变现的模式,在此不多赘述,以下章节将针对开源软件商业模式简化并进一步阐述,以方便读者理解。

2)国际开源商业化

① 开源商业模式验证
i. 1999-2021 全球开源软件 VC 投资统计

由 1999-2021 年全球开源软件 VC 投资统计图可知,不论在投资个案数,还是投资的金额,都是非常可观,且逐年递增,在 2021 年统计已经达到 50 多亿美金。

ii. 融资-上市/并购-退出

”融资-上市/并购-退出” 是投资机构的进场和退出的常见机制。我们以 RedHat (红帽) 为例,它在 1999 年上市,当时的市值达到 36 亿美元,而在 2019 年 IBM 完成收购 RedHat 的价格达到了 340 亿美元的天价里程碑。此后投资机构的回报金额越来越高,而回报周期越来越短。

iii. 主要开源软件公司成立及资本市场退出时间段

这里显示了主要开源软件公司成立以及资本市场退出的时间段,由此可见资本市场退出时间,整个周期越来越短,金额越来越高,退出时间越来越短。因此,对于资本市场,投资开源,新创公司是回报高,且回收(退出)快的一门生意。

iv. 上市之初的估值

有些开源新创公司成功的上市之后,公司的市值表现越来越好,例如 mongoDB 在上市时,市值估值已达到 353 亿美元这样一个惊人的市值。

v. 上市之后的表现

这些成功上市的开源软件公司上市后的表现也令人惊艳。例如年复合增长率、毛利率、市销率(市值营收比:以公司市值除以上一财年或季度的营业收入,或以公司股价除以每股营业收入)、净收入留存(指不仅有老顾客续费,还增加了新的订阅收入的比率)等营运绩效指标都在高速增长,表示这些公司的客户非常忠心,且会不断为公司创造越来越多的营收,因此这些公司的年收入复合增长也会越来越高,从而对股东及投资机构带来了持续地高价值回报。

② 开源软件的商业闭环
i. 开源商业化发展历程

最早的开源软件由一个黑客,因为自己喜欢以及为了自己方便或者社会大众方便,把该软件开源出来。后期像 RedHat 这类公司,提供了开源软件支持服务,再到开源 2.0版本,开放核心,在增值功能上提供差异化闭源商业版本;到 3.0 版本,简称托管服务,或者称之为 SaaS 服务,与公有云的兴起有极大关系。商业模式在不断变化,越来越多公司在 3.0 版本上茁壮发展。

时间迭代代表案例供给侧需求侧创造价值
2015 - 现在开源 3.0 云托管 Cloud Hosting 作为服务托管在云上databricks, GitHub, mongoDB, elastic公有云兴起快速弹性降低运维成本付用量弹性/按需付费,免于部署运维,原厂专业支持
2005 - 2015开源 2.0 开放核心Open-Core 提供差异化商业版本cloudera, confluent软件体系化生态逐渐完善用户对软件易用性需求提升,需要完善的解决方案完整的软件生态服务与解决方案
1995 - 2005开源 1.0 支持服务Support 技术支持及咨询服务Red Hat、MySQL软件越来越复杂和专业用户对软件稳定性需求提升,需要专业的技术支持专业可靠的技术支持提高软件稳定性
1980s - 1995开源 0.0 自由软件Free Software开发者、个人爱好Geek 的个性化软件需求自由可定制的软件
ii. 开源的良性循环

开源新创企业的快速增长及优质表现,开启了开源的良性循环:开源带来的科技创新,提升开源软件的可靠性及项目的可靠性,透过开源项目社区快速发展,帮助更多用户转化成企业付费的客户,开源项目社区与商业化不断的良性增长,更多用户与贡献者加速开源项目与开源企业的创新,同时也得到资本市场的支持与验证之后,会有更多的商业创新,比如最早一代像 RedHat 这样的付费服务,到第二代将核心开源,在增值的高价值模块上做商业化版本,再晋升到云托管服务和 SaaS 的服务之上,因此更多的商业创新模式形成了良性循环,当开源商业越成功,越能吸引更多的高手/好手。

③ 商业开源成功的三大支柱

成功的商业新创公司,他们成功的主要因素来自三方面:

i. 项目-社区契合

项目足够创新,能吸引很多开发者和贡献者不断优化该项目,因此项目与社区相互契合,其中主角为开发者,stars 及 contributors 均能作为具体的成功指标,目标为社区达到临界规模。比如 databricks、mobgoDB 等项目的成功,社区快速成长,贡献者能在很短时间内飞速增长,这主要归于项目具有创意,且拥有好的社区运营,让贡献者愿意参与,一起携手达成项目愿景与目标。

ii. 产品-市场契合

当项目越来越成熟之后,很多用户会下载并使用它,逐渐个人用户与部门级用户或者中小企业开始尝试使用,使产品市场越来越大,产品越来越成熟,因此产品与市场契合,用户为主角,下载/注册量作为相应成功指标,用户需要下载项目来解决问题,项目社区的负责人负责开源软件路线图,与协作者共同帮助用户解决问题。

iii. 价值-市场契合

当产品越来越好,不再只是部门及或个人级的应用,而是跨企业/行业,在行业里能体现开源项目价值时,比如性能绩效的提升、审计的功能、企业级流畅的服务以及高稳定性、高可用性、高安全性的工具等,用户愿意为其付费,价值与市场相契合,愿意付费的企业成了主角,具体指标为营收。

iv. 价值-市场契合范例

Confluent 提供云服务、控制中心等,databricks 为数据科学家提供的工具等,elastic 为企业提供报表和高级安全服务等,HashiCorp 提供治理与政策方面的服务等...

v. 价值-市场契合的商业模式

a. 支持与服务:Red Hat;

b. 开放核心:confluent、elastic、GitLab 等,提供专属与增强的功能,即核心是开源的,但高价值的功能闭源,且是收费的商业版本;

c. SaaS 服务:databricks、Automattic 等,为商业化的托管、工具和运维。

vi. 案例分析一:GitLab

a. 发展历史

  • 2001年,前CTO Dmitriy Zaporozhets 创建了 GitLab;2012年,Dmitriy 制作了 GitLab CI的第一个版本。

  • 2013年,CEO Sytse Sijbrandij 和 Dmitriy 联合推出 GitLab 企业版。

  • 2014年,GitLab 正式注册为有限责任公司。

  • 2017年,首位 10 万美元 ARR(Annual Recurring Revenue:年度经常性收入)客户。

  • 2018年,接触了 500 多位贡献者和 20 位价值 10 万美元 ARR 客户。

  • 2019年,首个100万美元ARR客户。

  • 2020年,与 AWS、Google Cloud 和主要的系统集成商和分销商合作。

  • 2021年,与 Atlassian 和 Red Hat 合作。

b. 经营状况

  • 从年度的经常性收入可看出,2017 年才一个价值 10 万美元 ARR 的客户,现在年度经常性收入价值 10 万美元的客户超过 383 位,

  • 净收入留存率(NDR or NRR:Net Dolloar Retention or Net Revenue Retention - 指在一定的时间周期内经常性收入的续费收入比例,用于反映公司现有收入在某段时间内的变化情况)达到惊人的 152%,

  • 可见 GitLab 客户的粘性以及持续增加的购买能力。

c. 商业模式

    Open Core 模式,三条产品线

  • 标准版 GitLab(针对个人用户)

    DevOps 全生命周期所有阶段;自带 GitLab CI 运行器;支持任意生产环境部署;免费静态网站;获取每月 400 分钟的 CI/CD 流水线时间;

  • 专业版 GitLab(提高团队协作)

    更好的代码评审;运维可视化;项目管理发布控制;SaaS 用户每月 10,000 分钟 CI/CD 流水线时间;

  • 旗舰版 GitLab(企业级安全、合规、规划)

    高级安全测试;合规性;项目组合管理;价值流分析 访客不计入计费用户;SaaS 用户每月 50,000 分钟 CI/CD 流水线时间。

vii. 案例分析二:GitHub

    虽然 GitHub 并非开源企业,但是它却托管了全球大量的开源项目。因此在此我们也探究其商业模式与 GitLab 这样的开源新创企业的不同之处。GitHub 采用了复合式的商业模式,有免费版本、教育版本、SaaS 个人和部门级的自助服务式版本、应用市场(用来给第三方合作伙伴开发各种各样应用),以及专属闭源服务,包括私有库托管服务、高级支持服务、专业服务等。

    目前 GitHub 已有 8,300 多万的开发者用户,预估 2025 年,使用 GitHub 的开发者用户数量将达到一亿以上。

④ 商业开源与公有云竞争

开源新创公司的商业化过程中不可避免会遇到竞争,尤其在公有云方面,如何在竞争中保持优势,构建云竞争的护城河,主要在以下两方面:保护性许可证、差异化区隔。

i. 保护性许可证

例如 Elastic License 及 SSPL(Server Side Public License),其目标是防御公有云厂商在开源项目的原来基础上加上简单功能进行收费的白嫖行为。

ii. 差异化区隔

a. 企业客户不希望供应商锁定

    云服务、应用等都用同一个供应商,迁移相对比较困难);

b. 企业客户更希望从真正写代码的人处购买服务

    例如托管的云厂商,客户只能买托管服务,其他很多事情托管云厂商做不了,只有编写代码的人才能做。

c. 大公司没有开源新创企业的某些专长

    大公司什么都做了,但什么都不一定那么精,最精的可能是云计算的服务,但对某个开源项目里特别的功能,大公司没有人力做这件事。

iii. Databricks vs. AWS

a. Databricks 的三个决定

  • 坚持做云服务

      许多员工或是投资人当初不理解或不支持,但是 2018 及之后的云计算风潮,也证明了 Databricks 创始团队的远见

  • 不做技术支持服务

      创业困难时期,有客户愿意出资千万美元请 Databricks 为其提供专业支持服务,但是仍然遭到拒绝

  • 专注于数据科学(Data Science)

      创始人团队的七位 UC Berkerley 师生在参加 Netflix 举办的人工智能大赛时发现他们无法在一台服务器上实现需要的能力,因此开启了 Spark 项目,其后将该项目捐赠给 Apache 软件基金会成为大数据领域顶尖的 Apache Spark 项目,并以此项目为基础创办了 Databricks 公司,并决心专注于数据科学领域(大数据、人工智能、深度学习等)

b. 如何与 AWS 竞争?

    因为一些受欢迎的第三方开源项目已经开源,AWS 直接拿来加上一些简单的功能服务进行了包装,并以优势的价格提供给其客户,从而与第三方解决方案厂商直接竞争。那么 Databricks 如何与 AWS 进行竞争?

  • 人才密度

      Databricks 首先加强了人才密度,最好的数据科学人才,不论是大数据、人工智能还是深度学习人才,都愿意去databricks而不是云厂商(如 AWS),更愿意去专业公司发挥其能力;

  • 差异化区隔

      Databricks 在性能、稳定性、深度数据挖掘以及数据模型和框架等方面进行差异化区隔

  • 销售策略

      大企业对数据科学,尤其是人工智能深度学习有非常大的需求,因此 Databricks 成立了企业级销售团队,针对 CxO 做高级销售服务

  • 多云与多赢

      Databricks 与几家云大厂都达成了双赢合作,例如与微软 Azure 联合推出了 Azure Databricks 套餐,如此也填补了微软在大数据、人工智能与深度学习解决方案的不足之处。Databricks 也与 AWS 以及 Google GCP 都有紧密的合作,从而实现了多云与多赢的策略,亦即客户赢、Databricks 赢、云厂商赢。

  • 应用市场

      Databricks 与许多开源新创企业正联手云大厂开始攻略应用商店(Marketplace)的市场。目前应用商店的市场规模大约 40 亿美元,预计到 2025 年时将达到 250 亿美元的规模。Databricks 更于今年六月宣布推出自己的应用商店 Databricks Marketplace (for Data Solutions),后续发展很令人期待。

⑤ 常见的失败模式

i. 开源用户增长不能带来付费客户增长

   资源重心放在开源社区和项目能力及成长上,用户会认为开源项目已经很好用了,不需要付费购买闭源产品,因此导致资源上配置以及方向上配置的误差。

ii. 开源用户的增长落后于付费客户增长

   资源都放在闭源的商业版产  品上,开源社区的贡献者或免费下载的用户增长越来越缓慢,只向“钱”看,会让开发者社区以及用户社区越来越萎缩,积累越来越多不满。

iii. 商业产   品破坏开发者社区中的信誉

   有些开源商业化产品,破坏了开发者社区中的信誉,比如上面所述的保护性许可证,为了保护商业产品不被云厂商白嫖,会设置各种许可或限制,或者把开源社区项目里面的功能挪到商业版里,因此导致社区内的人非常不满,感觉是平白替商业公司的利益打工,从而导致开源项目社区的失败。

iv. 成功是什么样子的?

成功的商业开源和商业产品应专注于如何为用户提供价值。在商业上面,对客户的服务层次进行区分,根据客户群体的大小与客户的需求不同,相应做不同的服务。例如对个人客户,提供免费下载的简单好用的自助式服务;对部门级客户可能需要用电话销售来了解真实需求,进而满足服务;对企业级客户进行现场销售。

⑥ OSS 3.0 开源吞噬软件

开源的开发模式或者商业模式不断演进,开源带来技术创新,比如区块链、开放数据、人工智能等,都在快速增长。同时也带来商业创新,比如广告收入,例如 Facebook、twitter、Google等广告收入为大头的公司越来越多,不少开源新创公司也正朝该方向前进;开放数据也带来很多数据资产,很多开源新创公司也开始将数据资产作为公司营收来源;区块链的加密通证也带来新的商机。因此技术创新带来商业创新,再带来技术创新,形成一个良性增长循环。

4、中国开源现状

1)中国的开源方兴未艾

近年来,中国开源开发者数量呈爆发式增长,不论是再 GitHub 或是 Gitee 上的数据增长都是惊人的。据统计,目前中国的开源开发者数量已经达到了 755 万人。

2)GitHub 中国项目活跃度排名 Top 30

GitHub 的数据表明,中国项目活跃度排名前 30 中就有好些成功的开源商业化项目。下图有红色 Apache 羽毛者(10 个)以及打绿勾者(PingCAP 公司)为部分进行商业化的开源项目。

5、中国开源商业化

1)开源新创企业融资

2)国内案例分析

① Jina AI

    Jina 首创的“神经搜索”,可以让企业利用可操作的非结构化数据构建搜索解决方案,做出更有效的业务决策。

    Jina AI 的社区运营,不论在关注度,还是下载量、贡献组织上都是非常成功的,其融资过程也非常顺利可喜。

② Zilliz

    Zilliz 是研发面向人工智能的新一代数据处理和分析平台 ,其主要是为应用型企业提供底层技术。

    Milvus 于 2019 年 10 月在 GitHub 开源,Stars 和 Docker Pulls 数量持续高速增长,2021 年 6 月达到 6,000+,拥有近 300 位贡献者和 10,000+ 用户的开发者社区。

    Zilliz 在 B & B+ 轮共获 1.13 亿美元,成为全球开源基础软件最大单笔 B 轮融资,表明了投资机构对 Zilliz 未来发展潜力的看好。

③ EMQ

    EMQ于 2013 年开源,2017 年公司成立,覆盖云边端的开源物联网消息中间件及流数据库产品。

    目前在全球拥有近 1 万家开源用户、近 400 家企业客户和 20 多家世界五百强合作伙伴,包括 HPE、VMware、Ericsson、Verifone、Telstra、Nokia、华为、中国电信、中国移动、上汽大众、中国银联、国家电网、台积电等海内外大型企业。

五、结语

不论是新创企业、领头羊企业,投资人、工具链、政府政策、开源组织、高校及科研机构以及媒体等组成的整个开源生态体系,都是围绕用户,以用户为中心的开源生态,因此用户是生态要素的消费者,也是生产者,是开源生态发展的重要引擎,期待有更多的企业用户携手开源雨林一起参与、使用、

开源使用优秀实践分享

开源生态优秀实践分享