Token Exchange refused Error

Ok, I have opted to purge docker-engine and docker-engine docker-ce & docker-ce-cli from the ubuntu vm to start this process again from scratch and this time round post all my steps. Please bear with me as I am learning about TTN as I go and I am no expert.

The objective - to have a fully working Things Stack CE installation running on a ubuntu 18.04 virtual machine and set up a private LoRaWAN network server using The Things Stack for LoRaWAN.

I am starting off with a Ubuntu 18.04.5 LTS box running on a LAN. It has a local IP address and is also assigned a public IP address and a domain name. The domain name A record has been updated to point to the public IP address of the host.

I want to make sure I can make requests to the host publicly. I decide to install apache2 so that I can access the host via http. Now when I visit my-domain.com from a seperate 4G connection I get the Apache 2 default page. Also when I connect to the host via ssh and run command curl -4 icanhazip.com on the cli, the result is my public IP address.

So this looks good to me because I want to meet the requirements in order to use Automatic Certificate Management on The Things Stack which requires a domain name publicly accessible for TLS certs from Let’s Encrypt.

Next I move on to Installing The Things Stack and I am following these instructions, I am assuming that I am on the right track and if I am lost, I would be delighted if anyone lends a hand to help me along.

Prerequisites

  1. A server with a recommended 4 virtual CPUs and 16GB RAM running Docker and Docker Compose*
  2. DNS records pointing to your server’s IP address

My checks from previous post where I did a few things to make sure I can make requests to the host publicly actually satisfy prerequisite number 2. DNS records pointing to your server’s IP address.

To satisfy prerequisite number 1; I am following the Docker documentation suggested in the instructions.

On following the Docker ubuntu installation docs, I ran the following command:
sudo apt-get install docker-ce docker-ce-cli containerd.io

This installs the highest possible version as I did not see anywhere on The Things Stack installation that instructs to install a specific Docker version.

I complete this step by running sudo docker run hello-world which downloads a test image and runs it in a container. The result is:

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Next I also follow the Docker docs to install Docker Compose; and run docker-compose --version which results: docker-compose version 1.27.4, build 40524192

At this point I am assuming Prerequisites 1 & 2 are both satisfied.

Hi @Tigere, you state that your aim is…

This forum is for the TTN community network that uses shared (not private) gateways and servers. The TTN is currently running the V2 software. So, you probably won’t get any detailed support here unless one of the developers of the TT Stack responds. TTI offers commercial support for their products used to build private networks.

Hi @cultsdotelecomatgmai, am I confused? because the getting started installation guide has the following notice:

Enterprise and Open Source Only

The following instructions apply to Enterprise and Open Source distributions. See the downloads page for a feature breakdown of distributions of The Things Stack.

This is a guide for setting up a private LoRaWAN network server using The Things Stack for LoRaWAN.

Am I missing something here?

Hi @Tigere,

The Things Network (TTN) is a PUBLIC LoRaWAN network run for the common good of all users.
Your network will be a PRIVATE LoRaWAN network.
This forum is for the users of the public network.

The origin of the software used on both public and private networks is The Things Industries (TTI). The TTI software is open source so you can download it and use it yourself. TTI also offers commercial support, hosted services and Amazon images because - as you are finding out - engineering and operating a LoRaWAN core is a complex business.

Actually the forum is for support of the open source software as well. However there are far fewer forum users working with the open source stack. As a result knowledge about what might be the OP issue is scarce.

1 Like

Hi @cultsdotelecomatgmai, Thank you very much for clarifying this for me.

Thank you very much @kersing.

Hi @kersing and @Tigere,

Mr. Kersing is, of course, completely correct, my mistake. As the public TTN currently operates mostly on V2 of the software and as very few forum users operate private networks it is almost entirely about the public network whereas you are trying to build a V3 private network.

Update:

I now have can access the console but with a hack for now, i.e I have edited all occurrences of https:// to http:// in my ttn-lw-stack-docker.yml . This is enough to move on in a test environment while I dive deeper into this issue with Token exchange, SSL, ubuntu 18.04 and Things Stack running in docker container.

I will get to the bottom of this and I shall keep you posted.

image

Hey @Tigere, I’ve just managed to get https with a custom certificate working on my open source TTS server, and it looks like you want to use HTTPS, so I’ll post instructions here.

First, download docker-compose.yml and ttn-lw-stack-docker.yml and configure them as normal. In my case, this meant replacing thethings.example.com with the static ip address of the machine hosting my docker containers. Then, uncomment the sections about using custom certificates.

At the bottom of docker-compose.yml:
image

Near the top of ttn-lw-stack-docker.yml (don’t forget to comment out the let’s encrypt section):
image

Next, install cfssl and cfssljson:
go get -u github.com/cloudflare/cfssl/cmd/cfssl
go get -u github.com/cloudflare/cfssl/cmd/cfssljson

You can run the installed binaries from ~/go/bin or add them to your PATH.

You are now ready to follow the instructions for using a custom certificate. I created ca.json exactly as shown. For cert.json, I replaced thethings.example.com with the static ip address of the host (as I had done in docker-compose.yml and ttn-lw-stack-docker.yml). After creating the two json files, I ran the commands to generate the certificates and put the relevant files into my project:

