Skip to content

Commit 6a0058f

Browse files
Introduce TLS-related rabbitmq.conf settings for definition import
currently only used by the HTTPS mechanism but can be used by any other.
1 parent f3a5235 commit 6a0058f

File tree

5 files changed

+207
-6
lines changed

5 files changed

+207
-6
lines changed

deps/rabbit/priv/schema/rabbit.schema

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,101 @@ end}.
159159
{mapping, "definitions.https.url", "rabbit.definitions.url",
160160
[{datatype, string}]}.
161161

162+
%% Client-side TLS settings used by e.g. HTTPS definition loading mechanism.
163+
%% These can be reused by other clients.
164+
165+
{mapping, "definitions.tls.verify", "rabbit.definitions.ssl_options.verify", [
166+
{datatype, {enum, [verify_peer, verify_none]}}]}.
167+
168+
{mapping, "definitions.tls.fail_if_no_peer_cert", "rabbit.definitions.ssl_options.fail_if_no_peer_cert", [
169+
{datatype, {enum, [true, false]}}]}.
170+
171+
{mapping, "definitions.tls.cacertfile", "rabbit.definitions.ssl_options.cacertfile",
172+
[{datatype, string}, {validators, ["file_accessible"]}]}.
173+
174+
{mapping, "definitions.tls.certfile", "rabbit.definitions.ssl_options.certfile",
175+
[{datatype, string}, {validators, ["file_accessible"]}]}.
176+
177+
{mapping, "definitions.tls.cacerts.$name", "rabbit.definitions.ssl_options.cacerts",
178+
[{datatype, string}]}.
179+
180+
{translation, "rabbit.definitions.ssl_options.cacerts",
181+
fun(Conf) ->
182+
Settings = cuttlefish_variable:filter_by_prefix("definitions.tls.cacerts", Conf),
183+
[ list_to_binary(V) || {_, V} <- Settings ]
184+
end}.
185+
186+
{mapping, "definitions.tls.cert", "rabbit.definitions.ssl_options.cert",
187+
[{datatype, string}]}.
188+
189+
{translation, "rabbit.definitions.ssl_options.cert",
190+
fun(Conf) ->
191+
list_to_binary(cuttlefish:conf_get("definitions.tls.cert", Conf))
192+
end}.
193+
194+
{mapping, "definitions.tls.reuse_session", "rabbit.definitions.ssl_options.reuse_session",
195+
[{datatype, {enum, [true, false]}}]}.
196+
197+
{mapping, "definitions.tls.crl_check", "rabbit.definitions.ssl_options.crl_check",
198+
[{datatype, [{enum, [true, false, peer, best_effort]}]}]}.
199+
200+
{mapping, "definitions.tls.depth", "rabbit.definitions.ssl_options.depth",
201+
[{datatype, integer}, {validators, ["byte"]}]}.
202+
203+
{mapping, "definitions.tls.dh", "rabbit.definitions.ssl_options.dh",
204+
[{datatype, string}]}.
205+
206+
{translation, "rabbit.definitions.ssl_options.dh",
207+
fun(Conf) ->
208+
list_to_binary(cuttlefish:conf_get("definitions.tls.dh", Conf))
209+
end}.
210+
211+
{translation, "rabbit.definitions.ssl_options.key",
212+
fun(Conf) ->
213+
case cuttlefish_variable:filter_by_prefix("definitions.tls.key", Conf) of
214+
[{[_,_,Key], Val}|_] -> {list_to_atom(Key), list_to_binary(Val)};
215+
_ -> cuttlefish:unset()
216+
end
217+
end}.
218+
219+
{mapping, "definitions.tls.keyfile", "rabbit.definitions.ssl_options.keyfile",
220+
[{datatype, string}, {validators, ["file_accessible"]}]}.
221+
222+
{mapping, "definitions.tls.log_alert", "rabbit.definitions.ssl_options.log_alert",
223+
[{datatype, {enum, [true, false]}}]}.
224+
225+
{mapping, "definitions.tls.password", "rabbit.definitions.ssl_options.password",
226+
[{datatype, string}]}.
227+
228+
{mapping, "definitions.tls.secure_renegotiate", "rabbit.definitions.ssl_options.secure_renegotiate",
229+
[{datatype, {enum, [true, false]}}]}.
230+
231+
{mapping, "definitions.tls.reuse_sessions", "rabbit.definitions.ssl_options.reuse_sessions",
232+
[{datatype, {enum, [true, false]}}]}.
233+
234+
{mapping, "definitions.tls.versions.$version", "rabbit.definitions.ssl_options.versions",
235+
[{datatype, atom}]}.
236+
237+
{translation, "rabbit.definitions.ssl_options.versions",
238+
fun(Conf) ->
239+
Settings = cuttlefish_variable:filter_by_prefix("definitions.tls.versions", Conf),
240+
[V || {_, V} <- Settings]
241+
end}.
242+
243+
{mapping, "definitions.tls.ciphers.$cipher", "rabbit.definitions.ssl_options.ciphers",
244+
[{datatype, string}]}.
245+
246+
{translation, "rabbit.definitions.ssl_options.ciphers",
247+
fun(Conf) ->
248+
Settings = cuttlefish_variable:filter_by_prefix("definitions.tls.ciphers", Conf),
249+
lists:reverse([V || {_, V} <- Settings])
250+
end}.
251+
252+
{mapping, "definitions.tls.log_level", "rabbit.definitions.ssl_options.log_level",
253+
[{datatype, {enum, [emergency, alert, critical, error, warning, notice, info, debug]}}]}.
254+
162255
%%
163-
%% Security / AAA
164-
%% ==============
256+
%% Seed User, Authentication, Access Control
165257
%%
166258

