Let’s Encrypt

Using Let’s Encrypt with anything, including FlashMQ, is easy, as long as port 80 is not occupied. But with MQTT, you may want to run unencrypted websockets on port 80. For that, FlashMQ includes the listener directive acme_redirect_url. This page will describe using Let’s Encrypt traditionally, and using this new feature.

Both of these approaches avoid having Nginx in the traffic path, because that causes unnecessary overhead and TCP port restrictions.

Running Certbot on port 80

If you don’t need to bind FlashMQ to port 80, which you would mostly only need if you want unencrypted web sockets, it’s easy to to simply run Certbot in it’s stand-alone mode. No Nginx is required (but still possible if for some reason you want to use it in front of FlashMQ).

Running Certbot is as easy as:

certbot --email "admin@domain.com" --agree-tos --standalone --http-01-port 80 certonly --domain my.domain.com

Then you can add a listener to FlashMQ like:

listen {
  protocol websockets                                                                                                                                                                                                                                                          
  port 443
  fullchain /etc/letsencrypt/live/my.domain.com/fullchain.pem
  privkey /etc/letsencrypt/live/my.domain.com/privkey.pem
}

Certbot will likely already have an auto-renewal set up, but for completeness, you can renew like:

certbot renew --standalone --preferred-challenges http-01 --http-01-port 80 --quiet
systemctl reload flashmq.service

Certbot provides the ability to define post-renewal hooks in /etc/letsencrypt/renewal-hooks/post/, in which you can place the reload command.

Using acme_redirect_url

If FlashMQ is already running on port 80, you can use acme_direct_url to point the ACME verification process somewhere else. Unfortunately, it still has to be port 80, so you’ll have to define a second IP(v6) for the host, or redirect to another host completely. If using the same host, you may also need to proxy the ACME hostname with Nginx to limit the binding to that dedicated IP address.

As an example, you can catch the ACME urls with something like this:

server {
        listen 1.2.3.4:80 default_server;
        listen [1:2:3:4::]:80 default_server;

        root /var/www/html;

        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                try_files $uri $uri/ =404;
        }

        location /.well-known/acme-challenge/ {
            proxy_pass http://127.0.0.1:20081;
            proxy_set_header Host $host;
            auth_basic off;
            allow all;

            add_header Cache-Control "no-cache, no-store";
        }
}

In this example, certbot is expected to listen on port 20081. Apart from that, the way to run it is the same as above.

See the man page for details about acme_redirect_url.