Automated TLS certificate renewal and credential bundle packaging for LoRaWAN infrastructure.
Works alongside LoRaWAN CUPS server to keep CUPS and LNS servers supplied with fresh certificates and gateway credential bundles.
This tool manages the full certificate lifecycle for a LoRaWAN stack running behind load-balanced servers. It handles three renewal flows:
- CUPS certificate — Generates a new TLS key and certificate, deploys them to all droplets behind the CUPS load balancer, and restarts the CUPS server (
lorawan-cups-server). - LNS certificate — Same flow for the LNS (LoRaWAN Network Server), deploying to all droplets behind the LNS load balancer and restarting ChirpStack.
- Device credential bundle — Generates a new
tc_cred.bin(trust chain + cert + key in DER format) and uploads it to S3-compatible object storage, wherelorawan-cups-servercan retrieve it for gateway provisioning.
All certificates are signed by your own Certificate Authority (CA). You manage the CA material and supply it via environment variables.
index.sh
├── cups-cert-renew.sh # Renews CUPS server TLS cert, deploys to droplets, uploads cups_cred.bin
└── tc-cert-renew.sh # Renews LNS server TLS cert, deploys to droplets, uploads tc_cred.bin
Each script:
- Generates an EC P-256 private key and CSR
- Signs the certificate with your CA
- Fetches the droplet IPs behind the target load balancer via the DigitalOcean API
- Deploys the new cert and key to each droplet over SSH/SCP
- Restarts the target service via
docker-compose - Converts the certificates to DER format, concatenates them into a binary bundle, and uploads to S3-compatible storage using AWS CLI
- OpenSSL — for key, CSR, and certificate generation
- curl + jq — for DigitalOcean API calls
- SSH access — key-based access to your server droplets
- AWS CLI v2 — for uploading credential bundles to S3-compatible storage
- DigitalOcean API token — with read access to load balancers and droplets
- Your own CA certificate and key
sudo apt update && sudo apt install -y unzip curl
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install-
Clone the repository:
git clone https://github.com/nxtgrid/lorawan-cert-renewer.git cd lorawan-cert-renewer -
Create your
.envfile based on.env.example:cp .env.example .env
Fill in all required values (see Environment Variables below).
-
Place your CA files on the host running this tool, and set
CA_CRT_PATHandCA_KEY_PATHin.envto their absolute paths. -
Configure AWS CLI with a named profile matching
SPACES_PROFILEfor S3-compatible storage access:aws configure --profile your-spaces-profile
-
Run the renewal:
bash index.sh
All configuration is done via a .env file. See .env.example for the full list.
| Variable | Description |
|---|---|
DO_API_TOKEN |
DigitalOcean API token (read access to load balancers and droplets) |
CUPS_LOAD_BALANCER_ID |
ID of the DigitalOcean load balancer fronting the CUPS servers |
LNS_LOAD_BALANCER_ID |
ID of the DigitalOcean load balancer fronting the LNS servers |
SSH_USER |
SSH username for connecting to droplets |
SSH_KEY_PATH |
Path to the SSH private key used for droplet access |
REMOTE_PATH |
Absolute path on the remote droplet where cert files are placed |
CN |
Common Name for the generated certificate (typically your server hostname) |
CUPS_CERT_NAME |
Base filename for the CUPS certificate (e.g. cups) |
LNS_CERT_NAME |
Base filename for the LNS certificate (e.g. lns) |
CA_CRT_PATH |
Absolute path to your CA certificate (PEM) |
CA_KEY_PATH |
Absolute path to your CA private key (PEM) |
CUPS_SERVER_DIR |
Absolute path on the CUPS droplet where docker-compose.yml lives |
LNS_SERVER_DIR |
Absolute path on the LNS droplet where docker-compose.yml lives |
SPACES_REGION |
Region of your S3-compatible storage (e.g. ams3) |
SPACES_BUCKET |
Bucket name in your S3-compatible storage |
SPACES_PROFILE |
AWS CLI named profile to use for storage access |
| File | Description |
|---|---|
cups_cred.bin |
DER-encoded bundle (CA trust + CUPS cert + CUPS key) uploaded to <bucket>/cups/cups_cred.bin |
tc_cred.bin |
DER-encoded bundle (CA trust + LNS cert + LNS key) uploaded to <bucket>/cups/tc_cred.bin |
These files are consumed by lorawan-cups-server to provision gateways.
.
├── index.sh # Entry point: runs both renewal scripts sequentially
├── cups-cert-renew.sh # CUPS certificate renewal and credential bundle upload
├── tc-cert-renew.sh # LNS certificate renewal and credential bundle upload
├── .env.example # Template for required environment variables
├── certs/ # Working directory for certificate files (gitignored)
└── tmp/ # Temporary build files (gitignored)
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.