167259
%% The default "guest" user is only permitted to access the server
@@ -283,13 +375,16 @@ end}.
283375
fun(Conf) ->
284376
case cuttlefish_variable:filter_by_prefix("ssl_options.key", Conf) of
285377
[{[_,_,Key], Val}|_] -> {list_to_atom(Key), list_to_binary(Val)};
286-
_ -> undefined
378+
_ -> cuttlefish:unset()
287379
end
288380
end}.
289381

290382
{mapping, "ssl_options.keyfile", "rabbit.ssl_options.keyfile",
291383
[{datatype, string}, {validators, ["file_accessible"]}]}.
292384

385+
{mapping, "ssl_options.log_level", "rabbit.ssl_options.log_level",
386+
[{datatype, {enum, [emergency, alert, critical, error, warning, notice, info, debug]}}]}.
387+
293388
{mapping, "ssl_options.log_alert", "rabbit.ssl_options.log_alert",
294389
[{datatype, {enum, [true, false]}}]}.
295390

deps/rabbit/src/rabbit_definitions_import_https.erl

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616

1717

18-
-import(rabbit_misc, [pget/2]).
18+
-import(rabbit_misc, [pget/2, pget/3]).
1919
-import(rabbit_data_coercion, [to_binary/1]).
2020
-import(rabbit_definitions, [import_raw/1]).
2121

@@ -38,9 +38,20 @@ is_enabled() ->
3838
end.
3939

4040
load(Proplist) ->
41+
rabbit_log:debug("Definitions proprties: ~p", [Proplist]),
4142
URL = pget(url, Proplist),
42-
%% TODO
43-
HTTPOptions = [],
43+
TLSOptions0 = [
44+
%% avoids a peer verification warning emitted by default if no certificate chain and peer verification
45+
%% settings are provided: these are not essential in this particular case (client-side downloads that likely
46+
%% will happen from a local trusted source)
47+
{log_level, error},
48+
%% use TLSv1.2 by default
49+
{versions, ['tlsv1.2']}
50+
],
51+
TLSOptions = pget(ssl_options, Proplist, TLSOptions0),
52+
HTTPOptions = [
53+
{ssl, TLSOptions}
54+
],
4455
load_from_url(URL, HTTPOptions).
4556

