ci: verbose diagnostic Trust step to pinpoint PartialChain cause
CI/CD / CI · API (dotnet build + test) (push) Failing after 3s
CI/CD / CI · Admin API (dotnet build) (push) Failing after 2s
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

Previous attempt used curl -sf which silently swallows failures, so
we never knew if ISRG Root YR was actually fetched. This run:
  • set -euo pipefail  → step fails fast and loudly on any error
  • curl -v            → shows connection result / error in log
  • openssl verify     → confirms cert bundle is good before restore
  • openssl s_client   → shows full chain verify against live mirror

If the AIA URL (http://yr.i.lencr.org/) is unreachable from the
runner, the step will fail HERE rather than silently at dotnet restore.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-07 08:09:18 +03:30
parent 1db8a8f08c
commit 7b77bb4722
+47 -30
View File
@@ -80,29 +80,44 @@ jobs:
</configuration>
EOF
- name: Trust Nexus mirror CA
# 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.
- name: Trust Nexus mirror CA (diagnostic)
# Verbose / fail-fast version to expose exactly where the chain trust breaks.
# Step exits non-zero on any unexpected failure so the CI log shows the cause.
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)
set -euo pipefail
echo "=== OS / OpenSSL info ==="
cat /etc/os-release | head -4 || true
openssl version || true
echo "=== Fetch ISRG Root YR from AIA (HTTP) ==="
curl -v --max-time 15 http://yr.i.lencr.org/ -o /tmp/isrg-root-yr.der 2>&1
echo "File size: $(wc -c < /tmp/isrg-root-yr.der) bytes"
openssl x509 -inform DER -in /tmp/isrg-root-yr.der \
-out /usr/local/share/ca-certificates/isrg-root-yr.crt
openssl x509 -noout -subject -issuer \
-in /usr/local/share/ca-certificates/isrg-root-yr.crt
echo "=== Add YR2 intermediate ==="
cp docker/nexus-mirror-ca.crt /usr/local/share/ca-certificates/nexus-mirror-ca.crt
# 3. Update OS trust store
openssl x509 -noout -subject -issuer -in docker/nexus-mirror-ca.crt
echo "=== Update OS trust store ==="
update-ca-certificates
# 4. Append directly to the OpenSSL active bundle (dotnet reads this on Linux)
echo "=== Append to OpenSSL bundle ==="
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
cat /usr/local/share/ca-certificates/isrg-root-yr.crt >> /etc/ssl/certs/ca-certificates.crt
echo "Bundle size: $(wc -l < /etc/ssl/certs/ca-certificates.crt) lines"
echo "=== Verify YR2 against bundle ==="
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt \
/usr/local/share/ca-certificates/nexus-mirror-ca.crt
echo "=== Full chain verify against mirror ==="
echo | openssl s_client -connect mirror.soroushasadi.com:443 \
-CAfile /etc/ssl/certs/ca-certificates.crt 2>&1 | tail -5
echo "=== Done ==="
- name: Restore
run: dotnet restore src/Meezi.API/Meezi.API.csproj --configfile /tmp/nuget.ci.config
@@ -153,21 +168,23 @@ jobs:
</configuration>
EOF
- name: Trust Nexus mirror CA
# See api-build for full explanation. Same fix: fetch ISRG Root YR root +
# add YR2 intermediate + belt-and-suspenders append to ca-certificates.crt.
- name: Trust Nexus mirror CA (diagnostic)
# Same verbose/fail-fast step as api-build — see that job for full comments.
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"
set -euo pipefail
curl -v --max-time 15 http://yr.i.lencr.org/ -o /tmp/isrg-root-yr.der 2>&1
echo "File size: $(wc -c < /tmp/isrg-root-yr.der) bytes"
openssl x509 -inform DER -in /tmp/isrg-root-yr.der \
-out /usr/local/share/ca-certificates/isrg-root-yr.crt
openssl x509 -noout -subject -issuer \
-in /usr/local/share/ca-certificates/isrg-root-yr.crt
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
cat /usr/local/share/ca-certificates/isrg-root-yr.crt >> /etc/ssl/certs/ca-certificates.crt
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt \
/usr/local/share/ca-certificates/nexus-mirror-ca.crt
echo "=== Done ==="
- name: Restore
run: dotnet restore src/Meezi.Admin.API/Meezi.Admin.API.csproj --configfile /tmp/nuget.ci.config