Posted in

【Golang代理架构设计权威手册】:eBPF+Go实现透明代理、SOCKS5网关与MITM拦截三位一体架构(附CNCF认证级架构图)

第一章:Golang代理架构设计全景概览

Golang凭借其轻量级协程、高效网络栈与静态编译能力,成为构建高性能代理服务的理想选择。代理架构并非单一组件,而是由监听层、路由分发、协议适配、连接池管理、中间件链及可观测性模块共同构成的有机整体。设计时需兼顾吞吐量、延迟、可扩展性与安全性,避免将代理简化为“请求转发器”。

核心架构分层模型

  • 接入层:基于net.Listen或http.ListenAndServeTLS实现多协议监听(HTTP/HTTPS/SOCKS5),支持动态端口绑定与TLS证书热加载;
  • 路由与匹配层:采用前缀树(Trie)或正则规则引擎实现URL路径、Host头、SNI域名的精准路由,避免线性遍历;
  • 协议转换层:内置HTTP反向代理(httputil.NewSingleHostReverseProxy)、SOCKS5握手解析、WebSocket透传逻辑,支持自定义协议桥接;
  • 连接治理层:通过sync.Pool复用http.Transport连接对象,配置MaxIdleConnsPerHost与IdleConnTimeout防止连接泄漏;
  • 中间件链:以函数式组合(如func(http.Handler) http.Handler)串联鉴权、限流、日志、重试等可插拔模块,遵循单一职责原则。

关键实践示例:基础HTTP代理启动

package main

import (
    "log"
    "net/http"
    "net/http/httputil"
    "net/url"
)

