Golang如何防范供应链攻击
Golang如何防范供应链攻击 在经历了 tj-actions/changed-files 供应链攻击后,我一直在尝试加强我的 Docker 文件安全性,具体做法是在 Docker 镜像中添加哈希值。
FROM golang:1.24.2@sha256:991aa6a6e4431f2f01e869a812934bd60fbc87fb939e4a1ea54b8494ab9d2fc6 AS build
Dependabot 已配置为更新 Docker 文件,因此后来它自动更新为:
FROM golang:1.24.2@sha256:1ecc479bc712a6bdb56df3e346e33edcc141f469f82840bab9f4bc2bc41bf91d AS build
问题是,如何防止未来的供应链攻击发布一个未来被篡改的 Docker 镜像?Dependabot 会尽职尽责地将其更新到我的代码仓库中。
我正在寻找一种方法,来确认 golang:1.24.2 的哈希值变更是预期的、经过授权的、有效的。
谢谢。
更多关于Golang如何防范供应链攻击的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang如何防范供应链攻击的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这是一个很好的安全问题。针对 Docker 镜像哈希值的供应链攻击防范,核心在于建立可信的镜像来源验证机制。以下是几种专业方案:
1. 使用 Docker Content Trust (DCT) 验证镜像签名
Docker 官方镜像通常使用 Notary 进行签名。你可以配置 Docker 客户端只拉取已签名的镜像。
// 在构建环境中启用DCT
export DOCKER_CONTENT_TRUST=1
// Dockerfile中保持标签不变,Docker会自动验证签名
FROM golang:1.24.2 AS build
然后在 CI/CD 流水线中设置环境变量:
# 在CI脚本中
DOCKER_CONTENT_TRUST=1 docker build -t your-app .
2. 使用 Cosign 进行签名验证
Cosign 是 Sigstore 项目的一部分,提供更强的签名验证能力:
// 安装cosign
go install github.com/sigstore/cosign/v2/cmd/cosign@latest
// 验证Golang官方镜像签名
cosign verify \
--certificate-identity-regexp="^https://github.com/docker-library/" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
docker.io/library/golang:1.24.2
3. 实现自动化哈希验证脚本
创建一个 Go 程序来验证镜像哈希的合法性:
package main
import (
"context"
"fmt"
"os"
"strings"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
)
func verifyImageHash(expectedDigest string) error {
ref, err := name.ParseReference("golang:1.24.2")
if err != nil {
return fmt.Errorf("解析镜像引用失败: %w", err)
}
desc, err := remote.Get(ref, remote.WithAuthFromKeychain(authn.DefaultKeychain))
if err != nil {
return fmt.Errorf("获取镜像描述失败: %w", err)
}
actualDigest := desc.Digest.String()
if !strings.HasSuffix(expectedDigest, actualDigest) {
return fmt.Errorf("哈希值不匹配: 期望包含 %s, 实际 %s", expectedDigest, actualDigest)
}
// 可选:验证签名
fmt.Printf("镜像验证通过: %s\n", actualDigest)
return nil
}
func main() {
// 从安全配置或环境变量获取预期哈希
expectedHash := os.Getenv("EXPECTED_GOLANG_DIGEST")
if err := verifyImageHash(expectedHash); err != nil {
panic(err)
}
}
4. 使用 SLSA Provenance 验证构建来源
结合 GitHub Actions 的 SLSA 生成器:
# .github/workflows/verify.yaml
name: Verify Image Provenance
on:
pull_request:
paths:
- 'Dockerfile'
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: slsa-framework/slsa-github-generator/attest@v2
- run: |
# 验证镜像来源
slsa-verifier verify-image docker.io/library/golang:1.24.2 \
--source-uri github.com/docker-library/golang \
--builder-id "https://github.com/docker-library/actions"
5. 创建允许列表策略
使用 OPA (Open Policy Agent) 或 Kyverno 定义镜像策略:
# image_validation.rego
package main
allowed_digests := {
"golang": {
"1.24.2": "sha256:1ecc479bc712a6bdb56df3e346e33edcc141f469f82840bab9f4bc2bc41bf91d",
}
}
default allow = false
allow {
input.image.name == "golang"
input.image.tag == "1.24.2"
input.image.digest == allowed_digests["golang"]["1.24.2"]
}
6. 集成到 CI/CD 的完整示例
// verify_images.go
package main
import (
"crypto/sha256"
"encoding/hex"
"io"
"net/http"
"os"
)
type ImageVerifier struct {
trustedSources map[string]string
}
func NewImageVerifier() *ImageVerifier {
return &ImageVerifier{
trustedSources: map[string]string{
"golang:1.24.2": "https://hub.docker.com/v2/repositories/library/golang/tags/1.24.2",
},
}
}
func (v *ImageVerifier) VerifyFromOfficialSource(image, expectedHash string) error {
sourceURL, ok := v.trustedSources[image]
if !ok {
return fmt.Errorf("未配置可信源: %s", image)
}
resp, err := http.Get(sourceURL)
if err != nil {
return fmt.Errorf("获取官方信息失败: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("读取响应失败: %w", err)
}
// 解析JSON响应,验证哈希值
// 这里需要根据Docker Hub API的实际响应结构解析
if !strings.Contains(string(body), expectedHash) {
return fmt.Errorf("官方源中未找到指定哈希值")
}
return nil
}
func main() {
verifier := NewImageVerifier()
if err := verifier.VerifyFromOfficialSource(
"golang:1.24.2",
os.Getenv("GOLANG_IMAGE_DIGEST"),
); err != nil {
panic(err)
}
}
关键点:
- 多层验证:结合签名验证、哈希验证和来源证明
- 自动化检查:在 CI/CD 流水线中集成验证步骤
- 零信任原则:不自动信任任何更新,即使来自 Dependabot
- 审计追踪:记录所有镜像验证结果
这些方案可以单独或组合使用,为 Docker 镜像提供供应链安全防护。

