diff --git a/apps/emqx/src/emqx_tls_lib.erl b/apps/emqx/src/emqx_tls_lib.erl index 3540bddd5..653f26708 100644 --- a/apps/emqx/src/emqx_tls_lib.erl +++ b/apps/emqx/src/emqx_tls_lib.erl @@ -389,7 +389,7 @@ is_pem(MaybePem) -> %% Also a potentially half-written PEM file (e.g. due to power outage) %% can be corrected with an overwrite. save_pem_file(Dir, KeyPath, Pem, DryRun) -> - Path = pem_file_name(Dir, KeyPath), + Path = pem_file_name(Dir, KeyPath, Pem), case filelib:ensure_dir(Path) of ok when DryRun -> {ok, Path}; @@ -412,11 +412,14 @@ is_managed_ssl_file(Filename) -> _ -> false end. -pem_file_name(Dir, KeyPath) -> - Suffix = binary:encode_hex(crypto:strong_rand_bytes(8)), +pem_file_name(Dir, KeyPath, Pem) -> + % NOTE + % Wee need to have the same filename on every cluster node. Segments = lists:map(fun ensure_bin/1, KeyPath), Filename0 = iolist_to_binary(lists:join(<<"_">>, Segments)), Filename1 = binary:replace(Filename0, <<"file">>, <<>>), + Fingerprint = crypto:hash(md5, [Dir, Filename1, Pem]), + Suffix = binary:encode_hex(binary:part(Fingerprint, 0, 8)), Filename = <>, filename:join([pem_dir(Dir), Filename]). diff --git a/apps/emqx/test/emqx_tls_lib_tests.erl b/apps/emqx/test/emqx_tls_lib_tests.erl index 8eea21596..4e8435484 100644 --- a/apps/emqx/test/emqx_tls_lib_tests.erl +++ b/apps/emqx/test/emqx_tls_lib_tests.erl @@ -206,6 +206,24 @@ ssl_file_replace_test() -> ?assert(filelib:is_regular(IssuerPem2)), ok. +ssl_file_deterministic_names_test() -> + SSL0 = #{ + <<"keyfile">> => test_key(), + <<"certfile">> => test_key() + }, + Dir0 = filename:join(["/tmp", ?FUNCTION_NAME, "ssl0"]), + Dir1 = filename:join(["/tmp", ?FUNCTION_NAME, "ssl1"]), + {ok, SSLFiles0} = emqx_tls_lib:ensure_ssl_files(Dir0, SSL0), + ?assertEqual( + {ok, SSLFiles0}, + emqx_tls_lib:ensure_ssl_files(Dir0, SSL0) + ), + ?assertNotEqual( + {ok, SSLFiles0}, + emqx_tls_lib:ensure_ssl_files(Dir1, SSL0) + ), + _ = file:del_dir_r(filename:join(["/tmp", ?FUNCTION_NAME])). + bin(X) -> iolist_to_binary(X). test_key() ->