ejabberdctl request_certificate crashes
Environment
- ejabberd version: 24.07
- Erlang version: Erlang (SMP,ASYNC_THREADS) (BEAM) emulator version 15.0.1
- OS: Linux (Arch Linux)
- Installed from: distro package
Errors from error.log/crash.log
12:36:38.730 [error] GenServer :ejabberd_acme terminating
** (stop) {:invalid_ejson, {"crv", "P-256"}}
(jiffy 1.1.2) /build/ejabberd/src/ejabberd-24.07/deps/jiffy/src/jiffy.erl:91: :jiffy.encode/2
(jose 1.11.10) src/json/jose_json_jiffy.erl:26: :jose_json_jiffy.encode/1
(jose 1.11.10) src/jws/jose_jws.erl:134: :jose_jws.to_binary/1
(jose 1.11.10) src/jws/jose_jws.erl:307: :jose_jws.sign/4
(p1_acme 1.0.23) /build/ejabberd/src/ejabberd-24.07/deps/p1_acme/src/p1_acme.erl:923: :p1_acme.jose_json/3
(p1_acme 1.0.23) /build/ejabberd/src/ejabberd-24.07/deps/p1_acme/src/p1_acme.erl:286: anonymous fn/1 in :p1_acme.request_new_account/1
(p1_acme 1.0.23) /build/ejabberd/src/ejabberd-24.07/deps/p1_acme/src/p1_acme.erl:614: :p1_acme.http_request/3
(p1_acme 1.0.23) /build/ejabberd/src/ejabberd-24.07/deps/p1_acme/src/p1_acme.erl:290: :p1_acme.request_new_account/1
Last message: {:"$gen_cast", {:request, ["conference.example.org", "example.org", "proxy.xmpp.example.org", "pubsub.xmpp.example.org", "upload.example.org"]}}
(replaced my domain by example.org)
Bug description
In addition to the error above, ejabberdctl request_certificate all (as well as ejabberdctl request_certificate "example.org") crashes as well:
Unhandled exception occurred executing the command:
** exception exit: {{{invalid_ejson,{<<"crv">>,<<"P-256">>}},
[{jiffy,encode,2,
[{file,
"/build/ejabberd/src/ejabberd-24.07/deps/jiffy/src/jiffy.erl"},
{line,91}]},
{jose_json_jiffy,encode,1,
[{file,"src/json/jose_json_jiffy.erl"},{line,26}]},
{jose_jws,to_binary,1,
[{file,"src/jws/jose_jws.erl"},{line,134}]},
{jose_jws,sign,4,
[{file,"src/jws/jose_jws.erl"},{line,307}]},
{p1_acme,jose_json,3,
[{file,
"/build/ejabberd/src/ejabberd-24.07/deps/p1_acme/src/p1_acme.erl"},
{line,923}]},
{p1_acme,'-request_new_account/1-fun-0-',1,
[{file,
"/build/ejabberd/src/ejabberd-24.07/deps/p1_acme/src/p1_acme.erl"},
{line,286}]},
{p1_acme,http_request,3,
[{file,
"/build/ejabberd/src/ejabberd-24.07/deps/p1_acme/src/p1_acme.erl"},
{line,614}]},
{p1_acme,request_new_account,1,
[{file,
"/build/ejabberd/src/ejabberd-24.07/deps/p1_acme/src/p1_acme.erl"},
{line,290}]}]},
{gen_server,call,
[ejabberd_acme,
{request,
[<<"example.org">>,<<"proxy.xmpp.example.org">>,
<<"pubsub.xmpp.example.org">>,
<<"conference.example.org">>,
<<"upload.example.org">>]},
600000]}}
in function gen_server:call/3 (gen_server.erl, line 1126)
in call from ejabberd_acme:request_certificate/1 (src/ejabberd_acme.erl, line 491)
in call from ejabberd_ctl:call_command/4 (src/ejabberd_ctl.erl, line 328)
in call from ejabberd_ctl:try_call_command/4 (src/ejabberd_ctl.erl, line 289)
in call from ejabberd_ctl:process2/4 (src/ejabberd_ctl.erl, line 229)
in call from ejabberd_ctl:process/2 (src/ejabberd_ctl.erl, line 207)
in call from erpc:execute_call/4 (erpc.erl, line 1250)
I added https://github.com/processone/p1_acme/commit/cd292d02ca12ff9cdcad17732c4b02c289288958 in p1_acme library that i think will help with that error.
I get the same error as svbergerem reported here. Tried to fix it by recompiling ejabberd with the commit cd292d0 (and ef06ff8) to p1_acme, however, the problem still persists.
Output of ejabberdctl request_certificate all:
Unhandled exception occurred executing the command:
** exception exit: {{{invalid_ejson,{<<"crv">>,<<"P-256">>}},
[{jiffy,encode,2,
[{file,
"/build/ejabberd/src/ejabberd-24.07/deps/jiffy/src/jiffy.erl"},
{line,91}]},
{jose_json_jiffy,encode,1,
[{file,"src/json/jose_json_jiffy.erl"},{line,26}]},
{jose_jws,to_binary,1,
[{file,"src/jws/jose_jws.erl"},{line,134}]},
{jose_jws,sign,4,
[{file,"src/jws/jose_jws.erl"},{line,307}]},
{p1_acme,jose_json,3,
[{file,
"/build/ejabberd/src/ejabberd-24.07/deps/p1_acme/src/p1_acme.erl"},
{line,923}]},
{p1_acme,'-request_new_account/1-fun-0-',1,
[{file,
"/build/ejabberd/src/ejabberd-24.07/deps/p1_acme/src/p1_acme.erl"},
{line,286}]},
{p1_acme,http_request,3,
[{file,
"/build/ejabberd/src/ejabberd-24.07/deps/p1_acme/src/p1_acme.erl"},
{line,614}]},
{p1_acme,request_new_account,1,
[{file,
"/build/ejabberd/src/ejabberd-24.07/deps/p1_acme/src/p1_acme.erl"},
{line,290}]}]},
{gen_server,call,
[ejabberd_acme,
{request,
[<<"conversations.p***.de">>,
<<"pubsub.conversations.p***.de">>,
<<"conference.conversations.p***.de">>,
<<"proxy.conversations.p***.de">>,
<<"upload.conversations.p***.de">>]},
600000]}}
in function gen_server:call/3 (gen_server.erl, line 1126)
in call from ejabberd_acme:request_certificate/1 (src/ejabberd_acme.erl, line 491)
in call from ejabberd_ctl:call_command/4 (src/ejabberd_ctl.erl, line 328)
in call from ejabberd_ctl:try_call_command/4 (src/ejabberd_ctl.erl, line 289)
in call from ejabberd_ctl:process2/4 (src/ejabberd_ctl.erl, line 229)
in call from ejabberd_ctl:process/2 (src/ejabberd_ctl.erl, line 207)
in call from erpc:execute_call/4 (erpc.erl, line 1250)
You could apply this debugging patch. It allows you to check if ejabberd is really using the patched p1_acme binaries, and also prints the arguments that provoke the crash:
diff --git a/src/p1_acme.erl b/src/p1_acme.erl
index 8e22352..211d52f 100644
--- a/src/p1_acme.erl
+++ b/src/p1_acme.erl
@@ -910,6 +910,7 @@ jose_json(#state{account = {Key, AccURL}, nonce = Nonce} = State, Data, URL) ->
end,
JwsMap0 = #{<<"nonce">> => Nonce,
<<"url">> => iolist_to_binary(URL)},
+ ?INFO_MSG("JOSE privkey: ~p~npubkey: ~p", [PrivKey, PubKey]),
JwsMap = case AccURL of
undefined ->
{_, BinaryPubKey} = jose_jwk:to_binary(PubKey),
@@ -919,7 +920,7 @@ jose_json(#state{account = {Key, AccURL}, nonce = Nonce} = State, Data, URL) ->
JwsMap0#{<<"kid">> => iolist_to_binary(AccURL)}
end,
JwsObj = jose_jws:from(maps:merge(JwsMap, AlgMap)),
- ?DEBUG("JOSE payload: ~s~nJOSE protected: ~p", [Data, JwsObj]),
+ ?INFO_MSG("JOSE payload: ~s~nJOSE protected: ~p", [Data, JwsObj]),
{_, JoseJSON} = jose_jws:sign(PrivKey, Data, JwsObj),
encode_json(JoseJSON).
Thank you for your input. You are right with your assumption, my test ejabberd was indeed compiled with a p1_acme version tagged 1.0.23 instead of the latest head, although I placed the current version in the deps directory. My mistake. Now with commits cd292d0 and ef06ff8 correctly applied during compilation, certificate renewal works as expected.
How did you resolve it? I don't understand how to compile it against p1_acme HEAD. Can someone explain what I need to do? Also on Arch Linux. I hope this is fixed in the next releases soon...
@a4r7gc4ttfwsqcey
You can checkout the current build scripts from arch using:
git clone https://gitlab.archlinux.org/archlinux/packaging/packages/ejabberd.git
In the resulting directory ejabberd replace the PKGBUILD with the one from this archive, also copy certificate_renew.patch included in this archive to the ejabberd directory.
Make sure to have the devtools package installed (pacman -S devtools), then compile ejabberd with the patch using a clean chroot environment: extra-x86_64-build (or the equivalent if building for another architecture).
@knoelli Thank you so much man, just did that and it worked perfectly!
@svbergerem: Have you solved your problem with @prefiks, @badlop comments?
@Neustradamus No, I temporarily “fixed” the problem by renewing the certificates manually using certbot. I won't build the package myself and rather wait for the next release. However, since others already confirmed that the bug has been fixed, I guess this issue can be closed.