Skip to content

Local MQTT Relay and TLS

The OctoEverywhere plugin's local MQTT relay lets apps on your network share one upstream MQTT connection to a Bambu Lab or Elegoo Centauri Carbon 2 printer. Connect to the computer running the plugin using MQTT 3.1.1 over TCP, with TLS enabled in your client.

For internet access through an App Connection or Shared Connection, use the MQTT over WebSocket proxy. That hosted wss:// endpoint uses OctoEverywhere's HTTPS certificate. The certificate settings on this page apply to the plugin's local TCP relay.

Ports and Authentication

Setting Default behavior
Host The IP address or hostname of the computer running OctoEverywhere
Primary port 1883 Detects plaintext MQTT or TLS separately for each connection
Additional port 8883 Accepts TLS connections only
TLS version TLS 1.2 or newer
MQTT credentials The credentials used by the plugin's upstream printer connection, unless separate relay credentials are configured

For a Bambu LAN connection, the default credentials are username bblp and the printer's access code. For Elegoo CC2, use elegoo and the access code. Bambu cloud connections use cloud credentials, so configure a separate relay login when local apps need a different login. See the relay authentication guide.

TLS and MQTT authentication are independent. Disabling MQTT authentication does not fix a certificate error. Disabling certificate verification in a client also does not disable TLS encryption.

The relay carries MQTT status and commands. Camera streams, file uploads, and FTP/FTPS need their own connections. Keep the local relay on your trusted network; use the hosted WebSocket proxy for remote access.

Automatic Certificates

When no custom certificate is configured, the plugin automatically creates a unique self-signed certificate and private key at startup. No certificate setup is needed to enable TLS, but clients must accept or explicitly trust this certificate.

The files are stored in mqtt-tls alongside the instance's octoeverywhere.conf, or in /data/mqtt-tls inside Docker:

File Use
server.pem Certificate and private key. Keep this file private on the relay.
server.crt Public certificate only. Export this file to clients that need to trust it.

Generated certificates last 365 days. On startup, the plugin renews a certificate within 30 days of expiry, preserving a usable existing key. Renewal is checked at startup; restart long-running installations before expiry. Keep the instance's data directory across updates. Clients that imported or pinned a certificate may need the replacement public certificate after renewal.

Automatic certificate management uses the OpenSSL command-line tool. install.sh installs it as an optional, separate step: installation failure prints a warning and does not stop plugin setup. The official Docker image includes OpenSSL. Loading a valid custom certificate does not require the OpenSSL command-line tool.

Configure the Relay

Edit the existing [mqtt] section of octoeverywhere.conf, then restart the plugin. Docker environment variables override the corresponding saved settings when supplied.

Config key Docker variable Default
enable MQTT_RELAY_ENABLED true
port MQTT_RELAY_PORT 1883
tls_port MQTT_RELAY_TLS_PORT 8883
tls_cert_path MQTT_RELAY_TLS_CERT_PATH Empty; use automatic credentials
tls_key_path MQTT_RELAY_TLS_KEY_PATH Empty; use the key in the certificate PEM, or automatic credentials

Setting tls_port = 0 disables the additional TLS-only listener; TLS detection on the primary port remains enabled. Setting both ports to the same value creates one listener that accepts both plaintext and TLS.

For Docker Compose, publish the required ports on your existing service:

ports:
  - "1883:1883"
  - "8883:8883"

Preserve the printer environment settings and /data mount, then run docker compose up -d. Existing containers must be recreated to apply new port mappings. For another relay on the same host, use distinct host ports, such as 1884:1883 and 8884:8883, and a separate data directory. Apps fixed to port 8883 need a separate host IP or computer for each relay.

Use Your Own Certificate

Provide a PEM certificate chain with the server certificate first, followed by any intermediate certificates, and its matching unencrypted private key. The certificate's Subject Alternative Name (SAN) must cover the hostname or IP your app uses to reach the OctoEverywhere host. The app must trust its issuer. A private CA's signing key belongs outside the relay.

For standalone Linux, use absolute paths readable by the plugin's service user, and restrict access to the private key:

[mqtt]
tls_cert_path = /home/pi/oe-mqtt-certs/fullchain.pem
tls_key_path = /home/pi/oe-mqtt-certs/privkey.pem

Replace the example paths with your own and restart the plugin. For Docker Compose, merge these settings into the existing service:

environment:
  - MQTT_RELAY_TLS_CERT_PATH=/certs/fullchain.pem
  - MQTT_RELAY_TLS_KEY_PATH=/certs/privkey.pem
volumes:
  - ./data:/data
  - ./certs:/certs:ro

Keep your existing data mount and printer settings. Put the certificate and key in the host's ./certs directory and make them readable by the container's application user. The environment variables use paths inside the container. Run docker compose up -d to apply the settings.

For a combined PEM containing both the certificate chain and private key, set only the certificate path and clear the separate key path. A key path without a certificate path is invalid.

The plugin uses configured custom credentials in preference to automatic credentials. It never overwrites or renews custom certificates. Manage renewal yourself and restart the plugin after replacing the files. Invalid custom credentials cause TLS connections to fail; the plugin does not generate a replacement for them.

To return to automatic certificates, clear both saved path settings and restart. In Docker, also remove the environment overrides; removing an environment variable alone does not clear the value already saved in octoeverywhere.conf.

Export and Trust the Generated Certificate

Start the plugin with automatic certificates enabled, then copy only server.crt to the computer or container running your client. For Docker Compose, replace the service name if yours differs:

docker compose cp octoeverywhere-connect:/data/mqtt-tls/server.crt ./octoeverywhere-mqtt.crt

For standalone Linux, fetch it over SSH from the client computer. Replace the user, host, and instance directory with your own:

scp pi@OE_HOST:.octoeverywhere-bambu/mqtt-tls/server.crt ./octoeverywhere-mqtt.crt

The credential directory is private, so the copy may need help from the plugin's owner or administrator. Do not distribute server.pem, which contains the private key. If custom credentials are configured, distribute their public certificate or issuing CA instead; the automatic server.crt is not updated to match them.

Inspect the exported certificate on a computer with OpenSSL installed:

openssl x509 -in ./octoeverywhere-mqtt.crt -noout -fingerprint -sha256 -dates
openssl x509 -in ./octoeverywhere-mqtt.crt -noout -text

Confirm its origin and check Subject Alternative Name in the output. Automatic certificates cover localhost, loopback addresses, the hostname visible to the plugin, and a specific bind address supplied at generation. The default wildcard bind does not add your LAN IP; Docker's hostname may be the container hostname. Changing the bind address does not immediately regenerate an existing certificate. Importing trust does not fix a hostname or IP mismatch: use a covered, reachable address or supply your own certificate with the correct SAN.

Import octoeverywhere-mqtt.crt using your client's trusted-certificate setting if it supports self-signed server certificates, and keep TLS and verification enabled. For apps using the operating system's trust store, follow the Windows, macOS, and Linux trust-store instructions. Apply trust on the client machine and under the account running the app. Apps with their own bundles or containers may ignore the system store. The generated certificate is a server certificate, not a CA; apps requiring CA-issued certificates need the custom-certificate setup.

To check TLS independently of MQTT authentication, use a hostname included in the SAN:

openssl s_client -connect oe-host.example:8883 -servername oe-host.example -CAfile ./octoeverywhere-mqtt.crt -verify_hostname oe-host.example -verify_return_error

Replace the host and port as needed. When connecting by IP, use -verify_ip YOUR_IP instead of -verify_hostname, and omit -servername. Look for Verify return code: 0 (ok), then press Ctrl+C. This checks TLS only; the relay may close the connection when no MQTT CONNECT packet follows.

TLS Failures and Recovery

If OpenSSL is missing, generation fails, or certificate files cannot be loaded, the plugin logs TLS setup failed with the cause and continues running. TLS requests on the primary port are rejected and logged. The configured TLS-only listener also rejects and logs connections, including clients that have not sent any bytes. Plain MQTT on the primary port remains usable. TLS connections never fall back to plaintext.

Install the OS package openssl (openssl-util on OpenWrt), fix the certificate files or permissions, or configure valid custom credentials. Restart the plugin after fixing the problem to retry TLS setup. A successful install.sh run does not guarantee that optional OpenSSL installation succeeded.

If the additional TLS port cannot bind, check for another broker or plugin instance using it. The primary port remains available, including TLS when certificate setup succeeded. Docker host port conflicts must be resolved in the container's port mappings.

The older error CONNECT fixed header flags must be 0x0, got 0x6 usually means a TLS client reached a plaintext-only relay. Update and restart the plugin to use TLS detection. Changing MQTT credentials cannot resolve that transport mismatch.