fix(ci): fetch ISRG Root YR root cert at build time + belt-and-suspenders
CI/CD / CI · API (dotnet build + test) (push) Failing after 3m35s
CI/CD / CI · Admin API (dotnet build) (push) Failing after 6m23s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m6s
CI/CD / CI · Admin Web (tsc) (push) Successful in 37s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / Deploy · all services (push) Has been skipped

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 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-07 07:34:52 +03:30
parent 82145b0d21
commit 1db8a8f08c
+30 -6
View File
@@ -81,13 +81,28 @@ jobs:
EOF EOF
- name: Trust Nexus mirror CA - name: Trust Nexus mirror CA
# The mirror's Let's Encrypt cert renewed under the new ISRG Root YR, which is # The mirror's cert chains to ISRG Root YR (new LE ECDSA root, 2025).
# not yet in the SDK image's trust store. The npm jobs skip TLS via # This root is NOT in the .NET SDK image's trust store, causing PartialChain.
# --strict-ssl=false; dotnet validates, so add the mirror's intermediate # Fix: fetch ISRG Root YR via its HTTP AIA URL (plain HTTP, no TLS) then
# (CA:TRUE, valid to Sept 2028) as a trust anchor. # 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: | 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 cp docker/nexus-mirror-ca.crt /usr/local/share/ca-certificates/nexus-mirror-ca.crt
# 3. Update OS trust store
update-ca-certificates 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 - name: Restore
run: dotnet restore src/Meezi.API/Meezi.API.csproj --configfile /tmp/nuget.ci.config run: dotnet restore src/Meezi.API/Meezi.API.csproj --configfile /tmp/nuget.ci.config
@@ -139,11 +154,20 @@ jobs:
EOF EOF
- name: Trust Nexus mirror CA - name: Trust Nexus mirror CA
# See api-build: trust the mirror's intermediate so dotnet restore validates # See api-build for full explanation. Same fix: fetch ISRG Root YR root +
# the new ISRG Root YR chain (npm jobs sidestep this with --strict-ssl=false). # add YR2 intermediate + belt-and-suspenders append to ca-certificates.crt.
run: | 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 cp docker/nexus-mirror-ca.crt /usr/local/share/ca-certificates/nexus-mirror-ca.crt
update-ca-certificates 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 - name: Restore
run: dotnet restore src/Meezi.Admin.API/Meezi.Admin.API.csproj --configfile /tmp/nuget.ci.config run: dotnet restore src/Meezi.Admin.API/Meezi.Admin.API.csproj --configfile /tmp/nuget.ci.config