emqx_authn_https_SUITE.erl 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2020-2022 EMQ Technologies Co., Ltd. All Rights Reserved.
  3. %%
  4. %% Licensed under the Apache License, Version 2.0 (the "License");
  5. %% you may not use this file except in compliance with the License.
  6. %% You may obtain a copy of the License at
  7. %%
  8. %% http://www.apache.org/licenses/LICENSE-2.0
  9. %%
  10. %% Unless required by applicable law or agreed to in writing, software
  11. %% distributed under the License is distributed on an "AS IS" BASIS,
  12. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. %% See the License for the specific language governing permissions and
  14. %% limitations under the License.
  15. %%--------------------------------------------------------------------
  16. -module(emqx_authn_https_SUITE).
  17. -compile(nowarn_export_all).
  18. -compile(export_all).
  19. -include("emqx_authn.hrl").
  20. -include_lib("eunit/include/eunit.hrl").
  21. -include_lib("common_test/include/ct.hrl").
  22. -include_lib("emqx/include/emqx_placeholder.hrl").
  23. -define(PATH, [?CONF_NS_ATOM]).
  24. -define(HTTPS_PORT, 33333).
  25. -define(HTTPS_PATH, "/auth").
  26. -define(CREDENTIALS, #{username => <<"plain">>,
  27. password => <<"plain">>,
  28. listener => 'tcp:default',
  29. protocol => mqtt
  30. }).
  31. all() ->
  32. emqx_common_test_helpers:all(?MODULE).
  33. init_per_suite(Config) ->
  34. _ = application:load(emqx_conf),
  35. emqx_common_test_helpers:start_apps([emqx_authn]),
  36. application:ensure_all_started(cowboy),
  37. Config.
  38. end_per_suite(_) ->
  39. emqx_authn_test_lib:delete_authenticators(
  40. [authentication],
  41. ?GLOBAL),
  42. emqx_common_test_helpers:stop_apps([emqx_authn]),
  43. application:stop(cowboy),
  44. ok.
  45. init_per_testcase(_Case, Config) ->
  46. {ok, _} = emqx_cluster_rpc:start_link(node(), emqx_cluster_rpc, 1000),
  47. emqx_authn_test_lib:delete_authenticators(
  48. [authentication],
  49. ?GLOBAL),
  50. {ok, _} = emqx_authn_http_test_server:start_link(?HTTPS_PORT, ?HTTPS_PATH, server_ssl_opts()),
  51. ok = emqx_authn_http_test_server:set_handler(fun cowboy_handler/2),
  52. Config.
  53. end_per_testcase(_Case, _Config) ->
  54. ok = emqx_authn_http_test_server:stop().
  55. %%------------------------------------------------------------------------------
  56. %% Tests
  57. %%------------------------------------------------------------------------------
  58. t_create(_Config) ->
  59. {ok, _} = create_https_auth_with_ssl_opts(
  60. #{<<"server_name_indication">> => <<"authn-server">>,
  61. <<"verify">> => <<"verify_peer">>,
  62. <<"versions">> => [<<"tlsv1.2">>],
  63. <<"ciphers">> => [<<"ECDHE-RSA-AES256-GCM-SHA384">>]}),
  64. ?assertMatch(
  65. {ok, _},
  66. emqx_access_control:authenticate(?CREDENTIALS)).
  67. t_create_invalid_domain(_Config) ->
  68. {ok, _} = create_https_auth_with_ssl_opts(
  69. #{<<"server_name_indication">> => <<"authn-server-unknown-host">>,
  70. <<"verify">> => <<"verify_peer">>,
  71. <<"versions">> => [<<"tlsv1.2">>],
  72. <<"ciphers">> => [<<"ECDHE-RSA-AES256-GCM-SHA384">>]}),
  73. ?assertEqual(
  74. {error, not_authorized},
  75. emqx_access_control:authenticate(?CREDENTIALS)).
  76. t_create_invalid_version(_Config) ->
  77. {ok, _} = create_https_auth_with_ssl_opts(
  78. #{<<"server_name_indication">> => <<"authn-server">>,
  79. <<"verify">> => <<"verify_peer">>,
  80. <<"versions">> => [<<"tlsv1.1">>]}),
  81. ?assertEqual(
  82. {error, not_authorized},
  83. emqx_access_control:authenticate(?CREDENTIALS)).
  84. t_create_invalid_ciphers(_Config) ->
  85. {ok, _} = create_https_auth_with_ssl_opts(
  86. #{<<"server_name_indication">> => <<"authn-server">>,
  87. <<"verify">> => <<"verify_peer">>,
  88. <<"versions">> => [<<"tlsv1.2">>],
  89. <<"ciphers">> => [<<"ECDHE-ECDSA-AES256-SHA384">>]}),
  90. ?assertEqual(
  91. {error, not_authorized},
  92. emqx_access_control:authenticate(?CREDENTIALS)).
  93. %%------------------------------------------------------------------------------
  94. %% Helpers
  95. %%------------------------------------------------------------------------------
  96. create_https_auth_with_ssl_opts(SpecificSSLOpts) ->
  97. AuthConfig = raw_https_auth_config(SpecificSSLOpts),
  98. emqx:update_config(?PATH, {create_authenticator, ?GLOBAL, AuthConfig}).
  99. raw_https_auth_config(SpecificSSLOpts) ->
  100. SSLOpts = maps:merge(
  101. emqx_authn_test_lib:client_ssl_cert_opts(),
  102. #{enable => <<"true">>}),
  103. #{
  104. mechanism => <<"password_based">>,
  105. enable => <<"true">>,
  106. backend => <<"http">>,
  107. method => <<"get">>,
  108. url => <<"https://127.0.0.1:33333/auth">>,
  109. body => #{<<"username">> => ?PH_USERNAME, <<"password">> => ?PH_PASSWORD},
  110. headers => #{<<"X-Test-Header">> => <<"Test Value">>},
  111. ssl => maps:merge(SSLOpts, SpecificSSLOpts)
  112. }.
  113. start_apps(Apps) ->
  114. lists:foreach(fun application:ensure_all_started/1, Apps).
  115. stop_apps(Apps) ->
  116. lists:foreach(fun application:stop/1, Apps).
  117. cert_path(FileName) ->
  118. Dir = code:lib_dir(emqx_authn, test),
  119. filename:join([Dir, <<"data/certs">>, FileName]).
  120. cowboy_handler(Req0, State) ->
  121. Req = cowboy_req:reply(
  122. 200,
  123. Req0),
  124. {ok, Req, State}.
  125. server_ssl_opts() ->
  126. [{keyfile, cert_path("server.key")},
  127. {certfile, cert_path("server.crt")},
  128. {cacertfile, cert_path("ca.crt")},
  129. {verify, verify_none},
  130. {versions, ['tlsv1.2', 'tlsv1.3']},
  131. {ciphers, ["ECDHE-RSA-AES256-GCM-SHA384", "TLS_CHACHA20_POLY1305_SHA256"]}
  132. ].