我们开源了隐私代理 CLI
调试隐私保护协议是一项艰巨的任务。Oblivious HTTP 涉及四个不同参与方的多个步骤,更不用说二进制 HTTP 编码以及分散在许多草案 RFC 中的细节。我们将操作 Oblivious HTTP 时从每秒数百万请求规模中学到的知识,封装成一个简洁的命令行工具——今天我们将其开源。
我们称之为 <strong>privacy-client</strong> 或 <strong>pvcli</strong>。我们在 Apache-2.0 许可下发布它,并且它是 [开放接受贡献](https://github.com/cloudflareresearch/pvcli)。
以下是一行代码,执行带有中继、网关和源的完整 Oblivious HTTP 请求。如果你不明白这意味着什么,别担心,我们接下来会详细介绍。
我们将解释构建该工具的原因,并展示它的便利之处。
### 为什么隐私协议难以调试
让我们更仔细地看看创建 pvcli 的动力。随着时间的推移,隐私团队的产品组合和客户基础不断扩大。我们添加了 Privacy Proxy 和 Privacy Gateway 等产品,支持苹果的 [Private Relay](https://blog.cloudflare.com/icloud-private-relay/)、微软的 [Edge Secure Network VPN](https://blog.cloudflare.com/cloudflare-now-powering-microsoft-edge-secure-network/) 以及 Flo Health 的 [Anonymous Mode](https://www.cloudflare.com/case-studies/flo-health/) 等。随之而来的还有越来越多的特别客户需求、领域知识和复杂性。这导致我们在开发和事件响应中面临更大的摩擦。
为了具体说明这一点,让我们看看我们的一个产品如何实现 [Oblivious HTTP](https://developers.cloudflare.com/privacy-gateway/),也称为 OHTTP。首先,先简单介绍一下。OHTTP 为用户提供隐私保证:没有人能够同时知道 <em>谁</em> 发起了请求和 <em>他们在请求什么</em>。为了实现这一点,OHTTP 需要两台服务器,一个中继和一个网关,由两个不相互勾结的参与方操作。
以下是 OHTTP 的顺序图,其中我们的客户拥有中继,而 Cloudflare 拥有网关。从高层次看,OHTTP 可以分为以下步骤:
1. 客户端从网关获取公钥。
2. 客户端加密请求并将其发送到中继。
3. 中继从加密请求中移除客户的身份信息,然后将其发送到网关。
4. 网关解密请求并将其发送到目标。
5. 目标处理请求,并将响应发送到网关。
6. 网关加密响应并发送到中继。
7. 中继将加密响应发送给客户端。
8. 客户端解密,并获取明文响应。
如你所见,这个过程涉及相当多的往返。
每一步都是我们在调试时需要考虑的潜在故障点!
尤其是在调试 OHTTP 时,我们看到某些类型的问题。
- 客户要求从他们这边测试实时系统,而我们经常为特定客户的部署编写一次性定制客户端。
- 找出哪个步骤导致了问题耗时费力。根本原因是我们系统中的错误还是客户系统中的错误?
- 检查原始数据位是一项繁琐且容易出错的工作。OHTTP 构建在二进制 HTTP 之上,二进制 HTTP 是一种二进制编码的 HTTP 请求。每当我们需要检查二进制编码时,都会费尽心思地检查原始数据位。
因此,我们决定将所有隐私协议放在一个工具中。该工具具有干净的界面,已经非常熟悉,以顺序显示协议的每一个步骤,还灵活到可以支持新协议和架构。
接下来,让我们看看使用 pvcli 进行 OHTTP 调试的不同之处。
### 使用 pvcli 之前的调试
假设我们操作一个位于客户网关前的 OHTTP 中继。客户要求我们进行一次端到端测试,发送请求:
回顾一下之前 OHTTP 的步骤。第一步是从网关获取公钥。我们使用 curl 从客户网关获取它,得到以下结果:
这是一个大的十六进制二进制字符串。为了弄清楚它的内容,我们查阅 OHTTP [RFC 9458 §3](https://www.rfc-editor.org/rfc/rfc9458#name-key-configuration-encoding),并手动解析:
- `0029` 在十进制中是 41,表示这个公钥条目有 41 字节。
- `55` 是公钥 ID。
- `0020` 识别我们可以使用的非对称加密方法。在这种情况下,DHKEM(X25519, HKDF-SHA256)。
- `b9bb667e2230dc01c6d6cc047f94a1083beb185c63e50ec09f7692a5a0832540` 是公钥。
- `0004` 表示接下来有 4 字节的对称加密 ID。
- `0001` 和 `0001` 识别我们可以使用的对称加密方法:HKDF-SHA256 和 AES-128-GCM。
我们对二进制字符串中的每个公钥重复这个过程。
接下来,我们将原始 HTTP 请求转换为二进制 HTTP,参考 [RFC 9292](https://www.rfc-editor.org/rfc/rfc9292)。我们凭借一些定制脚本手动构建二进制。
我们验证每个字段:
- `02` 意味着这是一个不确定长度的请求
- `04504f5354` 是 `POST`
- `056874747073` 是 https
- `117461726765742e6f687474702e696e666f` 是 `target.ohttp.info`
- 其他依此类推
最后,我们形成一个包裹 HTTP 请求,来包含我们的 OHTTP 请求。为此,我们又花了一些时间编写另外一个临时脚本,以 OHTTP 指定的方式使用之前的公钥加密二进制 HTTP 请求。我们创建一个头部,头部是公钥 ID、非对称加密方法 ID 和对称加密方法 ID 的连接。然后我们将头部和加密的二进制 HTTP 请求连接起来,形成:
我们将这些字节放入包裹 HTTP 请求的主体中,并发送给我们的中继。我们得到了响应。
这意味着什么?我们联系客户,询问是否可以共享他们网关的日志。与此同时,我们再次检查我们制作的位。解码后的公钥看起来不错。二进制 HTTP 请求……哦!我们发现:
BHTTP 是带长度前缀的。这意味着我们指定一个长度(0x0a 是 10 的十进制),然后后面跟着 10 个字节。但此处,后面跟着 11 个字节。在 `00` 之前多了一个 20。20 代表一个空格字符,因此我们在构建主体时可能不小心添加了这个。我们删除多余的字符,重新发送,成功了!
### 使用 pvcli 的调试
有了 pvcli,所有这些现在只需一条命令:
它为我们处理所有的二进制解析和加密,并在我们想深入了解时打印日志。
过去脆弱的过程——涉及操作位、拼接脚本和参考冗长的 RFC——如今只需一条命令。
### pvcli 能做什么
要安装:
pvcli 受到 curl 的启发。我们在设计时遵循“最小惊讶原则”。因此,许多参数与 curl 相同!尝试执行一个快速的 GET 请求到我们的 [cdn-cgi endpoint](https://developers.cloudflare.com/fundamentals/reference/cdn-cgi-endpoint/):
如果你想了解底层发生了什么,可以使用 `-v` 获取详细日志:
顺便说一下之前提到的 OHTTP 命令:你可以使用 `--ohttp` 来告诉 pvcli 构建一个 OHTTP 请求。你将中继作为 `--first-hop`,将网关作为 `--proxy`。目标将是一个回声服务器,这样你就可以看到目标所看到的内容。在这个命令中,我们用来自 [ohttp.info](http://ohttp.info) 的中继、网关和目标填充了参数。
尝试自己运行这个命令!
我们遇到过许多情况,我们希望将标头传递给中继,而不是目标。你可以使用 `--first-hop-header` 来做到这一点。
同样,我们也遇到过想通过 [mTLS](https://www.cloudflare.com/learning/access-management/what-is-mutual-tls/) 验证中继的情况,以确保正确的客户端与正确的中继通信。为此,你可以使用 `--first-hop-client` 和 `--first-hop-key`。
而且它就是这样运作的。需要测试完整的 Oblivious HTTP 请求,带有中继、网关、任意标头和 mTLS?还是仅通过网关请求?或许你只是想查看 OHTTP 密钥配置?pvcli 可以通过一条命令完成,调试已包括在内。
### 为什么要构建我们自己的工具?
市面上已经存在一些很好的 OHTTP 工具。马丁·汤姆森(Martin Thomson)的 [Rust 实现](https://github.com/martinthomson/ohttp) 和克里斯·伍德(Chris Wood)的 [Go 实现](https://github.com/chris-wood/ohttp-go) 在我们几年前构建原始 OHTTP 实现时给予了我们巨大的帮助。但是,pvcli 不仅专注于 OHTTP。我们希望尽可能多地将隐私保护协议添加到该工具中。因此,尽管市场上有其他开源工具可用来调试 OHTTP,但没有一个工具能够将 OHTTP、CONNECT 代理、MASQUE 和隐私通行证(即将到来)全部集成在一个地方。
### 贡献 pvcli
Oblivious HTTP 是一项令人惊叹的协议,我们希望看到你使用它。我们希望这个工具能帮助人们调试 OHTTP 并编写自己的 OHTTP 实现。
我们欢迎贡献!要开始,请克隆 [这个代码库](https://github.com/cloudflareresearch/pvcli),并提交一个拉取请求。
如果你在寻找贡献的方式,这里有一些在待办事项列表上的事情。对于 MASQUE,我们计划增加对通过 HTTP/3 代理 TCP、HTTP/2 和 HTTP/3 代理 UDP 和/或 IP 的支持。对于 OHTTP,我们计划支持后量子密码学,添加时间/延迟信息,支持 Chunked OHTTP,并改进日志记录。
如果你有兴趣使用 Cloudflare 的 OHTTP 中继和网关,请 [联系我们](https://www.cloudflare.com/lp/privacy-edge/)。
---
原文链接:[点击查看](https://blog.cloudflare.com/open-sourcing-our-privacy-proxy-cli/)
我们称之为 <strong>privacy-client</strong> 或 <strong>pvcli</strong>。我们在 Apache-2.0 许可下发布它,并且它是 [开放接受贡献](https://github.com/cloudflareresearch/pvcli)。
以下是一行代码,执行带有中继、网关和源的完整 Oblivious HTTP 请求。如果你不明白这意味着什么,别担心,我们接下来会详细介绍。
我们将解释构建该工具的原因,并展示它的便利之处。
### 为什么隐私协议难以调试
让我们更仔细地看看创建 pvcli 的动力。随着时间的推移,隐私团队的产品组合和客户基础不断扩大。我们添加了 Privacy Proxy 和 Privacy Gateway 等产品,支持苹果的 [Private Relay](https://blog.cloudflare.com/icloud-private-relay/)、微软的 [Edge Secure Network VPN](https://blog.cloudflare.com/cloudflare-now-powering-microsoft-edge-secure-network/) 以及 Flo Health 的 [Anonymous Mode](https://www.cloudflare.com/case-studies/flo-health/) 等。随之而来的还有越来越多的特别客户需求、领域知识和复杂性。这导致我们在开发和事件响应中面临更大的摩擦。
为了具体说明这一点,让我们看看我们的一个产品如何实现 [Oblivious HTTP](https://developers.cloudflare.com/privacy-gateway/),也称为 OHTTP。首先,先简单介绍一下。OHTTP 为用户提供隐私保证:没有人能够同时知道 <em>谁</em> 发起了请求和 <em>他们在请求什么</em>。为了实现这一点,OHTTP 需要两台服务器,一个中继和一个网关,由两个不相互勾结的参与方操作。
以下是 OHTTP 的顺序图,其中我们的客户拥有中继,而 Cloudflare 拥有网关。从高层次看,OHTTP 可以分为以下步骤:
1. 客户端从网关获取公钥。
2. 客户端加密请求并将其发送到中继。
3. 中继从加密请求中移除客户的身份信息,然后将其发送到网关。
4. 网关解密请求并将其发送到目标。
5. 目标处理请求,并将响应发送到网关。
6. 网关加密响应并发送到中继。
7. 中继将加密响应发送给客户端。
8. 客户端解密,并获取明文响应。
如你所见,这个过程涉及相当多的往返。
每一步都是我们在调试时需要考虑的潜在故障点!
尤其是在调试 OHTTP 时,我们看到某些类型的问题。
- 客户要求从他们这边测试实时系统,而我们经常为特定客户的部署编写一次性定制客户端。
- 找出哪个步骤导致了问题耗时费力。根本原因是我们系统中的错误还是客户系统中的错误?
- 检查原始数据位是一项繁琐且容易出错的工作。OHTTP 构建在二进制 HTTP 之上,二进制 HTTP 是一种二进制编码的 HTTP 请求。每当我们需要检查二进制编码时,都会费尽心思地检查原始数据位。
因此,我们决定将所有隐私协议放在一个工具中。该工具具有干净的界面,已经非常熟悉,以顺序显示协议的每一个步骤,还灵活到可以支持新协议和架构。
接下来,让我们看看使用 pvcli 进行 OHTTP 调试的不同之处。
### 使用 pvcli 之前的调试
假设我们操作一个位于客户网关前的 OHTTP 中继。客户要求我们进行一次端到端测试,发送请求:
回顾一下之前 OHTTP 的步骤。第一步是从网关获取公钥。我们使用 curl 从客户网关获取它,得到以下结果:
这是一个大的十六进制二进制字符串。为了弄清楚它的内容,我们查阅 OHTTP [RFC 9458 §3](https://www.rfc-editor.org/rfc/rfc9458#name-key-configuration-encoding),并手动解析:
- `0029` 在十进制中是 41,表示这个公钥条目有 41 字节。
- `55` 是公钥 ID。
- `0020` 识别我们可以使用的非对称加密方法。在这种情况下,DHKEM(X25519, HKDF-SHA256)。
- `b9bb667e2230dc01c6d6cc047f94a1083beb185c63e50ec09f7692a5a0832540` 是公钥。
- `0004` 表示接下来有 4 字节的对称加密 ID。
- `0001` 和 `0001` 识别我们可以使用的对称加密方法:HKDF-SHA256 和 AES-128-GCM。
我们对二进制字符串中的每个公钥重复这个过程。
接下来,我们将原始 HTTP 请求转换为二进制 HTTP,参考 [RFC 9292](https://www.rfc-editor.org/rfc/rfc9292)。我们凭借一些定制脚本手动构建二进制。
我们验证每个字段:
- `02` 意味着这是一个不确定长度的请求
- `04504f5354` 是 `POST`
- `056874747073` 是 https
- `117461726765742e6f687474702e696e666f` 是 `target.ohttp.info`
- 其他依此类推
最后,我们形成一个包裹 HTTP 请求,来包含我们的 OHTTP 请求。为此,我们又花了一些时间编写另外一个临时脚本,以 OHTTP 指定的方式使用之前的公钥加密二进制 HTTP 请求。我们创建一个头部,头部是公钥 ID、非对称加密方法 ID 和对称加密方法 ID 的连接。然后我们将头部和加密的二进制 HTTP 请求连接起来,形成:
我们将这些字节放入包裹 HTTP 请求的主体中,并发送给我们的中继。我们得到了响应。
这意味着什么?我们联系客户,询问是否可以共享他们网关的日志。与此同时,我们再次检查我们制作的位。解码后的公钥看起来不错。二进制 HTTP 请求……哦!我们发现:
BHTTP 是带长度前缀的。这意味着我们指定一个长度(0x0a 是 10 的十进制),然后后面跟着 10 个字节。但此处,后面跟着 11 个字节。在 `00` 之前多了一个 20。20 代表一个空格字符,因此我们在构建主体时可能不小心添加了这个。我们删除多余的字符,重新发送,成功了!
### 使用 pvcli 的调试
有了 pvcli,所有这些现在只需一条命令:
它为我们处理所有的二进制解析和加密,并在我们想深入了解时打印日志。
过去脆弱的过程——涉及操作位、拼接脚本和参考冗长的 RFC——如今只需一条命令。
### pvcli 能做什么
要安装:
pvcli 受到 curl 的启发。我们在设计时遵循“最小惊讶原则”。因此,许多参数与 curl 相同!尝试执行一个快速的 GET 请求到我们的 [cdn-cgi endpoint](https://developers.cloudflare.com/fundamentals/reference/cdn-cgi-endpoint/):
如果你想了解底层发生了什么,可以使用 `-v` 获取详细日志:
顺便说一下之前提到的 OHTTP 命令:你可以使用 `--ohttp` 来告诉 pvcli 构建一个 OHTTP 请求。你将中继作为 `--first-hop`,将网关作为 `--proxy`。目标将是一个回声服务器,这样你就可以看到目标所看到的内容。在这个命令中,我们用来自 [ohttp.info](http://ohttp.info) 的中继、网关和目标填充了参数。
尝试自己运行这个命令!
我们遇到过许多情况,我们希望将标头传递给中继,而不是目标。你可以使用 `--first-hop-header` 来做到这一点。
同样,我们也遇到过想通过 [mTLS](https://www.cloudflare.com/learning/access-management/what-is-mutual-tls/) 验证中继的情况,以确保正确的客户端与正确的中继通信。为此,你可以使用 `--first-hop-client` 和 `--first-hop-key`。
而且它就是这样运作的。需要测试完整的 Oblivious HTTP 请求,带有中继、网关、任意标头和 mTLS?还是仅通过网关请求?或许你只是想查看 OHTTP 密钥配置?pvcli 可以通过一条命令完成,调试已包括在内。
### 为什么要构建我们自己的工具?
市面上已经存在一些很好的 OHTTP 工具。马丁·汤姆森(Martin Thomson)的 [Rust 实现](https://github.com/martinthomson/ohttp) 和克里斯·伍德(Chris Wood)的 [Go 实现](https://github.com/chris-wood/ohttp-go) 在我们几年前构建原始 OHTTP 实现时给予了我们巨大的帮助。但是,pvcli 不仅专注于 OHTTP。我们希望尽可能多地将隐私保护协议添加到该工具中。因此,尽管市场上有其他开源工具可用来调试 OHTTP,但没有一个工具能够将 OHTTP、CONNECT 代理、MASQUE 和隐私通行证(即将到来)全部集成在一个地方。
### 贡献 pvcli
Oblivious HTTP 是一项令人惊叹的协议,我们希望看到你使用它。我们希望这个工具能帮助人们调试 OHTTP 并编写自己的 OHTTP 实现。
我们欢迎贡献!要开始,请克隆 [这个代码库](https://github.com/cloudflareresearch/pvcli),并提交一个拉取请求。
如果你在寻找贡献的方式,这里有一些在待办事项列表上的事情。对于 MASQUE,我们计划增加对通过 HTTP/3 代理 TCP、HTTP/2 和 HTTP/3 代理 UDP 和/或 IP 的支持。对于 OHTTP,我们计划支持后量子密码学,添加时间/延迟信息,支持 Chunked OHTTP,并改进日志记录。
如果你有兴趣使用 Cloudflare 的 OHTTP 中继和网关,请 [联系我们](https://www.cloudflare.com/lp/privacy-edge/)。
---
原文链接:[点击查看](https://blog.cloudflare.com/open-sourcing-our-privacy-proxy-cli/)
评论
暂无评论。