Skip to content

Latest commit

 

History

History
149 lines (114 loc) · 4.16 KB

File metadata and controls

149 lines (114 loc) · 4.16 KB

Device Agent - TypeScript Version

Overview

This TypeScript device agent is designed for efficient outbound mTLS WebSocket communication with a central server, providing control over multiple USB-to-serial devices on Debian. It supports hot-plug detection, multiple serial sessions, nonce-based replay protection, and CLI access for operators with pubkey-based authentication.

The agent is optimized for low memory usage and high throughput on typical serial rates (e.g., 11500 baud). It can be used for managing serial-connected devices.


Features

  • Outbound mTLS WebSocket: Secure connection to a central server, keeps alive and automatically reconnects with exponential backoff.
  • Auto Serial Discovery: Detects /dev/ttyUSB*, /dev/ttyACM*, /dev/ttyAMA*, etc., dynamically, and reports changes to central.
  • Serial Session Management: Open multiple serial sessions with unique session IDs; streams raw binary to server.
  • Hotplug Handling: Automatically detects USB serial devices being plugged/unplugged, prevents crashes.
  • Replay Protection: Nonce DB with persistence to disk prevents replay attacks.
  • CLI Access: Unix domain socket CLI with pubkey-based operator authentication, supports commands list, open, close, and status.
  • Minimal Memory Footprint: Streams data, no unnecessary buffering.
  • Graceful Shutdown: Closes all sessions on WebSocket drop or process termination.

Dependencies

  • ws - WebSocket client library
  • @serialport/stream and @serialport/bindings-cpp - USB-to-serial support
  • fs-extra - File persistence for nonce DB
  • uuid - Session ID generation
  • Node.js >= 18

Project Structure

agent/
├── src/
│   ├── agent.ts           # Main agent logic
│   ├── serialManager.ts   # Serial session handling and hotplug
│   ├── wsClient.ts        # WebSocket connection and messaging
│   ├── cliServer.ts       # Unix socket CLI
│   ├── utils.ts           # Logging, nonce DB, helpers
│   └── types.ts           # Type definitions
├── package.json
├── tsconfig.json
├── certs/                 # Device and CA certificates
└── data/                  # Persistent storage (nonce DB)

Key TypeScript Concepts

  • Interfaces & Types

    interface SerialSession {
      sessionId: string;
      portPath: string;
      baudRate: number;
      port: SerialPortStream;
      writer: WritableStreamDefaultWriter<Buffer>;
    }
    
    interface CommandMessage {
      cmd: string;
      session_id?: string;
      port?: string;
      baud?: number;
      nonce: string;
      ts: string;
      operator_id?: string;
      signature?: string;
    }
  • Async Iteration for Serial Reads

    async function readSerialData(session: SerialSession) {
      const reader = session.port.readable.getReader();
      try {
        while (true) {
          const { value, done } = await reader.read();
          if (done) break;
          if (value) {
            // send to server
          }
        }
      } finally {
        reader.releaseLock();
      }
    }
  • WebSocket with mTLS

    const ws = new WebSocket(url, {
      cert: fs.readFileSync(certPath),
      key: fs.readFileSync(keyPath),
      ca: fs.readFileSync(caPath),
      perMessageDeflate: false
    });
  • Hotplug Detection

    setInterval(() => {
      const current = discoverDevices();
      const added = current.filter(d => !knownDevices.has(d));
      const removed = Array.from(knownDevices).filter(d => !current.includes(d));
      // update knownDevices and notify central
    }, 2000);
  • CLI Communication

    const client = net.createConnection(SOCKET_PATH);
    client.write(JSON.stringify(signedCommand) + '\n');

Security

  • mTLS for WebSocket communication.
  • Pubkey-based CLI authentication: operators sign requests, agent verifies signatures.
  • Nonce-based replay protection.
  • Permissions: agent runs as serialsvc user, /dev/ttyUSB* assigned via udev rules.

Recommended Build

  • Use tsc to compile TypeScript:
tsc
  • Ensure tsconfig.json has strict types and ES2022 modules.
  • Deploy compiled JS with Node >= 20.