Ejabberd / Swag(Nginx) / LetsEncrypt

My domain is: cespedes.fr

My web server is (include version): Swag(Nginx/Fail2ban/LetsEncrypt-Docker) 2.10.0-ls300

The operating system my web server runs on is (include version): Debian/Raspberry Pi OS

My hosting provider, if applicable, is: self-hosted

I can login to a root shell on my machine (yes or no, or I don't know): yes

I'm using a control panel to manage my site (no, or provide the name and version of the control panel): no

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot): certbot 2.10.0 through Swag

Hello, I have a problem of integration of Swag and Ejabberd (dockerised) in order to fetch LetsEncrypt certificates. I have found no example of Swag/Nginx configuration for Jabber. Jabber wants direct access to port 80 of the host in order to fetch the LE certificate, and so does Swag. As of now, I have to de-activate Swag, route ports 80:2080 to fetch the cert, the reactivate Swag and re-route 80:80. I suppose there is a seamless way either to share the cert fetched by Swag with Jabber, or to have Swag transport the cert dedicated to Jabber. Do you have a simple nginx.conf and/or ejabberd.yml related to that issue ?

I have looked at this tutorial but it is hard to apply to a dockerised context.

Thanks a lot

1 Like

Hello @Eirikr70, welcome to the Let's Encrypt community. :slightly_smiling_face:

There 3 Challenge Types - Let's Encrypt they are:

  1. HTTP-01 challenge the most common; and states "The HTTP-01 challenge can only be done on port 80."
  2. DNS-01 challenge
  3. TLS-ALPN-01

Since you mentioned that I assume the HTTP-01 challenge
Best Practice - Keep Port 80 Open

Try the HTTP-01 challenge with a TOKEN of sometestfile

$ curl -Ii http://cespedes.fr/.well-known/acme-challenge/sometestfile
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Wed, 15 May 2024 23:19:49 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://cespedes.fr/.well-known/acme-challenge/sometestfile

Redirects from HTTP to HTTPS, however HTTP Response Code is HTTP/2 200

$ curl -k -Ii https://cespedes.fr/.well-known/acme-challenge/sometestfile
HTTP/2 200
server: nginx
date: Wed, 15 May 2024 23:19:50 GMT
content-type: text/html
content-length: 1345
last-modified: Wed, 29 Nov 2023 20:33:14 GMT
etag: "6567a00a-541"
permissions-policy: interest-cohort=()
referrer-policy: same-origin
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-ua-compatible: IE=Edge
x-xss-protection: 1; mode=block
strict-transport-security: max-age=63072000; includeSubDomains; preload
accept-ranges: bytes

Well let try again, who knows you might have the token sometestfile;
but I highly doubt you would have a token of vtZvFj5QW5uK5yn7CJfSYw0wR5JNiVlpNgSR28Tk

$ curl -Ii http://cespedes.fr/.well-known/acme-challenge/vtZvFj5QW5uK5yn7CJfSYw0wR5JNiVlpNgSR28Tk
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Wed, 15 May 2024 23:19:57 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://cespedes.fr/.well-known/acme-challenge/vtZvFj5QW5uK5yn7CJfSYw0wR5JNiVlpNgSR28Tk

And again we redirects from HTTP to HTTPS, however HTTP Response Code is HTTP/2 200
expect to find a HTTP Response Code of 404

$ curl -k -Ii https://cespedes.fr/.well-known/acme-challenge/vtZvFj5QW5uK5yn7CJfSYw0wR5JNiVlpNgSR28Tk
HTTP/2 200
server: nginx
date: Wed, 15 May 2024 23:20:03 GMT
content-type: text/html
content-length: 1345
last-modified: Wed, 29 Nov 2023 20:33:14 GMT
etag: "6567a00a-541"
permissions-policy: interest-cohort=()
referrer-policy: same-origin
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-ua-compatible: IE=Edge
x-xss-protection: 1; mode=block
strict-transport-security: max-age=63072000; includeSubDomains; preload
accept-ranges: bytes

Please show the output of sudo nginx -T ; that is a Capital T

2 Likes

Hello and thanks for you fast response,
The output of sudo docker exec -ti swag nginx -T is huge and it includes all my nginx configuration. I'm not sur I am willing to make it public. I should have specified that my setup is actually running fine. My problem is just that of automating the renewal without having to unplug Swag from port 80, plug Ejabberd, renew, then unplug Ejabberd and plug Swag again. I suppose there is a way for Swag to fetch the certs for Ejabberd.

2 Likes

Kindly wait to see if there are more knowledgeable Let's Encrypt community volunteers willing to assist.

1 Like

That sounds very complicated and I don't know how many people here will be familiar with all those components to suggest an answer to your port 80 problem. Look at the Certbot pre-hook and post-hook. Maybe you could automate stopping / starting the required parts to allow the challenge.

Another option is switching to the DNS Challenge. It looks like you use OVH as your DNS provider and Certbot has a plug-in for that. I do not know if this is compatible with all the other pieces you have. Usually a DNS Challenge is harder to automate but in your case it might be easier. It only uses DNS records to satisfy the challenge and does not interact with any HTTP(S) ports.

See:
https://certbot-dns-ovh.readthedocs.io/en/stable/

2 Likes

Still another option is to use some kind of reverse proxy (nginx itself or traefik are popular options at the moment) to listen on port 80 and forward requests to different localhost services depending on the path of the request. This is a common way to "share a port" with different URL routes going to different backends.

However if you're really running Certbot successfully for the Swag part, those files exist at predictable locations on disk and you could presumably configure Jabber to read it. If you need to inform Jabber when the new certificate are available, there is a Certbot option called --renew-hook which can be used to run arbitrary commands whenever a certificate is successfully renewed (although if everything is thoroughly containerized with Docker, this may require a little additional thought in order to successfully send notifications from one container to another).

2 Likes