Git配置自签名证书

在企业内网环境中,部署Gitea私有代码仓库并配置自签名证书(或私有CA证书)及内网域名后,开发人员常遇到Git操作(如git fetch、git pull)抛出SSL证书验证错误:SSL certificate problem: unable to get local issuer certificate(OpenSSL验证错误码20)。本文围绕Git配置自签名证书的核心场景,从问题根源剖析、前置排查方法、针对性解决方案三个维度,提供严谨可行的落地思路,兼顾安全性与实操性,助力企业解决自签名证书验证异常问题。

一、问题背景与核心成因

内网环境中,为保障Gitea仓库访问的安全性,通常会配置私有CA签发的SSL证书(或自签名证书),以实现HTTPS协议的加密传输。Git底层依赖OpenSSL库执行证书验证流程,当OpenSSL无法从证书链中检索到本地信任的根证书(CA)时,将触发该验证错误。具体成因可归纳为以下三类:

  • 配置对象错误,误将服务器证书(server.crt)作为验证依据,未配置签发该服务器证书的根CA证书,导致OpenSSL无法验证证书来源的合法性;

  • 证书链不完整,缺少中间CA证书或根CA证书,导致证书验证链条断裂,无法完成全链路信任校验;

  • Git配置存在优先级冲突,或证书路径、格式不符合规范,导致Git无法正确加载并应用指定证书。

需明确的是,OpenSSL验证错误码20(OpenSSL verify result: 20)是该问题的核心标识,其直接指向「无法获取本地颁发机构证书」,与证书过期、域名不匹配等其他SSL错误存在本质区别,需精准区分排查。

二、前置排查:快速定位问题根源

在开展问题修复前,建议先通过以下命令完成前置排查,明确问题核心诱因,避免盲目操作。所有命令可在Git Bash(Windows系统)或终端(Linux/macOS系统)中执行。

1. 查看Git SSL相关配置

首先核查Git是否已配置证书路径,同时确认是否存在配置冲突(如全局证书配置与指定网址证书配置冲突),执行以下命令:

1
2
3
4
# 查看全局所有SSL相关配置
git config --global --get-regexp ssl
# 查看全局所有HTTP相关配置(重点关注sslCAInfo、sslVerify等关键参数)
git config --global --get-regexp http

若输出结果中包含http.https://你的内网Gitea域名.sslCAInfo,说明已为目标域名配置专属证书;若存在http.sslCAInfo(全局证书配置),需注意配置优先级——指定网址的证书配置优先级高于全局证书配置,避免因优先级冲突导致配置失效。

2. 开启Git调试模式,查看证书验证详情

通过开启Git调试模式执行相关操作,可获取OpenSSL证书验证的完整日志,明确错误根源(如证书路径错误、证书链缺失等),执行命令如下:

1
2
# 替换为内网Gitea仓库实际地址,执行fetch操作并输出调试日志
GIT_CURL_VERBOSE=1 git fetch https://gitea.your-internal-domain.com/your/repo.git

日志分析需重点关注以下核心信息:

  • CAfile:Git实际加载的证书路径,确认该路径与配置的证书路径是否一致;

  • SSL certificate verify result:除错误码20外,关注是否存在补充提示(如「certificate chain too short」提示证书链不完整);

  • SSL: no alternative certificate subject name matches target host name:若出现该提示,说明证书绑定的域名与访问域名不匹配,需核查证书配置的域名信息。

三、针对性解决方案(按优先级排序)

以下解决方案按「安全合规性」优先级排序,优先推荐不降低系统安全性的方案,规避全局禁用SSL验证带来的安全风险,确保内网代码传输的安全性。

方案1:为指定网址配置根CA证书(推荐方案)

该方案为最精准、最安全的解决方案,仅为内网Gitea域名配置专属根CA证书,不影响其他Git仓库(如GitHub、GitLab)的SSL验证流程,符合企业内网安全管理规范。

操作步骤:

  1. 确认根CA证书有效性:使用文本编辑器(如记事本、vim)打开证书文件,若文件仅包含1段-----BEGIN CERTIFICATE-----内容,大概率为服务器证书(server.crt),需获取签发该服务器证书的根CA证书(通常命名为internal-ca-root.crt、ca.crt等);

  2. 配置指定网址的证书路径
    `# 核心命令(替换为内网Gitea实际域名及根CA证书绝对路径)

git config –global http.https://gitea.your-internal-domain.com.sslCAInfo “/绝对路径/到/internal-ca-root.crt”`

- `--global`:该参数表示配置对当前用户所有Git仓库生效;若仅需对单个仓库生效,进入目标仓库目录后,移除该参数执行命令即可;

- 证书路径必须采用**绝对路径**,相对路径可能导致Git无法正常加载证书,支持.crt、.pem、.cer三种格式;

- 若Gitea服务运行在非默认HTTPS端口(如8443),需在域名后添加端口信息,配置命令如下:
           `git config --global http.https://gitea.your-internal-domain.com:8443.sslCAInfo "/绝对路径/到/internal-ca-root.crt"`
  1. 验证配置生效状态
    `# 查看指定网址的证书配置是否正确

git config –global –get http.https://gitea.your-internal-domain.com.sslCAInfo`若命令输出配置的根CA证书绝对路径,说明配置已生效。

方案2:补齐证书链,配置完整证书文件