cfssl genkey -initca ca.json | cfssljson -bare ca
cfssl gencert -ca ca.pem -ca-key ca-key.pem cert.json | cfssljson -bare cert
mv cert-key.pem tts/key.pem
mv cert.pem tts/cert.pem
mv ca.pem tts/ca.pem

Like the instructions say, your project directory (tts in my case) should look like this:

.
├── blob
├── ca.pem
├── cert.pem
├── config
│   └── stack
│       └── ttn-lw-stack-docker.yml
├── docker-compose.yml
└── key.pem

Finally, add ca.pem to the certificate store(s) on any machines that will be interacting with your TTS installation.

sudo cp ca.pem /usr/local/share/ca-certificates/ca.crt
sudo update-ca-certificates

You can discard the other files created during the certificate signing process - you no longer need them (ca-key.pem, ca.csr, ca.json, cert.csr, cert.json).

Now, run the things stack as normal and you should be good to go.

By the way, can you explain how you’ve set up the redirects to allow logging in to the things stack? When I log in using the console I get HTTP 403 Forbidden due to an invalid redirect URL. If I log in using ttn-lw-cli I can see that it’s basing all the URL paths off localhost, which is not gonna work. I’ve followed solution 1 in the config instructions for a local server (and tried solution 2 with the same result) so I’m not sure why the redirect isn’t working.

EDIT: For more detail, here’s my attempt to log in using ttn-lw-cli --redirect=false. You can see it’s trying to use localhost, which is incorrect:

/ $ ttn-lw-cli login --callback=false
INFO Opening your browser on https://localhost/oauth/authorize?client_id=cli&redirect_uri=code&response_type=code
WARN Could not open your browser, you'll have to go there yourself error=exec: "xdg-open": executable file not found in $PATH
INFO After logging in and authorizing the CLI, we'll get an access token for future commands.
INFO Please paste the authorization code and press enter
> MF2XI.BRLWSW36IE6UTIBFLH2X5FHM7ULP4SH3NERMY3A.4UOKLQWNJP7QKBZ7XYN7MN4EWB2FGTSRUTKI673BS236XAKZ3CZQ
ERROR Could not exchange OAuth access token    error=Post "https://localhost/oauth/token": dial tcp 127.0.0.1:443: connect: connection refused
Post "https://localhost/oauth/token": dial tcp 127.0.0.1:443: connect: connection refused

This thread appears to have been neglected. However, further information on the Token Exchange Refused Error can be found here: TheThingsStack V3.8.7 with self-signed certificate -> Forbidden Token exchange refused

Note: one command is missing from my post above about setting up TLS. After creating the certificates and placing them in the project directory, run sudo chown 886:886 ./cert.pem ./key.pem

2 Likes

Can you post the results of ttn-lw-stack config | grep localhost ?

Thanks for pointing this out - I’ll add a note in the documentation

Thanks mate, if you could add that to the documentation would be great. I ended up getting it working after I wrote that post using instructions from IronNinja in the other thread I mentioned. There are a few loose ends to tie up but it will be easiest to just do it all in that thread, so I’ll post there with a full explanation.

Many thanks @dsmith, your detailed post has been extremely helpful. It helped me to setup self signed certs.

I was still unable to access the console and the Forbidden Token exchange refused is raised again and again. Below are the logged errors when I request the host url.

stack_1     |   INFO Client error                             duration=2ms http.method=GET http.path=/console/api/auth/token http.status=401 namespace=web peer.address=10.2.80.77:60957 request_id=01ES4FK2W7YAHGC27QCKS11KHP

stack_1     |   INFO Client error                             duration=1.4ms http.method=GET http.path=/oauth/api/me http.status=401 namespace=web peer.address=10.2.80.77:60957 request_id=01ES4FK4BN25BMEWQ2BG5BTYZT

stack_1     |   INFO Client error                             duration=2m10.5133s http.method=GET http.path=/console/oauth/callback http.status=403 namespace=web peer.address=10.2.80.77:60957 request_id=01ES4FK9R35TJDG1YNGS7VKZNV

stack_1     |   INFO Client error                             duration=1.2ms http.method=GET http.path=/console/api/auth/token http.status=401 namespace=web peer.address=10.2.80.77:60957 request_id=01ES4FQDHR83CJ4A50R4582X06

Finally, got to understand this as a hostname resolution or DNS issue which the result of running running a vm within a vm. As I am running the TTN docker images within my ubuntu 18.04 vm. Resolved this by adding to the ubuntu 18.04 VM’s /etc/hosts file, the host IP address and domain name values.

e.g.
10.101.31.123 mydomain.com

1 Like

Good to hear you got it all running in the end. Likewise, I was having issues with stacked VMs so I ended up just running docker directly in windows (rather than in a ubuntu vm) to get it working. The stacked VMs are a pain, but glad to see you’ve worked out a way around that.

There was some further discussion between benolayinka and myself in the other thread on self-signed certs, and benolayinka is updating the docs with the missing instructions.

1 Like