From 5c5ecbe3cf377c99fd54e3da845392b655dc3988 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Sat, 16 Dec 2023 23:09:12 +0100 Subject: [PATCH] fix(gw): unbreak schema + transform DTLS options properly Thus ensuring full backward compatibility. Unsupported options (`gc_after_handshake`, `ocsp`) are silently ignored now. Also make sure that UDP configuration are part of DTLS option set, as expected by `esockd`. --- apps/emqx_gateway/src/emqx_gateway_schema.erl | 6 +-- apps/emqx_gateway/src/emqx_gateway_utils.erl | 48 +++++++++++++++---- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/apps/emqx_gateway/src/emqx_gateway_schema.erl b/apps/emqx_gateway/src/emqx_gateway_schema.erl index ed54383f5..d51bf93a9 100644 --- a/apps/emqx_gateway/src/emqx_gateway_schema.erl +++ b/apps/emqx_gateway/src/emqx_gateway_schema.erl @@ -174,11 +174,7 @@ fields(dtls_opts) -> reuse_sessions => true, versions => dtls_all_available }, - %% NOTE - %% Although dTLS listener is started through `esockd`, it doesn't really support stuff - %% more tightly related to `emqx_listeners` (`enable_crl_check`, `oscp`) and plain TLS - %% (`gc_after_handshake`). - _IsRanchListener = true + _IsRanchListener = false ). desc(gateway) -> diff --git a/apps/emqx_gateway/src/emqx_gateway_utils.erl b/apps/emqx_gateway/src/emqx_gateway_utils.erl index c8cf979e3..7d6b4c172 100644 --- a/apps/emqx_gateway/src/emqx_gateway_utils.erl +++ b/apps/emqx_gateway/src/emqx_gateway_utils.erl @@ -273,7 +273,7 @@ merge_default(Udp, Options) -> udp -> {udp_options, default_udp_options()}; dtls -> - {udp_options, default_udp_options()}; + {dtls_options, default_udp_options()}; tcp -> {tcp_options, default_tcp_options()}; ssl -> @@ -525,9 +525,10 @@ esockd_opts(Type, Opts0) when ?IS_ESOCKD_LISTENER(Type) -> udp -> Opts2#{udp_options => sock_opts(udp_options, Opts0)}; dtls -> + UDPOpts = sock_opts(udp_options, Opts0), + DTLSOpts = ssl_opts(dtls_options, Opts0), Opts2#{ - udp_options => sock_opts(udp_options, Opts0), - dtls_options => ssl_opts(dtls_options, Opts0) + dtls_options => UDPOpts ++ DTLSOpts } end ). @@ -541,12 +542,41 @@ sock_opts(Name, Opts) -> ). ssl_opts(Name, Opts) -> - Type = - case Name of - ssl_options -> tls; - dtls_options -> dtls - end, - emqx_tls_lib:to_server_opts(Type, maps:get(Name, Opts, #{})). + SSLOpts = maps:get(Name, Opts, #{}), + emqx_utils:run_fold( + [ + fun ssl_opts_crl_config/2, + fun ssl_opts_drop_unsupported/2, + fun ssl_server_opts/2 + ], + SSLOpts, + Name + ). + +ssl_opts_crl_config(#{enable_crl_check := true} = SSLOpts, _Name) -> + HTTPTimeout = emqx_config:get([crl_cache, http_timeout], timer:seconds(15)), + NSSLOpts = maps:remove(enable_crl_check, SSLOpts), + NSSLOpts#{ + %% `crl_check => true' doesn't work + crl_check => peer, + crl_cache => {emqx_ssl_crl_cache, {internal, [{http, HTTPTimeout}]}} + }; +ssl_opts_crl_config(SSLOpts, _Name) -> + %% NOTE: Removing this because DTLS doesn't like any unknown options. + maps:remove(enable_crl_check, SSLOpts). + +ssl_opts_drop_unsupported(SSLOpts, ssl_options) -> + %% TODO: Support OCSP stapling + maps:without([ocsp], SSLOpts); +ssl_opts_drop_unsupported(SSLOpts, dtls_options) -> + %% TODO: Support OCSP stapling + %% NOTE: Removing those because DTLS doesn't like any unknown options. + maps:without([ocsp, gc_after_handshake], SSLOpts). + +ssl_server_opts(SSLOpts, ssl_options) -> + emqx_tls_lib:to_server_opts(tls, SSLOpts); +ssl_server_opts(SSLOpts, dtls_options) -> + emqx_tls_lib:to_server_opts(dtls, SSLOpts). ranch_opts(Type, ListenOn, Opts) -> NumAcceptors = maps:get(acceptors, Opts, 4),