mirror of
https://github.com/XRPLF/rippled.git
synced 2026-08-22 14:50:54 +00:00
fix: Report telemetry config errors instead of aborting at startup
makeTelemetrySetup() rejects a contradictory [telemetry] mutual-TLS setup by throwing, but it is called from ApplicationImp's member-initializer list. A try/catch in the constructor body cannot reach a throw from there, and nothing further up the stack caught it either, so a config mistake reached std::terminate: the default handler printed a terminate dump and raised SIGABRT, leaving a core file instead of a startup error. Catch std::exception around makeApplication() in run(), report the reason on stderr and return -1, so the failure is a clean non-zero exit with a message an operator can act on. Only the construction is wrapped. setup() starts subsystems whose shutdown order is delicate and is left outside deliberately, because unwinding a half-started Application would skip the normal stop sequence. Gate both validation guards on enabled. A node with telemetry switched off previously refused to start over certificate paths that nothing would read. Document both throws on makeTelemetrySetup(), state in cfg/xrpld-example.cfg and the configuration reference that a partial mutual-TLS setup is fatal and that the checks apply only when enabled=1, and add a runbook troubleshooting entry keyed on the two error messages. Tests cover both guards with the message asserted so the two are told apart, both enabled=0 paths, and the default plaintext configuration.
This commit is contained in:
@@ -108,24 +108,37 @@ makeTelemetrySetup(
|
||||
setup.tlsClientCertPath = section.valueOr<std::string>(key::tlsClientCert, "");
|
||||
setup.tlsClientKeyPath = section.valueOr<std::string>(key::tlsClientKey, "");
|
||||
|
||||
// Mutual TLS needs both the client certificate and its private key.
|
||||
// Supplying only one fails later with a cryptic SSL handshake error, so
|
||||
// reject the partial configuration here with an actionable message.
|
||||
if (setup.tlsClientCertPath.empty() != setup.tlsClientKeyPath.empty())
|
||||
// The mutual TLS (mTLS) checks below are fatal, so gate them on the one
|
||||
// thing this parser can know: `enabled` is 1. With `enabled` 0 a leftover
|
||||
// cert line must never stop the node from booting.
|
||||
//
|
||||
// The predicate is only that config switch, not whether an exporter can
|
||||
// exist. This file has no preprocessor guard, so both checks also run in a
|
||||
// -Dtelemetry=OFF build, where makeTelemetry() returns the null
|
||||
// implementation whatever `enabled` says.
|
||||
if (setup.enabled)
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
"[telemetry] tls_client_cert and tls_client_key must be set together "
|
||||
"(set both for mutual TLS, or neither for one-way TLS).");
|
||||
}
|
||||
// mTLS needs both the client certificate and its private key.
|
||||
// Supplying only one fails later with a cryptic SSL handshake error, so
|
||||
// reject the partial configuration here with an actionable message.
|
||||
if (setup.tlsClientCertPath.empty() != setup.tlsClientKeyPath.empty())
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
"[telemetry] tls_client_cert and tls_client_key must be set together "
|
||||
"(set both for mutual TLS, or neither for one-way TLS).");
|
||||
}
|
||||
|
||||
// Mutual TLS only takes effect when TLS is on. Certificate paths set with
|
||||
// use_tls=0 would be silently ignored and the exporter would connect in
|
||||
// plaintext, so reject that contradiction instead of failing open.
|
||||
if (!setup.tlsClientCertPath.empty() && !setup.useTls)
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
"[telemetry] tls_client_cert/tls_client_key require use_tls=1 "
|
||||
"(set use_tls=1 to enable mutual TLS, or remove the cert paths).");
|
||||
// Still inside the enabled branch. mTLS only takes effect when TLS is
|
||||
// on, so a client certificate set with use_tls=0 would be ignored and
|
||||
// any exporter that did run would connect in plaintext. Reject that
|
||||
// contradiction instead of failing open. tls_ca_cert is deliberately
|
||||
// not checked this way.
|
||||
if (!setup.tlsClientCertPath.empty() && !setup.useTls)
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
"[telemetry] tls_client_cert/tls_client_key require use_tls=1 "
|
||||
"(set use_tls=1 to enable mutual TLS, or remove the cert paths).");
|
||||
}
|
||||
}
|
||||
|
||||
// Head sampling is intentionally fixed at 1.0 (sample everything) and is
|
||||
|
||||
Reference in New Issue
Block a user