fix(tls): Ensure tls config integrity
For default tsl version and ciphers, we try to use otp release number to determin if we want to use tlsv1.3 For default configs, we try to porivde both tlsv1.3 and ciphers in config (even for commented out configs)
This commit is contained in:
parent
2852ac79d4
commit
f000b6583c
|
@ -74,11 +74,10 @@ translate_env(EnvName) ->
|
||||||
(_) ->
|
(_) ->
|
||||||
true
|
true
|
||||||
end, [{keyfile, KeyFile}, {certfile, CertFile}, {cacertfile, CACertFile}]),
|
end, [{keyfile, KeyFile}, {certfile, CertFile}, {cacertfile, CACertFile}]),
|
||||||
TlsVers = ['tlsv1.2','tlsv1.1',tlsv1],
|
NTLSOpts = [ {versions, emqx_tls_lib:default_versions()}
|
||||||
NTLSOpts = [{versions, TlsVers},
|
, {ciphers, emqx_tls_lib:default_ciphers()}
|
||||||
{ciphers, lists:foldl(fun(TlsVer, Ciphers) ->
|
| TLSOpts
|
||||||
Ciphers ++ ssl:cipher_suites(all, TlsVer)
|
],
|
||||||
end, [], TlsVers)} | TLSOpts],
|
|
||||||
[{transport, ssl}, {transport_opts, [Inet | NTLSOpts]}]
|
[{transport, ssl}, {transport_opts, [Inet | NTLSOpts]}]
|
||||||
end,
|
end,
|
||||||
PoolOpts = [{host, Host},
|
PoolOpts = [{host, Host},
|
||||||
|
|
|
@ -43,7 +43,7 @@ auth.pgsql.ssl = off
|
||||||
## You can configure multi-version use "," split,
|
## You can configure multi-version use "," split,
|
||||||
## default value is :tlsv1.2
|
## default value is :tlsv1.2
|
||||||
## Example:
|
## Example:
|
||||||
## tlsv1.1,tlsv1.2,tlsv1.3
|
## tlsv1.2,tlsv1.1
|
||||||
##
|
##
|
||||||
#auth.pgsql.ssl.tls_versions = tlsv1.2
|
#auth.pgsql.ssl.tls_versions = tlsv1.2
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ bridge.mqtt.emqx2.ciphers = ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-S
|
||||||
bridge.mqtt.emqx2.keepalive = 60s
|
bridge.mqtt.emqx2.keepalive = 60s
|
||||||
|
|
||||||
## Supported TLS version
|
## Supported TLS version
|
||||||
bridge.mqtt.emqx2.tls_versions = tlsv1.2,tlsv1.1,tlsv1
|
bridge.mqtt.emqx2.tls_versions = tlsv1.3,tlsv1.2,tlsv1.1,tlsv1
|
||||||
|
|
||||||
## Forwarding topics of the message
|
## Forwarding topics of the message
|
||||||
bridge.mqtt.emqx2.forwards = sensor1/#,sensor2/#
|
bridge.mqtt.emqx2.forwards = sensor1/#,sensor2/#
|
||||||
|
|
|
@ -133,9 +133,6 @@ EMQ X MQTT bridging principle: Create an MQTT client on the EMQ X broker, and co
|
||||||
## Key file of Client SSL connection
|
## Key file of Client SSL connection
|
||||||
bridge.mqtt.emqx2.keyfile = etc/certs/client-key.pem
|
bridge.mqtt.emqx2.keyfile = etc/certs/client-key.pem
|
||||||
|
|
||||||
## SSL encryption
|
|
||||||
bridge.mqtt.emqx2.ciphers = ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384
|
|
||||||
|
|
||||||
## TTLS PSK password
|
## TTLS PSK password
|
||||||
## Note 'listener.ssl.external.ciphers' and 'listener.ssl.external.psk_ciphers' cannot be configured at the same time
|
## Note 'listener.ssl.external.ciphers' and 'listener.ssl.external.psk_ciphers' cannot be configured at the same time
|
||||||
##
|
##
|
||||||
|
@ -146,7 +143,10 @@ EMQ X MQTT bridging principle: Create an MQTT client on the EMQ X broker, and co
|
||||||
bridge.mqtt.emqx2.keepalive = 60s
|
bridge.mqtt.emqx2.keepalive = 60s
|
||||||
|
|
||||||
## Supported TLS version
|
## Supported TLS version
|
||||||
bridge.mqtt.emqx2.tls_versions = tlsv1.2,tlsv1.1,tlsv1
|
bridge.mqtt.emqx2.tls_versions = tlsv1.2
|
||||||
|
|
||||||
|
## SSL encryption
|
||||||
|
bridge.mqtt.emqx2.ciphers = ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384
|
||||||
|
|
||||||
## Forwarding topics of the message
|
## Forwarding topics of the message
|
||||||
bridge.mqtt.emqx2.forwards = sensor1/#,sensor2/#
|
bridge.mqtt.emqx2.forwards = sensor1/#,sensor2/#
|
||||||
|
|
|
@ -128,6 +128,7 @@ bridge.mqtt.aws.keepalive = 60s
|
||||||
|
|
||||||
## TLS versions used by the bridge.
|
## TLS versions used by the bridge.
|
||||||
##
|
##
|
||||||
|
## NOTE: Do not use tlsv1.3 if emqx is running on OTP-22 or earlier
|
||||||
## Value: String
|
## Value: String
|
||||||
bridge.mqtt.aws.tls_versions = tlsv1.3,tlsv1.2,tlsv1.1,tlsv1
|
bridge.mqtt.aws.tls_versions = tlsv1.3,tlsv1.2,tlsv1.1,tlsv1
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@
|
||||||
|
|
||||||
{mapping, "bridge.mqtt.$name.tls_versions", "emqx_bridge_mqtt.bridges", [
|
{mapping, "bridge.mqtt.$name.tls_versions", "emqx_bridge_mqtt.bridges", [
|
||||||
{datatype, string},
|
{datatype, string},
|
||||||
{default, "tlsv1,tlsv1.1,tlsv1.2"}
|
{default, "tlsv1.3,tlsv1.2,tlsv1.1,tlsv1"}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
{mapping, "bridge.mqtt.$name.reconnect_interval", "emqx_bridge_mqtt.bridges", [
|
{mapping, "bridge.mqtt.$name.reconnect_interval", "emqx_bridge_mqtt.bridges", [
|
||||||
|
|
|
@ -671,12 +671,6 @@ format_data([], Msg) ->
|
||||||
format_data(Tokens, Msg) ->
|
format_data(Tokens, Msg) ->
|
||||||
emqx_rule_utils:proc_tmpl(Tokens, Msg).
|
emqx_rule_utils:proc_tmpl(Tokens, Msg).
|
||||||
|
|
||||||
tls_versions() ->
|
|
||||||
['tlsv1.2','tlsv1.1', tlsv1].
|
|
||||||
|
|
||||||
ciphers(Ciphers) ->
|
|
||||||
string:tokens(str(Ciphers), ", ").
|
|
||||||
|
|
||||||
subscriptions(Subscriptions) ->
|
subscriptions(Subscriptions) ->
|
||||||
scan_binary(<<"[", Subscriptions/binary, "].">>).
|
scan_binary(<<"[", Subscriptions/binary, "].">>).
|
||||||
|
|
||||||
|
@ -749,6 +743,8 @@ options(Options, PoolName) ->
|
||||||
Topic ->
|
Topic ->
|
||||||
[{subscriptions, [{Topic, Get(<<"qos">>)}]} | Subscriptions]
|
[{subscriptions, [{Topic, Get(<<"qos">>)}]} | Subscriptions]
|
||||||
end,
|
end,
|
||||||
|
%% TODO check why only ciphers are configurable but not versions
|
||||||
|
TlsVersions = emqx_tls_lib:default_versions(),
|
||||||
[{address, binary_to_list(Address)},
|
[{address, binary_to_list(Address)},
|
||||||
{bridge_mode, GetD(<<"bridge_mode">>, true)},
|
{bridge_mode, GetD(<<"bridge_mode">>, true)},
|
||||||
{clean_start, true},
|
{clean_start, true},
|
||||||
|
@ -761,12 +757,13 @@ options(Options, PoolName) ->
|
||||||
{proto_ver, mqtt_ver(Get(<<"proto_ver">>))},
|
{proto_ver, mqtt_ver(Get(<<"proto_ver">>))},
|
||||||
{retry_interval, cuttlefish_duration:parse(str(GetD(<<"retry_interval">>, "30s")), s)},
|
{retry_interval, cuttlefish_duration:parse(str(GetD(<<"retry_interval">>, "30s")), s)},
|
||||||
{ssl, cuttlefish_flag:parse(str(Get(<<"ssl">>)))},
|
{ssl, cuttlefish_flag:parse(str(Get(<<"ssl">>)))},
|
||||||
{ssl_opts, [{versions, tls_versions()},
|
{ssl_opts, [ {keyfile, str(Get(<<"keyfile">>))}
|
||||||
{ciphers, ciphers(Get(<<"ciphers">>))},
|
, {certfile, str(Get(<<"certfile">>))}
|
||||||
{keyfile, str(Get(<<"keyfile">>))},
|
, {cacertfile, str(Get(<<"cacertfile">>))}
|
||||||
{certfile, str(Get(<<"certfile">>))},
|
, {versions, TlsVersions}
|
||||||
{cacertfile, str(Get(<<"cacertfile">>))}
|
, {ciphers, emqx_tls_lib:integral_ciphers(TlsVersions, Get(<<"ciphers">>))}
|
||||||
]}] ++ Subscriptions1
|
]}
|
||||||
|
] ++ Subscriptions1
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -75,10 +75,7 @@ end}.
|
||||||
Ciphers =
|
Ciphers =
|
||||||
case cuttlefish:conf_get("coap.dtls.ciphers", Conf, undefined) of
|
case cuttlefish:conf_get("coap.dtls.ciphers", Conf, undefined) of
|
||||||
undefined ->
|
undefined ->
|
||||||
lists:foldl(
|
lists:append([ssl:cipher_suites(all, V, openssl) || V <- ['dtlsv1.2', 'dtlsv1']]);
|
||||||
fun(TlsVer, Ciphers) ->
|
|
||||||
Ciphers ++ ssl:cipher_suites(all, TlsVer)
|
|
||||||
end, [], ['dtlsv1', 'dtlsv1.2']);
|
|
||||||
C ->
|
C ->
|
||||||
SplitFun(C)
|
SplitFun(C)
|
||||||
end,
|
end,
|
||||||
|
|
|
@ -105,7 +105,8 @@ dashboard.listener.http.ipv6_v6only = false
|
||||||
## TLS versions only to protect from POODLE attack.
|
## TLS versions only to protect from POODLE attack.
|
||||||
##
|
##
|
||||||
## Value: String, seperated by ','
|
## Value: String, seperated by ','
|
||||||
## dashboard.listener.https.tls_versions = tlsv1.2,tlsv1.1,tlsv1
|
## NOTE: Do not use tlsv1.3 if emqx is running on OTP-22 or earlier
|
||||||
|
## dashboard.listener.https.tls_versions = tlsv1.3,tlsv1.2,tlsv1.1,tlsv1
|
||||||
|
|
||||||
## See: 'listener.ssl.<name>.ciphers' in emq.conf
|
## See: 'listener.ssl.<name>.ciphers' in emq.conf
|
||||||
##
|
##
|
||||||
|
|
|
@ -425,8 +425,8 @@ udp_opts() ->
|
||||||
|
|
||||||
ssl_opts() ->
|
ssl_opts() ->
|
||||||
Certs = certs("key.pem", "cert.pem", "cacert.pem"),
|
Certs = certs("key.pem", "cert.pem", "cacert.pem"),
|
||||||
[{versions, ['tlsv1.2','tlsv1.1',tlsv1]},
|
[{versions, emqx_tls_lib:default_versions()},
|
||||||
{ciphers, ciphers('tlsv1.2')},
|
{ciphers, emqx_tls_lib:default_ciphers()},
|
||||||
{verify, verify_peer},
|
{verify, verify_peer},
|
||||||
{fail_if_no_peer_cert, true},
|
{fail_if_no_peer_cert, true},
|
||||||
{secure_renegotiate, false},
|
{secure_renegotiate, false},
|
||||||
|
@ -437,9 +437,6 @@ dtls_opts() ->
|
||||||
Opts = ssl_opts(),
|
Opts = ssl_opts(),
|
||||||
lists:keyreplace(versions, 1, Opts, {versions, ['dtlsv1.2', 'dtlsv1']}).
|
lists:keyreplace(versions, 1, Opts, {versions, ['dtlsv1.2', 'dtlsv1']}).
|
||||||
|
|
||||||
ciphers(Version) ->
|
|
||||||
proplists:get_value(ciphers, emqx_ct_helpers:client_ssl(Version)).
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Client-Opts
|
%% Client-Opts
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,8 @@ management.listener.http.ipv6_v6only = false
|
||||||
## management.listener.https.keyfile = etc/certs/key.pem
|
## management.listener.https.keyfile = etc/certs/key.pem
|
||||||
## management.listener.https.cacertfile = etc/certs/cacert.pem
|
## management.listener.https.cacertfile = etc/certs/cacert.pem
|
||||||
## management.listener.https.verify = verify_peer
|
## management.listener.https.verify = verify_peer
|
||||||
## management.listener.https.tls_versions = tlsv1.2,tlsv1.1,tlsv1
|
## NOTE: Do not use tlsv1.3 if emqx is running on OTP-22 or earlier
|
||||||
|
## management.listener.https.tls_versions = tlsv1.3,tlsv1.2,tlsv1.1,tlsv1
|
||||||
## management.listener.https.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,ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-AES256-SHA384,ECDHE-RSA-AES256-SHA384,ECDHE-ECDSA-DES-CBC3-SHA,ECDH-ECDSA-AES256-GCM-SHA384,ECDH-RSA-AES256-GCM-SHA384,ECDH-ECDSA-AES256-SHA384,ECDH-RSA-AES256-SHA384,DHE-DSS-AES256-GCM-SHA384,DHE-DSS-AES256-SHA256,AES256-GCM-SHA384,AES256-SHA256,ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES128-SHA256,ECDHE-RSA-AES128-SHA256,ECDH-ECDSA-AES128-GCM-SHA256,ECDH-RSA-AES128-GCM-SHA256,ECDH-ECDSA-AES128-SHA256,ECDH-RSA-AES128-SHA256,DHE-DSS-AES128-GCM-SHA256,DHE-DSS-AES128-SHA256,AES128-GCM-SHA256,AES128-SHA256,ECDHE-ECDSA-AES256-SHA,ECDHE-RSA-AES256-SHA,DHE-DSS-AES256-SHA,ECDH-ECDSA-AES256-SHA,ECDH-RSA-AES256-SHA,AES256-SHA,ECDHE-ECDSA-AES128-SHA,ECDHE-RSA-AES128-SHA,DHE-DSS-AES128-SHA,ECDH-ECDSA-AES128-SHA,ECDH-RSA-AES128-SHA,AES128-SHA
|
## management.listener.https.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,ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-AES256-SHA384,ECDHE-RSA-AES256-SHA384,ECDHE-ECDSA-DES-CBC3-SHA,ECDH-ECDSA-AES256-GCM-SHA384,ECDH-RSA-AES256-GCM-SHA384,ECDH-ECDSA-AES256-SHA384,ECDH-RSA-AES256-SHA384,DHE-DSS-AES256-GCM-SHA384,DHE-DSS-AES256-SHA256,AES256-GCM-SHA384,AES256-SHA256,ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES128-SHA256,ECDHE-RSA-AES128-SHA256,ECDH-ECDSA-AES128-GCM-SHA256,ECDH-RSA-AES128-GCM-SHA256,ECDH-ECDSA-AES128-SHA256,ECDH-RSA-AES128-SHA256,DHE-DSS-AES128-GCM-SHA256,DHE-DSS-AES128-SHA256,AES128-GCM-SHA256,AES128-SHA256,ECDHE-ECDSA-AES256-SHA,ECDHE-RSA-AES256-SHA,DHE-DSS-AES256-SHA,ECDH-ECDSA-AES256-SHA,ECDH-RSA-AES256-SHA,AES256-SHA,ECDHE-ECDSA-AES128-SHA,ECDHE-RSA-AES128-SHA,DHE-DSS-AES128-SHA,ECDH-ECDSA-AES128-SHA,ECDH-RSA-AES128-SHA,AES128-SHA
|
||||||
## management.listener.https.fail_if_no_peer_cert = true
|
## management.listener.https.fail_if_no_peer_cert = true
|
||||||
## management.listener.https.inet6 = false
|
## management.listener.https.inet6 = false
|
||||||
|
|
|
@ -58,7 +58,8 @@ stomp.listener.max_connections = 512
|
||||||
## TLS versions only to protect from POODLE attack.
|
## TLS versions only to protect from POODLE attack.
|
||||||
##
|
##
|
||||||
## Value: String, seperated by ','
|
## Value: String, seperated by ','
|
||||||
## stomp.listener.tls_versions = tlsv1.2,tlsv1.1,tlsv1
|
## NOTE: Do not use tlsv1.3 if emqx is running on OTP-22 or earlier
|
||||||
|
## stomp.listener.tls_versions = tlsv1.3,tlsv1.2,tlsv1.1,tlsv1
|
||||||
|
|
||||||
## SSL Handshake timeout.
|
## SSL Handshake timeout.
|
||||||
##
|
##
|
||||||
|
|
|
@ -354,12 +354,11 @@ pool_opts(Params = #{<<"url">> := URL}) ->
|
||||||
(_) ->
|
(_) ->
|
||||||
true
|
true
|
||||||
end, [{keyfile, KeyFile}, {certfile, CertFile}, {cacertfile, CACertFile}]),
|
end, [{keyfile, KeyFile}, {certfile, CertFile}, {cacertfile, CACertFile}]),
|
||||||
TlsVers = ['tlsv1.2', 'tlsv1.1', tlsv1],
|
NTLSOpts = [ {verify, VerifyType}
|
||||||
NTLSOpts = [{verify, VerifyType},
|
, {versions, emqx_tls_lib:default_versions()}
|
||||||
{versions, TlsVers},
|
, {ciphers, emqx_tls_lib:default_ciphers()}
|
||||||
{ciphers, lists:foldl(fun(TlsVer, Ciphers) ->
|
| TLSOpts
|
||||||
Ciphers ++ ssl:cipher_suites(all, TlsVer)
|
],
|
||||||
end, [], TlsVers)} | TLSOpts],
|
|
||||||
[{transport, ssl}, {transport_opts, [Inet | NTLSOpts]}]
|
[{transport, ssl}, {transport_opts, [Inet | NTLSOpts]}]
|
||||||
end,
|
end,
|
||||||
[{host, Host},
|
[{host, Host},
|
||||||
|
@ -397,4 +396,4 @@ test_http_connect(Conf) ->
|
||||||
Err:Reason:ST ->
|
Err:Reason:ST ->
|
||||||
?LOG(error, "check http_connectivity failed: ~p, ~0p", [Conf, {Err, Reason, ST}]),
|
?LOG(error, "check http_connectivity failed: ~p, ~0p", [Conf, {Err, Reason, ST}]),
|
||||||
false
|
false
|
||||||
end.
|
end.
|
||||||
|
|
|
@ -75,12 +75,11 @@ translate_env() ->
|
||||||
TLSOpts = lists:filter(fun({_K, V}) ->
|
TLSOpts = lists:filter(fun({_K, V}) ->
|
||||||
V /= <<>> andalso V /= undefined andalso V /= "" andalso true
|
V /= <<>> andalso V /= undefined andalso V /= "" andalso true
|
||||||
end, [{keyfile, KeyFile}, {certfile, CertFile}, {cacertfile, CACertFile}]),
|
end, [{keyfile, KeyFile}, {certfile, CertFile}, {cacertfile, CACertFile}]),
|
||||||
TlsVers = ['tlsv1.2','tlsv1.1',tlsv1],
|
NTLSOpts = [ {verify, VerifyType}
|
||||||
NTLSOpts = [{verify, VerifyType},
|
, {versions, emqx_tls_lib:default_versions()}
|
||||||
{versions, TlsVers},
|
, {ciphers, emqx_tls_lib:default_ciphers()}
|
||||||
{ciphers, lists:foldl(fun(TlsVer, Ciphers) ->
|
| TLSOpts
|
||||||
Ciphers ++ ssl:cipher_suites(all, TlsVer)
|
],
|
||||||
end, [], TlsVers)} | TLSOpts],
|
|
||||||
[{transport, ssl}, {transport_opts, [Inet | NTLSOpts]}]
|
[{transport, ssl}, {transport_opts, [Inet | NTLSOpts]}]
|
||||||
end,
|
end,
|
||||||
PoolOpts = [{host, Host},
|
PoolOpts = [{host, Host},
|
||||||
|
@ -114,4 +113,4 @@ parse_host(Host) ->
|
||||||
{ok, _} -> {inet6, Host};
|
{ok, _} -> {inet6, Host};
|
||||||
{error, _} -> {inet, Host}
|
{error, _} -> {inet, Host}
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
|
@ -1317,7 +1317,8 @@ listener.ssl.external.access.1 = allow all
|
||||||
## See: http://erlang.org/doc/man/ssl.html
|
## See: http://erlang.org/doc/man/ssl.html
|
||||||
##
|
##
|
||||||
## Value: String, seperated by ','
|
## Value: String, seperated by ','
|
||||||
## listener.ssl.external.tls_versions = tlsv1.2,tlsv1.1,tlsv1
|
## NOTE: Do not use tlsv1.3 if emqx is running on OTP-22 or earlier
|
||||||
|
## listener.ssl.external.tls_versions = tlsv1.3,tlsv1.2,tlsv1.1,tlsv1
|
||||||
|
|
||||||
## TLS Handshake timeout.
|
## TLS Handshake timeout.
|
||||||
##
|
##
|
||||||
|
@ -1785,7 +1786,7 @@ listener.wss.external.access.1 = allow all
|
||||||
## Supported subprotocols
|
## Supported subprotocols
|
||||||
##
|
##
|
||||||
## Default: mqtt, mqtt-v3, mqtt-v3.1.1, mqtt-v5
|
## Default: mqtt, mqtt-v3, mqtt-v3.1.1, mqtt-v5
|
||||||
## listener.ws.external.supported_protocols = mqtt, mqtt-v3, mqtt-v3.1.1, mqtt-v5
|
## listener.wss.external.supported_protocols = mqtt, mqtt-v3, mqtt-v3.1.1, mqtt-v5
|
||||||
|
|
||||||
## Enable the Proxy Protocol V1/2 support.
|
## Enable the Proxy Protocol V1/2 support.
|
||||||
##
|
##
|
||||||
|
@ -1806,7 +1807,8 @@ listener.wss.external.access.1 = allow all
|
||||||
## See: listener.ssl.$name.tls_versions
|
## See: listener.ssl.$name.tls_versions
|
||||||
##
|
##
|
||||||
## Value: String, seperated by ','
|
## Value: String, seperated by ','
|
||||||
## listener.wss.external.tls_versions = tlsv1.2,tlsv1.1,tlsv1
|
## NOTE: Do not use tlsv1.3 if emqx is running on OTP-22 or earlier
|
||||||
|
## listener.wss.external.tls_versions = tlsv1.3,tlsv1.2,tlsv1.1,tlsv1
|
||||||
|
|
||||||
## Path to the file containing the user's private PEM-encoded key.
|
## Path to the file containing the user's private PEM-encoded key.
|
||||||
##
|
##
|
||||||
|
|
|
@ -47,7 +47,7 @@ integral_versions(Desired) ->
|
||||||
|
|
||||||
%% @doc Return a list of default (openssl string format) cipher suites.
|
%% @doc Return a list of default (openssl string format) cipher suites.
|
||||||
-spec default_ciphers() -> [string()].
|
-spec default_ciphers() -> [string()].
|
||||||
default_ciphers() -> default_ciphers(tls_versions()).
|
default_ciphers() -> default_ciphers(default_versions()).
|
||||||
|
|
||||||
%% @doc Return a list of (openssl string format) cipher suites.
|
%% @doc Return a list of (openssl string format) cipher suites.
|
||||||
-spec default_ciphers([ssl:tls_version()]) -> [string()].
|
-spec default_ciphers([ssl:tls_version()]) -> [string()].
|
||||||
|
@ -68,7 +68,7 @@ integral_ciphers(Versions, Ciphers) when Ciphers =:= [] orelse Ciphers =:= undef
|
||||||
integral_ciphers(Versions, default_ciphers(Versions));
|
integral_ciphers(Versions, default_ciphers(Versions));
|
||||||
integral_ciphers(Versions, Ciphers) when ?IS_STRING_LIST(Ciphers) ->
|
integral_ciphers(Versions, Ciphers) when ?IS_STRING_LIST(Ciphers) ->
|
||||||
%% ensure tlsv1.3 ciphers if none of them is found in Ciphers
|
%% ensure tlsv1.3 ciphers if none of them is found in Ciphers
|
||||||
dedup(ensure_tls1_3_cipher(lists:member('tlsv1.3', Versions), Ciphers));
|
dedup(ensure_tls13_cipher(lists:member('tlsv1.3', Versions), Ciphers));
|
||||||
integral_ciphers(Versions, Ciphers) when is_binary(Ciphers) ->
|
integral_ciphers(Versions, Ciphers) when is_binary(Ciphers) ->
|
||||||
%% parse binary
|
%% parse binary
|
||||||
integral_ciphers(Versions, binary_to_list(Ciphers));
|
integral_ciphers(Versions, binary_to_list(Ciphers));
|
||||||
|
@ -78,20 +78,20 @@ integral_ciphers(Versions, Ciphers) ->
|
||||||
|
|
||||||
%% In case tlsv1.3 is present, ensure tlsv1.3 cipher is added if user
|
%% In case tlsv1.3 is present, ensure tlsv1.3 cipher is added if user
|
||||||
%% did not provide it from config --- which is a common mistake
|
%% did not provide it from config --- which is a common mistake
|
||||||
ensure_tls1_3_cipher(true, Ciphers) ->
|
ensure_tls13_cipher(true, Ciphers) ->
|
||||||
Tls13Ciphers = default_ciphers(['tlsv1.3']),
|
Tls13Ciphers = default_ciphers(['tlsv1.3']),
|
||||||
case lists:any(fun(C) -> lists:member(C, Tls13Ciphers) end, Ciphers) of
|
case lists:any(fun(C) -> lists:member(C, Tls13Ciphers) end, Ciphers) of
|
||||||
true -> Ciphers;
|
true -> Ciphers;
|
||||||
false -> Tls13Ciphers ++ Ciphers
|
false -> Tls13Ciphers ++ Ciphers
|
||||||
end;
|
end;
|
||||||
ensure_tls1_3_cipher(false, Ciphers) ->
|
ensure_tls13_cipher(false, Ciphers) ->
|
||||||
Ciphers.
|
Ciphers.
|
||||||
|
|
||||||
%% tlsv1.3 is available from OTP-22 but we do not want to use until 23.
|
%% tlsv1.3 is available from OTP-22 but we do not want to use until 23.
|
||||||
default_versions(OtpRelease) when OtpRelease >= 23 ->
|
default_versions(OtpRelease) when OtpRelease >= 23 ->
|
||||||
['tlsv1.3' | default_tls_versions(22)];
|
['tlsv1.3' | default_versions(22)];
|
||||||
default_versions(_) ->
|
default_versions(_) ->
|
||||||
['tlsv1.2','tlsv1.1', tlsv1].
|
['tlsv1.2', 'tlsv1.1', tlsv1].
|
||||||
|
|
||||||
%% Deduplicate a list without re-ordering the elements.
|
%% Deduplicate a list without re-ordering the elements.
|
||||||
dedup([]) -> [];
|
dedup([]) -> [];
|
||||||
|
|
Loading…
Reference in New Issue