Skip to content

ejabberd: Use Let's Encrypt certificate, also across cert renewals.

Sunil Mohan Adapa requested to merge JoKeyser:LEandEjabberd into master

Created by: JoKeyser

Hi, let me know how I can help with review.

Summary and context
This PR lets ejabberd use the LE certificate - if one is available for the current domain, thus would fix issue #565 (closed). The proposed ejabberd action is extended with add/drop cert commands, based on previous @jvalleroy's PR #579. The other half of the work is integration with the recently added cert renewal management #891.

The proposed solution revolves around the cert renewal configuration file at /etc/letsencrypt/renewal/CURRENT_DOMAIN.conf. It's the only place where the state is stored - which is a feature because it's very transparent to administration via console. I think the biggest drawback of the current PR is the lack of logging via Plinth, see first point of the listed issues below. I've tried to write everything quite general, such that other modules would be easily added. Basically a module's action only need to provide analogous add/drop commands.

Certificate deletion, domain change, and inactivation of Plinth's renewal management will undo the use of the LE certificate, i.e. revert to the self-signed one. (Re-)Obtaining a cert will not (yet) activate module integration.

Here a screenshot:

lewithejabberd

How to test this?
To make a full test, edit the file /etc/letsencrypt/$CURRENT_DOMAIN.conf and set renew_before_exiry = 100 days or something. Then call certbot renew. I've tested this in the vagrant image; the renew-hook indeed adds the cert to ejabberd (and restarts apache2), and logs to /var/log/letsencrypt/letsencrypt.log, so errors are traceable. To manually verify that ejabberd is using the cert, test ports 5222 (c2s) and 5269 (s2s):

openssl s_client -connect freedombox:5222 -starttls xmpp < /dev/null
openssl s_client -connect freedombox:5269 -starttls xmpp-server < /dev/null

Discussion and potential issues:

  1. Most importantly, the current design is to let the letsencrypt action call other actions (and they import some LE-related variables); I'm not sure whether hat approach is the most sensible one. To avoid calling other actions, one could instead put all LE add/drop commands (per supported module) within the letsencrypt action. However, then the letsencrypt action would have to import many modules' config paths etc, which seems more messy to me (but I haven't tried that). Currently, the action letsencrypt run_renew_hooks calls a simplified version of plinth/actions.py run() to iterate over the add-actions of other modules. Pro: It's straight-forward and callable anytime from the command line, so it's quite transparent. Con: Some code duplication, and no logs in plinth (though in certbot, if called as renew hook). Maybe it's possible to use plinth.actions.run to run all commands directly from Plinth, but that seemed complicated to me. (Just calling the actions.py:run function won't work because it needs Plinth's settings.) I'm open to suggestions, but also think improvements can be added in the future, since all that's changed on a system is the renewal config file - future versions could just handle that differently/better. Maybe logging to plinth's logfile is easy to set up?
  2. The module integration only works for current domain, to keep it simple (at least for now).
  3. Use of cert by modules could/should be default(?), but that's not yet done.
  4. The Delete button will undo use of cert; therefore merging this PR might conflict with PR #916. fixed, see below
  5. I'm unsure what to do with the Revoke button - currently nothing happens in regards to certificate renewal.
  6. Maybe the letsencrypt html templates can be made more Django-esque in the future.
  7. Automatic tests could be written for the new actions.

Merge request reports

Loading