万里侯头像
关注

Docker 安全排查三入口:构建密钥、容器特权与镜像供应链

Docker 安全排查三入口:构建密钥、容器特权与镜像供应链

说明:文中的扫描与签名命令是检查样例,实际策略需结合镜像来源、构建平台和 Kubernetes 安全策略验证。

在容器化推进的过程中,很多团队会将精力集中在基础镜像的 CVE 漏洞扫描上(如使用 Trivy 扫描漏洞)。然而在真正的安全攻防实践中,大部分容器被入侵或发生逃逸的事故,并不是因为基础镜像中存在某个中危 CVE,而是因为在 Dockerfile 构建逻辑、容器运行权限控制以及秘钥管理入口 上留下了致命的破防点。

如果忽视了这些隐蔽入口,漏洞扫描得分再高的镜像,在生产环境中依然形同虚设。

graph TD
    subgraph "Docker 容器四重安全防线"
        N1["入口一: 镜像构建阶段秘钥遗留<br/>• 防线: BuildKit --secret 挂载<br/>• 禁用 ENV/ARG 传递明文 Token"]
        N2["入口二: 供应链镜像毒化<br/>• 防线: Cosign 镜像数字签名<br/>• 仅信任私有镜像仓库与已签名 Tag"]
        N3["入口三: Docker Socket 挂载滥用<br/>• 防线: 严禁将 /var/run/docker.sock 挂入业务 Pod<br/>• 采用 Sidecar / Kaniko 替代"]
        N4["入口四: 容器 Root 权限与 Capabilities 滥用<br/>• 防线: Non-root 用户运行 + Distroless<br/>• Drop ALL Linux Capabilities"]
    end
    N1 --> N2 --> N3 --> N4

隐蔽破防入口一:构建阶段敏感密钥遗留

最常见的误区是在 Dockerfile 中使用 ARGENV 来传递 Git 秘钥、私有 Maven/NPM 仓库凭据:

# ❌ 错误示范:秘钥将被永久固化在镜像 Layer 的 Meta 中
FROM node:20
ARG NPM_TOKEN=secret_abc123890
RUN echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc \
    && npm install \
    && rm -f .npmrc

哪怕在后续指令中删除了 .npmrc,攻击者依然可以通过 docker history --no-trunc 轻松还原 NPM_TOKEN 的明文数据!

正确方案:使用 Docker BuildKit Secret 挂载

通过 BuildKit 提供的 --secret 挂载,敏感文件仅在构建的具体步骤中挂载为内存临时文件,绝不写入任何镜像分层:

# ✅ 正确示范:使用 BuildKit secret 隔离
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
# 挂载 secret,构建完成后自动卸载,不留残余
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci
COPY . .
RUN npm run build

构建命令:

DOCKER_BUILDKIT=1 docker build --secret id=npmrc,src=$HOME/.npmrc -t apps/web:v1.0.0 .
sequenceDiagram
    autonumber
    participant Dev as 开发/CI 流水线
    participant BuildKit as Docker BuildKit 引擎
    participant Secret as 宿主机 Secret 文件
    participant Layer as 镜像 Cache 分层

    Dev->>BuildKit: docker build --secret id=npmrc,src=~/.npmrc
    BuildKit->>Secret: 挂载文件至 /root/.npmrc (Tmpfs 内存挂载)
    BuildKit->>BuildKit: 执行 npm ci 读取凭据下载依赖
    BuildKit->>Secret: 卸载内存挂载点
    BuildKit->>Layer: 提交包含 node_modules 的镜像层 (元数据无 Secret)

隐蔽破防入口二:容器特权与 Linux Capabilities 滥用

默认情况下,Docker 运行容器时虽然隔离了 Namespace,但如果未明确指定 USER,容器内的进程将以 root 用户运行。更严重的是,若向容器赋予了 CAP_SYS_ADMINCAP_NET_ADMIN 等 Capabilities,或者直接挂载了宿主机的 /var/run/docker.sock,攻击者便可通过 Docker API 直接在宿主机上拉起挂载根目录的特权容器,瞬间完成容器逃逸。

生产级 Pod 安全上下文(SecurityContext)规范

在 Kubernetes 部署清单中,必须进行硬约束防线配置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hardened-app
  namespace: production
spec:
  replicas: 3
  template:
    spec:
      securityContext:
        # 强制整 Pod 以非 root 用户/组运行
        runAsNonRoot: true
        runAsUser: 10001
        runAsGroup: 10001
        fsGroup: 10001
      containers:
        - name: app
          image: my-registry.internal/apps/hardened-app:v1.0.0
          securityContext:
            # 禁止容器提升权限
            allowPrivilegeEscalation: false
            # 将容器根文件系统设为只读
            readOnlyRootFilesystem: true
            # 剥离所有 Linux 特权能力
            capabilities:
              drop:
                - ALL
          volumeMounts:
            - mountPath: /tmp
              name: tmp-volume
      volumes:
        - name: tmp-volume
          emptyDir: {}

隐蔽破防入口三:供应链毒化与基础镜像签名

直接从公共 Docker Hub 拉取形如 python:latest 或非官方维护的镜像,极易受到供应链攻击(如镜像被植入挖矿木马或后门)。

Cosign 镜像签名与校验实战

必须为私有镜像仓库建立基于 Cosign 的数字签名校验机制:

# 1. 生成公私钥对
cosign generate-key-pair

# 2. 对 CI/CD 构建出的镜像进行数字签名
cosign sign --key cosign.key my-registry.internal/apps/hardened-app:v1.0.0

# 3. 部署前对镜像签名进行确定性验证(必须验证通过才允许部署)
cosign verify --key cosign.pub my-registry.internal/apps/hardened-app:v1.0.0

生产安全诊断与巡检命令工具

运维团队应当将安全检查嵌入例行巡检与 CI 流水线中。

核心安全审计指令

# 1. 深入检查 Docker 镜像构建历史,排查明文凭据与 ARG 泄漏
docker history --no-trunc my-registry.internal/apps/hardened-app:v1.0.0 | grep -E "TOKEN|PASSWORD|SECRET|KEY"

# 2. 使用 dockle 工具对镜像实施容器最佳实践安全审计
dockle --exit-code 1 --exit-level fatal my-registry.internal/apps/hardened-app:v1.0.0

# 3. 检查 K8s 集群中哪些 Pod 挂载了高危的 docker.sock
kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{"/"}{.metadata.name}{"\t"}{.spec.volumes[*].hostPath.path}{"\n"}{end}' | grep "docker.sock"

# 4. 动态检测运行中容器的 Linux Capabilities
getpcaps $(pgrep -f "server")

总结:容器安全的三道硬红线

  1. 绝对不给容器挂载 /var/run/docker.sock:构建任务请采用 Kaniko、Buildah 等无 Docker 依赖工具。
  2. 绝对不以 Root 用户运行容器进程:基础镜像推荐使用 distroless 或 Alpine 并显示配置 USER 10001
  3. 绝对不让构建凭据进入镜像 Layer:全面开启 BuildKit 强制使用 --secret

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/qwe0iop0/article/details/163701442

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--