若SSL证书为「服务器证书+中间CA证书+根CA证书」的组合形式,仅配置根CA证书可能导致验证失败(部分环境下OpenSSL需校验完整的证书链),此时需合并证书链后再进行配置。

操作步骤:

  1. 合并证书链:按「服务器证书 → 中间CA证书 → 根CA证书」的顺序,将三类证书合并至单个文件(顺序不可颠倒),执行命令如下:
    `# Linux/macOS系统合并命令(替换为实际证书文件名)
    cat server.crt intermediate-ca.crt root-ca.crt > full-chain.crt

Windows系统(Git Bash环境)合并命令

cat server.crt intermediate-ca.crt root-ca.crt > full-chain.crt合并完成后,打开full-chain.crt文件,应包含3段—–BEGIN CERTIFICATE—–—–END CERTIFICATE—–`内容,确保证书链完整。

  1. 配置合并后的完整证书
    git config --global http.https://gitea.your-internal-domain.com.sslCAInfo "/绝对路径/到/full-chain.crt"

方案3:将根CA证书导入系统信任库(彻底解决方案)

若需实现多应用共享证书信任(如浏览器、curl、wget等应用均需访问内网Gitea仓库),可将根CA证书导入系统信任库,实现证书信任的全局生效,从根本上解决验证问题。

不同系统操作方法:

  • Linux系统(Ubuntu/Debian系列)
    `# 将根CA证书复制至系统信任证书目录

sudo cp /绝对路径/到/internal-ca-root.crt /usr/local/share/ca-certificates/

更新系统证书缓存,使配置生效

sudo update-ca-certificates`

  • Windows系统

    1. 右键点击根CA证书文件,选择「安装证书」选项;

    2. 选择「本地计算机」,点击「下一步」(需具备管理员权限);

    3. 选择「将所有证书放入下列存储」,点击「浏览」,选中「受信任的根证书颁发机构」;

    4. 点击「完成」,重启Git Bash或终端,确保配置生效。

  • macOS系统
    # 导入根CA证书至系统钥匙串(需管理员权限) sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /绝对路径/到/internal-ca-root.crt

根CA证书导入系统信任库后,Git将自动调用系统信任的证书完成验证,无需额外配置sslCAInfo参数(若此前已配置,可保留或通过git config –unset命令删除)。

方案4:临时禁用指定网址的SSL验证(应急方案)

若根CA证书丢失、证书链无法补齐等特殊情况导致上述方案无法落地,可临时禁用目标内网Gitea域名的SSL验证。该方案仅对指定域名生效,相较于全局禁用SSL验证,安全性更高,仅建议作为应急处置手段。

1
2
# 仅禁用内网Gitea域名的SSL证书验证
git config --global http.https://gitea.your-internal-domain.com.sslVerify false

⚠️ 注意:该方案会关闭目标域名的SSL证书验证功能,存在数据传输安全风险,问题解决后需及时通过git config –unset命令恢复证书验证配置,保障代码传输安全。

四、验证修复效果

配置完成后,建议通过以下命令验证问题是否彻底解决,确保证书验证流程正常:

1
2
3
4
# 1. 用curl验证证书有效性(替换为内网Gitea域名及根CA证书路径)
curl --cacert /绝对路径/到/internal-ca-root.crt -v https://gitea.your-internal-domain.com
# 2. 执行Git操作,验证访问是否正常
git fetch

若curl命令输出「SSL certificate verify ok」,且git fetch操作无SSL验证错误,说明证书验证功能已恢复正常。

五、常见问题与注意事项

  • 证书路径错误:配置时务必使用绝对路径,Windows系统在Git Bash环境中需采用类Linux路径格式(如/c/Users/用户名/证书路径),不可使用Windows原生路径(如C:\Users\用户名\证书路径),避免路径解析失败;

  • 配置优先级冲突:Git证书配置优先级遵循「仓库本地配置(无–global参数)> 用户全局配置(–global参数)> 系统级配置」,若存在多维度配置冲突,可通过git config –unset命令删除无用配置,确保目标配置生效;

  • 证书格式错误:确保证书为PEM文本格式(包含-----BEGIN CERTIFICATE----------END CERTIFICATE-----标识),避免使用DER二进制格式,否则将导致Git无法解析证书;

  • Git版本兼容性:低版本Git可能存在证书配置兼容问题,建议将Git版本升级至2.30及以上(可通过git --version命令查看当前版本),提升配置兼容性与稳定性。

六、总结

Git SSL证书错误(unable to get local issuer certificate,错误码20)的核心诱因是「OpenSSL无法检索到本地信任的根CA证书」,问题解决的关键在于:确保配置对象为根CA证书(而非服务器证书),或补齐完整的证书验证链

解决方案推荐优先级:方案1(指定网址配置根CA证书)→ 方案2(补齐证书链)→ 方案3(导入系统信任库)→ 方案4(临时禁用验证)。其中,方案1与方案2兼顾安全性与精准性,是企业内网环境的最优落地方案;方案3适用于多应用共享证书信任的场景;方案4仅作为应急处置手段,不可长期使用。

通过本文所述的排查方法与解决方案,可有效解决内网Gitea仓库的Git SSL证书验证问题,保障内网代码传输的安全性与稳定性,为企业私有代码仓库的正常运行提供支撑。

(注:文档部分内容可能由 AI 生成)