Installing ChirpStack LoRaWan network server for Helium

ChirpStack is an open-source LoRaWAN network server that is being use in a coming future with Helium as a replacement of the console. This blog post explains how to install it with the companion solution I’ve built to interact with Helium router.

This blog post requires you to own an OUI.

Understand the architecture

The solution is based on different components, some managed by NovaLabs / Helium and some you will manage.

Helium / Chirpstack architecture

The Hotspot will soon report all the received packets to Helium router. This central router will decide to purchase the packets based on the configuration made by the Helium / Chirpstack backend.

The packets sent to the Chirpstack instance based on the OUI routing (the network support numerous LoRa Network Servers (LNS) as previously. Due to Chirpstack architecture, each region uses a different port and a different gateway bridges to handle this traffic.

Traffic goes to the LNS through a MQTT broker. The Helium / Chirpstack back-end is capturing the communication from this source for counting the DC related to this communication to invoice the end-user for this traffic.

The device addition / removal, the sessions signature are tracked by the Helium-Chirpstack to manage the configuration routing with the Helium routing service.

The Helium-Chripstack front-end allow the user to transparently use Chirpstack and manage the fleet consumption and communication payment.

Helium / Chirstack front end integration

Quick install

This blog post gives all the details for a manual installation, but if your configuration is really standard, like for a personal usage of the software, I made a script to simplify the process.

This script has been built to be ran on a blank ubuntu 22.04 LTS and proceed automatically to the whole installation process described above. It will ask you some questions all along the process.

Run the makeiteasy.sh script is a such situation.

Manual Install – Pre-requisite

Setup a virtual machine

The environment for running all the stack is a Linux server wit Docker containers. I’m installing it a on standard server with 4VCPU, 8-16GB of RAM and 128GB of storage (development sizing), running Ubuntu 22.04 LTS

Install docker & docker-compose

For this installation, i just followed the docker guide.

Install Java JDK and YARN

Java and Yarn are required to compile the helium-chirpstack interface. Let’s start with Java

[root ~]apt-get install default-jdk make

Install Yarn now

[root ~] apt remove cmdtest
[root ~] curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
[root ~] echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
[root ~] apt-get update
[root ~] apt-get install yarn

Setup helium console

Prepare your deployment

Get the helium-chirpstack project last release. The Chirpstack comes with a docker compose template and configuration files. You can start from that point by cloning the docker template repository.

[root ~]git clone https://github.com/disk91/helium-chirpstack.git
[root ~]cd helium-chirpstack
[root ~helium-chirpstack]# eventually git checkout last Release  - check releases on git

We need to initialize the environnement, the default is to install everything in /helium/ so you can attach a specific drive to that location and backup it easily.

[root ~helium-chirpstack] make init

SETUP HELIUM CLI

With the helium CLI we are going to get the OUI information required for finishing setup. For this we need to get the helium configuration service client:

[root ~] git clone https://github.com/helium/helium-config-service-cli.git
[root ~] curl https://sh.rustup.rs -sSf | sh
[root ~] apt-get install build-essential libssl-dev pkg-config protobuf-compiler
[root ~] source "$HOME/.cargo/env"
[root ~] cd helium-config-service-cli
[root ~] cargo b --release
[root ~] cp target/release/helium-config-service-cli /helium/cli/helium_cli
[root ~] cargo clean

The next step is to create a public / private key for protecting and authenticating the communications with the router.

[root ~] cd /helium/cli
[root /helium/cli] ./helium_cli env generate-keypair keypair.bin

Once you get the key.bin file, you need to request its public key to be added as a delegated key to your OUI. Contact Helium Foundation for this.

Once you have this key declared, you should be able to declare your OUI parameters.

You can configure the environment, using your own OUI. The Max copies is the maximum number of duplicates you want to receive.

[root /helium/cli]./helium_cli env init
----- Leave blank to ignore...
Config Service Host: http://mainnet-config.helium.io:6080/
Keypair Location: ./keypair.bin
----- Enter all zeros to ignore...
Net ID: 000024
----- Enter zero to ignore...
Assigned OUI: 16
Default Max Copies: 99
✓ 
Put these in your environment
------------------------------------
HELIUM_CONFIG_HOST=http://mainnet-config.helium.io:6080/
HELIUM_KEYPAIR_BIN=./keypair.bin
HELIUM_NET_ID=000024
HELIUM_OUI=16
HELIUM_MAX_COPIES=99

Now, create a file env.sh exporting these environment variable:

export HELIUM_CONFIG_HOST=http://mainnet-config.helium.io:6080/
export HELIUM_KEYPAIR_BIN=./keypair.bin
export HELIUM_NET_ID=000024
export HELIUM_OUI=16
export HELIUM_MAX_COPIES=99

Now, on every session you need to use the CLI, you can source this environment file:

[root /helium/cli] . ./env.sh

Setup chirpstack

We are going to deploy the whole solution with docker-compose. This is based on chirpstack-docker project modified and with verified version.

Regarding PostgreSQL, I recommend to change the default password ‘fdfce449c0ba34332525’ by something different:

You can use the following command to get a random string

[~] echo $RANDOM | md5sum | head -c 20; echo;

Then update the configuration files:

[root ~] vi /helium/configuration/postgresql/initdb/001-init-chirpstack.sh
#!/bin/bash
set -e

psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
    create role chirpstack with login password 'fdfce449c0ba34332525';
    create database chirpstack with owner chirpstack;
EOSQL

Now you need to update the chirpstack configuration file to match the database password

[root ~] vi /helium/configuration/chirpstack/chirpstack.toml
[postgresql]
...
dsn="postgres://chirpstack:fdfce449c0ba34332525@$POSTGRESQL_HOST/chirpstack?sslmode=disable"
...

Then change the secrets and the dev addresses associated to the OUI. To create a secret, you can use the following command:

[root ~] openssl rand -base64 32

To get the list of dev addresses, you can use the following command ( then you need to convert it from range to mask), for 8 devAddr, the mask will be 29 for 16 it will be 28… :

[root /helium/cli] ./helium_cli org get
...
"devaddr_constraints": [
    {
      "start_addr": "49000400",
      "end_addr": "490007FF"
    }
  ]
[root ~] vi /helium/configuration/chirpstack/chirpstack.toml
...
[api]
  ...
  bind="0.0.0.0:8080"
  ...
  secret="MIy62sTfjD87B8PJxaQkk5tt8dbUNH3p2CZmVwFB4F4="
[network]
  net_id="000024"
  ...
  # List devAddr range you own
  #dev_addr_prefixes=["FC014C30/28","FC014C50/28","FC014C10/29"]
  dev_addr_prefixes=["49000400/21"]
...
[gateway]
  allow_unknown_gateways=true

Setup & Build Helium-Chirpstack companion

Setup configuration file

You need to setup the configuration file, there are many important settings, lets review them by categories:

[root ~] vi /helium/configuration/helium/configuration.properties

Then you need to setup the service information, this will be used in email communication. By setting signup at true, you authorize unknown user to register on the console.

helium.console.url=https://console.foo.bar
helium.console.name=Foo Bar Helium Console
helium.mail.from=contact@foo.bar
...

There are the technical information where you setup the password you previously set for the database:

## PostgreSQL
spring.datasource.url=jdbc:postgresql://postgres:5432/chirpstack
spring.datasource.username=chirpstack
spring.datasource.password=<type here the password>

You need to setup the helium api and OUI with the public key obtained previously. The keyfile should not be changed, it is mounted in the docker-compose file. The helium GRPC server and port as not yet disclosed.

You need some elements like your public key:

[root /helium/cli] ./helium_cli env info | grep public_key
"public_key_from_keypair": "14pcx1R...KLBakfoLX"

Create a random value for your JWT tokens

[root ~] echo $RANDOM | md5sum | head -c 32; echo -n; echo $RANDOM | md5sum | head -c 32; echo;

eb23a5f79015a8b26ff1d100bc8332dd888f7e7bfc6f5bb230040db1a6eaad50
## Helium GPRC
helium.grpc.public.key=14pcx1R...KLBakfoLX
helium.route.oui=<Your OUI>
helium.route.host=console.foo.bar

## Console API
helium.jwt.signature.key=eb23a5f...

You will need to create an API key for chirpstack, we will do this later. Right now, just makes this entry empty.

## Chirpstack API
chirpstack.api.base=http://chirpstack:8080
chirpstack.api.admin.key=

Setup the email configuration, email is required to create user accounts. Here is an example for sendgrid

## #############################################################
## Email configuration
spring.mail.host=smtp.sendgrid.net
spring.mail.port=25
spring.mail.username=apikey
spring.mail.password=G.A_Wv9...

Setup your billing information according to the documentation in the configuration file.

You also need to setup the option you give to user to add DCs, you can enable DC transfer between tenants and DC purchasing with stripe. If you enable stripe, you need to specify the public and private key of your stripe account. If you don’t specify them, by default it has the stripe demo keys.

## Stripe
helium.stripe.key.private=sk_test_51H...
helium.stripe.key.public=pk_test_51Hnj...
helium.stripe.enable=true
helium.transfer.enable=true

Setup the NGINX Server

In case you want to deploy http without domain name but just IP, you can directly use /helium/configuration/nginx/default.conf.nossl file. Edit the file and change the @DOMAIN@ with your IP address. Save the file as default.conf and skip the next steps, directly going to “build the software image”.

For all the others, the normal way is to deploy https with a domain name : In the /helium/configuration/nginx/default.conf file, you need to change the server name to match with your server:

server {
    listen 80;
    listen [::]:80;

    server_name console.foo.bar;
    ...
    location / {
        return 301 https://console.foo.bar$request_uri;
    }

In the /helium/configuration/nginx/default.conf.withssl file, you need to change the server name to match with your server:

server {
    listen 80;
    listen [::]:80;

    server_name console.foo.bar;
    ...
    location / {
        return 301 https://console.foo.bar$request_uri;
    }
    ...
server {
    listen 443 default_server ssl http2;
    listen [::]:443 ssl http2;

    server_name console.foo.bar;
    ssl_certificate /etc/nginx/ssl/live/console.foo.bar/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/live/console.foo.bar/privkey.pem;

Build the software image

This part is going to build the back and the front part. You need to set some parameter like the Console name you want to display and the link to the user terms you want your user to accept before registering. Edit the Makefile and update the env variable

[root ~helium-chirpstack] vi Makefile
...
CONSOLE_NAME=Helium-IoT
CONSOLE_TERMS=https://...
API_HOST=
CHIRPSTACK_HOST=
...

CONSOLE_NAME is what will be displayed as a title in the console, CONSOLE_TERMS is the link given to user when registering with e service conditions. API_HOST and CHIRPSTACK_HOST are left blank with the docker-compose setup.

[root ~helium-chirpstack] make build

You can put your own favicon (it will not be override later) by copying it into /helium/front/static/front/favicon.ico

FIRST Run to terminate setup

We are close to the final steps, now we can start the stack, then we will need to make the final steps

[root /helium] docker compose up -d

The system should start, now we can request the initial ssl certificate (change with your server name)

[root ~helium-chirpstack/chirpstack] docker compose run --rm certbot certonly --webroot --webroot-path /var/www/certbot/ -d console.foo.bar

Restart with the ssl configuration

[root ~] docker stop helium-nginx-1
[root ~] mv /helium/configuration/nginx/default.conf /helium/configuration/nginx/default.conf.withoutssl
[root ~] mv /helium/configuration/nginx/default.conf.withssl /helium/configuration/nginx/default.conf
[root ~] docker start helium-nginx-1

Once done, you need to directly connect to chirpstack to setup admin password and API key. With your browser go on https://console.foo.bar/?override=true

Chirpstack login page

The default user password is admin / admin. The first step is to change your admin password.

Then you can create an API key :

create an api key with admin rights

Give a name to the key, whatever, then copy the given token and add it into the /helium/configuration/helium/configuration.properties

## Chirpstack API
chirpstack.api.base=http://chirpstack:8080
chirpstack.api.admin.key=eyJ0eXAiOiJK...

Then restart the docker container running the backend to take it into account

[root ~] docker restart helium-helium-1

At this step … you should get it working 😉 You can connect to the solution on https://console.foor.bar

Configure invoicing

If you want to use stripe for DC purchasing, you need to setup your company profile to get the right information printed on invoices. For this, in the application, connected as admin, edit the invoice setup:

Setup your company setting to generate invoices

Deploy forwarder component

Forwarder component allows to transform & enrich the chirpstack payload to preserve the compatibility with helium existing integrations. See helium-forwarder in github. This solution also enrich the payload with the gateway locations. You need to have at least version 1.1.1 for getting started with this.

The first step is to deploy the project and specific configurations.

[root ~helium-chirpstack] make init-forwarder

In the /helium/configuration/forwarder directory you need to update setup:

## Loadbalancer.properties / node1.properties / node2.properties
# Same values as in your helium/configuration.property file
forwarder.url=
spring.datasource.password=
helium.jwt.signature.key=

## node1.properties / node2.properties
chirpstack.api.admin.key=

You also need to setup the downlink endpoint with the right server name

# node1.properties
helium.downlink.endpoint=https://console.foo.bar/forwarder1/1.0/downlink/{key}/

# node2.properties
helium.downlink.endpoint=https://console.foo.bar/forwarder2/1.0/downlink/{key}/

Now, you need to edit the nginx configuration file /helium/configuration/nginx/default.conf and un-comment the forwarder related parts. ( if you upgrade from a version prior to 1.1.0, see file in chirpstack/configuration/nginx/default.withssl )

Start the forwarder

[root /helium] docker compose up -d

Update your letsencrypt certificate

When you will need to update you certificate, here is the command to use

[root ~helium-chirpstack/chirpstack/] docker compose run --rm certbot renew
[root ~helium-chirpstack/chirpstack/] docker restart helium-nginx-1

Update from a previous release

If you upgrade Helium companion from a previous release, please make sure you review the configuration file update and add the missing config entries

[root ~helium-chirpstack] diff chirpstack/configuration/helium/configuration.properties /helium/configuration/helium/configuration.properties

Update some parameters in configuration.properties

The configuration file can be updated on /helium/configuration/helium/configuration.properties then you need to restart the docker container:

[root ~] docker restart helium-helium-1

Some misc useful things

Get the internal network IP Address of posgresql

[root ~] docker inspect   -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}'  helium-postgres-1

10 thoughts on “Installing ChirpStack LoRaWan network server for Helium

  1. Dear Disk91,

    I am trying to search for how to be involved in the beta testing of HIP70, specifically the ChirpStack version for Helium – could you point me in the right direction for this?

    Best regards,

  2. So looking at the architecture diagram, it seems that Nova Labs (Private Company, for profit) is in the position of controlling all packets from Helium (Foundation), which is certainly a not so good thing for the community….
    Is there any plans to have the foundation taking over that Nova Lab layer?

  3. Hi Disk91,
    thanks for your tutorial, it has been helpful, however when i get to start the docker containers i get the error : Error response from daemon: pull access denied for disk91/console, repository does not exist or may require ‘docker login’: denied: requested access to the resource is denied.
    ive looked through the docker repository and cant seem to find it.
    are you able to assist me?
    also i was wondering if i could use a different payment solution other than stripe?
    thanks for your time and effort it is much appreciated

    • Hello,
      Don’t do docker pull directly as disk91/console is locally compiled. You can docker pull with –ignore-pull-failure as an option.

  4. Hi,
    thanks for the message, i eventualy worked this out…….felt a bit stupid but got it installed.
    i can get to chirpstack by going to https://console.foo.bar/?override=true
    but when i go direct to https://console.foo.bar it breifly shows the login page but then switches to show an error.

    ive found this error in the logs [error] 21#21: *1 connect() failed (113: No route to host) while connecting to upstream, client: “IP OF CLIENT”
    not sure how to troubleshoot this error. ive tried reinstalling many times.
    could possibly be an issue with docker networking?
    thanks for your time

    • Why do you want a go on console.foo.bar ? foo.bar is like john doe … it means you need to replace it by your own domain

      • Hi Paul, as it was used in the installation instructions ive used it here……….in the real world i use my own domain iot.mydomain.com but the key point is the overide, when i add the “?override=true” to the end as per instructions
        i can get to the chirpstack login page, to change details and get api key but when i go to the iot.mydomain.com i get the login page breifly then it changes to an error.
        Thanks for your time

      • The login page fall back to error page when the backend API does not respond. Have a look to the helium-helium-1 container logs to see what’s wrong.
        Please contact me on discord / twitter for support. comment on block post is hard to follow and slow response time

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.