Posted in

Go Modules在Mac激活后频繁proxy失败?Apple Private Relay+DNS over HTTPS双重干扰下的5种代理穿透方案

第一章:Go Modules在Mac激活后的代理失效现象全景透视

当 macOS 用户启用 Go Modules 后,常遭遇 go getgo mod download 突然失败、超时或返回 proxy.golang.org:443: dial tcp: i/o timeout 等错误,而此前配置的 GOPROXY(如 https://goproxy.cn,direct)看似生效却实际被绕过。该现象并非代理服务宕机所致,而是 Go 工具链在特定条件下自动降级或忽略代理配置的深层行为。

代理失效的核心诱因

Go 自 1.13 起默认启用模块验证(GOSUMDB=sum.golang.org),该服务强制通过 HTTPS 访问校验和数据库;若系统证书链异常(如安装了自签名根证书)、DNS 解析受干扰,或 sum.golang.org 被防火墙拦截,Go 会静默回退至直连模式(direct),同时跳过所有 GOPROXY 设置——即使 go env GOPROXY 显示正常。

验证代理是否真实生效

执行以下命令观察实际网络路径:

# 启用详细调试日志
GO111MODULE=on GOPROXY=https://goproxy.cn,direct GOSUMDB=off go mod download -x rsc.io/quote@v1.5.2

注:GOSUMDB=off 临时禁用校验和检查,避免其干扰代理路由;-x 输出每步执行命令与网络请求目标。若日志中出现 https://goproxy.cn/... 则代理生效;若直接访问 https://proxy.golang.org/...https://rsc.io/quote/@v/v1.5.2.info,说明代理已被绕过。

常见修复路径

问题类型 检查项 解决方案
系统证书异常 curl -v https://goproxy.cn 更新 macOS 根证书或设置 GODEBUG=x509ignoreCN=1(仅测试)
GOSUMDB 干扰 go env GOSUMDB 设为 off 或替换为可信镜像(如 sum.golang.google.cn
DNS 污染 dig sum.golang.org +short 修改 /etc/resolv.conf 使用纯净 DNS(如 1.1.1.1

终极配置建议

永久生效需同步调整三项环境变量:

echo 'export GOPROXY=https://goproxy.cn,direct' >> ~/.zshrc
echo 'export GOSUMDB=sum.golang.google.cn' >> ~/.zshrc
echo 'export GOINSECURE=""' >> ~/.zshrc  # 避免私有模块误触发 insecure 模式
source ~/.zshrc

此后运行 go mod download 将严格遵循代理链路,且校验和服务与模块代理协同工作,不再出现“配置存在但未生效”的幻觉。

第二章:Apple Private Relay与DoH双重干扰机制深度解析

2.1 Apple Private Relay的网络流量劫持原理与Go proxy请求拦截路径分析

Apple Private Relay 通过双重代理架构实现隐私保护:客户端流量先经 iCloud Edge 节点(加密并剥离原始 IP),再转发至出口 ISP 节点(解密并访问目标服务)。该机制本质是 TLS 流量的透明代理劫持,依赖系统级网络配置(如 NEPacketTunnelProvider)重定向 IPv4/IPv6 流量。

Go HTTP Client 的代理拦截点

Go 的 http.Transport 默认尊重 HTTP_PROXY 环境变量或显式设置的 Proxy 字段:

transport := &http.Transport{
    Proxy: http.ProxyURL(&url.URL{
        Scheme: "https",
        Host:   "relay.icloud.com:443", // Private Relay 入口网关
    }),
}

此配置强制所有 http.Client 请求经 Relay 入口节点中转;但需注意:https:// 代理方案在 Go 中实际触发 CONNECT 隧道,而 Private Relay 不支持标准 HTTPS 代理语义——真实实现依赖 macOS/iOS 系统层的 NSURLSession 与 Network Extension 协同,Go 应用仅能被动适配系统代理策略。

关键拦截路径对比

层级 是否可被 Go 程序直接控制 说明
应用层代理 http.Transport.Proxy
系统网络扩展 NEPacketTunnelProvider 强制重路由
TLS 会话层 ⚠️(受限) tls.Config.GetConfigForClient 可干预 SNI,但 Relay 要求固定 SNI 值
graph TD
    A[Go HTTP Client] --> B{Transport.Proxy set?}
    B -->|Yes| C[CONNECT tunnel to relay.icloud.com]
    B -->|No| D[System NE extension intercepts socket]
    D --> E[Encrypted tunnel to iCloud Edge]
    C --> E
    E --> F[Exit node → target server]

2.2 DNS over HTTPS对GOPROXY域名解析的静默覆盖与缓存污染实测验证

实验环境配置

使用 curl + doq(DoH客户端)向 Cloudflare DoH 端点 https://1.1.1.1/dns-query 发起查询,对比系统默认 DNS 解析结果:

# 查询 proxy.golang.org 的 A 记录(启用 DoH)
curl -H "accept: application/dns-json" \
     "https://1.1.1.1/dns-query?name=proxy.golang.org&type=A" \
     | jq '.Answer[].data'  # 输出:104.18.24.250(Cloudflare CDN IP)

该请求绕过本地 /etc/resolv.conf,强制走加密通道,导致 Go 构建时 GOPROXY 域名被静默重定向至非官方 CDN 节点。

缓存污染现象

时间戳 解析源 proxy.golang.org IP 是否触发 go mod download
T₀ 系统 DNS 216.239.36.21 ✅ 正常代理
T₁ DoH(1.1.1.1) 104.18.24.250 ❌ 返回 403(非授权 CDN)

关键路径污染示意

graph TD
    A[go build] --> B[GOPROXY=proxy.golang.org]
    B --> C{DNS 解析}
    C -->|系统 DNS| D[Google CDN IP]
    C -->|DoH 强制路由| E[Cloudflare CDN IP]
    E --> F[HTTP 403 Forbidden]

此污染不可见于 go env -w GOPROXY,亦不报错,仅静默失败。

2.3 Go client TLS握手与SNI字段在Private Relay隧道中的异常丢包复现

当Go客户端通过Private Relay隧道建立TLS连接时,tls.Config.ServerName未显式设置将导致SNI字段为空,触发Relay网关策略丢弃初始ClientHello。

SNI缺失引发的握手中断

cfg := &tls.Config{
    // ❌ 遗漏 ServerName → SNI为空
    InsecureSkipVerify: true,
}
conn, err := tls.Dial("tcp", "relay.example.com:443", cfg)

逻辑分析:Go标准库中若ServerName == ""NextProtos为空,clientHandshake会跳过SNI写入;Private Relay依赖SNI路由至后端服务,空SNI被策略引擎标记为非法并静默丢包。

复现关键条件

  • Private Relay隧道MTU限制为1300字节
  • ClientHello长度 > 1300(含证书扩展)
  • SNI字段缺失触发“无目标路由”丢包
环境变量 影响
GODEBUG=tls13=1 启用 扩展字段增多,加剧超限
TCP_NODELAY=1 启用 减少Nagle延迟,加速暴露
graph TD
    A[Go client Dial] --> B{ServerName set?}
    B -->|No| C[Omit SNI in ClientHello]
    B -->|Yes| D[Include SNI]
    C --> E[Relay drops packet]
    D --> F[Handshake proceeds]

2.4 macOS系统级网络扩展(NEFilterDataProvider)对go mod download的透明重定向追踪

macOS 的 NEFilterDataProvider 可在内核级拦截并重写 DNS/HTTP 流量,影响 go mod download 的模块获取路径。

重定向机制原理

go mod download 发起 HTTPS 请求(如 proxy.golang.org)时,NEFilterDataProvider 可通过 setTunnelProvider 注入自定义 TLS 握手逻辑,将请求透明转发至本地代理端点。

关键代码片段

override func handleNewFlow(_ flow: NEAppProxyTCPFlow) {
    guard let url = URL(string: "http://127.0.0.1:8080\(flow.remoteEndpoint.path)") else { return }
    // 将原始 go toolchain 请求重定向至本地 HTTP 拦截服务
    flow.read { data, error in
        // 解析 Go module fetch 的 Accept: application/vnd.go-remote-module 标头
        let request = HTTPRequest(data: data)
        if request.headers["User-Agent"]?.contains("go") == true {
            self.interceptGoModRequest(request, flow: flow)
        }
    }
}

此处 flow.remoteEndpoint.path 包含 /github.com/user/repo/@v/v1.2.3.info 等标准模块路径;interceptGoModRequest 负责解析语义版本并注入私有仓库映射规则。

常见拦截行为对比

行为 默认 go proxy NEFilterDataProvider 重定向
请求目标域名解析 proxy.golang.org 127.0.0.1:8080
TLS SNI 字段 proxy.golang.org 不变(保持原 SNI 以绕过证书校验)
模块元数据响应格式 JSON+HTTP 200 完全兼容,仅 origin header 修改
graph TD
    A[go mod download] --> B[NEFilterDataProvider]
    B --> C{是否匹配 go-toolchain UA?}
    C -->|Yes| D[解析 module path & version]
    C -->|No| E[直通 upstream]
    D --> F[查询本地 registry 映射表]
    F --> G[返回重写后的 module zip/info]

2.5 Go 1.21+默认HTTP/2客户端与Private Relay兼容性缺陷的Wireshark抓包佐证

Wireshark 抓包显示:Go 1.21+ 默认启用 http2.Transport,但未正确协商 SETTINGS_ENABLE_CONNECT_PROTOCOL=1,导致 Private Relay(如 Apple 的 iCloud Private Relay)拒绝 CONNECT 请求。

关键握手差异

  • ✅ 正常 HTTP/2 客户端:发送 SETTINGS 帧含 0x8(ENABLE_CONNECT_PROTOCOL)
  • ❌ Go 1.21.0–1.22.3:SETTINGS 中缺失该标志,Wireshark 过滤表达式:http2.settings.flags == 0x0 && http2.settings.id == 8

复现代码片段

// go1.22.3 默认行为(缺陷)
tr := &http.Transport{
    // 无显式配置 → 使用默认 http2.Transport
}
client := &http.Client{Transport: tr}
_, _ = client.Get("https://example.com") // 触发 HTTP/2 握手

此代码触发的 TLS ALPN 协商为 h2,但 SETTINGS 帧中 ENABLE_CONNECT_PROTOCOL(ID=8)未置位,Private Relay 服务端据此返回 REFUSED_STREAM

Wireshark 验证表

字段 Go 1.21+ 实际值 RFC 9113 要求 合规性
SETTINGS_ENABLE_CONNECT_PROTOCOL (ID=8) absent must be set for proxy-aware endpoints
SETTINGS_MAX_CONCURRENT_STREAMS 100 ≥1
graph TD
    A[Go HTTP Client] --> B[ALPN=h2]
    B --> C[HTTP/2 SETTINGS Frame]
    C --> D[Missing ID=8 flag]
    D --> E[Private Relay rejects CONNECT]

第三章:本地代理穿透的核心技术选型与可行性评估

3.1 基于SOCKS5+TLS隧道的Go proxy流量隔离方案(goproxy.io + cloudflared)

该方案通过双重加密与协议分层实现应用级流量隔离:goproxy.io 提供轻量 SOCKS5 代理服务,cloudflared 构建 TLS 封装隧道,规避中间设备深度包检测(DPI)。

核心组件协同流程

graph TD
    A[客户端] -->|SOCKS5 over TLS| B(goproxy.io)
    B -->|HTTP/2 Tunnel| C(cloudflared)
    C --> D[Cloudflare边缘节点]
    D --> E[目标服务]

部署关键配置

  • goproxy.io 启动命令:

    # 启用TLS透传模式,绑定本地SOCKS5端口
    goproxy -listen :1080 -tls -tls-cert cert.pem -tls-key key.pem

    此命令使代理监听 :1080 并原生支持 TLS 握手透传,避免 TLS 终止导致证书校验失败;-tls 参数启用 TLS 模式而非明文 SOCKS5。

  • cloudflared 隧道配置(config.yml):

    tunnel: abc123...
    credentials-file: /etc/cloudflared/abc123.json
    ingress:
    - hostname: proxy.example.com
    service: http://localhost:1080  # 指向 goproxy
组件 协议层 职责 安全边界
goproxy.io 应用层 SOCKS5 请求解析/转发 客户端到边缘
cloudflared 传输层 TLS 1.3 封装 & 路由 边缘到 Cloudflare

3.2 DNS预解析+Hosts硬绑定绕过DoH干扰的实战配置与自动化脚本

当DoH(DNS over HTTPS)被中间设备拦截或篡改时,传统DNS查询失效。此时需结合客户端主动预解析与静态映射双路径协同防御。

预解析触发机制

现代浏览器支持 <link rel="dns-prefetch" href="//example.com">,可在页面加载前发起DNS查询(明文UDP),绕过DoH策略限制。

Hosts硬绑定自动化脚本

#!/bin/bash
# 自动同步可信域名列表并写入/etc/hosts(需sudo)
DOMAINS=("api.pay.example.com" "cdn.static.example.net")
IP="192.168.10.55"
for domain in "${DOMAINS[@]}"; do
  sed -i "/$domain/d" /etc/hosts
  echo "$IP $domain" >> /etc/hosts
done

该脚本清除旧条目后追加新映射,确保每次更新原子性;sed -i "/$domain/d" 防止重复写入,>> 保证幂等追加。

关键参数说明

参数 作用 安全影响
rel="dns-prefetch" 触发浏览器提前解析 明文暴露域名,但规避DoH劫持
/etc/hosts 写入 强制本地解析优先级最高 需root权限,应配合签名验证
graph TD
  A[页面加载] --> B[触发dns-prefetch]
  A --> C[读取/etc/hosts]
  B --> D[UDP DNS查询]
  C --> E[直接返回IP]
  D & E --> F[建立TLS连接]

3.3 利用macOS Network Extension API构建轻量级Go模块代理拦截器(Swift+libproxy)

核心架构设计

采用 NEPacketTunnelProvider 拦截网络流量,通过 Swift 封装 libproxy C API 实现 PAC 自动代理发现,并将解析结果透传至 Go 编写的轻量级代理核心(goproxy)。

关键集成点

  • Swift 层调用 px_proxy_factory_get_proxies() 获取代理链
  • Go 模块通过 CGO 导出 SetProxyRules() 接口接收规则
  • 所有 HTTP/HTTPS 流量经隧道重定向至本地 127.0.0.1:8080
// Swift 调用 libproxy 示例
let url = "https://example.com".cString(using: .utf8)!
let proxies = px_proxy_factory_get_proxies(factory, url)
defer { px_proxy_factory_free_proxies(proxies) }
if let proxy = proxies?.first {
    let proxyStr = String(cString: proxy!)
    goSetProxyRules(proxyStr) // CGO 导出函数
}

逻辑分析:px_proxy_factory_get_proxies() 基于系统 PAC 或环境变量推导代理地址;proxyStr 格式为 http://user:pass@host:port,Go 模块据此动态更新转发策略。

协议支持对比

协议 支持方式 TLS 处理
HTTP 直接重写 Host/Port 不介入
HTTPS TLS 中继 + SNI 解析 使用 tls.Conn 透传
graph TD
    A[NEPacketTunnelProvider] --> B[libproxy PAC 解析]
    B --> C[Go 代理核心]
    C --> D[SOCKS5/HTTP 正向代理]
    D --> E[原始目标服务器]

第四章:五种生产级代理穿透方案的工程化落地

4.1 方案一:dnsmasq+stubby本地DoH降级为传统DNS的全链路验证

该方案构建本地可信DNS解析闭环:客户端 → dnsmasq(缓存/转发) → stubby(DoH上行) → Cloudflare/Quad9 DoH服务器,当DoH不可达时自动降级至上游传统DNS。

架构流程

graph TD
    A[客户端请求] --> B[dnsmasq监听53端口]
    B --> C{stubby是否可用?}
    C -->|是| D[stubby via HTTPS to 1.1.1.1/dns-query]
    C -->|否| E[dnsmasq直连8.8.8.8:53]
    D & E --> F[返回DNS响应]

配置关键片段

# /etc/dnsmasq.conf
port=53
no-resolv
server=127.0.0.1#5053  # 指向stubby监听地址
bind-interfaces

server=127.0.0.1#5053 显式将所有查询转发至 stubby 的本地 DoH 代理端口;no-resolv 禁用系统 resolv.conf,确保控制权完全在 dnsmasq。

降级机制验证项

  • ✅ stubby 进程存活检测(systemctl is-active stubby
  • ✅ DoH TLS 握手超时(默认 5s,由 stubby timeout: 控制)
  • ✅ dnsmasq fallback 日志关键字:forwarding server 8.8.8.8
组件 监听端口 协议 作用
dnsmasq 53 UDP/TCP 本地缓存与路由
stubby 5053 DoH 加密上行与失败回退

4.2 方案二:goproxy.cn镜像源+自签名CA证书注入Keychain的HTTPS信任链重建

该方案通过可信镜像加速模块拉取,同时解决 goproxy.cn 自签证书未被 macOS Keychain 默认信任的问题。

证书注入流程

# 1. 下载 goproxy.cn 的 CA 证书(PEM 格式)
curl -o goproxy-ca.pem https://goproxy.cn/goproxy-ca.pem

# 2. 注入并设为系统信任(需管理员权限)
sudo security add-trusted-cert -d -p ssl -k /Library/Keychains/System.keychain goproxy-ca.pem

add-trusted-cert-d 表示永久信任,-p ssl 指定用途为 HTTPS 验证,-k 指定系统级 Keychain,确保 go get 等工具全局生效。

关键配置项对比

环境变量 作用
GOPROXY https://goproxy.cn 启用国内 HTTPS 镜像源
GOSUMDB sum.golang.org 保持校验服务(可选替换为 off

信任链重建逻辑

graph TD
    A[go get 请求] --> B{HTTPS 连接 goproxy.cn}
    B --> C[验证服务器证书]
    C --> D[查找 Keychain 中对应 CA]
    D --> E[匹配成功 → 建立 TLS 连接]
    D -.-> F[匹配失败 → x509: certificate signed by unknown authority]

此方式兼顾安全性与可用性,避免关闭 GOSUMDB 或设置 GOPRIVATE 的副作用。

4.3 方案三:基于launchd守护进程的go env动态重写机制(支持Private Relay开关联动)

核心设计思路

利用 macOS 原生 launchd 持久监听 GOPATH/GOROOT 变更事件,并联动 iCloud Private Relay 状态切换,实现环境变量的实时、安全重写。

动态重写逻辑

# ~/Library/LaunchAgents/io.dev.goenv.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>io.dev.goenv</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/local/bin/goenv-sync</string>
  </array>
  <key>WatchPaths</key>
  <array>
    <string>~/Library/Preferences/com.apple.networkextension.plist</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

该配置使 launchd 在 Private Relay 配置变更时自动触发 /usr/local/bin/goenv-syncWatchPaths 监控系统网络扩展偏好项,精准捕获 Relay 开关事件;RunAtLoad 确保登录即激活,避免首次启动延迟。

状态联动映射表

Private Relay GOPROXY GOSUMDB
Enabled https://proxy.golang.org sum.golang.org
Disabled direct off

执行流程

graph TD
  A[launchd 检测 plist 变更] --> B{Private Relay ON?}
  B -->|Yes| C[写入代理/校验URL]
  B -->|No| D[回退至 direct/off]
  C & D --> E[刷新 shell 环境变量]

4.4 方案四:Clash for Mac规则分流+TUN模式直连GOPROXY域名的YAML策略精调

核心设计思路

TUN 模式接管全栈网络栈,配合精细化域名规则,实现 GOPROXY 流量零代理直连,兼顾性能与可控性。

关键 YAML 片段(带注释)

tun:
  enable: true
  stack: system  # 使用系统协议栈,兼容性最佳
  dns-hijack: ["any:53"]  # 拦截 DNS 请求,交由 Clash 处理

rules:
  - DOMAIN-SUFFIX,goproxy.io,DIRECT
  - DOMAIN-KEYWORD,goproxy,DIRECT
  - MATCH,PROXY  # 默认走代理

DOMAIN-SUFFIX 精准匹配主域名;DOMAIN-KEYWORD 覆盖子路径或镜像站(如 goproxy.cn);MATCH 作为兜底策略确保其他流量不漏。

分流效果对比表

规则类型 匹配示例 适用场景
DOMAIN-SUFFIX goproxy.io 主站及标准子域
DOMAIN-KEYWORD goproxy.cn 第三方镜像/自建实例

流量路径示意

graph TD
  A[Go build 请求] --> B{Clash TUN 拦截}
  B --> C[DNS 解析 → goproxy.io]
  C --> D[规则匹配 DOMAIN-SUFFIX]
  D --> E[路由至 DIRECT 接口]
  E --> F[内核直连,绕过代理链]

第五章:面向未来的Go模块生态兼容性演进路径

模块代理与校验机制的协同升级

Go 1.21起,GOSUMDB=sum.golang.orgGOPROXY=https://proxy.golang.org,direct 已形成强绑定校验链。某金融级微服务集群在迁移到 Go 1.22 时发现:当私有模块(如 git.internal.bank.com/go/ledger/v3)未配置 replace 且未接入企业级 sumdb 时,go build -mod=readonly 直接失败。解决方案是部署 Hashicorp Vault 驱动的自签名 sumdb,并在 ~/.netrc 中注入凭证:

machine sum.golang.org login vault-token password s.vault-xxxxx

多版本共存的语义化路径隔离

Kubernetes v1.28 的 client-go v0.28.x 强依赖 golang.org/x/net v0.14.0,而新项目需 v0.22.0 以支持 HTTP/3。通过 go mod edit -replace golang.org/x/net=github.com/golang/net@v0.22.0 并配合 //go:build go1.21 条件编译,在同一代码库中实现双栈网络协议支持。关键在于 vendor/modules.txt 中保留两套 checksum 记录,由 go list -m -f '{{.Path}} {{.Version}}' all 验证无冲突。

构建约束驱动的模块裁剪策略

某 IoT 边缘网关项目需将二进制体积压缩至 8MB 以内。采用以下组合策略:

  • go.mod 中声明 // +build !debug 标签排除调试模块
  • 使用 go build -trimpath -ldflags="-s -w" 清除符号表
  • github.com/prometheus/client_golang 执行模块级裁剪:
    go mod edit -droprequire github.com/prometheus/common@v0.45.0
    go mod tidy

企业级模块镜像仓库的灰度发布流程

下表展示某云厂商模块仓库从 v1.0 到 v2.0 的兼容性迁移矩阵:

模块路径 Go 1.19 支持 Go 1.22 支持 破坏性变更类型 回滚方案
cloud.io/storage 接口方法签名调整 replace cloud.io/storage => cloud.io/storage@v1.9.3
cloud.io/auth/jwt 移除 LegacySigner 类型 依赖方需重构调用链

跨语言模块桥接的实践验证

使用 cgo 封装 Rust 编写的加密模块 rust-crypto-sys 时,需在 go.mod 中声明:

//go:build cgo
// +build cgo

package crypto

/*
#cgo LDFLAGS: -L${SRCDIR}/lib -lrust_crypto_sys
#include "rust_crypto.h"
*/
import "C"

同时通过 go mod vendorrust_crypto.h.a 文件纳入版本控制,确保 CI 流水线在 Ubuntu 22.04 和 macOS 14 上构建结果一致。

graph LR
A[开发者提交新模块] --> B{CI 检查}
B -->|通过| C[推送到 internal-proxy]
B -->|失败| D[阻断并标记 incompatible]
C --> E[自动触发兼容性测试]
E --> F[对比 go.sum 哈希差异]
F --> G[生成兼容性报告]
G --> H[发布到 production-proxy]

静态分析工具链的嵌入式集成

在 Drone CI 中嵌入 gosecgovulncheck 双引擎:

- name: security-scan
  image: golang:1.22
  commands:
    - go install github.com/securego/gosec/v2/cmd/gosec@latest
    - go install golang.org/x/vuln/cmd/govulncheck@latest
    - gosec -exclude=G104 -out=report.json ./...
    - govulncheck -format=json ./... > vuln.json

govulncheck 检测到 golang.org/x/text 的 CVE-2023-39325 时,自动触发 go mod upgrade golang.org/x/text@v0.13.0 并提交 PR。

模块签名验证的硬件级加固

某政务系统要求所有模块必须经国密 SM2 签名。通过 cosign sign --key hsm://pkcs11:token=GO_MODULE_TOKEN 将签名写入 OCI registry,再在构建节点配置:

export COSIGN_EXPERIMENTAL=1
go run github.com/sigstore/cosign/cmd/cosign@v2.2.0 verify \
  --certificate-oidc-issuer https://login.gov.cn \
  --certificate-identity gov-module@internal \
  ghcr.io/bank-modules/ledger:v3.1.0

用实验精神探索 Go 语言边界,分享压测与优化心得。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注