Deployment guide

ChirpStack

Overview

This AMI runs ChirpStack 4.19, an open-source LoRaWAN Network Server. ChirpStack provides the complete LoRaWAN stack in a single server: the network server and application server, multi-tenant device and gateway management, device profiles, adaptive data rate, downlink queueing, MQTT and HTTP integrations, firmware update over the air (FUOTA) and a full gRPC and gRPC web API. You drive it all from a modern web console. ChirpStack is the control plane that your LoRa gateways and sensors connect to.

SecureAnyCloud delivers ChirpStack fully installed and reverse-proxied behind nginx over HTTPS. PostgreSQL 16, Redis 7, the Mosquitto MQTT broker and the ChirpStack Gateway Bridge are already configured and managed by systemd, so a complete LoRaWAN network server is operational within minutes of launch.

What you get:

  • ChirpStack 4.19 installed from the official ChirpStack apt repository as native systemd services
  • PostgreSQL 16 for application and device data on a dedicated, independently resizable EBS volume, and Redis 7 for device session and device queue state
  • The Mosquitto 2 MQTT broker, bound to loopback and not exposed to the network
  • The ChirpStack Gateway Bridge, which lets real LoRa gateways that use the Semtech UDP packet forwarder or BasicStation connect over UDP 1700
  • The ChirpStack server bound to 127.0.0.1:8080 and fronted by nginx on port 443 with a per-instance self-signed TLS certificate
  • Six systemd units enabled and active: postgresql, redis-server, mosquitto, chirpstack, chirpstack-gateway-bridge and nginx
  • Secure by default: no admin account and no shared secret ship in the image. ChirpStack's well-known default admin / admin login is rotated to a unique per-instance password on first boot. The database password, the API/JWT signing secret and the TLS certificate are also generated on first boot, and all of them are written to a root-only file
  • A fully patched Ubuntu 24.04 LTS base with unattended security upgrades enabled
  • 24/7 SecureAnyCloud support

Connecting to your instance

Connect over SSH on port 22 as the default login user for the operating system variant you launched. Use the key pair you selected at launch.

OS variant SSH login user Example

Ubuntu 24.04 LTS ubuntu ssh -i your-key.pem ubuntu@<instance-public-ip>

The image is the LoRaWAN network and application server, not the radio hardware. A working LoRaWAN deployment also needs your own LoRa gateways pointed at this server (see Step 8).

Prerequisites

You need an AWS account, an EC2 key pair, and a VPC with a subnet in the target region.

m5.large is the recommended instance type for evaluation and small networks. For large fleets, choose a type with more memory.

Configure the security group to allow inbound 22/tcp from your management network and 443/tcp for the web console. Port 80/tcp is optional, because it only issues a redirect to HTTPS. If you will connect real LoRa gateways that use the Semtech UDP packet forwarder, also allow 1700/udp from your gateways.

Step 1 - Launch the AMI

Subscribe to the listing in AWS Marketplace, choose Continue to Launch, and launch the AMI in your VPC. Select the m5.large instance type (or larger), your key pair, and a security group that allows inbound 22/tcp and 443/tcp, plus 1700/udp if you will connect gateways. You can also launch from the CLI:

aws ec2 run-instances \
  --image-id <ami-id> \
  --instance-type m5.large \
  --key-name your-key \
  --security-group-ids <sg-id> \
  --subnet-id <subnet-id> \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=chirpstack}]'

Wait about 60 seconds after the instance reaches the running state for first-boot credential generation to complete.

Step 2 - Retrieve the per-instance admin password

Nothing secret is baked into the image. ChirpStack normally ships with a default admin / admin console login, but on this image that default is rotated away on the first boot.

A one-shot service (chirpstack-firstboot.service) generates a fresh database password, a fresh API/JWT signing secret, a fresh TLS certificate and a unique administrator password. All of them are unique to your instance. The service writes them to /root/chirpstack-credentials.txt, which only root can read. SSH in and read them:

$
sudo cat /root/chirpstack-credentials.txt
# ChirpStack - generated on first boot by chirpstack-firstboot.service.
# These credentials are unique to THIS VM. Store them somewhere safe. chirpstack.url=https://44.208.163.188/ chirpstack.admin.user=admin chirpstack.admin.pass=Xq7pR2mK9wU4nZ8vB3hL6yD1
# Canonical keys consumed by the sac smoke verifier + guide substitution: CHIRPSTACK_ADMIN_PASSWORD=<set-at-first-boot> CHIRPSTACK_URL=https://44.208.163.188/

The rotation service is ordered before the ChirpStack server and the nginx console, so the console becomes reachable only after the default password has been replaced. The username stays admin. The password above is an example, and your instance has its own unique value.

Step 3 - Confirm the services are running

Check that PostgreSQL, Redis, Mosquitto, the ChirpStack server, the gateway bridge and nginx are all active:

sudo systemctl is-active postgresql redis-server mosquitto chirpstack chirpstack-gateway-bridge nginx

All six report active. The ChirpStack API and the MQTT broker bind to loopback only (127.0.0.1:8080 and 127.0.0.1:1883). nginx publishes the console on 443, with a redirect on 80, and the gateway bridge listens for gateways on UDP 1700:

sudo ss -tlnp | grep -E ':(80|443|8080|1883) '

The API and MQTT broker are bound to 127.0.0.1, so they are never reachable from the network. Only nginx on 80/443 is exposed.

