feat(listeners): Ensure no tlsv1.3 for otp 22 or earlier
This commit is contained in:
parent
8f6e02c322
commit
2d150127d4
|
@ -134,7 +134,18 @@ start_listener(Proto, ListenOn, Options) when Proto == https; Proto == wss ->
|
|||
start_http_listener(fun cowboy:start_tls/3, 'mqtt:wss', ListenOn,
|
||||
ranch_opts(Options), ws_opts(Options)).
|
||||
|
||||
start_mqtt_listener(Name, ListenOn, Options) ->
|
||||
replace(Opts, Key, Value) -> [{Key, Value} | proplists:delete(Key, Opts)].
|
||||
|
||||
drop_tls13_for_old_otp(Options) ->
|
||||
case proplists:get_value(ssl_options, Options) of
|
||||
undefined -> Options;
|
||||
SslOpts ->
|
||||
SslOpts1 = emqx_tls_lib:drop_tls13_for_old_otp(SslOpts),
|
||||
replace(Options, ssl_options, SslOpts1)
|
||||
end.
|
||||
|
||||
start_mqtt_listener(Name, ListenOn, Options0) ->
|
||||
Options = drop_tls13_for_old_otp(Options0),
|
||||
SockOpts = esockd:parse_opt(Options),
|
||||
esockd:open(Name, ListenOn, merge_default(SockOpts),
|
||||
{emqx_connection, start_link, [Options -- SockOpts]}).
|
||||
|
@ -151,7 +162,8 @@ ws_opts(Options) ->
|
|||
ProxyProto = proplists:get_value(proxy_protocol, Options, false),
|
||||
#{env => #{dispatch => Dispatch}, proxy_header => ProxyProto}.
|
||||
|
||||
ranch_opts(Options) ->
|
||||
ranch_opts(Options0) ->
|
||||
Options = drop_tls13_for_old_otp(Options0),
|
||||
NumAcceptors = proplists:get_value(acceptors, Options, 4),
|
||||
MaxConnections = proplists:get_value(max_connections, Options, 1024),
|
||||
TcpOptions = proplists:get_value(tcp_options, Options, []),
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
, default_ciphers/0
|
||||
, default_ciphers/1
|
||||
, integral_ciphers/2
|
||||
, drop_tls13_for_old_otp/1
|
||||
]).
|
||||
|
||||
%% non-empty string
|
||||
|
@ -140,3 +141,58 @@ split_by_comma(Bin) ->
|
|||
%% trim spaces
|
||||
trim_space(Bin) ->
|
||||
hd([I || I <- binary:split(Bin, <<" ">>), I =/= <<>>]).
|
||||
|
||||
%% @doc Drop tlsv1.3 version and ciphers from ssl options
|
||||
%% if running on otp 22 or earlier.
|
||||
drop_tls13_for_old_otp(SslOpts) ->
|
||||
case list_to_integer(erlang:system_info(otp_release)) < 23 of
|
||||
true -> drop_tls13(SslOpts);
|
||||
false -> SslOpts
|
||||
end.
|
||||
|
||||
%% The ciphers that ssl:cipher_suites(exclusive, 'tlsv1.3', openssl)
|
||||
%% should return when running on otp 23.
|
||||
%% But we still have to hard-code them because tlsv1.3 on otp 22 is
|
||||
%% not trustworthy.
|
||||
-define(TLSV13_EXCLUSIVE_CIPHERS, [ "TLS_AES_256_GCM_SHA384"
|
||||
, "TLS_AES_128_GCM_SHA256"
|
||||
, "TLS_CHACHA20_POLY1305_SHA256"
|
||||
, "TLS_AES_128_CCM_SHA256"
|
||||
, "TLS_AES_128_CCM_8_SHA256"
|
||||
]).
|
||||
drop_tls13(SslOpts0) ->
|
||||
SslOpts1 = case proplists:get_value(versions, SslOpts0) of
|
||||
undefined -> SslOpts0;
|
||||
Vsns -> replace(SslOpts0, versions, Vsns -- ['tlsv1.3'])
|
||||
end,
|
||||
case proplists:get_value(ciphers, SslOpts1) of
|
||||
undefined -> SslOpts1;
|
||||
Ciphers -> replace(SslOpts1, ciphers, Ciphers -- ?TLSV13_EXCLUSIVE_CIPHERS)
|
||||
end.
|
||||
|
||||
replace(Opts, Key, Value) -> [{Key, Value} | proplists:delete(Key, Opts)].
|
||||
|
||||
-if(?OTP_RELEASE > 22).
|
||||
-ifdef(TEST).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
drop_tls13_test() ->
|
||||
Versions = default_versions(),
|
||||
?assert(lists:member('tlsv1.3', Versions)),
|
||||
Ciphers = default_ciphers(),
|
||||
?assert(has_tlsv13_cipher(Ciphers)),
|
||||
Opts0 = [{versions, Versions}, {ciphers, Ciphers}, other, {bool, true}],
|
||||
Opts = drop_tls13(Opts0),
|
||||
?assertNot(lists:member('tlsv1.3', proplists:get_value(versions, Opts))),
|
||||
?assertNot(has_tlsv13_cipher(proplists:get_value(ciphers, Opts))).
|
||||
|
||||
drop_tls13_no_versions_cipers_test() ->
|
||||
Opts0 = [other, {bool, true}],
|
||||
Opts = drop_tls13(Opts0),
|
||||
?_assertEqual(Opts0, Opts).
|
||||
|
||||
has_tlsv13_cipher(Ciphers) ->
|
||||
lists:any(fun(C) -> lists:member(C, Ciphers) end, ?TLSV13_EXCLUSIVE_CIPHERS).
|
||||
|
||||
-endif.
|
||||
-endif.
|
||||
|
|
Loading…
Reference in New Issue