Skip to content

nxtgrid/lorawan-cups-server

Repository files navigation

LoRaWAN CUPS Server

A minimal, production-ready CUPS (Configuration and Update Server) implementation using Fastify and TypeScript.
This server parses raw binary requests and responds per the Semtech CUPS binary protocol, dynamically generating and serving gateway credentials, and storing them in S3-compatible object storage.


System Context

This server is one half of a two-part LoRaWAN credential management system:

  • lorawan-cups-server (this repo) — the CUPS server that gateways connect to in order to receive updated credentials and configuration.
  • lorawan-cert-renewer — the companion tool that periodically renews TLS certificates, deploys them to this server, and uploads fresh credential bundles to S3.

lorawan-cert-renewer is responsible for keeping the certificates and S3 credential bundles that this server depends on up to date.


Features

  • CUPS Binary Protocol: Handles /update-info POST requests per Semtech's CUPS specification.
  • Dynamic Credential Generation: Generates gateway-specific credential bundles (CA, client cert, private key) on demand using OpenSSL.
  • S3 Integration: Stores and retrieves credential bundles from S3-compatible storage.
  • HTTPS by Default: Uses provided certificates for secure communication.
  • TypeScript & Modern Tooling: Linting, type-checking, and pre-commit hooks for code quality.

Project Structure

.
├── certs/                # Certificates and credential bundles (gitignored except .gitkeep)
├── src/
│   ├── s3.ts             # S3 client and helpers
│   └── utils.ts          # Utility functions (ID parsing, cert generation, etc.)
├── index.ts              # Main Fastify server and CUPS logic
├── package.json
├── README.md
└── ...

Prerequisites

  • Node.js 18+
  • OpenSSL installed and available in your PATH
  • Access to an S3-compatible object storage (e.g., AWS S3, MinIO)
  • Gateway CA and server certificates (see below)

Setup

  1. Install dependencies:

    npm install
  2. Environment variables:

    Create a .env file based on .env.example with at least:

    S3_BUCKET_NAME=your-bucket
    S3_BUCKET_REGION=your-region
    S3_BUCKET_ENDPOINT=https://your-s3-endpoint
    S3_ACCESS_KEY_ID=your-access-key
    S3_SECRET_ACCESS_KEY=your-secret-key
    CERT_PATH=certs
    CERT_HOST_PATH=
    CREDENTIAL_MIN_VALID_DAYS=
    TC_URI=https://your-tc-uri
    CUPS_URI=https://your-cups-uri
    
  3. Certificates:

    • Place your CUPS server key and certificate in the certs/ directory as cups.key and cups.crt.
    • Place your CA key and certificate as ca.key and ca.crt in the same directory.
    • When using Docker, the certs/ directory is mounted from the host. Set CERT_HOST_PATH in your environment to override the host-side path (defaults to ./certs relative to docker-compose.yml).

Usage

Development

npm run dev

Runs the server with ts-node for live TypeScript execution.

Production

npm run build
npm start

Builds to dist/ and runs the compiled JavaScript.


Endpoints

POST /update-info

  • Accepts: application/octet-stream (raw binary)
  • Responds: CUPS binary response with updated credentials and signature

Code Quality

  • Lint: npm run eslint
  • Type Check: npm run check-types
  • Pre-commit: Husky and lint-staged block commits on lint/type errors

Certificates & Credential Bundles

  • The server dynamically generates gateway credential bundles if not found or expiring soon, and stores them in S3.
  • Bundles are stored as binary files in the S3 bucket under the cups/ prefix.
  • The certs/ directory is gitignored except for .gitkeep.

Glossary

TC (Trust Center)

TC stands for Trust Center. In the context of LoRaWAN and this project, the Trust Center is the secure endpoint (often the LNS—LoRaWAN Network Server) that gateways authenticate with using credentials provided by the CUPS server. The CUPS server manages and distributes both CUPS credentials (for itself) and TC credentials (for the Trust Center) to gateways. The TC credential bundle (e.g., tc_cred.bin) contains the certificates and keys required for secure gateway authentication with the Trust Center endpoint.

CUPS (Configuration and Update Server)

CUPS is the Configuration and Update Server. It provides gateways with configuration updates, new credentials, and firmware updates, enabling secure and automated device management in LoRaWAN networks.

LNS (LoRaWAN Network Server)

LNS stands for LoRaWAN Network Server. It is the backend server responsible for managing LoRaWAN network traffic, device sessions, and security. Gateways typically connect to the LNS for data forwarding and authentication.

S3 (Simple Storage Service)

S3 refers to Amazon Simple Storage Service or any S3-compatible object storage. In this project, S3 is used to store and retrieve credential bundles and certificates as binary files.

DER (Distinguished Encoding Rules)

DER is a binary encoding format for cryptographic certificates and keys. It is commonly used for efficient storage and transmission of X.509 certificates and private keys.

PEM (Privacy Enhanced Mail)

PEM is a text-based encoding format for cryptographic certificates and keys, using Base64 with header and footer lines. PEM files are human-readable and commonly used for configuration and transport.

CSR (Certificate Signing Request)

CSR is a Certificate Signing Request. It is a file generated by an entity (such as a gateway) to request a digital certificate from a Certificate Authority (CA), containing the public key and identifying information.

Gateway

A Gateway is a hardware device that bridges LoRaWAN end devices and the network server (LNS). It receives LoRa radio transmissions and forwards them to the backend over IP, and vice versa.


Generating Client Credentials and Bundles (OpenSSL)

To generate client keys, certificate signing requests (CSRs), certificates, and the tc_cred.bin bundle for use with this CUPS server, you can use the following OpenSSL commands. These are useful for understanding or manually creating the credential bundles used by gateways.

1. Generate a new EC private key (P-256)

openssl ecparam -name prime256v1 -genkey -noout -out client.key

2. Generate a certificate signing request (CSR)

Replace 0000000000000000 with your desired Common Name (CN), typically the gateway/router ID (EUI-64).

openssl req -new -key client.key -out client.csr -subj "/CN=0000000000000000"

3. Prepare certificate extensions file

Create a file named cert_ext.cnf with the following content:

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer

4. Sign the CSR with your CA to generate the client certificate

Replace ca.crt and ca.key with your CA certificate and key. Adjust validity days as needed.

openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out client.crt -days 365 -sha256 -extfile cert_ext.cnf -extensions v3_req

5. Convert certificates and key to DER format

openssl x509 -in ca.crt -outform DER -out ca.der
openssl x509 -in client.crt -outform DER -out client.crt.der
openssl ec -in client.key -outform DER -out client.key.der

6. Bundle the credentials for TC (Thing Credential)

Concatenate the CA, client certificate, and client key in DER format to create the binary bundle:

cat ca.der client.crt.der client.key.der > tc_cred.bin

This tc_cred.bin file can then be uploaded to S3 or used directly by the CUPS server as a credential bundle for a gateway.


License

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. See the LICENSE file distributed with this project for full text.


References

About

A minimal, production ready CUPS (Configuration and Update Server) implementation. This server parses raw binary requests and responds per the Semtech CUPS binary protocol, dynamically generating and serving gateway credentials, and storing them in S3-compatible object storage.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors