Remove all usage of `cacerts` from configuration schemas

As mentioned in discussion #14426, the way that `cacerts` is handled by
cuttlefish schemas simply will not work if set.

If `cacerts` were set to a string value containing one X509 certificate,
it would eventually result in a crash because the `cacerts` ssl option
must be of [this type](https://www.erlang.org/doc/apps/ssl/ssl.html#t:client_option_cert/0):

```
{cacerts, CACerts :: [public_key:der_encoded()] | [public_key:combined_cert()]}
```

Neither of those are strings, of course.

This PR removes all use of `cacerts` in cuttlefish schemas. In addition,
it filters out `cacerts` and `certs_keys` from being JSON-encoded by an
HTTP API call to `/api/overview`. It _is_ technically possible to set
`cacerts` via `advanced.config`, so, if set, it would crash this API
call, as would `certs_keys`.
This commit is contained in:
Luke Bakken 2025-09-30 16:40:30 -07:00
parent 40728af80d
commit ce86fb989e
No known key found for this signature in database
GPG Key ID: D99DE30E43EAE440
9 changed files with 13 additions and 87 deletions

View File

@ -180,15 +180,6 @@ end}.
{mapping, "definitions.tls.certfile", "rabbit.definitions.ssl_options.certfile",
[{datatype, string}, {validators, ["file_accessible"]}]}.
{mapping, "definitions.tls.cacerts.$name", "rabbit.definitions.ssl_options.cacerts",
[{datatype, string}]}.
{translation, "rabbit.definitions.ssl_options.cacerts",
fun(Conf) ->
Settings = cuttlefish_variable:filter_by_prefix("definitions.tls.cacerts", Conf),
[ list_to_binary(V) || {_, V} <- Settings ]
end}.
{mapping, "definitions.tls.cert", "rabbit.definitions.ssl_options.cert",
[{datatype, string}]}.
@ -330,15 +321,6 @@ end}.
{mapping, "ssl_options.certfile", "rabbit.ssl_options.certfile",
[{datatype, string}, {validators, ["file_accessible"]}]}.
{mapping, "ssl_options.cacerts.$name", "rabbit.ssl_options.cacerts",
[{datatype, string}]}.
{translation, "rabbit.ssl_options.cacerts",
fun(Conf) ->
Settings = cuttlefish_variable:filter_by_prefix("ssl_options.cacerts", Conf),
[ list_to_binary(V) || {_, V} <- Settings ]
end}.
{mapping, "ssl_options.cert", "rabbit.ssl_options.cert",
[{datatype, string}]}.
@ -1931,9 +1913,6 @@ end}.
{mapping, "log.syslog.ssl_options.certfile", "syslog.protocol",
[{datatype, string}, {validators, ["file_accessible"]}]}.
{mapping, "log.syslog.ssl_options.cacerts.$name", "syslog.protocol",
[{datatype, string}]}.
{mapping, "log.syslog.ssl_options.cert", "syslog.protocol",
[{datatype, string}]}.
@ -2021,8 +2000,7 @@ fun(Conf) ->
DefinedSettings) ++
[ {K, V}
|| {K, V} <-
[{cacerts, [ list_to_binary(V) || {_, V} <- cuttlefish_variable:filter_by_prefix("log.syslog.ssl_options.cacerts", Conf)]},
{versions, [ V || {_, V} <- cuttlefish_variable:filter_by_prefix("log.syslog.ssl_options.versions", Conf) ]},
[{versions, [ V || {_, V} <- cuttlefish_variable:filter_by_prefix("log.syslog.ssl_options.versions", Conf)]},
{key, case cuttlefish_variable:filter_by_prefix("log.syslog.ssl_options.key", Conf) of
[{[_,_,Key], Val}|_] -> {list_to_atom(Key), list_to_binary(Val)};
_ -> undefined

View File

@ -49,15 +49,6 @@ end}.
{mapping, "auth_http.ssl_options.certfile", "rabbitmq_auth_backend_http.ssl_options.certfile",
[{datatype, string}, {validators, ["file_accessible"]}]}.
{mapping, "auth_http.ssl_options.cacerts.$name", "rabbitmq_auth_backend_http.ssl_options.cacerts",
[{datatype, string}]}.
{translation, "rabbitmq_auth_backend_http.ssl_options.cacerts",
fun(Conf) ->
Settings = cuttlefish_variable:filter_by_prefix("auth_http.ssl_options.cacerts", Conf),
[ list_to_binary(V) || {_, V} <- Settings ]
end}.
{mapping, "auth_http.ssl_options.cert", "rabbitmq_auth_backend_http.ssl_options.cert",
[{datatype, string}]}.

View File

@ -251,15 +251,6 @@ end}.
{mapping, "auth_ldap.ssl_options.certfile", "rabbitmq_auth_backend_ldap.ssl_options.certfile",
[{datatype, string}, {validators, ["file_accessible"]}]}.
{mapping, "auth_ldap.ssl_options.cacerts.$name", "rabbitmq_auth_backend_ldap.ssl_options.cacerts",
[{datatype, string}]}.
{translation, "rabbitmq_auth_backend_ldap.ssl_options.cacerts",
fun(Conf) ->
Settings = cuttlefish_variable:filter_by_prefix("auth_ldap.ssl_options.cacerts", Conf),
[ list_to_binary(V) || {_, V} <- Settings ]
end}.
{mapping, "auth_ldap.ssl_options.cert", "rabbitmq_auth_backend_ldap.ssl_options.cert",
[{datatype, string}]}.

View File

@ -220,15 +220,6 @@ end}.
{mapping, "management.listener.ssl_opts.certfile", "rabbitmq_management.listener.ssl_opts.certfile",
[{datatype, string}, {validators, ["file_accessible"]}]}.
{mapping, "management.listener.ssl_opts.cacerts.$name", "rabbitmq_management.listener.ssl_opts.cacerts",
[{datatype, string}]}.
{translation, "rabbitmq_management.listener.ssl_opts.cacerts",
fun(Conf) ->
Settings = cuttlefish_variable:filter_by_prefix("management.listener.ssl_opts.cacerts", Conf),
[ list_to_binary(V) || {_, V} <- Settings ]
end}.
{mapping, "management.listener.ssl_opts.honor_cipher_order", "rabbitmq_management.listener.ssl_opts.honor_cipher_order",
[{datatype, {enum, [true, false]}}]}.
@ -660,4 +651,4 @@ end}.
{mapping, "management.require_auth_for_api_reference", "rabbitmq_management.require_auth_for_api_reference", [
{datatype, {enum, [true, false]}},
{include_default, false}
]}.
]}.

View File

@ -317,6 +317,17 @@ format_socket_opts([{user_lookup_fun, _Value} | Tail], Acc) ->
format_socket_opts(Tail, Acc);
format_socket_opts([{sni_fun, _Value} | Tail], Acc) ->
format_socket_opts(Tail, Acc);
%% https://www.erlang.org/doc/apps/ssl/ssl.html#t:server_option_cert/0
format_socket_opts([{cacerts, Cacerts} | Tail], Acc) ->
CacertsMsg = rabbit_data_coercion:to_utf8_binary(
io_lib:format("(~b cacerts entries)", [length(Cacerts)])),
format_socket_opts(Tail, [{cacerts, CacertsMsg} | Acc]);
%% https://www.erlang.org/doc/apps/ssl/ssl.html#t:common_option_cert/0
%% https://www.erlang.org/doc/apps/ssl/ssl.html#t:cert_key_conf/0
format_socket_opts([{certs_keys, CertsKeys} | Tail], Acc) ->
CertsKeysMsg = rabbit_data_coercion:to_utf8_binary(
io_lib:format("(~b certs_keys entries)", [length(CertsKeys)])),
format_socket_opts(Tail, [{cacerts, CertsKeysMsg} | Acc]);
%% we do not report SNI host details in the UI,
%% so skip this option and avoid some recursive formatting
%% complexity

