thinkst/package-proxy
GitHub: thinkst/package-proxy
部署于 Cloudflare Workers 的软件包仓库内联代理,为 pip、cargo、npm 等包管理器提供安装行为的可观测性与供应链安全策略控制。
Stars: 49 | Forks: 4
## Package Proxy
这是一个 Cloudflare Worker,可以被设置为 `uv/pip` 的 `index-url`、`cargo` 的 `registry` 或 `npm` 的 `registry`,并无缝地将请求代理到官方仓库。欲了解更多信息,请查看[博客文章](https://blog.thinkst.com/2026/06/introducing-package-proxy-supply-chain-safety-checks-without-client-side-software.html)。
### 安装说明
[](https://deploy.workers.cloudflare.com/?url=https%3A%2F%2Fgithub.com%2Fthinkst%2Fpackage-proxy)
#### 客户端配置
在 `./scripts/SetupPackageProxy.sh` 中有一个适用于 MacOS 的便捷设置脚本,只需使用你的 Cloudflare worker [子]域名编辑 `PACKAGE_PROXY_HOST`,并将其分发到你的整个设备群中。
或者,以下是手动步骤:
1. 将变量 `DOMAIN` 设置为 Worker 正在运行的 [子]域名:
```$ export DOMAIN=thinkst-package-proxy.mypackageproxy.workers.dev```
2. **pip**:
```$ pip config set global.index-url https://$USER@$DOMAIN$/pypi/```
3. **uv**:
```$ echo "index-url = \"https://$USER@$DOMAIN/pypi/\"" >> ~/.config/uv/uv.toml```
4. **cargo**:
```$ echo -e "[registries]\npackage-proxy = { index = \"sparse+https://$USER@$DOMAIN/\" }\n[source.crates-io]\nreplace-with = \"package-proxy\"" >> ~/.cargo/config.toml```
5. **npm**:
```$ npm config set registry https://$DOMAIN && npm config set //$DOMAIN/:_auth=$(echo -n "$USER:" | base64)```
### 用法
像往常一样使用包管理器,不过如果某个包版本已被下架,客户端将直接报告未找到(HTTP 404),而不会显示其下架的具体错误/原因。
### 包规则
代理默认配置为阻止安装符合以下条件的包:
- 发布时间少于 10 天的版本 (`MIN_AGE_DAYS`)
- 未被“撤回”的版本 (`ALLOW_YANKED`)
- 发布方式不如前一版本可靠的版本 (`ALLOW_CHANGED_PUBLISHER`)
- 特定的已知恶意版本(以 [PURL 类型](https://github.com/package-url/purl-spec)开头),例如 `npm/axios==0.30.4`,或 `pypi/base-x-64: ALL` (`blocklist`)
其余配置选项包括:
- `npm audit` 是否可以绕过最低时间限制 (`ALLOW_AUDIT_OVERRIDE`)
- 下载内容本身是否应通过代理提供服务(这也是执行日志记录的环节)(`REWRITE_DOWNLOAD_URLS`)
- 特定版本的允许列表 (`allowlist`)
- 可以定义一个 webhook URL (`webhook-url`),某些被阻止下载的详细信息将被发送到该地址。这在例如集成了 Slack 的环境中非常有用,可以为包无法安装提供上下文说明。
#### 划分配置范围
这些配置可以针对组织内的逻辑单元进行指定。如果提供了组织名称(子域名),那么
代理将在 KV store 中查找 `org-`(例如,acme.packageproxy.dev 将在 `org-acme` 中配置)。否则,
将使用 `default` 键的配置。如果不存在任何配置,系统将创建一个默认配置,其中包含
`./scripts/default-kv.json` 中的值。可以使用 `npx wrangler kv` 命令或通过
[Web 仪表板](https://dash.cloudflare.com)编辑此文件并将其推送到 KV store。
#### 修改规则值
规则存储在 KV store 中。为了手动修改它们:
1. 登录 Cloudflare [仪表板](https://dash.cloudflare.com)
2. 点击 "Storage & databases" > "Workers KV"
3. 点击与你的 Package Proxy 关联的 KV store
4. 点击 "KV Pairs" 标签页
5. 点击 `org-` 键上的 "View",然后点击 "Edit"
6. 更新你想要修改的配置值,然后点击 "Save"。更改将立即(在一两秒内)对 Worker 生效,无需进行任何进一步操作。
也可以使用 wrangler:
1. 获取当前设置:
```
$ namespace_id=$( \
npx wrangler kv namespace list | \
jq -r '.[] | select(.title | endswith("package-proxy")) | .id' \
)
$ org_name=$(npx wrangler kv key list --remote --namespace-id "${namespace_id}" | jq -r '.[] | select(.name | startswith("org-")) | .name')
$ npx wrangler kv key get --remote --namespace-id "${namespace_id}" "${org_name}" > "${org_name}.json"
```
2. 现在编辑 `${org_name}.json`,更新你的规则并保存。
3. 确认它仍然是有效的 JSON:
```
$ jq . "${org_name}.json"
```
4. 最后,写回 Cloudflare:
```
$ npx wrangler kv key put --remote --namespace-id "${namespace_id}" "${org_name}" "$(cat ${org_name}.json)"
```
## 可观测性
一旦代理被用于安装包,它将把用户和组织记录到已创建的 D1 数据库中。可以通过 [Cloudflare 仪表板](https://dash.cloudflare.com)、`wrangler` CLI 或 [API](https://developers.cloudflare.com/api/resources/d1) 查询或探索这些数据。
一些示例查询包括:
- 返回所有安装过特定包的用户(及相应版本):`SELECT DISTINCT UserId, CONCAT(PackageName, '@', PackageVersion) as Installed FROM Installs WHERE PackageName LIKE ?;`
- 获取已安装包的总数:`SELECT COUNT(*) FROM Installs;`
- 获取所有已安装包的名称:`SELECT DISTINCT PackageName FROM Installs;`
使用 Wrangler,这些操作变为:
```
# 已安装的所有 packages 的名称
$ npx wrangler d1 execute install-logs --remote --command 'SELECT DISTINCT PackageName FROM Installs'
# 查明谁安装了 requests
$ npx wrangler d1 execute install-logs --remote --command "SELECT DISTINCT UserId, CONCAT(PackageName, '@', PackageVersion) as Installed FROM Installs WHERE PackageName LIKE '%requests'"
# 已安装的 packages 总数
$ npx wrangler d1 execute install-logs --remote --command 'SELECT COUNT(*) FROM Installs'
```
标签:代理服务, 依赖管理, 安全策略, 提示词设计, 数据可视化, 程序员工具, 自动化攻击