4657

@@ -54,6 +65,7 @@ load_from_url(URL, HTTPOptions0) ->
5465
{body_format, binary}
5566
],
5667
HTTPOptions = HTTPOptions0 ++ [
68+
{connect_timeout, 120000},
5769
{autoredirect, true}
5870
],
5971
rabbit_log:info("Applying definitions from remote URL"),

deps/rabbit/test/config_schema_SUITE_data/rabbit.snippets

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,52 @@ credential_validator.regexp = ^abc\\d+",
683683
]}],
684684
[]},
685685

686+
%% modern configuration key, HTTPS source
687+
{definition_files, "definitions.import_backend = https
688+
definitions.https.url = https://rabbitmq.eng.megacorp.local/env-1/case1.json
689+
definitions.tls.versions.1 = tlsv1.2
690+
definitions.tls.log_level = error
691+
692+
definitions.tls.secure_renegotiate = true
693+
694+
definitions.tls.ciphers.1 = ECDHE-ECDSA-AES256-GCM-SHA384
695+
definitions.tls.ciphers.2 = ECDHE-RSA-AES256-GCM-SHA384
696+
definitions.tls.ciphers.3 = ECDH-ECDSA-AES256-GCM-SHA384
697+
definitions.tls.ciphers.4 = ECDH-RSA-AES256-GCM-SHA384
698+
definitions.tls.ciphers.5 = DHE-RSA-AES256-GCM-SHA384
699+
definitions.tls.ciphers.6 = DHE-DSS-AES256-GCM-SHA384
700+
definitions.tls.ciphers.7 = ECDHE-ECDSA-AES128-GCM-SHA256
701+
definitions.tls.ciphers.8 = ECDHE-RSA-AES128-GCM-SHA256
702+
definitions.tls.ciphers.9 = ECDH-ECDSA-AES128-GCM-SHA256
703+
definitions.tls.ciphers.10 = ECDH-RSA-AES128-GCM-SHA256
704+
definitions.tls.ciphers.11 = DHE-RSA-AES128-GCM-SHA256
705+
definitions.tls.ciphers.12 = DHE-DSS-AES128-GCM-SHA256",
706+
[{rabbit, [
707+
{definitions, [
708+
{import_backend, rabbit_definitions_import_https},
709+
{url, "https://rabbitmq.eng.megacorp.local/env-1/case1.json"},
710+
{ssl_options, [
711+
{log_level, error},
712+
{secure_renegotiate, true},
713+
{versions, ['tlsv1.2']},
714+
{ciphers, [
715+
"ECDHE-ECDSA-AES256-GCM-SHA384",
716+
"ECDHE-RSA-AES256-GCM-SHA384",
717+
"ECDH-ECDSA-AES256-GCM-SHA384",
718+
"ECDH-RSA-AES256-GCM-SHA384",
719+
"DHE-RSA-AES256-GCM-SHA384",
720+
"DHE-DSS-AES256-GCM-SHA384",
721+
"ECDHE-ECDSA-AES128-GCM-SHA256",
722+
"ECDHE-RSA-AES128-GCM-SHA256",
723+
"ECDH-ECDSA-AES128-GCM-SHA256",
724+
"ECDH-RSA-AES128-GCM-SHA256",
725+
"DHE-RSA-AES128-GCM-SHA256",
726+
"DHE-DSS-AES128-GCM-SHA256"
727+
]}
728+
]}
729+
]}]}],
730+
[]},
731+
686732
%%
687733
%% Raft
688734
%%

deps/rabbit/test/definition_import_SUITE.erl

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ all() ->
1919
{group, boot_time_import_using_classic_source},
2020
%% uses rabbit.definitions with import_backend set to local_filesystem
2121
{group, boot_time_import_using_modern_local_filesystem_source},
22+
{group, boot_time_import_using_public_https_source},
2223
{group, roundtrip},
2324
{group, import_on_a_running_node}
2425
].
@@ -55,6 +56,10 @@ groups() ->
5556
import_on_a_booting_node_using_modern_local_filesystem_source
5657
]},
5758

