diff --git a/apps/emqx/i18n/emqx_schema_i18n.conf b/apps/emqx/i18n/emqx_schema_i18n.conf index 6faa0c511..0054ddea9 100644 --- a/apps/emqx/i18n/emqx_schema_i18n.conf +++ b/apps/emqx/i18n/emqx_schema_i18n.conf @@ -1868,6 +1868,21 @@ fields_mqtt_quic_listener_keep_alive_interval { } } +fields_mqtt_quic_listener_ssl_options { + desc { + en: """ +TLS options for QUIC transport +""" + zh: """ +QUIC 传输层的 TLS 选项 +""" + } + label: { + en: "TLS Options" + zh: "TLS 选项" + } +} + base_listener_bind { desc { en: """IP address and port for the listening socket.""" diff --git a/apps/emqx/src/emqx_listeners.erl b/apps/emqx/src/emqx_listeners.erl index 860a62082..fedf583e2 100644 --- a/apps/emqx/src/emqx_listeners.erl +++ b/apps/emqx/src/emqx_listeners.erl @@ -370,19 +370,23 @@ do_start_listener(quic, ListenerName, #{bind := Bind} = Opts) -> case [A || {quicer, _, _} = A <- application:which_applications()] of [_] -> DefAcceptors = erlang:system_info(schedulers_online) * 8, + SSLOpts = maps:merge( + maps:with([certfile, keyfile], Opts), + maps:get(ssl_options, Opts, #{}) + ), ListenOpts = [ - {cert, maps:get(certfile, Opts)}, - {key, maps:get(keyfile, Opts)}, + {certfile, str(maps:get(certfile, SSLOpts))}, + {keyfile, str(maps:get(keyfile, SSLOpts))}, {alpn, ["mqtt"]}, {conn_acceptors, lists:max([DefAcceptors, maps:get(acceptors, Opts, 0)])}, {keep_alive_interval_ms, maps:get(keep_alive_interval, Opts, 0)}, {idle_timeout_ms, maps:get(idle_timeout, Opts, 0)}, {handshake_idle_timeout_ms, maps:get(handshake_idle_timeout, Opts, 10000)}, {server_resumption_level, 2}, - {verify, maps:get(verify, Opts, verify_none)} + {verify, maps:get(verify, SSLOpts, verify_none)} ] ++ - case maps:get(cacertfile, Opts, undefined) of + case maps:get(cacertfile, SSLOpts, undefined) of undefined -> []; CaCertFile -> [{cacertfile, binary_to_list(CaCertFile)}] end, diff --git a/apps/emqx/src/emqx_schema.erl b/apps/emqx/src/emqx_schema.erl index 546613023..7b4b21fb7 100644 --- a/apps/emqx/src/emqx_schema.erl +++ b/apps/emqx/src/emqx_schema.erl @@ -845,31 +845,20 @@ fields("mqtt_wss_listener") -> ]; fields("mqtt_quic_listener") -> [ - {"cacertfile", - sc( - binary(), - #{ - default => undefined, - required => false, - desc => ?DESC(common_ssl_opts_schema_cacertfile) - } - )}, {"certfile", sc( string(), - #{desc => ?DESC(fields_mqtt_quic_listener_certfile)} + #{ + %% TODO: deprecated => {since, "5.1.0"} + desc => ?DESC(fields_mqtt_quic_listener_certfile) + } )}, {"keyfile", sc( string(), - #{desc => ?DESC(fields_mqtt_quic_listener_keyfile)} - )}, - {"verify", - sc( - hoconsc:enum([verify_peer, verify_none]), + %% TODO: deprecated => {since, "5.1.0"} #{ - default => verify_none, - desc => ?DESC(common_ssl_opts_schema_verify) + desc => ?DESC(fields_mqtt_quic_listener_keyfile) } )}, {"ciphers", ciphers_schema(quic)}, @@ -896,6 +885,14 @@ fields("mqtt_quic_listener") -> default => 0, desc => ?DESC(fields_mqtt_quic_listener_keep_alive_interval) } + )}, + {"ssl_options", + sc( + ref("listener_quic_ssl_opts"), + #{ + required => false, + desc => ?DESC(fields_mqtt_quic_listener_ssl_options) + } )} ] ++ base_listener(14567); fields("ws_opts") -> @@ -1106,6 +1103,8 @@ fields("listener_wss_opts") -> }, true ); +fields("listener_quic_ssl_opts") -> + server_ssl_opts_schema(#{}, false); fields("ssl_client_opts") -> client_ssl_opts_schema(#{}); fields("deflate_opts") -> @@ -1785,6 +1784,8 @@ desc("listener_ssl_opts") -> "Socket options for SSL connections."; desc("listener_wss_opts") -> "Socket options for WebSocket/SSL connections."; +desc("listener_quic_ssl_opts") -> + "TLS options for QUIC transport."; desc("ssl_client_opts") -> "Socket options for SSL clients."; desc("deflate_opts") ->