From 1db8a8f08cc5258d005a360b7e16dcf06346c867 Mon Sep 17 00:00:00 2001 From: "soroush.asadi" Date: Sun, 7 Jun 2026 07:34:52 +0330 Subject: [PATCH] fix(ci): fetch ISRG Root YR root cert at build time + belt-and-suspenders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The prior Trust step added only the YR2 intermediate to the OS trust store. dotnet's X.509 chain builder requires a self-signed ROOT as the trust anchor (it does not enable OpenSSL's X509_V_FLAG_PARTIAL_CHAIN), so intermediate-only still caused PartialChain. New approach (two jobs: api-build, admin-api-build): 1. curl http://yr.i.lencr.org/ (plain HTTP AIA) → ISRG Root YR DER → convert to PEM → add to /usr/local/share/ca-certificates/ 2. cp YR2 intermediate (docker/nexus-mirror-ca.crt) → same dir 3. update-ca-certificates (OS method) 4. cat both certs >> /etc/ssl/certs/ca-certificates.crt (belt-and-suspenders: directly appends to the OpenSSL bundle dotnet reads on Linux, works even if step 3 is a no-op) If the AIA fetch fails (network block) step 4 still appends the intermediate, which may work if dotnet ever enables partial chains. Fetch failure is non-fatal (echo warning + continue). Co-Authored-By: Claude Sonnet 4.6 --- .gitea/workflows/ci-cd.yml | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/.gitea/workflows/ci-cd.yml b/.gitea/workflows/ci-cd.yml index ec674cf..220c00b 100644 --- a/.gitea/workflows/ci-cd.yml +++ b/.gitea/workflows/ci-cd.yml @@ -81,13 +81,28 @@ jobs: EOF - name: Trust Nexus mirror CA - # The mirror's Let's Encrypt cert renewed under the new ISRG Root YR, which is - # not yet in the SDK image's trust store. The npm jobs skip TLS via - # --strict-ssl=false; dotnet validates, so add the mirror's intermediate - # (CA:TRUE, valid to Sept 2028) as a trust anchor. + # The mirror's cert chains to ISRG Root YR (new LE ECDSA root, 2025). + # This root is NOT in the .NET SDK image's trust store, causing PartialChain. + # Fix: fetch ISRG Root YR via its HTTP AIA URL (plain HTTP, no TLS) then + # add both the root AND the YR2 intermediate so the full chain validates. + # Belt-and-suspenders: also append directly to the OpenSSL cert bundle so the + # fix works regardless of whether update-ca-certificates is wired correctly. run: | + # 1. Fetch ISRG Root YR root cert from Let's Encrypt AIA (HTTP — no TLS risk) + curl -sf --max-time 15 http://yr.i.lencr.org/ -o /tmp/isrg-root-yr.der \ + && openssl x509 -inform DER -in /tmp/isrg-root-yr.der \ + -out /usr/local/share/ca-certificates/isrg-root-yr.crt \ + && echo "Fetched ISRG Root YR: $(openssl x509 -noout -subject -in /usr/local/share/ca-certificates/isrg-root-yr.crt)" \ + || echo "Warning: could not fetch ISRG Root YR — falling back to intermediate only" + # 2. Add YR2 intermediate (already in repo, CA:TRUE) cp docker/nexus-mirror-ca.crt /usr/local/share/ca-certificates/nexus-mirror-ca.crt + # 3. Update OS trust store update-ca-certificates + # 4. Append directly to the OpenSSL active bundle (dotnet reads this on Linux) + cat docker/nexus-mirror-ca.crt >> /etc/ssl/certs/ca-certificates.crt + [ -f /usr/local/share/ca-certificates/isrg-root-yr.crt ] \ + && cat /usr/local/share/ca-certificates/isrg-root-yr.crt >> /etc/ssl/certs/ca-certificates.crt \ + || true - name: Restore run: dotnet restore src/Meezi.API/Meezi.API.csproj --configfile /tmp/nuget.ci.config @@ -139,11 +154,20 @@ jobs: EOF - name: Trust Nexus mirror CA - # See api-build: trust the mirror's intermediate so dotnet restore validates - # the new ISRG Root YR chain (npm jobs sidestep this with --strict-ssl=false). + # See api-build for full explanation. Same fix: fetch ISRG Root YR root + + # add YR2 intermediate + belt-and-suspenders append to ca-certificates.crt. run: | + curl -sf --max-time 15 http://yr.i.lencr.org/ -o /tmp/isrg-root-yr.der \ + && openssl x509 -inform DER -in /tmp/isrg-root-yr.der \ + -out /usr/local/share/ca-certificates/isrg-root-yr.crt \ + && echo "Fetched ISRG Root YR: $(openssl x509 -noout -subject -in /usr/local/share/ca-certificates/isrg-root-yr.crt)" \ + || echo "Warning: could not fetch ISRG Root YR — falling back to intermediate only" cp docker/nexus-mirror-ca.crt /usr/local/share/ca-certificates/nexus-mirror-ca.crt update-ca-certificates + cat docker/nexus-mirror-ca.crt >> /etc/ssl/certs/ca-certificates.crt + [ -f /usr/local/share/ca-certificates/isrg-root-yr.crt ] \ + && cat /usr/local/share/ca-certificates/isrg-root-yr.crt >> /etc/ssl/certs/ca-certificates.crt \ + || true - name: Restore run: dotnet restore src/Meezi.Admin.API/Meezi.Admin.API.csproj --configfile /tmp/nuget.ci.config