View File

@ -367,15 +367,6 @@ end}.
{mapping, "cluster_formation.consul.ssl_options.certfile", "rabbit.cluster_formation.peer_discovery_consul.ssl_options.certfile",
[{datatype, string}, {validators, ["file_accessible"]}]}.
{mapping, "cluster_formation.consul.ssl_options.cacerts.$name", "rabbit.cluster_formation.peer_discovery_consul.ssl_options.cacerts",
[{datatype, string}]}.
{translation, "rabbit.cluster_formation.peer_discovery_consul.ssl_options.cacerts",
fun(Conf) ->
Settings = cuttlefish_variable:filter_by_prefix("cluster_formation.consul.ssl_options.cacerts", Conf),
[ list_to_binary(V) || {_, V} <- Settings ]
end}.
{mapping, "cluster_formation.consul.ssl_options.cert", "rabbit.cluster_formation.peer_discovery_consul.ssl_options.cert",
[{datatype, string}]}.

View File

@ -188,15 +188,6 @@ end}.
{mapping, "cluster_formation.etcd.ssl_options.certfile", "rabbit.cluster_formation.peer_discovery_etcd.ssl_options.certfile",
[{datatype, string}, {validators, ["file_accessible"]}]}.
{mapping, "cluster_formation.etcd.ssl_options.cacerts.$name", "rabbit.cluster_formation.peer_discovery_etcd.ssl_options.cacerts",
[{datatype, string}]}.
{translation, "rabbit.cluster_formation.peer_discovery_etcd.ssl_options.cacerts",
fun(Conf) ->
Settings = cuttlefish_variable:filter_by_prefix("cluster_formation.etcd.ssl_options.cacerts", Conf),
[ list_to_binary(V) || {_, V} <- Settings ]
end}.
{mapping, "cluster_formation.etcd.ssl_options.cert", "rabbit.cluster_formation.peer_discovery_etcd.ssl_options.cert",
[{datatype, string}]}.

View File

@ -194,15 +194,6 @@ end}.
{mapping, "management.listener.ssl_opts.certfile", "rabbitmq_management.listener.ssl_opts.certfile",
[{datatype, string}, {validators, ["file_accessible"]}]}.
{mapping, "management.listener.ssl_opts.cacerts.$name", "rabbitmq_management.listener.ssl_opts.cacerts",
[{datatype, string}]}.
{translation, "rabbitmq_management.listener.ssl_opts.cacerts",
fun(Conf) ->
Settings = cuttlefish_variable:filter_by_prefix("management.listener.ssl_opts.cacerts", Conf),
[ list_to_binary(V) || {_, V} <- Settings ]
end}.
{mapping, "management.listener.ssl_opts.honor_cipher_order", "rabbitmq_management.listener.ssl_opts.honor_cipher_order",
[{datatype, {enum, [true, false]}}]}.

View File

@ -60,15 +60,6 @@ end}.
{mapping, "trust_store.ssl_options.certfile", "rabbitmq_trust_store.ssl_options.certfile",
[{datatype, string}, {validators, ["file_accessible"]}]}.
{mapping, "trust_store.ssl_options.cacerts.$name", "rabbitmq_trust_store.ssl_options.cacerts",
[{datatype, string}]}.
{translation, "rabbitmq_trust_store.ssl_options.cacerts",
fun(Conf) ->
Settings = cuttlefish_variable:filter_by_prefix("trust_store.ssl_options.cacerts", Conf),
[ list_to_binary(V) || {_, V} <- Settings ]
end}.
{mapping, "trust_store.ssl_options.cert", "rabbitmq_trust_store.ssl_options.cert",
[{datatype, string}]}.