要让私有化部署的 GitLab Runner 安全对接内网 HTTPS GitLab,必须显式注入并信任内网 CA 根证书,注册时使用 --tls-ca-file 指定证书路径,同时同步更新 Docker daemon 和作业容器的信任库,并排查 DNS、代理及证书链完整性问题。

要让私有化部署的 GitLab Runner 通过自定义 CA 证书,安全、稳定地对接内网 HTTPS GitLab 服务,核心不是绕过验证,而是让 Runner 完整信任你的内网证书链。关键在于三点:正确获取并注入 CA 根证书、确保所有通信路径(DNS、HTTP、Git)都使用该证书、避免因发行版差异或代理干扰导致验证失败。
准确获取并挂载你的内网 CA 根证书
GitLab Runner 自身不内置你私有 CA 的信任链,必须显式提供。不要从浏览器导出“服务器证书”,而要拿到签发 GitLab HTTPS 服务所用的 根 CA 证书(.crt 文件)。常见来源包括:
- 内网 PKI 系统导出的 Root CA 或 Intermediate CA 公钥证书(PEM 格式)
- GitLab 服务器上
/etc/gitlab/ssl/目录中与域名匹配的ca-bundle.crt(若已配置多级证书) - 用
openssl s_client -connect gitlab.internal:443 -showcerts抓取完整链,手动提取最上面的根证书部分
将该 .crt 文件放入 Runner 容器可访问路径,例如通过 Docker 挂载:-v /path/on/host/ca.crt:/etc/gitlab-runner/certs/gitlab-ca.crt:ro
注册时明确指定证书路径并禁用临时绕过方案
注册 Runner 时,必须使用 --tls-ca-file 参数指向你挂载的 CA 证书文件。这是唯一推荐的长期方案,不要使用 git config --global http.sslVerify false 或环境变量 GIT_SSL_NO_VERIFY=1 —— 这类方式会关闭全部 SSL 验证,带来中间人攻击风险,且在新版 Runner 中可能被策略拦截。
非交互式注册命令示例(关键参数已加粗):
gitlab-runner register \ --non-interactive \ --url "https://gitlab.internal/" \ --registration-token "GR134894..." \ <strong>--tls-ca-file "/etc/gitlab-runner/certs/gitlab-ca.crt"</strong> \ --executor "docker" \ --docker-image "alpine:latest" \ --description "internal-build-runner" \ --tag-list "internal,build"
同步配置容器运行时与作业执行环境的信任库
Runner 注册成功后,还需确保它拉取镜像、执行 CI 脚本时也信任该 CA。尤其当作业使用 docker 执行器时,Docker daemon 和容器内部都需识别证书:
-
Docker daemon 层:将同一份
ca.crt复制到宿主机/etc/docker/certs.d/gitlab.internal:443/ca.crt(注意端口匹配),然后重启docker.service -
作业容器层:在
.gitlab-ci.yml的before_script中,根据基础镜像类型安装证书:- Ubuntu/Debian:
cp /etc/gitlab-runner/certs/gitlab-ca.crt /usr/local/share/ca-certificates/ && update-ca-certificates - Alpine:
cp /etc/gitlab-runner/certs/gitlab-ca.crt /usr/local/share/ca-certificates/ && update-ca-certificates
- Ubuntu/Debian:
- 如使用
shell执行器,需确保 Runner 进程运行用户(如gitlab-runner)的系统信任库已更新,或在脚本中临时设置SSL_CERT_FILE=/etc/gitlab-runner/certs/gitlab-ca.crt
排查常见连接失败场景
即使证书已加载,仍可能因环境错位失败。优先检查以下三项:
-
DNS 解析是否可达:Runner 容器内运行
nslookup gitlab.internal或ping -c2 gitlab.internal,确认域名能解析到内网 IP;若失败,需在容器启动时通过--dns或挂载/etc/resolv.conf指定内网 DNS -
Git 是否意外走代理:CI 作业中出现
SSL certificate problem: self-signed certificate in certificate chain,但openssl s_client正常?很可能是 Git 走了 HTTP 代理。在.gitlab-ci.yml中添加:variables: NO_PROXY: "gitlab.internal" -
证书链完整性:用
openssl verify -CAfile /etc/gitlab-runner/certs/gitlab-ca.crt https://gitlab.internal测试全链校验。若提示 “unable to get issuer certificate”,说明你提供的只是中间证书,缺根证书;或 GitLab Nginx 配置未包含完整 chain(需检查ssl_certificate是否为fullchain.pem)
不复杂但容易忽略。只要 CA 根证书到位、路径传得准、各层环境都认它,Runner 就能像访问公网 GitHub 一样自然、安全地连上你的内网 GitLab。











