Secure Bare-Metal ThingsBoard with HAProxy and Let’s Encrypt

This guide applies to bare-metal setups only. If you’re running ThingsBoard on Kubernetes, refer to your ingress controller (e.g. Traefik or NGINX) for SSL termination.

Although ThingsBoard officially supports SSL for both HTTP and MQTT, I chose not to configure SSL directly inside ThingsBoard.

The reason is certificate renewal: Let’s Encrypt certs expire every 90 days. If SSL is handled by ThingsBoard itself, each renewal would require a server restart, causing downtime and potential telemetry loss from connected IoT devices.


Pre-requisite

Install ThingsBoard CE 4.0.1 on bare metal first:

Install ThingsBoard CE 4.0.1 on Bare-Metal Ubuntu 24.04

This sets up:

  • ThingsBoard HTTP endpoint: localhost:8080
  • MQTT broker: localhost:1883

What You’ll Achieve

ProtocolPublic PortSSL TerminatedForwarded To
HTTPS443HAProxy127.0.0.1:8080
MQTTS8883HAProxy127.0.0.1:1883

Domain: thingsboard.maksonlee.com (managed in Cloudflare)


  1. Install HAProxy + Certbot
sudo add-apt-repository ppa:vbernat/haproxy-3.0 -y
sudo apt-get install haproxy=3.0.\*
sudo apt install certbot python3-certbot-dns-cloudflare -y

  1. Create Cloudflare API Token
  • Go to: Cloudflare API Tokens
  • Use the “Edit zone DNS” template
  • Restrict it to your domain
  • Save the token securely

Create the credential file:

mkdir -p ~/.secrets/certbot
nano ~/.secrets/certbot/cloudflare.ini
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN
chmod 600 ~/.secrets/certbot/cloudflare.ini

  1. Issue the Certificate
sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \
  -d thingsboard.maksonlee.com

  1. Prepare Cert for HAProxy
sudo mkdir -p /etc/haproxy/certs

sudo bash -c 'cat /etc/letsencrypt/live/thingsboard.maksonlee.com/fullchain.pem \
  /etc/letsencrypt/live/thingsboard.maksonlee.com/privkey.pem \
  > /etc/haproxy/certs/thingsboard.maksonlee.com.pem'

sudo chmod 600 /etc/haproxy/certs/thingsboard.maksonlee.com.pem

  1. Configure HAProxy

Edit /etc/haproxy/haproxy.cfg, add following

# HTTPS (443 -> ThingsBoard HTTP 8080)
frontend https-in
        bind *:443 ssl crt /etc/haproxy/certs/thingsboard.maksonlee.com.pem
        mode http
        option httplog
        default_backend thingsboard-http

backend thingsboard-http
        mode http
        server tb-ui 127.0.0.1:8080 check

# MQTTS (8883 -> MQTT 1883)
frontend mqtts-in
        bind *:8883 ssl crt /etc/haproxy/certs/thingsboard.maksonlee.com.pem
        mode tcp
        option tcplog
        default_backend thingsboard-mqtt

backend thingsboard-mqtt
        mode tcp
        server tb-mqtt 127.0.0.1:1883 check

  1. Start HAProxy
sudo systemctl restart haproxy

Verify:

  • https://thingsboard.maksonlee.com
  • mqtts://thingsboard.maksonlee.com:8883 (IoT devices)

  1. Auto-Renew Certificate and Reload HAProxy

Create deploy hook:

sudo vi /etc/letsencrypt/renewal-hooks/deploy/haproxy-reload.sh
#!/bin/bash
DOMAIN="thingsboard.maksonlee.com"
cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem \
    /etc/letsencrypt/live/$DOMAIN/privkey.pem \
    > /etc/haproxy/certs/$DOMAIN.pem
chmod 600 /etc/haproxy/certs/$DOMAIN.pem
systemctl reload haproxy
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/haproxy-reload.sh

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top