google/trillian

GitHub: google/trillian

Trillian 是一个基于 Merkle 树的透明、高可扩展且密码学可验证的数据存储系统,主要用于构建证书透明性等透明日志应用。

Stars: 3738 | Forks: 452

# Trillian:通用透明度 [![Go Report Card](https://goreportcard.com/badge/github.com/google/trillian)](https://goreportcard.com/report/github.com/google/trillian) [![codecov](https://codecov.io/gh/google/trillian/branch/master/graph/badge.svg?token=QwofUwmvAs)](https://codecov.io/gh/google/trillian) [![GoDoc](https://godoc.org/github.com/google/trillian?status.svg)](https://godoc.org/github.com/google/trillian) [![Slack Status](https://img.shields.io/badge/Slack-Chat-blue.svg)](https://transparency-dev.slack.com/) - [概述](#overview) - [支持](#support) - [使用代码](#using-the-code) - [MySQL 设置](#mysql-setup) - [集成测试](#integration-tests) - [处理代码](#working-on-the-code) - [重新构建生成的代码](#rebuilding-generated-code) - [更新依赖](#updating-dependencies) - [运行代码库检查](#running-codebase-checks) - [设计](#design) - [设计概述](#design-overview) - [个性化应用](#personalities) - [Log 模式](#log-mode) - [用例](#use-cases) - [证书透明性日志](#certificate-transparency-log) ## 概述 Trillian 是以下文献中所描述概念的实现: [可验证数据结构](docs/papers/VerifiableDataStructures.pdf) 白皮书, 而该白皮书反过来也是支撑 [证书透明性](https://certificate-transparency.org) 的思想的扩展和推广。 Trillian 实现了一个 [Merkle 树](https://en.wikipedia.org/wiki/Merkle_tree), 其内容由数据存储层提供,以实现向超大型树的扩展性。在此 Merkle 树的基础上,Trillian 提供了以下功能: - 仅追加的 **Log** 模式,类似于最初的 [证书透明性](https://certificate-transparency.org) 日志。在此模式下,Merkle 树实际上是从左到右填充的,形成了一棵*密集的* Merkle 树。 请注意,Trillian 要求特定的应用程序在核心透明数据存储功能之上提供自己的[个性化应用](#personalities)。 [证书透明性 (CT)](https://tools.ietf.org/html/rfc6962) 是最著名且应用最广泛的透明性应用,在 [certificate-transparency-go 代码库](https://github.com/google/certificate-transparency-go/blob/master/trillian) 中提供了一个作为 Trillian 个性化应用的 CT 实现。其他 Trillian 个性化应用的示例可在 [trillian-examples](https://github.com/google/trillian-examples) 代码库中找到。 ## 使用代码 Trillian 代码库非常稳定,并被多个组织用于生产环境,包括许多大规模的 [证书透明性](https://certificate.transparency.dev) 日志运营方。 有鉴于此,我们不打算在此版本的 Trillian 中添加任何新功能,并会尽量避免任何进一步的不兼容代码和 schema 变更,但不能保证永远不需要这些变更。 当前的功能实现状态记录在[功能实现矩阵](docs/Feature_Implementation_Matrix.md)中。 要构建和测试 Trillian,您需要: - Go 1.25 或更高版本(Go 1.25 与 cloudbuild 匹配,推荐将向此项目提交 PR 的开发者使用)。 要运行许多测试(以及生产部署),您需要: - [MySQL](https://www.mysql.com/) 或 [MariaDB](https://mariadb.org/) 来提供数据存储层;请参阅 [MySQL 设置](#mysql-setup) 部分。 请注意,此代码库使用 Go 模块来管理依赖项;Go 会在构建/测试时自动获取并安装它们。 要获取代码、依赖项并构建 Trillian,请运行以下命令: ``` git clone https://github.com/google/trillian.git cd trillian go build ./... ``` 要构建仅包含您所需的存储和配额实现的更精简的 Trillian 二进制文件,请考虑指定 [构建标签](/storage/README.md#build-tags)。 要构建并运行测试,请使用: ``` go test ./... ``` 该代码库还包括多进程集成测试,将在下方的[集成测试](#integration-tests)部分中进行说明。 ### MySQL 设置 要运行 Trillian 的集成测试,您需要运行一个 MySQL 实例并将其配置为: - 监听标准 MySQL 端口 3306(这样 `mysql --host=127.0.0.1 --port=3306` 就能成功连接) - 不要求 `root` 用户提供密码 然后,您可以像这样在 `test` 数据库中设置[预期的表](storage/mysql/schema/storage.sql): ``` ./scripts/resetdb.sh Warning: about to destroy and reset database 'test' Are you sure? y > Resetting DB... > Reset Complete ``` ### 集成测试 Trillian 包含一个集成测试套件,用于确认基本的端到端功能,可以通过以下方式运行: ``` ./integration/integration_test.sh ``` 这会运行一个多进程测试: - 一个[测试](integration/log_integration_test.go),它会在 Log 模式下启动一个 Trillian 服务器以及一个签名器,记录许多叶子节点,并检查它们是否被正确整合。 ### 部署 您可以在 [deployment](/deployment) 和 [examples/deployment](/examples/deployment) 目录中找到有关如何部署 Trillian 的说明。 ## 处理代码 想要对 Trillian 代码库进行更改的开发者需要一些额外的依赖和工具,将在以下部分进行说明。[Cloud Build 配置](cloudbuild.yaml) 及其依赖的脚本也是所需工具和脚本的有用参考,因为它可能比本文档更新。 任何想要添加新存储和/或配额实现的人都应该了解 Trillian 如何使用 [构建标签](/storage/README.md#build-tags)。 ### 重新构建生成的代码 部分 Trillian Go 代码是从其他文件自动生成的: - [gRPC](http://www.grpc.io/) 消息结构最初以 [protocol buffer](https://developers.google.com/protocol-buffers/) 消息定义的形式提供。另请参阅 https://grpc.io/docs/protoc-installation/。 - 一些单元测试使用了接口的 mock 实现;这些是通过 [GoMock](https://github.com/golang/mock) 从真实实现中创建的。 - 一些枚举具有使用 [stringer](https://godoc.org/golang.org/x/tools/cmd/stringer) 工具(`go get golang.org/x/tools/cmd/stringer`)创建的字符串转换方法(满足 `fmt.Stringer` 接口)。 只有在更改原始文件时,才需要重新生成 mock 或 protobuffer 文件。推荐的方法是使用 Cloud Build 所使用的 Docker 镜像: ``` docker build -f ./integration/cloudbuild/testbase/Dockerfile -t trillian-builder . docker run -it --mount type=bind,src="$(pwd)",target=/src trillian-builder /bin/bash -c "cd /src; ./scripts/install_deps.sh; go generate -x ./..." ``` 这些命令首先根据本代码库中的 Dockerfile 创建一个 docker 镜像,然后基于该镜像启动一个挂载了本地目录的容器。系统会使用本代码库中的 `go.mod` 文件确定正确的工具版本,并安装这些工具。最后,所有的生成文件都会被重新生成,随后 Docker 退出。 或者,您可以在本地安装先决条件: - 一系列工具,使用 `go install` 确保版本兼容且经过测试: cd $(go list -f '{{ .Dir }}' github.com/google/trillian); \ go install github.com/golang/mock/mockgen; \ go install google.golang.org/protobuf/proto; \ go install google.golang.org/protobuf/cmd/protoc-gen-go; \ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc; \ go install github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc; \ go install golang.org/x/tools/cmd/stringer 并运行以下命令: ``` go generate -x ./... # hunts for //go:generate comments and runs them ``` ### 更新依赖 Trillian 代码库使用 go.mod 来声明其固定的依赖项版本。 使用 Go 模块时,更新依赖项只需运行 `go get` 即可: ``` go get package/path # Fetch the latest published version go get package/path@X.Y.Z # Fetch a specific published version go get package/path@HEAD # Fetch the latest commit ``` 要将所有依赖项更新到最新版本,请运行 `go get -u`。 但请注意,这可能会撤销那些为了解决其他非模块代码库中问题而特意选择的版本。 在运行 `go build` 和 `go test` 时,go 会将任何有歧义的传递依赖项添加到 `go.mod` 中 要清理它们,请运行: ``` go mod tidy ``` ### 运行代码库检查 [`scripts/presubmit.sh`](scripts/presubmit.sh) 脚本会在代码库上运行各种工具和测试。 #### 安装 [golangci-lint](https://golangci-lint.run/welcome/install/#install-from-sources)。 ``` go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.10.1 ``` #### 运行代码生成、构建、测试和 linter ``` ./scripts/presubmit.sh ``` #### 或者仅运行 linter ``` golangci-lint run ``` ## 设计 ### 设计概述 Trillian 主要被实现为一个 [gRPC 服务](http://www.grpc.io/docs/guides/concepts.html#service-definition); 该服务通过 gRPC 接收 get/set 请求,并从独立的存储层(目前使用 MySQL)检索相应的 Merkle 树数据,以确保在此过程中树的密码学属性得以保留。 Trillian 服务是多租户的——单个 Trillian 安装可以并行支持多棵 Merkle 树,并通过它们的 `TreeId` 进行区分——每棵树都在以下两种模式之一下运行: - **Log** 模式:一个仅追加的项目集合;它包含两个子模式: - 正常 Log 模式,Trillian 服务会在新的树条目到达时为其分配序列号 - “预排序” Log 模式,Merkle 树中条目的唯一序列号由外部指定 无论哪种情况,Trillian 的关键透明性属性在于:对于添加到服务中的数据项,都可以提供用于证明包含性/一致性的密码学证明。 ### 个性化应用 要构建一个完整的透明应用程序,需要将 Trillian 核心服务与称为*个性化应用* (personality) 的附加代码配对使用,该代码提供了特定于具体应用程序的功能。 特别地,个性化应用负责: * **准入标准** – 确保提交的内容符合应用程序的整体用途。 * **规范化** – 确保相同数据的等效版本获得相同的规范标识符,以便 Trillian 核心服务可以对它们进行去重。 * **外部接口** – 为外部用户提供 API,包括任何实际限制(ACL、负载均衡、DoS 防护等)。 这在[另一篇单独的文档中有更详细的描述](docs/Personalities.md)。 通常情况下,有关[透明 Log 应用程序的设计考量](docs/TransparentLogging.md)也会单独进行讨论。 ### Log 模式 在 Log 模式下运行时,Trillian 提供了一个 gRPC API,其操作类似于证书透明性日志可用的操作(参见 [RFC 6962](https://tools.ietf.org/html/6962))。这些操作包括: - `GetLatestSignedLogRoot` 返回有关日志当前 Merkle 树根的信息,包括树大小、哈希值、时间戳和签名。 - `GetLeavesByRange` 根据日志中的索引返回特定叶子的信息。 - `QueueLeaf` 请求将指定项包含在日志中。 - 对于预排序日志,`AddSequencedLeaves` 请求将指定项包含在树中指定的位置。 - `GetInclusionProof`、`GetInclusionProofByHash` 和 `GetConsistencyProof` 返回包含性和一致性证明数据。 在 Log 模式下(无论是正常模式还是预排序模式),Trillian 都包含一个额外的签名器 (Signer) 组件;该组件会定期处理待处理项目并将它们添加到 Merkle 树中,从而生成一个新的已签名树头。 ![Log 组件](https://static.pigsec.cn/wp-content/uploads/repos/cas/20/20514760d83646c08abacb445a9adfcbb9750b929f86529ed04d6163edd16a7a.png) (请注意,为了可扩展性和弹性,此图中的每个组件都可以是[分布式的](https://github.com/google/certificate-transparency-go/blob/master/trillian/docs/ManualDeployment.md#distribution)。) ## 用例 ### 证书透明性日志 Trillian 在 Log 模式下最明显的应用是提供证书透明性 (RFC 6962) 日志。为此,CT 日志的个性化应用需要包含所有特定于证书的处理——特别是,检查被建议包含的项目是否确实是链接到受信任根的有效证书。
标签:EVTX分析, Go, Merkle树, Python工具, Ruby工具, 可验证数据结构, 密码学, 手动系统调用, 日志审计, 请求拦截, 透明日志