Skip to content

Security Best Practices

This section discusses security considerations and best practices when using the Energy Manager IoT library.

Overview

Security is a critical aspect of any IoT system, especially one that manages device control and energy consumption. The Energy Manager IoT library provides several security features, but proper implementation is essential to ensure a secure deployment.

Connection Security

Using Secure MQTT Connections

Always use secure MQTT connections (mqtts://) in production environments:

await manager.connect('mqtts://broker.example.com:8883', {
  // TLS options
  rejectUnauthorized: true, // Verify server certificate
  ca: fs.readFileSync('ca-cert.pem') // Certificate Authority
});

TLS Certificate Verification

Properly validate server certificates to prevent man-in-the-middle attacks:

await manager.connect('mqtts://broker.example.com:8883', {
  rejectUnauthorized: true, // Always set to true in production
  ca: fs.readFileSync('ca-cert.pem'), // Custom CA if necessary
  cert: fs.readFileSync('client-cert.pem'), // Client certificate
  key: fs.readFileSync('client-key.pem') // Client private key
});

Private Key Security

Protect client private keys carefully and never include them in public code repositories.

Authentication

Username and Password Authentication

When username and password authentication is used, ensure strong passwords:

await manager.connect('mqtts://broker.example.com:8883', {
  username: 'device-manager',
  password: 'strong-unique-password'
});

Password Management

Use environment variables or secure credential management systems to store passwords:

await manager.connect('mqtts://broker.example.com:8883', {
  username: process.env.MQTT_USERNAME,
  password: process.env.MQTT_PASSWORD
});

Client Certificate Authentication

For higher security, use client certificate authentication:

await manager.connect('mqtts://broker.example.com:8883', {
  cert: fs.readFileSync('client-cert.pem'),
  key: fs.readFileSync('client-key.pem'),
  rejectUnauthorized: true
});

Access Control

MQTT Topic Structure

Design your topic structure with security in mind:

  • Use the topic prefix to create logical separation
  • Limit subscription patterns to only what's needed
  • Consider using topic hierarchies for access control
const manager = new EnergyManager({
  topicPrefix: 'org/division/facility/floor1/'
});

Broker-Level Access Control

Configure MQTT broker access control lists (ACLs) to restrict:

  1. Which clients can publish to which topics
  2. Which clients can subscribe to which topics
  3. Whether clients can publish retained messages

Command Security

Command Validation

Always validate commands before processing:

if (command.type === CommandType.SET_REPORTING) {
  // Validate command parameters
  if (!command.payload ||
      typeof command.payload.interval !== 'number' ||
      command.payload.interval < 10 ||
      command.payload.interval > 3600) {
    throw new Error('Invalid reporting interval');
  }

  // Process valid command
}

Command Authentication

Consider implementing a command authentication mechanism:

function verifyCommandAuthenticity(command) {
  // Implement verification logic:
  // - Check command signature
  // - Verify timestamp is recent (prevent replay attacks)
  // - Validate authorization for specific command
  if (!isValidSignature(command) || isCommandExpired(command)) {
    throw new SecurityError('Invalid or expired command');
  }
}

Device Management Security

Device Registration

Implement secure device registration:

// Verify device identity before registration
function registerNewDevice(deviceId, deviceSecret) {
  // Verify device identity with backend system
  if (authenticateDevice(deviceId, deviceSecret)) {
    manager.registerDevice(deviceId, deviceName, deviceType);
    return true;
  }
  return false;
}

Group-Based Security

Use groups to implement logical security boundaries:

// Create groups with different security levels
manager.createGroup('admin-devices');
manager.createGroup('user-devices');

// Limit sensitive commands to admin devices
async function sendAdminCommand(command, payload) {
  // Only send to admin devices
  await manager.sendCommandToGroup('admin-devices', command, payload);
}

Network Security

Network Segmentation

Place the MQTT broker in an appropriate network segment:

  • Use firewalls to restrict access to the broker
  • Consider using VLANs or network segmentation
  • Implement IP filtering if supported by your broker

Port Security

Use standard MQTT ports but restrict access:

  • Port 1883: Standard MQTT (only use in secure networks)
  • Port 8883: MQTT over TLS (recommended for external connections)
  • Port 443: MQTT over WebSockets with TLS (for web clients)

Operational Security

Logging and Monitoring

Use the logging system to monitor for security events:

// Set up monitoring for security-related events
manager.on('error', (error) => {
  if (error.type === ErrorType.AUTHENTICATION) {
    securityLogger.warn('Authentication error detected', error);
    alertSecurityTeam(error);
  }
});

Secure Error Handling

Be careful about error information being exposed:

try {
  await manager.sendCommand('device-id', CommandType.RESTART);
} catch (error) {
  // Log full error details internally
  logger.error('Command failed', error);

  // Return limited information to clients
  return {
    success: false,
    message: 'Command failed to execute',
    errorCode: error instanceof EnergyManagerError ? error.code : 'UNKNOWN'
  };
}

Implementation Checklist

Use this checklist to ensure secure implementation:

  • Use TLS/SSL encryption (mqtts://) for all connections
  • Implement strong authentication (certificates preferred)
  • Configure proper access control at the broker level
  • Use unique, random client IDs
  • Validate all commands and payloads
  • Implement proper error handling
  • Use secure default configurations
  • Enable logging for security auditing
  • Keep the library and dependencies updated
  • Protect credentials and certificates

Advanced Security Considerations

Penetration Testing

Regularly test your MQTT infrastructure for security vulnerabilities:

  • Test MQTT broker configuration
  • Verify TLS implementation
  • Attempt unauthorized access
  • Test command injection

Certificate Management

Implement proper certificate lifecycle management:

  • Create a process for certificate rotation
  • Monitor certificate expiration
  • Implement certificate revocation

Rate Limiting

Consider implementing rate limiting for commands:

const commandTracking = new Map();

function checkCommandRateLimit(deviceId) {
  const now = Date.now();
  const history = commandTracking.get(deviceId) || [];

  // Only keep commands from last 60 seconds
  const recentCommands = history.filter(time => now - time < 60000);

  // Update history
  commandTracking.set(deviceId, [...recentCommands, now]);

  // Check if too many commands
  if (recentCommands.length >= 10) {
    throw new EnergyManagerError(
      'Rate limit exceeded',
      ErrorType.RATE_LIMIT_EXCEEDED,
      { deviceId, commandCount: recentCommands.length },
      ErrorSeverity.MEDIUM
    );
  }
}

// Use before sending commands
async function secureCommand(deviceId, command, payload) {
  checkCommandRateLimit(deviceId);
  await manager.sendCommand(deviceId, command, payload);
}

References

  1. MQTT Security Fundamentals
  2. OWASP IoT Security Guidance
  3. NIST Guide to Industrial Control Systems Security