Setting up a Private Handler connected to the Public Community Network

Hylke Visser

TTN Core Team

Posted on 12-01-2017

This article is a guide for setting up a private handler that is connected to the public community network. This setup allows for end-to-end encryption between a node and your server.

The server where you are going to deploy the private handler needs a static IP address and/or (sub)domain. In this guide will use the domain Your firewall needs to allow access to the ports 1904 (for the handler API), 8084 (for the HTTP API) and 1883/8883 (for MQTT/MQTTs) or 5672/5671 (for AMQP/AMQPs). We will rely on the community account server of The Things Network ( so that you can use your TTN Account to manage devices in your private handler. If you don't want your handler to use community accounts, you should look at setting up a private routing environment and use your own account server implementation.


  • Install and start Redis.
  • Install and start RabbitMQ and its MQTT plugin.
    • You should also create a ttn.handler exchange using the web interface or with rabbitmqadmin declare exchange name=ttn.handler type=topic auto_delete=false durable=true.
  • Create a working directory. In this document we will use ~/ttn. All commands are executed from this directory.
  • Download ttn (master branch) macOS, 64 bit Linux, 32 bit Linux or arm Linux.


Before we can connect your handler, it needs to be registered in the account server. This links the private handler to your account, making sure that others can't impersonate your private handler to retrieve your data. To do so, we use ttnctl and add a new handler component with the name mynetwork-handler:

ttnctl components add handler mynetwork-handler
  INFO Added network component                  id=mynetwork-handler type=handler

Next, we have retrieve an access token that your private handler will use to prove it's identity when it announces with the discovery server. With this announcement, your private handler informs other components in the network about the address and connection security (public key and certificate) of your handler.

ttnctl components token handler mynetwork-handler
  INFO Got component token                      id=mynetwork-handler type=handler


For security reasons, this access token is only valid for a limited amount of time (about 3 months), so don't forget to rotate it regularly by requesting a new one and reloading your configuration. You probably want to write a script that does this every month or so.

Handler Configuration

The configuration for the Handler will be stored in ~/ttn/handler/ttn.yml:

id: mynetwork-handler
tls: true
key-dir: handler/
  ttn-account-v2: ""


  broker-id: ttn-broker-eu
  mqtt-address: localhost:1883

This configuration defines a Handler mynetwork-handler on the address It connects to the Broker ttn-broker-eu (located in Europe; you can get a list of Brokers with the command ttnctl discover broker).

Now we have to generate a public/private keypair and a TLS certificate for secure communication:

ttn handler gen-keypair --config ./handler/ttn.yml
ttn handler gen-cert --config ./handler/ttn.yml

Starting the Handler

ttn handler --config handler/ttn.yml


Configuration of ttnctl is done by editing $XDG_CONFIG_HOME/config.yml or ~/.ttnctl.yml:

handler-id: mynetwork-handler

Now you can register your application to your private Handler. This command creates the necessary information in the handler and publishes the mapping (appID->handlerID) to the discovery server so that other components know where to send your data.

ttnctl applications register

And manage your devices in the same way as you would do on the public community network. Keep in mind that components cache application registrations, so it may take up to 10 minutes before data is sent to your handler.

Questions or Issues

If you have questions or remarks after following this guide, feel free use the forum or the #support or #backend channels on Slack. This is a community-supported guide, so please help each other out.

What's Next

You should now have a working private handler. Now you should probably do some of the following:

  • Read how to deploy the private handler using docker-compose. Although that guide is meant for complete private backends, you can just skip the steps for all other components and only look at the steps relevant for the handler.
  • Periodically update ttn to the latest version
  • Enable persistence in Redis
  • Configure backups
  • Secure your MQTT/AMQP broker with usernames and passwords
  • Help with development of TTN's open source routing services