Edit

Share via


Run the agent with a self-signed certificate

Azure DevOps Server 2022 - Azure DevOps Server 2019

This topic explains how to run a self-hosted agent with a self-signed certificate.

Work with SSL server certificate

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.

Agent diagnostic log shows:

[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

This security error may indicate the server certificate you used on your Azure Devops Server host machine isn't trusted by the build machine. Make sure you install your self-signed ssl server certificate into the OS certificate store.

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

You can easily verify whether the certificate is installed correctly by running few commands. You should be good as long as SSL handshake finished correctly even you get a 401 for the request.

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)

If somehow you can't successfully install certificate into your machine's certificate store due to various reasons, like: you don't have permission or you are on a customized Linux machine. The agent version 2.125.0 or above has the ability to ignore SSL server certificate validation error.

Important

Ignoring SSL server certificate validation errors isn't secure and not recommended, we highly suggest you install the certificate into your machine certificate store.

Pass --sslskipcertvalidation during agent configuration

./config.cmd/sh --sslskipcertvalidation

Note

To use the --sslskipcertvalidation flag on Linux and macOS, the libcurl library on your Linux or macOS machine must be built with OpenSSL. More information

Git get sources fails with SSL certificate problem (Windows agent only)

We ship command-line Git as part of the Windows agent. We use this copy of Git for all Git related operations. When you have a self-signed SSL certificate for your on-premises Azure DevOps Server machine, make sure to configure the Git we shipped to allow that self-signed SSL certificate. There are two approaches to solve the problem.

  1. Set the following git config in global level by the agent's run as user.

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

    Note

    Setting system level Git config isn't reliable on Windows. The system .gitconfig file is stored with the copy of Git we packaged, which gets replaced whenever the agent is upgraded to a new version.

  2. Enable git to use SChannel during configure with 2.129.0 or higher version agent Pass --gituseschannel during agent configuration

    ./config.cmd --gituseschannel
    

    Note

    Git SChannel has more restrict requirement for your self-signed certificate. Self-signed certificate that generated by IIS or PowerShell command may not be capable with SChannel.

Work with SSL client certificate

IIS has an SSL setting that requires all incoming requests to Azure DevOps Server must present client certificate in addition to the regular credential.

When that IIS SSL setting enabled, you need to use version 2.125.0 or newer and follow these extra steps in order to configure the build machine against your Azure DevOps Server.

  • Prepare all required certificate information

    • CA certificate(s) in .pem format (This file should contain the public key and signature of the CA certificate, you need put the root ca certificate and all your intermediate ca certificates into one .pem file)
    • Client certificate in .pem format (This file should contain the public key and signature of the Client certificate)
    • Client certificate private key in .pem format (This file should contain only the private key of the Client certificate)
    • Client certificate archive package in .pfx format (This file should contain the signature, public key and private key of the Client certificate)
    • Use SAME password to protect Client certificate private key and Client certificate archive package, since they both have client certificate's private key
  • Install CA certificate(s) into machine certificate store

    • Linux: OpenSSL certificate store
    • macOS: System or User Keychain
    • Windows: Windows certificate store
  • Pass --sslcacert, --sslclientcert, --sslclientcertkey. --sslclientcertarchive and --sslclientcertpassword during agent configuration.

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

    Your client certificate private key password is securely stored on each platform.

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

Verifying Root Certificate Authority Trust

The build agent utilizes Node.js that relies on its own certificate store derived from Mozilla's trusted root certificates. It's crucial that any root certificate used for secure communication is trusted by the Node.js Certificate Authority store, which helps avoid the following errors after updating a certificate on the Azure DevOps Server machine:

  • unable to get local issuer certificate
  • SELF_SIGNED_CERT_IN_CHAIN
  • unable to verify the first certificate

The tls.rootCertificates array can be used to verify trusted root Certificate Authorities (CAs) used for verifying TLS/SSL connections.

# 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" 

To configure Node.js to trust a certificate NODE_EXTRA_CA_CERTS environment variable, introduced in Node v7.3.0, allows you to specify a file containing one or more additional CA certificates that Node will trust in addition to the default bundle. NODE_EXTRA_CA_CERTS appends to the trust store.

  1. Export the certificate(s) in PEM format: On your server or CA, export the root (and any intermediate, if needed) certificates as a PEM encoded file. This format is a text file with -----BEGIN CERTIFICATE----- and base64 data. Ensure it’s Base-64 encoded PEM, not DER. (On Windows, .CER files can be either; you may rename to .pem to avoid confusion. The file can actually have any extension, but .pem or .crt is standard.) If you have multiple internal CAs (a chain), you can concatenate them into one file – Node reads all certificates in that file.
  2. Make the PEM available on the build agent by placing it into a known path (e.g. C:\certs\CorpRootCA.pem or /etc/ssl/certs/CorpRootCA.pem).
  3. Set an OS environment variable NODE_EXTRA_CA_CERTS pointing to that PEM file. For example, on Windows, one can use PowerShell:
[Environment]::SetEnvironmentVariable("NODE_EXTRA_CA_CERTS", "C:\certs\CorpRootCA.pem", "Machine")

Learn more about agent client certificate support.