使用自签名证书运行代理

Azure DevOps Server |Azure DevOps Server 2022 |Azure DevOps Server 2020

本文介绍如何使用 Azure Pipelines 和 Azure DevOps Server 的自签名证书运行自承载代理。

使用 SSL 服务器证书

Enter server URL > https://corp.tfs.com/tfs
Enter authentication type (press enter for Integrated) >
Connecting to server ...
An error occurred while sending the request.

代理诊断日志显示:

[2017-11-06 20:55:33Z ERR  AgentServer] System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.Http.WinHttpException: A security error occurred

前面的安全错误可能表示生成计算机不信任在 Azure Devops Server 主机上使用的服务器证书。 请确保将自签名 SSL 服务器证书安装到 OS 证书存储中。

Windows: Windows certificate store
Linux: OpenSSL certificate store
macOS: OpenSSL certificate store for agent version 2.124.0 or below
       Keychain for agent version 2.125.0 or above

可以通过运行几个命令轻松验证证书是否已正确安装。 只要 SSL 握手正确完成(即使收到 401 错误请求),安装就成功了。

Windows: PowerShell Invoke-WebRequest -Uri https://corp.tfs.com/tfs -UseDefaultCredentials 
Linux: curl -v https://corp.tfs.com/tfs 
macOS: curl -v https://corp.tfs.com/tfs (agent version 2.124.0 or below, curl needs to be built for OpenSSL)
       curl -v https://corp.tfs.com/tfs (agent version 2.125.0 or above, curl needs to be built for Secure Transport)

如果由于各种原因无法成功将证书安装到计算机的证书存储中(例如你没有正确的权限或你位于自定义 Linux 计算机上),则还有另一个选项。 代理版本 2.125.0 或更高版本能够忽略 SSL 服务器证书验证错误。

重要

不建议忽略 SSL 服务器证书验证错误。 它不安全。 强烈建议将证书安装到计算机证书存储中。

在代理配置期间传递 --sslskipcertvalidation

./config.cmd/sh --sslskipcertvalidation

注释

若要在 --sslskipcertvalidation Linux 和 macOS 上使用标记,您的 Linux 或 macOS 计算机上的 libcurl 必须使用 OpenSSL 构建。

问题:Git get sources 命令由于 SSL 证书问题而失败(仅在 Windows 代理中发生)

我们将在 Windows 代理程序中包含命令行 Git,并使用这份 Git 副本进行所有与 Git 相关的操作。 为本地 Azure DevOps Server 计算机提供自签名 SSL 证书时,请将随附的 Git 配置为允许自签名 SSL 证书。

可通过两种方法解决此问题:

  • 在该代理以特定用户身份运行时,在全局级别设置以下内容 git config

    git config --global http."https://tfs.com/".sslCAInfo certificate.pem
    

    注释

    在 Windows 上设置系统级别 git config 并不可靠。 系统 .gitconfig 文件随打包的 Git 副本一起存储。 每当代理升级到新版本时,打包的 Git 都会被替换。

  • 当您使用 2.129.0 或更高版本的代理时,启用 Git 在配置期间使用 SChannel。 在代理配置期间传递 --gituseschannel

    ./config.cmd --gituseschannel
    

    注释

    Git SChannel 对自签名证书具有更严格的要求。 Internet Information Services (IIS) 或 PowerShell 命令生成的自签名证书可能不兼容 SChannel

使用 SSL 客户端证书

IIS 具有 SSL 设置,要求对 Azure DevOps Server 的所有传入请求都必须提供客户端证书和常规凭据。

启用 IIS SSL 设置后,需要使用版本 2.125.0 或更高版本,并执行以下额外步骤,以便针对 Azure DevOps Server 配置生成计算机。

  1. 准备所有必需的证书信息:

    • 证书颁发机构(CA)证书 .pem 的格式:此文件应包含 CA 证书的公钥和签名。 需要将根 CA 证书和所有中间 CA 证书放入一个 .pem 文件中。
    • 采用格式的 .pem 客户端证书:此文件应包含客户端证书的公钥和签名。
    • 采用格式的 .pem 客户端证书私钥:此文件应仅包含客户端证书的私钥。
    • 采用格式的 .pfx 客户端证书存档包:此文件应包含客户端证书的签名、公钥和私钥。
    • 密码:使用相同的密码来保护客户端证书私钥和客户端证书存档包,因为它们都具有客户端证书的私钥。
  2. 将 CA 证书安装到计算机证书存储中:

    • Linux:OpenSSL 证书存储
    • macOS:系统或用户密钥链
    • Windows:Windows 证书存储
  3. Pass--sslcacert, , --sslclientcert--sslclientcertkey. --sslclientcertarchive,并在配置代理期间--sslclientcertpassword

    .\config.cmd/sh --sslcacert ca.pem --sslclientcert clientcert.pem --sslclientcertkey clientcert-key-pass.pem --sslclientcertarchive clientcert-archive.pfx --sslclientcertpassword "mypassword"
    

    客户端证书私钥密码安全地存储在每个平台上。

    Linux: Encrypted with a symmetric key based on the machine ID
    macOS: macOS Keychain
    Windows: Windows Credential Store
    

验证根证书颁发机构信任

构建代理使用 Node.js,而它依赖于自己的证书存储,该存储从 Mozilla 的受信任根证书派生。 Node.js 证书授权机构存储必须信任任何您用于安全通信的根证书。 否则,在 Azure DevOps Server 计算机上更新证书后,可能会收到以下错误:

  • “无法获取本地颁发者证书”
  • 自签名证书在链中
  • “无法验证第一个证书”

可以使用 tls.rootCertificates 数组来验证用于验证 TLS/SSL 连接的受信任根 CA。

# Sample script to extract Node.js root certificates using Node.js.  
node -e ' 
const tls = require("tls"); 
console.log(tls.rootCertificates.join("\n")); 
' > "$ROOT_CERTS_FILE" 

Node v7.3.0 中引入的 NODE_EXTRA_CA_CERTS 环境变量允许指定包含节点信任的一个或多个 CA 证书的文件(除了默认捆绑包)。 NODE_EXTRA_CA_CERTS 追加到信任库。

  1. 在您的服务器或 CA 上,将根证书(以及任何需要的中间证书)导出为 PEM 编码的文件。 此格式是包含 -----BEGIN CERTIFICATE----- 和 Base64 数据的文本文件。 请确保使用 Base64 编码的 PEM,而不是 DER。 (在 Windows 上,.cer文件可以是任一;可以重命名为 .pem 以避免混淆。该文件实际上可以具有任何扩展名,但 .pem 或 .crt 是标准的。

    如果你有多个内部 CA(一个链),则可以将它们串联成一个文件。 节点读取该文件中的所有证书。

  2. 通过将 PEM 置于已知路径(例如), C:\certs\CorpRootCA.pem or /etc/ssl/certs/CorpRootCA.pem使 PEM 在生成代理上可用。

  3. 设置指向 PEM 文件的 OS 环境变量 NODE_EXTRA_CA_CERTS。 例如,可以在 Windows 上使用 PowerShell:

[Environment]::SetEnvironmentVariable("NODE_EXTRA_CA_CERTS", "C:\certs\CorpRootCA.pem", "Machine")

详细了解 代理客户端证书支持