59+
{boot_time_import_using_public_https_source, [], [
60+
import_on_a_booting_node_using_public_https_source
61+
]},
62+
5863
{roundtrip, [], [
5964
export_import_round_trip_case1,
6065
export_import_round_trip_case2
@@ -98,6 +103,38 @@ init_per_group(boot_time_import_using_modern_local_filesystem_source = Group, Co
98103
]}
99104
]}),
100105
rabbit_ct_helpers:run_setup_steps(Config2, rabbit_ct_broker_helpers:setup_steps());
106+
init_per_group(boot_time_import_using_public_https_source = Group, Config) ->
107+
Config1 = rabbit_ct_helpers:set_config(Config, [
108+
{rmq_nodename_suffix, Group},
109+
{rmq_nodes_count, 1}
110+
]),
111+
Config2 = rabbit_ct_helpers:merge_app_env(Config1,
112+
{rabbit, [
113+
{definitions, [
114+
{import_backend, rabbit_definitions_import_https},
115+
{url, "https://gist.githubusercontent.com/michaelklishin/e73b0114728d9391425d0644304f264a/raw/f15642771f099c60b6fa93f75d46a4246bb47c45/upstream.definitions.json"},
116+
{ssl_options, [
117+
{log_level, error},
118+
{secure_renegotiate, true},
119+
{versions, ['tlsv1.2']},
120+
{ciphers, [
121+
"ECDHE-ECDSA-AES256-GCM-SHA384",
122+
"ECDHE-RSA-AES256-GCM-SHA384",
123+
"ECDH-ECDSA-AES256-GCM-SHA384",
124+
"ECDH-RSA-AES256-GCM-SHA384",
125+
"DHE-RSA-AES256-GCM-SHA384",
126+
"DHE-DSS-AES256-GCM-SHA384",
127+
"ECDHE-ECDSA-AES128-GCM-SHA256",
128+
"ECDHE-RSA-AES128-GCM-SHA256",
129+
"ECDH-ECDSA-AES128-GCM-SHA256",
130+
"ECDH-RSA-AES128-GCM-SHA256",
131+
"DHE-RSA-AES128-GCM-SHA256",
132+
"DHE-DSS-AES128-GCM-SHA256"
133+
]}
134+
]}
135+
]}
136+
]}),
137+
rabbit_ct_helpers:run_setup_steps(Config2, rabbit_ct_broker_helpers:setup_steps());
101138
init_per_group(Group, Config) ->
102139
Config1 = rabbit_ct_helpers:set_config(Config, [
103140
{rmq_nodename_suffix, Group}
@@ -199,6 +236,14 @@ import_on_a_booting_node_using_modern_local_filesystem_source(Config) ->
199236
{error, timeout} -> ct:fail("virtual host ~p was not imported on boot", [VHost])
200237
end.
201238

239+
import_on_a_booting_node_using_public_https_source(Config) ->
240+
VHost = <<"bunny_testbed">>,
241+
%% verify that virtual host eventually starts
242+
case rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_vhost, await_running_on_all_nodes, [VHost, 3000]) of
243+
ok -> ok;
244+
{error, timeout} -> ct:fail("virtual host ~p was not imported on boot", [VHost])
245+
end.
246+
202247
%%
203248
%% Implementation
204249
%%

release-notes/3.9.4.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ consistent release schedule.
4848
definitions.import_backend = https
4949

5050
definitions.https.url = https://rabbitmq.eng.megacorp.local/env-1/definitions.json
51+
52+
definitions.tls.versions.1 = tlsv1.2
53+
definitions.tls.log_level = error
5154
```
5255

5356
GitHub issue: [#3249](https://github.com/rabbitmq/rabbitmq-server/issues/3249)

0 commit comments

Comments
 (0)