如何为Docker Alpine镜像添加受信任根CA解决MITM下的SSL验证失败问题
MITM网络环境下Alpine Docker镜像构建的证书信任死循环解法
场景说明
处在部署了SSL拦截防火墙的网络环境中:访问HTTPS站点时返回的证书并非由站点官方CA签发,而是由网络侧部署的自定义根CA重新签发,这类企业级流量审计模式在大型内网环境中十分常见。
问题复现
最初编写的极简Dockerfile:
FROM alpine:latest RUN apk --no-cache add curl
执行构建时直接出现SSL证书验证类报错:
=> ERROR [2/2] RUN apk --no-cache add curl 1.0s ------ > [2/2] RUN apk --no-cache add curl: #5 0.265 fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/main/x86_64/APKINDEX.tar.gz #5 0.647 140037857143624:error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed:ssl/statem/statem_clnt.c:1913: #5 0.649 WARNING: Ignoring https://dl-cdn.alpinelinux.org/alpine/v3.13/main: Permission denied #5 0.649 fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/community/x86_64/APKINDEX.tar.gz #5 0.938 140037857143624:error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed:ssl/statem/statem_clnt.c:1913: #5 0.940 WARNING: Ignoring https://dl-cdn.alpinelinux.org/alpine/v3.13/community: Permission denied #5 0.941 ERROR: unable to select packages: #5 0.942 curl (no such package): #5 0.942 required by: world[curl] ------ executor failed running [/bin/sh -c apk --no-cache add curl]: exit code: 1
常见解法的死循环困境
网络上所有同类问题的通用解法,都是将自定义根CA加入系统信任列表,再执行update-ca-certificates命令完成配置。但这个流程存在逻辑矛盾:
- 要执行
update-ca-certificates命令,必须先通过apk add ca-certificates安装对应工具包 - 要通过apk拉取安装包,必须先让apk能正常验证HTTPS请求的证书合法性
- 而要让apk认可自定义根CA签发的证书,又必须先完成系统信任列表的配置
三者形成无法自动打通的循环。
按照常规思路尝试先安装ca-certificates包的Dockerfile:
FROM alpine:latest USER root RUN apk --no-cache add ca-certificates \ && update-ca-certificates
执行后报错与之前完全一致,依然卡在拉取软件源时的证书验证环节,根本走不到安装包、执行证书更新命令的步骤:
=> ERROR [2/2] RUN apk --no-cache add ca-certificates && update-ca-certificates 1.0s ------ > [2/2] RUN apk --no-cache add ca-certificates && update-ca-certificates: #5 0.269 fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/main/x86_64/APKINDEX.tar.gz #5 0.662 140490932583240:error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed:ssl/statem/statem_clnt.c:1913: #5 0.663 fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/community/x86_64/APKINDEX.tar.gz #5 0.663 WARNING: Ignoring https://dl-cdn.alpinelinux.org/alpine/v3.13/main: Permission denied #5 0.929 140490932583240:error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed:ssl/statem/statem_clnt.c:1913: #5 0.931 WARNING: Ignoring https://dl-cdn.alpinelinux.org/alpine/v3.13/community: Permission denied #5 0.932 ERROR: unable to select packages: #5 0.933 ca-certificates (no such package): #5 0.933 required by: world[ca-certificates] ------ executor failed running [/bin/sh -c apk --no-cache add ca-certificates && update-ca-certificates]: exit code: 1
可行的破局方案
关键认知:Alpine官方基础镜像自带完整的预装信任CA证书集合,不需要等待ca-certificates包安装完成才能修改信任配置。可以直接手动将自定义根CA追加到内置的信任证书文件中,先打通apk拉源的SSL验证环节,后续再按照系统标准流程完成证书配置,完整实现如下:
FROM alpine:latest USER root # 临时绕开死循环:直接将自定义根CA追加到镜像内置的CA信任文件中 COPY my-root-ca.crt /root/my-root-ca.crt RUN cat /root/my-root-ca.crt >> /etc/ssl/certs/ca-certificates.crt # 此时apk已经可以正常完成HTTPS请求的证书校验,可正常拉取安装ca-certificates工具 RUN apk --no-cache add ca-certificates \ && rm -rf /var/cache/apk/* # 按照Alpine标准的证书配置流程完成正式的信任配置 COPY my-root-ca.crt /usr/local/share/ca-certificates RUN update-ca-certificates # 此时整套证书配置符合系统规范,可正常安装后续需要的业务包 RUN apk --no-cache add curl
思路对比
之前曾考虑过一套繁琐的替代方案:基于支持-k参数跳过证书验证的curl镜像,手动下载对应架构的.apk安装包,以本地文件形式完成ca-certificates的安装,再配置自定义根CA。该方案需要手动匹配软件版本、依赖关系、源路径,操作复杂度远高于上述直接修改内置CA文件的方案。
内容的提问来源于stack exchange,提问作者bedla.czech
相关产品推荐
相关产品推荐

