Jabrique opened a new pull request, #13373:
URL: https://github.com/apache/trafficserver/pull/13373
When a `traffic_ctl config reload` encounters a broken entry in
`ssl_multicert.yaml`, the current behavior is all-or-nothing: the
entire new SSLCertLookup is thrown away and the old configuration stays
active. This is safe but operationally painful, a single bad cert
blocks all other cert updates from going live until the broken one is
fixed.
This PR adds `proxy.config.ssl.server.multicert.partial_reload` (INT,
default 0). When set to 1, a reload that finds one or more unloadable
certs still commits the rest of the certs rather than discarding
everything. Any skipped cert produces an ERROR in diags.log and
increments the new `proxy.process.ssl.ssl_multicert_load_failures`
counter, so the degraded state is never silent.
The default (0) keeps the existing strict/atomic behaviour, no
existing deployments are affected.
**Implementation notes:**
- The commit gate is in `SSLCertificateConfig::reconfigure()`. The new
`partialCommit` path only activates when `configPartialReload == 1`
AND `SSL_CTX_get0_certificate(lookup->ssl_default.get()) != nullptr`.
The second check distinguishes a real user-loaded default from the
bare bootstrap context that `load()` creates when all certs fail,
committing a bare context would silently break TLS for every
connection.
- `retStatus` is flipped to `true` after a partial commit **only on
live reloads** (i.e. when `configid != 0` at entry). At initial
startup the lookup is always committed anyway (via the existing
`configid == 0` path), and `retStatus` must stay `false` so that
`startup()` can still honour `exit_on_load_fail`. This distinction
is captured via a `const bool initialLoad = (configid == 0)` that is
read before `configProcessor.set()` mutates `configid`.
- The new metric increment in `_load_items()` is guarded by a null
pointer check. Unlike other counters that are only incremented from
paths that execute after `SSLInitializeStatistics()`, `_load_items()`
can be called during early startup before the stats block is fully
initialized. The guard is intentional defensive programming, not an
inconsistency.
- This knob applies only to `SSLCertificateConfig` (TLS server certs).
`QUICCertConfig` (HTTP/3) retains strict all-or-nothing.
**Files changed:**
| File | Change |
|---|---|
| `src/records/RecordsConfig.cc` | Register new knob (`RECU_DYNAMIC`) |
| `src/iocore/net/P_SSLConfig.h` | Add `configPartialReload` field |
| `src/iocore/net/SSLConfig.cc` | Partial-commit gate in `reconfigure()`
with startup guard |
| `src/iocore/net/SSLStats.h/.cc` | New counter
`ssl_multicert_load_failures` |
| `src/iocore/net/SSLUtils.cc` | Increment counter on cert load failure
(with guard + comment) |
| `doc/admin-guide/files/records.yaml.en.rst` | Document new knob
(`:reloadable:`, QUIC limitation note) |
| `doc/admin-guide/monitoring/statistics/core/ssl.en.rst` | Document new
metric |
| `tests/gold_tests/tls/ssl_multicert_partial_reload.test.py` | New gold
test |
**Testing:**
Gold test `ssl_multicert_partial_reload` covers:
- **Scenario A** strict mode (default): a single bad cert causes the
whole reload to fail and the old config stays intact (verified by
CN of served cert).
- **Scenario B** partial mode: a bad cert is skipped, the newly
generated default cert (distinct CN `reloaded.example.com`) is
committed, proving the new config was applied and not the old one
silently retained. Also verifies:
- `ERROR` still appears in `diags.log` (degraded state is not silent)
- `proxy.process.ssl.ssl_multicert_load_failures` counter is ≥ 1
after the reload (via `traffic_ctl metric get`)
No regressions against the existing `ssl_multicert_loader` gold test.
**Known limitations / future work:**
- `QUICCertConfig` (HTTP/3) does not support partial reload yet.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]