DEV Community

Smrati
Smrati

Posted on

Securing IoT asset tracking systems: TLS, device auth, and certificate management

IoT asset tracking tutorials tend to focus on connecting sensors and getting data streaming. Very few of them tell you how to ensure that the data comes from your own devices and no one else can intercept that data along the way. Here is the complete cybersecurity stack: TLS, mutual authentication, and certificate lifecycle management.

Four actual attacks that you are protecting yourself against

πŸ•΅οΈ Eavesdropping

Capture of location and sensor data while in transit β€” particularly vulnerable on cellular or open WiFi networks

πŸ‘» Spoofing

Malicious device inserting location data into your asset tracking system through the magic of spoofing

πŸ”“ Broker hijack

Untrusted subscriber client connecting to your MQTT topics and consuming asset telemetry

♻️ Replay attack

Attacker reusing a valid packet to insert old or modified location data

Layer 1 – TLS in transit

All bytes sent from your IoT devices must be encrypted. That means, in the case of MQTT, MQTTS on port 8883 – MQTT over TLS. Never unencrypted MQTT on port 1883 in production – that’s okay just for development.

Mosquitto Configuration to Use TLS:

# /etc/mosquitto/mosquitto.conf
listener 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
require_certificate true    # enforce mutual TLS
tls_version tlsv1.3        # TLS 1.2 minimum, 1.3 preferred

# Disable unencrypted port entirely in production
# listener 1883 β€” DO NOT enable this
Enter fullscreen mode Exit fullscreen mode

From the client side, the connection uses the CA certificate to verify the identity of the broker:

// Node.js device client with TLS
const mqtt = require('mqtt')
const fs = require('fs')

const client = mqtt.connect('mqtts://broker.yourdomain.com:8883', {
  ca: fs.readFileSync('/certs/ca.crt'),
  cert: fs.readFileSync('/certs/device.crt'),  // device cert
  key: fs.readFileSync('/certs/device.key'),  // device private key
  rejectUnauthorized: true                    // never disable this
})
Enter fullscreen mode Exit fullscreen mode

This is always a no-no: "rejectUnauthorized: false". This means that you're not verifying any certificates at all. Your device will happily connect to anything – even the man-in-the-middle. Definitely not something you want to do in production.

Layer 2 – mTLS

The standard TLS verifies the server, but mutual TLS (mTLS) verifies both sides. The server verifies the client and vice versa, which means there’s no way someone can spoof it – only your devices with a verified certificate can connect.

To generate unique certificates for each device using OpenSSL:

# Step 1 β€” Create your Certificate Authority (once)
openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt \
  -subj "/CN=AssetTrackPro-CA"

# Step 2 β€” Generate a keypair for each device
openssl genrsa -out device-7821.key 2048
openssl req -new -key device-7821.key -out device-7821.csr \
  -subj "/CN=device-7821/O=fleet-north"

# Step 3 β€” Sign the device CSR with your CA
openssl x509 -req -days 365 \
  -in device-7821.csr \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out device-7821.crt
Enter fullscreen mode Exit fullscreen mode

CN field tip: Encode the device ID in the CN field of the certificate (CN=device-7821). The broker can then read this value from the client on connection and use it to enforce what topics the device may publish to β€” no additional authentication layer required.

Layer 3 β€” MQTT topic authorization

While mTLS ensures authenticity, it does not protect against compromised clients publishing to another client's topics. Enforce topic authorization per device using the Mosquitto ACL plugin:

# /etc/mosquitto/acl.conf
# Each device can only publish to its own topic
# %c = client ID extracted from CN field

pattern publish assets/%c/telemetry
pattern publish assets/%c/status

# Backend services get read access to all topics
user backend-service
topic read assets/#

# No device can subscribe to other devices' data
pattern deny subscribe assets/+/telemetry
Enter fullscreen mode Exit fullscreen mode

Layer 4 β€” Certificate renewal

Certificates have expiry dates. The IoT devices must have an automated method of updating certificates when they expire without human interaction. The following is a pattern for certificate auto-renewal:

// Device checks cert expiry on boot and renews if < 30 days left
async function checkAndRenewCert() {
  const cert = fs.readFileSync('/certs/device.crt')
  const expiry = getCertExpiry(cert)  // parse NotAfter field
  const daysLeft = (expiry - Date.now()) / (1000 * 86400)

  if (daysLeft < 30) {
    // Generate new CSR and request signing from backend
    const newCsr = await generateCSR(deviceId)
    const response = await fetch('https://api.yourdomain.com/cert/renew', {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${deviceToken}` },
      body: JSON.stringify({ csr: newCsr, deviceId })
    })
    const { cert: newCert } = await response.json()
    fs.writeFileSync('/certs/device.crt', newCert)
    scheduleRestart()  // reconnect with new cert
  }
}
Enter fullscreen mode Exit fullscreen mode

Security checklist

βœ“ MQTTS on 8883 β€” TLS 1.3 required, 1883 blocked in production mode
βœ“ Mutual TLS β€” device certificate is validated by the broker and vice versa
βœ“ Per-device certificates β€” each device has its own certificate with common name=device_id
βœ“ Topic-based access control β€” devices limited to publishing to their own topics
βœ“ Automatic certificate rotation β€” certificates renew automatically before they expire without human interaction
βœ“ Certificate revocation mechanismsβ€”CRL or OCSP configured to handle certificate compromises for devices
βœ— Never store private key within the device firmware code – use secure element or encryption
βœ— Never re-use certificates between devices – if one gets compromised, you lose only one device

Recommended stack

  1. Mosquitto + TLS
  2. OpenSSL / CFSSL
  3. Let's Encrypt (certificate broker)
  4. Hashicorp Vault (certificate authority)
  5. Node.js / Python

When considering production-level certificate management, the Hashicorp Vault PKI secrets engine can definitely be worth the hassle since it enables automatic CSR signing, expiry enforcement, and proper handling of revocation. If you’re working with a smaller deployment, self-hosting an OpenSSL certificate authority with a certificate renewal API will do nicely.

AssetTrackPro's communication between devices utilizes mTLS, per device certificates, and renewal of those certificates across all installations – keeping all of your data safe and encrypted.
Learn More β†’

Looking for a secure IoT tracking solution? AssetTrackPro takes care of device authentication, TLS, and certificate management – enabling you to launch fast while staying secure.

Try AssetTrackPro β†’

Top comments (0)