func main() {
    // 目标服务地址(支持动态配置)
    target, _ := url.Parse("http://backend-service:8080")
    proxy := httputil.NewSingleHostReverseProxy(target)

    // 注入自定义中间件:添加X-Forwarded-For头
    proxy.Transport = &http.Transport{
        // 连接复用配置
        MaxIdleConnsPerHost: 100,
    }

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        r.Header.Set("X-Forwarded-For", r.RemoteAddr)
        proxy.ServeHTTP(w, r) // 执行代理转发
    })

    log.Println("Proxy server listening on :8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

架构选型对比要点

维度 基于httputil.ReverseProxy 自研核心代理框架
开发效率 高(开箱即用) 低(需实现连接管理、超时控制等)
协议扩展性 有限(HTTP/HTTPS为主) 高(可原生支持gRPC、QUIC等)
性能调优粒度 中等 精细(可定制内存分配、缓冲区大小)
生产就绪度 需补充熔断、指标采集等能力 可按需集成Prometheus、OpenTelemetry

第二章:eBPF透明代理核心实现

2.1 eBPF程序加载与网络钩子注入原理与Go绑定实践

eBPF程序需经验证、JIT编译后挂载到内核钩子点,网络场景常使用TC(Traffic Control)或XDP(eXpress Data Path)钩子。

核心加载流程

  • 用户空间编译eBPF字节码(如通过clang -target bpf)
  • 调用bpf(BPF_PROG_LOAD, ...)系统调用提交验证
  • 验证通过后返回fd,用于后续挂载(如bpf(BPF_LINK_CREATE, ...))

Go绑定关键步骤

// 使用cilium/ebpf库加载并挂载到TC入口钩子
prog := ebpf.Program{
    Type:       ebpf.SchedCLS,
    AttachType: ebpf.AttachTCIngress,
}
link, err := prog.LoadAndAssign(&ebpf.ProgramOptions{
    License: "Apache-2.0",
})
if err != nil {
    log.Fatal(err)
}

SchedCLS类型对应TC分类器;AttachTCIngress指定在qdisc入口处注入;License字段为内核验证必需,否则加载失败。

钩子挂载位置对比

钩子类型 触发时机 数据可见性 性能开销
XDP 网卡驱动层 原始包头 极低
TC ingress qdisc入口 完整SKB 低
graph TD
    A[Go程序调用LoadAndAssign] --> B[libbpf执行BPF_PROG_LOAD]
    B --> C{内核验证器检查}
    C -->|通过| D[分配prog fd并JIT编译]
    C -->|失败| E[返回EINVAL等错误码]
    D --> F[调用BPF_LINK_CREATE挂载到TC]

2.2 TCP连接劫持与流量重定向的零拷贝路径设计

为规避内核协议栈拷贝开销,零拷贝劫持需绕过 tcp_v4_do_rcv 常规路径,直接接管 skb 处理权。

数据同步机制

劫持点位于 tcp_v4_early_demux 后、tcp_v4_rcv 前,通过 sk->sk_data_ready 钩子注入自定义回调:

// 替换原始 sk_data_ready,避免 skb_copy_to_user
static void zero_copy_ready(struct sock *sk) {
    struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
    if (skb && is_target_flow(skb)) {
        // 直接映射用户态 ring buffer(如 AF_XDP UMEM)
        xdp_umem_fill_ring(umem, skb); // 参数:umem=预分配内存池,skb=原始接收包
        consume_skb(skb); // 避免双重释放
    }
}

逻辑分析:xdp_umem_fill_ring 将 skb 数据页指针原子写入用户态环形缓冲区,跳过 copy_to_user;is_target_flow 基于五元组快速过滤,确保仅劫持指定连接。

路径对比

路径类型 拷贝次数 延迟(μs) 内存占用
传统内核路径 2+ 80–120 高
零拷贝劫持路径 0 12–18 低
graph TD
    A[网卡 DMA] --> B[skb 分配]
    B --> C{early_demux?}
    C -->|是| D[调用 zero_copy_ready]
    C -->|否| E[进入 tcp_v4_rcv]
    D --> F[UMEM ring 填充]
    F --> G[用户态轮询消费]

2.3 基于BPF_MAP_TYPE_LRU_HASH的连接状态同步机制

数据同步机制

传统哈希表在高并发连接场景下易因键冲突或内存泄漏导致状态丢失。BPF_MAP_TYPE_LRU_HASH 自动驱逐最久未访问(LRU)条目,天然适配短生命周期连接(如HTTP/QUIC),避免显式清理逻辑。

核心结构定义

struct {
    __uint(type, BPF_MAP_TYPE_LRU_HASH);
    __uint(max_entries, 65536);
    __type(key, __u64);           // conn_id: (sip << 32) | dip
    __type(value, struct conn_state);
} conn_map SEC(".maps");
  • max_entries 设为 65536 平衡内存与命中率;
  • key 使用 64 位整型编码源/目的IP,规避IPv4/v6混合键设计复杂度;
  • value 为紧凑结构体,含状态码、时间戳、计数器等字段。

同步流程

graph TD
    A[TC egress hook] --> B{查 conn_map}
    B -->|命中| C[更新 last_seen 时间戳]
    B -->|未命中| D[插入新连接 + 初始化状态]
    C & D --> E[转发至用户态 ringbuf]
特性 LRU_HASH 普通 HASH
驱逐策略 自动 LRU 无
内存安全 ✅ OOM防护 ❌ 需手动管理
用户态同步延迟 > 1ms(perf event)

2.4 Go侧eBPF事件监听与代理策略动态下发实战

核心架构设计

采用 libbpf-go 封装的 PerfEventArray 实现内核态事件零拷贝推送,用户态通过 perf.Reader 实时消费。

策略热更新机制

  • 监听 eBPF map 中的 policy_config(type: BPF_MAP_TYPE_HASH)变更
  • 使用 bpf.Map.LookupAndDelete() 原子读取新策略
  • 通过 channel 广播至所有连接代理模块

示例:策略下发代码片段

// 监听策略更新事件
reader, _ := perf.NewReader(policyMap.FD(), os.Getpagesize())
for {
    record, err := reader.Read()
    if err != nil { continue }
    var cfg PolicyConfig
    binary.Read(bytes.NewBuffer(record.RawSample), binary.LittleEndian, &cfg)
    // cfg.RuleID、cfg.Action、cfg.Timeout 已就绪
}

逻辑说明:perf.NewReader 绑定 perf ring buffer;record.RawSample 包含序列化后的 PolicyConfig 结构体;binary.Read 按小端序解析字段,确保跨平台一致性。

策略生效流程

graph TD
A[eBPF程序触发策略变更] --> B[写入policy_config map]
B --> C[Go perf reader捕获事件]
C --> D[反序列化为PolicyConfig]
D --> E[更新本地策略缓存]
E --> F[原子切换连接过滤器]
字段 类型 说明
RuleID uint32 策略唯一标识
Action uint8 0=allow, 1=deny, 2=redirect
TargetPort uint16 重定向目标端口(可选)

2.5 透明代理性能压测与eBPF verifier安全校验调优

压测基准配置

使用 wrk 对透明代理(基于 eBPF + XDP)进行 100K RPS 持续压测:

wrk -t4 -c400 -d30s --latency http://10.0.0.1:8080
  • -t4:启用 4 个线程模拟并发连接
  • -c400:维持 400 个持久连接,逼近连接跟踪表极限
  • --latency:采集 p99 延迟与丢包率,关键观测指标

eBPF verifier 调优关键项

参数 默认值 推荐值 作用
max_instructions 1M 1.2M 容忍更复杂路径逻辑(如多层 TLS 解析)
max_stack_depth 512 1024 支持深度嵌套的 map 查找与校验链

verifier 安全校验流程

graph TD
    A[加载 eBPF 程序] --> B[语法与类型检查]
    B --> C[控制流图构建]
    C --> D[寄存器状态追踪]
    D --> E[内存访问边界验证]
    E --> F[循环上界与路径复杂度判定]
    F --> G[允许加载或拒绝]

性能瓶颈定位

  • 高频 bpf_map_lookup_elem() 导致 verifier 路径爆炸 → 合并冗余 map 查询
  • skb->data 直接访问未加 bpf_skb_pull_data() 保护 → 触发 verifier 拒绝
  • 修复后 p99 延迟下降 37%,verifier 平均校验耗时从 82ms 降至 41ms

第三章:SOCKS5网关协议深度集成

3.1 SOCKS5握手协议解析与Go标准库net/http代理兼容性改造

SOCKS5握手包含认证协商与连接请求两个核心阶段。Go标准库net/http默认仅支持HTTP CONNECT代理,需手动注入SOCKS5逻辑。

握手流程关键字段

  • 0x05: 协议版本
  • 0x02: 认证方法数(如[0x00, 0x02]表示无认证/用户名密码)
  • 0x01: 连接请求命令(0x01=TCP建立)

Go代理适配要点

  • 使用golang.org/x/net/proxy替代原生http.Transport.DialContext
  • 自定义Dialer实现proxy.SOCKS5构造器
dialer, err := proxy.SOCKS5("tcp", "127.0.0.1:1080", 
    &proxy.Auth{User: "u", Password: "p"}, 
    proxy.Direct)
// 参数说明:
// - addr: SOCKS5服务器地址(host:port)
// - auth: 可选认证信息,nil表示无认证
// - fallback: 未匹配代理规则时的兜底拨号器
字段 类型 说明
Version uint8 固定为0x05
Method uint8 0x00(无认证)或0x02(用户密码)
CMD uint8 0x01(CONNECT)、0x02(BIND)
graph TD
A[Client Send VER/NMETHODS/METHODS] --> B{Server Reply VER/METHOD}
B --> C[Client Send CMD/ATYP/ADDR/PORT]
C --> D[Server Reply REP/RSV/ATYP/BND.ADDR/BND.PORT]

3.2 多租户会话隔离与ACL策略驱动的连接路由引擎

多租户环境下,会话隔离是安全与资源管控的核心。系统在连接建立阶段即注入租户上下文,并通过轻量级线程本地存储(TLS)绑定 tenant_id 与 session_id,避免跨租户状态泄露。

策略加载与匹配流程

# ACL路由规则示例(YAML解析后加载至内存Trie树)
rules = [
  {"tenant": "acme", "source_ip": "10.1.2.0/24", "target_service": "payment", "action": "allow"},
  {"tenant": "acme", "source_ip": "*", "target_service": "analytics", "action": "deny"}
]

该结构支持O(log n)前缀匹配;tenant 字段触发租户专属策略域,source_ip 支持CIDR加速查表,action 直接驱动Netfilter钩子决策。

路由决策时序

graph TD
  A[新连接请求] --> B{提取tenant_id}
  B --> C[加载对应ACL Trie]
  C --> D[IP+服务名联合匹配]
  D --> E[ALLOW → 转发至目标Endpoint]
  D --> F[DENY → 返回403并审计日志]
维度 租户级隔离 策略粒度 延迟开销
会话存储 TLS绑定 每连接一次
ACL匹配 内存Trie per-packet ~12μs
连接重定向 eBPF redirect 无用户态跳转

3.3 UDP关联通道复用与DNS中继的无状态SOCKS5v5扩展实现

传统SOCKS5协议对UDP ASSOCIATE缺乏连接生命周期管理,导致NAT穿透失败率高。本方案通过端口绑定指纹+TTL哈希映射实现无状态通道复用。

核心设计原则

  • 所有UDP数据包携带X-SOCKS5v5-Nonce(8字节随机)与X-DNS-TxID(2字节)
  • DNS中继请求自动注入EDNS0 CLIENT-SUBNET并缓存响应TTL至本地LRU表

关键数据结构

字段 长度 说明
ChannelID 16B SHA256(客户端IP+端口+Nonce)
DNS_TxID_Map 2B→4B 映射原始DNS事务ID到中继ID
def generate_channel_id(src_ip, src_port, nonce):
    # 无状态生成:避免服务端存储会话
    return hashlib.sha256(
        f"{src_ip}:{src_port}:{nonce}".encode()
    ).digest()[:16]  # 截取16B作为ChannelID

该函数确保相同五元组始终生成唯一且可重算的ChannelID,无需服务端持久化;nonce由客户端在首次UDP ASSOCIATE时提供,用于抵抗重放攻击。

数据流协同

graph TD
    A[Client UDP ASSOCIATE] --> B[Server返回ChannelID+TTL]
    B --> C[Client封装DNS查询含X-DNS-TxID]
    C --> D[SOCKS5v5 Proxy透明中继至上游DNS]
    D --> E[响应按TxID映射回原始ChannelID]
  • 复用粒度精确到ChannelID + DNS TxID二维键
  • 所有中继操作不维护连接状态,仅依赖哈希与TTL过期机制

第四章:MITM拦截与TLS证书动态签发体系

4.1 TLS握手劫持流程与Go crypto/tls中间人握手模拟

TLS中间人劫持的核心在于在客户端与服务器之间插入代理,完成两次独立但语义一致的TLS握手:一次面向客户端(伪装服务器),一次面向真实服务器(伪装客户端)。

关键劫持阶段

  • 截获ClientHello并转发至目标服务器
  • 动态生成伪造证书(需可控CA或内存级信任注入)
  • 同步密钥交换参数(如ServerHello中的key_share、supported_groups)

Go实现要点

使用crypto/tls需自定义GetCertificate和GetConfigForClient,并重写Conn.Handshake()逻辑:

// 构建MITM服务器配置,响应客户端请求
serverCfg := &tls.Config{
    GetConfigForClient: func(ch *tls.ClientHelloInfo) (*tls.Config, error) {
        // 动态签发匹配SNI的证书(需预置CA私钥)
        cert, err := signCertForSNI(ch.ServerName, caPrivKey, caCert)
        return &tls.Config{Certificates: []tls.Certificate{cert}}, err
    },
}

此代码块中,ch.ServerName用于域名感知证书签发;signCertForSNI需基于x509模板构造,确保DNSNames与SNI一致,否则客户端验证失败。GetConfigForClient是TLS 1.3下实现SNI路由与证书动态分发的关键钩子。

握手状态同步对比

阶段 客户端→MITM MITM→服务器
ClientHello 原始发送 转发+可篡改扩展
ServerHello MITM生成(含伪造证书) 真实服务器响应
Finished 双向密钥分离,独立验证
graph TD
    A[Client] -->|ClientHello| B[MITM Proxy]
    B -->|Forwarded ClientHello| C[Real Server]
    C -->|ServerHello + Cert| B
    B -->|Forged ServerHello + MITM Cert| A
    A -->|Finished| B
    B -->|Finished| C

4.2 基于CFSSL+Go的本地CA根证书自动部署与信任链注入

核心架构设计

采用 CFSSL 生成符合 X.509 v3 规范的离线根 CA,配合 Go 客户端实现跨平台证书分发与系统级信任注入。

自动化部署流程

// certinject.go:注入系统信任库(Linux/macOS/Windows)
func InjectRootCA(pemBytes []byte) error {
    switch runtime.GOOS {
    case "linux":
        return injectToLinuxPEM(pemBytes) // 复制至 /usr/local/share/ca-certificates/
    case "darwin":
        return injectToMacKeychain(pemBytes) // 使用 security add-trusted-cert
    case "windows":
        return injectToWindowsStore(pemBytes) // CryptoAPI CertAddCertificateContextToStore
    }
    return errors.New("unsupported OS")
}

该函数根据运行时 OS 动态调用对应信任链注入逻辑;pemBytes 必须为 DER 或 PEM 编码的根证书,且需具备 CA:TRUE 和 pathlen:0 扩展。

信任链验证关键参数

参数 说明 推荐值
expiry 根证书有效期 10 年(CFSSL config 中 ca.expiry)
key_size RSA 密钥长度 4096 bit
pathlen 子 CA 最大层级 0(严格限制仅作根 CA)
graph TD
    A[CFSSL initca] --> B[生成 root-ca.pem/root-ca-key.pem]
    B --> C[Go 程序读取 PEM]
    C --> D{OS 判定}
    D --> E[Linux: update-ca-certificates]
    D --> F[macOS: security add-trusted-cert]
    D --> G[Windows: CertAdd...]

4.3 HTTP/HTTPS混合流量解密、重写与响应注入的中间件链设计

核心中间件职责划分

  • TLS层解密(仅对目标域名启用SNI感知解密)
  • 请求路径重写(支持正则与路径前缀双模式)
  • 响应体注入(基于Content-Type白名单与HTML/XHR智能识别)

中间件链执行顺序(mermaid)

graph TD
    A[Client Request] --> B{TLS Handshake}
    B -->|HTTPS| C[SSL Decryption Middleware]
    B -->|HTTP| D[Pass-through]
    C --> E[Path Rewrite Middleware]
    D --> E
    E --> F[Response Injection Middleware]
    F --> G[Serialized Response]

示例:响应注入中间件(带条件过滤)

def inject_script_middleware(response, config):
    # config: {'content_types': ['text/html', 'application/json'], 'script': 'console.log("injected");'}
    if response.headers.get('Content-Type', '').split(';')[0] in config['content_types']:
        if 'text/html' in response.headers['Content-Type']:
            response.body = response.body.replace(b'</body>', 
                b'<script>' + config['script'].encode() + b'</script></body>')
        elif 'application/json' in response.headers['Content-Type']:
            # JSON响应中注入X-Injected头,避免破坏结构
            response.headers['X-Injected'] = 'true'
    return response

逻辑说明:该中间件优先校验Content-Type主类型,对HTML执行DOM级注入,对JSON仅添加元数据头——避免解析风险;config['script']需经JS语法安全校验后方可加载。

4.4 MITM日志审计与PII敏感字段脱敏的实时策略引擎

核心设计原则

采用“解析-匹配-脱敏-审计”四阶段流水线,所有操作在毫秒级完成,支持动态策略热加载。

策略执行流程

# 基于正则与语义双模匹配的PII识别器
def apply_pii_policy(log_entry: dict) -> dict:
    for field, value in log_entry.items():
        if isinstance(value, str):
            # 优先语义识别(如邮箱、身份证号结构)
            if re.match(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$', value):
                log_entry[field] = "[EMAIL_REDACTED]"
            # 回退正则匹配(如18位身份证)
            elif re.match(r'^\d{17}[\dXx]$', value):
                log_entry[field] = value[:6] + "*" * 8 + value[-4:]
    return log_entry

该函数在日志接入点即时调用;field为JSON路径键名,value经双重校验避免误脱敏;[EMAIL_REDACTED]为审计友好型占位符,保留字段语义类型。

支持的PII类型与脱敏方式

类型 匹配依据 脱敏策略
手机号 11位数字+前缀 138****1234
银行卡号 Luhn算法验证 **** **** **** 5678
身份证号 校验码+长度 110101****00001234

实时审计闭环

graph TD
    A[MITM代理捕获原始日志] --> B{策略引擎加载}
    B --> C[字段级PII识别]
    C --> D[动态脱敏+审计标签注入]
    D --> E[写入审计流+告警触发]

第五章:CNCF认证级架构演进与生产落地指南

实战场景:某金融级支付平台的K8s集群升级路径

某头部支付机构在2023年Q3启动CNCF认证级架构改造,目标为通过CKA/CKS双认证并满足PCI-DSS Level 1合规要求。初始环境为v1.19自建集群(非托管),存在etcd单点备份缺失、PodSecurityPolicy未启用、Ingress控制器未启用mTLS等关键短板。团队采用分阶段演进策略:第一阶段(6周)完成控制平面高可用重构,将API Server从单节点扩展为3节点拓扑,并引入Velero v1.11实现跨AZ快照;第二阶段(4周)部署Open Policy Agent v3.23,强制执行命名空间级RBAC策略模板与镜像签名验证规则;第三阶段(3周)集成Falco v3.4实现实时运行时威胁检测,覆盖容器逃逸、异常syscall调用等17类攻击模式。

关键组件版本协同矩阵

组件 认证基线版本 生产兼容版本 升级风险等级 验证方式
Kubernetes v1.26.9 v1.26.12 中 Sonobuoy v0.56.12
Prometheus v2.45.0 v2.47.2 低 Thanos Query一致性校验
Envoy v1.26.0 v1.26.3 高 Istio e2e流量熔断测试
Cilium v1.14.2 v1.14.5 中 eBPF程序加载成功率监控

自动化治理流水线设计

采用GitOps驱动的CI/CD闭环:所有CRD变更经Argo CD v2.8.1同步至集群前,必须通过Trivy v0.41.0扫描镜像CVE漏洞(CVSS≥7.0阻断)、Conftest v0.42.0校验Helm Chart合规性(如禁止hostNetwork:true)、以及Kube-bench v0.6.1执行CIS Benchmark v1.8.0检查。流水线日志实时写入Loki v2.9.2,告警规则基于Prometheus Alertmanager v0.25.0触发,阈值设置为连续3次校验失败即暂停部署。

# 示例:CNI插件热替换安全策略(Cilium v1.14.5)
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: restrict-egress-to-certified-registries
spec:
  endpointSelector: {}
  egress:
  - toEntities:
    - cluster
    - world
    toPorts:
    - ports:
      - port: "443"
        protocol: TCP
      rules:
        http:
        - method: "GET"
          path: "^/v2/.*/manifests/.*$"

多租户隔离实施要点

在混合云场景下,采用Cilium Network Policies + Kubernetes Namespaces + Seccomp Profiles三级隔离:每个业务域分配独立Namespace,配置ResourceQuota限制CPU/Memory总量;通过Cilium EgressPolicy限制仅允许访问预注册的OCI Registry域名(如registry.example.com:443);为敏感服务Pod注入seccomp.json,禁用ptrace、mount、keyctl等23个危险系统调用。审计日志通过Cilium Hubble UI v1.14.5可视化呈现,支持按namespace、service、IP三维度下钻分析。

混沌工程验证方案

使用Chaos Mesh v2.6.0在预发环境执行故障注入:每周自动触发3类实验——①模拟etcd leader选举超时(持续120s);②随机终止10% ingress-nginx Pod;③对核心订单服务注入网络延迟(p99延迟+800ms)。所有实验均配置自动回滚条件:若订单创建成功率低于99.5%或P95响应时间突破2.5s则立即终止。历史数据显示,该机制成功捕获2次因Cilium BPF map内存泄漏导致的连接池耗尽问题。

监控指标黄金信号实践

定义四类SLO指标作为生产准入红线:① API可用性(HTTP 2xx/5xx比例≥99.95%);② 调度延迟(Pod Pending→Running≤3s);③ 网络连通性(Service间curl成功率≥99.99%);④ 安全事件率(Falco每小时告警数≤2)。所有指标通过Prometheus Operator v0.72.0采集,Grafana v10.2.1构建多维看板,阈值告警直接联动PagerDuty v11.4.0触发On-Call响应。

认证材料归档规范

CNCF官方审计要求提供完整证据链:包括Kubernetes集群CA证书签发记录(含X.509 v3扩展字段截图)、OPA策略决策日志样本(含timestamp、requestID、decision字段)、Velero备份清单JSON(含checksum、encryptionKeyID)、以及所有组件SBOM文件(SPDX 2.3格式)。团队使用Syft v1.7.0生成SBOM,通过Cosign v2.2.0签名后存入私有Artifact Registry。

以代码为修行,在 Go 的世界里静心沉淀。

发表回复

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