Step 4 - Confirm the web console over HTTPS

The console is served over HTTPS on port 443 with a per-instance self-signed certificate. A request to the HTTPS endpoint returns 200, and the plain HTTP port 80 returns a 301 redirect to HTTPS:

curl -k -s -o /dev/null -w 'HTTPS %{http_code}\n' https://127.0.0.1/
curl -s -o /dev/null -w 'HTTP %{http_code}\n' http://127.0.0.1/

Because the certificate is self-signed, your browser shows a certificate warning on your first visit. Accept it to proceed, or install /etc/nginx/tls/chirpstack.crt as a trusted certificate. For production, replace it with a certificate for your own domain (see Step 9).

Step 5 - Sign in to the web console

Browse to https://<instance-public-ip>/ and sign in as admin with the password from /root/chirpstack-credentials.txt. ChirpStack opens on the login page.

After you sign in, you land on the dashboard. It summarizes your active devices, active gateways and device data rate usage, with the Network Server and Tenant navigation down the left.

The screenshots in this guide show ChirpStack populated with a small set of example objects. A freshly deployed instance starts empty, ready for you to model your own network.

Step 6 - Create applications, device profiles and devices

Under Applications, group the devices that share an integration, for example a fleet of environmental sensors or asset trackers. Each application lists its devices with their DevEUI, name and device profile.

Open an application to see its Devices tab. A device is identified by its 64-bit DevEUI and is bound to a device profile, which pins the LoRaWAN region (EU868, US915 and so on), MAC version and class.

Create device profiles under the tenant's Device Profiles. Then add devices to an application and provision their keys for OTAA activation.

Step 7 - Use the gRPC API

ChirpStack v4 exposes a gRPC and gRPC web API on the same port as the console. There is no separate JSON REST server in the core binary. The image includes grpcurl so that you can drive the API from the shell.

Log in with your per-instance admin password to obtain a JWT, then pass it as an authorization: Bearer header. This example logs in, lists tenants and lists the applications in the default tenant:

$
PW=$(sudo grep '^CHIRPSTACK_ADMIN_PASSWORD=' /root/chirpstack-credentials.txt | cut -d= -f2-) $
JWT=$(grpcurl -plaintext -d "{\"email\":\"admin\",\"password\":\"$PW\"}" \
  127.0.0.1:8080 api.InternalService/Login | jq -r .jwt) $ grpcurl -plaintext -H "authorization: Bearer $JWT" -d '{"limit":10}' \
  127.0.0.1:8080 api.TenantService/List | jq -r '.result[].name' ChirpStack $
TID=$(grpcurl -plaintext -H "authorization: Bearer $JWT" -d '{"limit":10}' \
  127.0.0.1:8080 api.TenantService/List | jq -r '.result[0].id') $ grpcurl -plaintext -H "authorization: Bearer $JWT" \
  -d "{\"tenantId\":\"$TID\",\"limit\":10}" \
  127.0.0.1:8080 api.ApplicationService/List | jq -r '.result[].name' Asset Trackers Environmental Sensors

The default admin / admin login is rejected on your instance, and so is an unauthenticated API call. Only the per-instance password issues a working token.

Use grpcurl -plaintext 127.0.0.1:8080 list to browse the available services (Tenant, Application, DeviceProfile, Device, Gateway and more), and grpcurl ... describe <service> for their methods. You can also create long-lived API keys from API Keys in the console.

Step 8 - Connect a LoRa gateway

Real LoRa gateways connect through the bundled ChirpStack Gateway Bridge. It listens for the Semtech UDP packet forwarder on UDP 1700 and translates it to the local MQTT broker.

First, open 1700/udp in the security group from your gateways. Then point your gateway's packet forwarder at this instance's public IP on UDP 1700, and add the gateway under the tenant's Gateways using its Gateway EUI. BasicStation is also supported.

The Mosquitto broker itself stays bound to loopback, so it is never exposed to the network.

Step 9 - Enable HTTPS with your own domain

The image ships with a per-instance self-signed certificate, so the console works over TLS immediately. For production, point a DNS record at the instance's public IP. Then replace the certificate at /etc/nginx/tls/chirpstack.crt and /etc/nginx/tls/chirpstack.key with a certificate for your domain, for example one obtained with certbot. Alternatively, terminate TLS at an Application Load Balancer in front of the instance.

Reload nginx after replacing the certificate:

$
sudo systemctl reload nginx

Administration and support

The ChirpStack configuration lives in /etc/chirpstack/ (chirpstack.toml plus the per-region region_*.toml files). Enable or disable LoRaWAN regions with the network.enabled_regions list, then restart with sudo systemctl restart chirpstack.

The gateway bridge configuration is in /etc/chirpstack-gateway-bridge/. The PostgreSQL data directory is on its own EBS volume at /var/lib/postgresql, which you can resize independently. The admin password and every per-instance secret live in /root/chirpstack-credentials.txt.

This image is a repackaged open-source software product with additional charges for SecureAnyCloud support services. Our engineers provide 24/7 support for deployment, upgrades, TLS termination with your own domain, gateway onboarding, MQTT exposure and integration, LoRaWAN region configuration and scaling. ChirpStack is a trademark of its respective owner. The name is used here only to identify the software this image packages.

Deploy on AWS

Launch ChirpStack LoRaWAN Network Server with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS