SSL/TLS for multi-container project

I’m using an RPi4 with Mosquitto, Node-Red, Influxdb, and Grafana to create a quick and easy way to deploy an IoT Gateway with a built-in dashboard.

I’ve successfully got each section running and passing data by using the Balena-sense project as a reference and adding the Balena-Node-Red. My next step is to ensure that each section is properly secured and I plan to enable TLS for all 4 containers.

I want to create the certificates on the first boot and store them in the persistent data. I will also need to download them to my pc in order to connect as a client to the MQTT broker.

Unfortunately, I have minimal experience using LetsEncrypt or similar services and have never used them on Balena. Is there a recommended method for creating the Certificates?

Thanks.

Interesting approach! I was reading how to do this, and found a detailed guide here - https://www.digitalocean.com/community/tutorials/how-to-secure-a-containerized-node-js-application-with-nginx-let-s-encrypt-and-docker-compose

Are you also using the public URL feature for balenaCloud along with this? Or is this just for internal communication between services?

Thanks for the link. I’ll give it a shot.

Currently, I am not using the public URL feature but I intend to use it in the future to give me remote access to the Grafana dashboard and the Node-Red interface. Are there any other steps needed to secure it for the public URL?

Thanks

Hey there, you can see an example repo here: https://github.com/balena-io-playground/balena-nginx on how to generate a certificate and use nginx as a reverse proxy. Aside from generating a certificate for your domain, you’ll need to protect your services using some form of authentication, as the public URL is public (as the name suggest :)) by default and we don’t provide any sort of authorization out of the box.

Thanks for the message. I’ll take a look at that repo.

For adding TLS for purely internal services - e.g without having the public URL turned on - will I need to use a domain name or can I use the IP address of the device?

I’m trying to make this as scale-able as possible so I don’t want to have to use a different domain name for each device.

I currently have set up the password authentication for both Node-Red and Grafana, and am in the process of ensuring that Influxdb is also secured by password.

What’s the reason for you needing a certificate for the internal services? If you need that, you can potentially create self-signed certificates, not sure if that would work for you though. You can check the let’s encrypt documentation and the repo I linked for more information, that should be a good start to figure out how to do start, please reach out if you’re still stuck :slight_smile:

I will look into creating self signed certificates, as well as creating them with the cert bot and a domain. I am not 100% sure if I will need the public URL on, so self signed may be the best option. I am only using them to ensure that my services are encrypted and secure, as the devices may be used on non-secure networks.

Thanks for pointing me in the right direction. :slight_smile:

You might want to consider traefik. Here is an example for balena: https://github.com/klutchell/balena-traefik

For internal certs you will need DNS let’s encrypt verification.

Another (more dynamic) traefik config example (it has other dependencies - e.g. hashi vault for secret management): https://github.com/izer-xyz/beast/blob/main/proxZ/traefik.yml.tpl

+1 for traefik, best proxy ever

This is our basic setup for this

Thanks for the replies, I’ve seen Traefik before but haven’t used it personally. I’ll give it a try as well.

Cheers.