go-licenses是Google官方Go许可证扫描工具,可准确提取go.mod中所有依赖的许可证文件并导出归档,不依赖网络,仅解析模块元数据和源码仓库中的声明。

用 go-licenses 扫描并导出许可证文件
go-licenses 是 Google 官方维护的 Go 模块许可证提取工具,能准确识别 go.mod 中所有依赖(含间接依赖)的许可证类型,并把原始 LICENSE 文件复制到本地目录归档。它不依赖网络请求或外部数据库,只解析模块元数据和源码仓库中的许可证声明。
安装与使用步骤:
- 执行
go install github.com/google/go-licenses@latest(Go 1.21+ 推荐加-buildvcs=false避免 Git 权限问题) - 确保当前目录含有效
go.mod,且已运行过go mod download(否则部分模块无法读取go.sum或源码) - 运行
go-licenses save . --save_path=third_party_licenses,它会为每个依赖创建子目录,放入LICENSE、NOTICE等文本文件 - 若某模块无明确许可证声明,
go-licenses会标为UNKNOWN,需人工核查其pkg.go.dev页面或 GitHub 仓库根目录
用 go list -m -json 提取许可证字段做自动化判断
go list -m -json all 输出的 JSON 中包含 License 字段,但该字段不可靠:它仅来自模块作者在 go.mod 中手动填写的字符串,或从 GitHub/GitLab 的 LICENSE 文件名启发式推断,**不校验内容真实性**。例如 github.com/gorilla/mux 的 License 字段常为空,而实际是 BSD-3-Clause。
更稳妥的做法是结合字段 + 路径规则做预筛:
立即学习“go语言免费学习笔记(深入)”;
Colly 是一个用于 Go 语言的快速开源爬取和爬虫框架。它适用于从简单的页面提取到异步爬虫处理大量页面集合,支持请求回调和结构化解析。
- 过滤出含
"License": "GPL"、"License": "AGPL"等高风险关键词的模块:go list -m -json all | jq -r 'select(.License and (.License | test("GPL|AGPL|SSPL"; "i"))) | .Path' - 对
.License为空的模块,用go list -m -f '{{.Path}} {{.Dir}}' <module>获取本地路径,再检查<Dir>/LICENSE*文件是否存在及内容 - 注意:标准库模块(如
net/http)不会出现在go list -m all结果中,无需扫描其许可证
规避 license-checker 等跨语言工具对 Go 的误判
像 license-checker(Node.js 工具)或 pip-licenses(Python 工具)虽声称支持多语言,但对 Go 项目基本无效——它们依赖 package.json 或 requirements.txt 解析逻辑,无法理解 go.mod 的模块路径映射、replace 规则或间接依赖的版本来源。强行运行可能漏掉 70% 以上依赖,或把 golang.org/x/net 这类子模块识别成独立包导致重复计数。
真正适配 Go 生态的只有三类工具:
- 专用于 Go 的:
go-licenses(导出文件)、gosbom(生成 SPDX SBOM) - 通用型但原生支持
go.mod解析的:osv-scanner(同时扫漏洞+许可证,命令为osv-scanner scan source --config=osv-scanner.toml) - CI/CD 插件:
syft(支持go-mod解析器,输出 CycloneDX,需加--file-type go-mod)
别用 npm ls --prod --depth=10 那套思路套 Go —— go list -m all 和 go mod graph 才是真实依赖图谱的唯一可信来源。
识别 GPL 类传染性许可证的实际风险点
扫描出某个依赖带 GPL 许可证不等于项目违规,关键看**链接方式和分发形态**。Go 静态链接特性让风险比 C/C++ 更隐蔽:
- 若你项目直接 import 了
github.com/evil/gpl-lib(GPLv3),且最终二进制分发给第三方,则整个项目需按 GPLv3 开源 —— 即使只调用了其中一行函数 - 但若该 GPL 库仅被某个测试工具(如
ginkgo)依赖,且未打包进生产二进制,风险可控 - 最易被忽略的是
golang.org/x/...系列模块:它们多数是 MIT,但个别(如旧版golang.org/x/crypto某些分支)曾含 GPL 兼容例外条款,需查具体 commit - 用
go mod why -m github.com/evil/gpl-lib确认它是否真被主模块 import;若输出# github.com/evil/gpl-lib后跟一堆(imported by)链,则必须处理
许可证合规不是“有没有 GPL”,而是“谁在什么上下文中用了它、怎么用的、要不要分发”。工具只能标出候选项,最终判断得靠人盯住 go mod graph 和实际构建产物。

















