Forbidden - Invalid redirect URI with The Things Stack v3 - Private Environment

Hello, everyone,

i have just installed a private instance of thingsnetwork according to this tutorial: https://thethingsstack.io/v3.6.0/guides/getting-started/

The installation worked without problems. Unfortunately, I’m not able to use the web console properly. The reason for this is that after I login in the web-console I’m redirect to a webpage saying: Forbidden Invalid redirect URI.

The shell output of this error looks as follows:

stack_1      |   WARN OAuth error                              error=error:pkg/oauth:invalid_redirect_uri (invalid redirect URI) error_cause=urls don't validate: https://thethings.example.com/console/oauth/callback / /console/oauth/callback method=GET namespace=web remote_addr=172.18.0.1:54238 request_id=01E4JZZAF0MVJYY98KVJZY9TH9 url=/oauth/authorize?client_id=console&redirect_uri=%2Fconsole%2Foauth%2Fcallback&response_type=code&state=WSg0i-WsagCvdGPg
stack_1      |   INFO Request handled                          duration=14.840563ms method=GET namespace=web remote_addr=172.18.0.1:54238 request_id=01E4JZZAF0MVJYY98KVJZY9TH9 response_size=1665 status=403 url=/oauth/authorize?client_id=console&redirect_uri=%2Fconsole%2Foauth%2Fcallback&response_type=code&state=WSg0i-WsagCvdGPg
stack_1      |   INFO Request handled                          duration=21.716396ms method=GET namespace=web remote_addr=172.18.0.1:54242 request_id=01E4JZZAPJXYAABX7W26C15G9Y response_size=209 status=200 url=/oauth/api/me

Some further information:

  • I tried to access the console via 127.0.0.1:1885 and via thethings.example.com:1885 (I maped the domain to my localhost in my /etc/hosts file. Threfore thethings.example.com -> 127.0.0.1).
  • The HTTPS port 8885 do not work at all. As soon as I open the website with https://127.0.0.1:8885 I get the following error message: SSL_ERROR_INTERNAL_ERROR_ALERT. In the shell I get the following error
    2020/03/29 11:48:36 http: TLS handshake error from 172.18.0.1:37460: open /var/lib/acme/acme_account+key093647609: permission denied
    [EDIT]
    I fixed some issues regarding the https access but now I keep getting the following error message:
    stack_1 | 2020/03/29 12:56:06 http: TLS handshake error from 172.21.0.1:55864: acme/autocert: server name component count invalid
    stack_1 | 2020/03/29 12:56:25 http: TLS handshake error from 172.21.0.1:55868: mkdir /var/lib/acme: permission denied
    stack_1 | 2020/03/29 12:56:45 http: TLS handshake error from 172.21.0.1:55882: acme/autocert: missing certificate
  • I do not use self-encrypted certificates. I use Let’s encrypt as mentioned in the documentation
  • I use docker-compose 1.25.4 and docker 19.03.08-ce
  • The operating system that I’m using is archlinux

Here is my docker-compose.yml:

version: '3.7'
services:

  cockroach:
    image: cockroachdb/cockroach
    command: start --http-port 26256 --insecure
    restart: unless-stopped
    volumes:
      - ${DEV_DATA_DIR:-.env/data}/cockroach:/cockroach/cockroach-data
    ports:
      - "127.0.0.1:26257:26257" # Cockroach
      - "127.0.0.1:26256:26256" # WebUI

  redis:
    image: redis
    command: redis-server --appendonly yes
    restart: unless-stopped
    volumes:
      - ${DEV_DATA_DIR:-.env/data}/redis:/data
    ports:
      - "127.0.0.1:6379:6379"

  stack:
    image: thethingsnetwork/lorawan-stack
    entrypoint: ttn-lw-stack
    command: start
    restart: unless-stopped
    depends_on:
      - redis
      - cockroach

    volumes:
      - ./blob:/srv/ttn-lorawan/public/blob
      - ./acme:/var/lib/acme

    ports:
      - "80:1885"
      - "443:8885"
      - "1881:1881"
      - "8881:8881"
      - "1882:1882"
      - "8882:8882"
      - "1883:1883"
      - "8883:8883"
      - "1884:1884"
      - "8884:8884"
      - "1885:1885"
      - "8885:8885"
      - "1887:1887"
      - "8887:8887"
      - "1700:1700/udp"

    environment:
      # If using CockroachDB:
      - TTN_LW_IS_DATABASE_URI=postgres://root@cockroach:26257/${DEV_DATABASE_NAME:-ttn_lorawan}?sslmode=disable
      - TTN_LW_REDIS_ADDRESS=redis:6379

      - TTN_LW_TLS_SOURCE=acme
      - TTN_LW_TLS_ACME_DIR=/var/lib/acme
      - TTN_LW_TLS_ACME_EMAIL=you@thethings.example.com
      - TTN_LW_TLS_ACME_HOSTS=thethings.example.com
      - TTN_LW_TLS_ACME_DEFAULT_HOST=thethings.example.com

      # HTTP Server configuration:
      - TTN_LW_HTTP_COOKIE_HASH_KEY=1196c3904d12e748e84187b68b976c373548f06265756ce9b02d4a746b369d2b341c8125e94ffd0ed7029b9236f9ab0ffc816b1d93d1e3ee051198d8af642430
      - TTN_LW_HTTP_COOKIE_BLOCK_KEY=8eed19fd9db8bfeaa8d914fe8d3066a3c33f25968a0219f5ecb1afac0b261ebe
      - TTN_LW_HTTP_METRICS_PASSWORD=password
      - TTN_LW_HTTP_PPROF_PASSWORD=password

      # Email configuration for "thethings.example.com":
      - TTN_LW_IS_EMAIL_SENDER_NAME=The Things Stack
      - TTN_LW_IS_EMAIL_SENDER_ADDRESS=noreply@thethings.example.com
      - TTN_LW_IS_EMAIL_NETWORK_CONSOLE_URL=https://thethings.example.com/console
      - TTN_LW_IS_EMAIL_NETWORK_IDENTITY_SERVER_URL=https://thethings.example.com/oauth

      # If sending email with Sendgrid:
      # - TTN_LW_IS_EMAIL_PROVIDER=sendgrid
      # - TTN_LW_IS_EMAIL_SENDGRID_API_KEY=enter Sendgrid API key

      # If sending email with SMTP:
      - TTN_LW_IS_EMAIL_PROVIDER=smtp
      - TTN_LW_IS_EMAIL_SMTP_ADDRESS=enter mail server address
      - TTN_LW_IS_EMAIL_SMTP_USERNAME=enter username
      - TTN_LW_IS_EMAIL_SMTP_PASSWORD=enter password

      # If Application Server enabled, defaults for "thethings.example.com":
      - TTN_LW_AS_MQTT_PUBLIC_ADDRESS=thethings.example.com:1883
      - TTN_LW_AS_MQTT_PUBLIC_TLS_ADDRESS=thethings.example.com:8883

      # If Application Server enabled, Application Server interoperability configuration:
      # If interoperability configuration repository is a directory on OS FS:
      # - TTN_LW_AS_INTEROP_DIRECTORY=/path/to/interop/repository
      # If interoperability configuration repository is a URL:
      # - TTN_LW_AS_INTEROP_URL=https://thethings.example.com
      # If interoperability configuration repository is a blob:
      # - TTN_LW_AS_INTEROP_BLOB_PATH=/path/to/interop/directory
      # - TTN_LW_AS_INTEROP_BLOB_BUCKET=enter bucket name

      # If Gateway Server enabled, defaults for "thethings.example.com":
      - TTN_LW_GS_MQTT_PUBLIC_ADDRESS=thethings.example.com:1882
      - TTN_LW_GS_MQTT_PUBLIC_TLS_ADDRESS=thethings.example.com:8882
      - TTN_LW_GS_MQTT_V2_PUBLIC_ADDRESS=thethings.example.com:1881
      - TTN_LW_GS_MQTT_V2_PUBLIC_TLS_ADDRESS=thethings.example.com:8881

      # If Gateway Configuration Server enabled, defaults for "thethings.example.com":
      - TTN_LW_GCS_BASIC_STATION_DEFAULT_LNS_URI=wss://thethings.example.com:8887
      - TTN_LW_GCS_THE_THINGS_GATEWAY_DEFAULT_MQTT_SERVER=mqtts://thethings.example.com:8881

      # If Network Server enabled, Network Server interoperability configuration:
      # If interoperability configuration repository is a directory on OS FS:
      # - TTN_LW_NS_INTEROP_DIRECTORY=/path/to/interop/repository
      # If interoperability configuration repository is a URL:
      # - TTN_LW_NS_INTEROP_URL=https://thethings.example.com
      # If interoperability configuration repository is a blob:
      # - TTN_LW_NS_INTEROP_BLOB_PATH=/path/to/interop/directory
      # - TTN_LW_NS_INTEROP_BLOB_BUCKET=enter bucket name

      # Web UI configuration for "thethings.example.com":
      - TTN_LW_IS_OAUTH_UI_CANONICAL_URL=https://thethings.example.com/oauth
      - TTN_LW_IS_OAUTH_UI_IS_BASE_URL=https://thethings.example.com/api/v3
      - TTN_LW_CONSOLE_OAUTH_AUTHORIZE_URL=https://thethings.example.com/oauth/authorize
      - TTN_LW_CONSOLE_OAUTH_TOKEN_URL=https://thethings.example.com/oauth/token
      - TTN_LW_CONSOLE_UI_CANONICAL_URL=https://thethings.example.com/console
      - TTN_LW_CONSOLE_UI_IS_BASE_URL=https://thethings.example.com/api/v3
      - TTN_LW_CONSOLE_UI_GS_BASE_URL=https://thethings.example.com/api/v3
      - TTN_LW_CONSOLE_UI_NS_BASE_URL=https://thethings.example.com/api/v3
      - TTN_LW_CONSOLE_UI_AS_BASE_URL=https://thethings.example.com/api/v3
      - TTN_LW_CONSOLE_UI_JS_BASE_URL=https://thethings.example.com/api/v3
      - TTN_LW_CONSOLE_UI_EDTC_BASE_URL=https://thethings.example.com/api/v3
      - TTN_LW_CONSOLE_UI_QRG_BASE_URL=https://thethings.example.com/api/v3

      # Console OAuth client and secret:
      - TTN_LW_CONSOLE_OAUTH_CLIENT_ID=console
      - TTN_LW_CONSOLE_OAUTH_CLIENT_SECRET=console # generate a good one (openssl rand -hex 32)

And the content of ttn-lw-stack.yml file:

# Example ttn-lw-stack configuration file

# Redis configuration
redis:
  address: 'redis:6379'

# Identity Server configuration
is:
  # If using CockroachDB
  database-uri: 'postgres://root@cockroach:26257/ttn_lorawan?sslmode=disable'

  # Email configuration for "thethings.example.com"
  email:
    sender-name: 'The Things Stack'
    sender-address: 'noreply@thethings.example.com'
    network:
      name: 'The Things Stack'
      console-url: 'https://thethings.example.com/console'
      identity-server-url: 'https://thethings.example.com/oauth'

  # Web UI configuration for "thethings.example.com":
  oauth:
    ui:
      canonical-url: 'https://thethings.example.com/oauth'
      is:
        base-url: 'https://thethings.example.com/api/v3'

# HTTP server configuration
http:
  cookie:
    # generate 32 bytes (openssl rand -hex 32)
    block-key: '0011223344556677001122334455667700112233445566770011223344556677'
    # generate 64 bytes (openssl rand -hex 64)
    hash-key: '00112233445566770011223344556677001122334455667700112233445566770011223344556677001122334455667700112233445566770011223344556677'
  metrics:
    password: 'password'               # choose a password
  pprof:
    password: 'password'                 # choose a password

# Let's encrypt for "thethings.example.com"
tls:
  source: 'acme'
  acme:
    dir: '/var/lib/acme'
    email: 'you@thethings.example.com'
    hosts: ['thethings.example.com']
    default-host: 'thethings.example.com'

# If Gateway Server enabled, defaults for "thethings.example.com":
gs:
  mqtt:
    public-address: 'thethings.example.com:1882'
    public-tls-address: 'thethings.example.com:8882'
  mqtt-v2:
    public-address: 'thethings.example.com:1881'
    public-tls-address: 'thethings.example.com:8881'

# If Gateway Configuration Server enabled, defaults for "thethings.example.com":
gcs:
  basic-station:
    default:
      lns-uri: 'wss://thethings.example.com:8887'
  the-things-gateway:
    default:
      mqtt-server: 'mqtts://thethings.example.com:8881'

# Web UI configuration for "thethings.example.com":
console:
  ui:
    canonical-url: 'https://thethings.example.com/console'
    is:
      base-url: 'https://thethings.example.com/api/v3'
    gs:
      base-url: 'https://thethings.example.com/api/v3'
    ns:
      base-url: 'https://thethings.example.com/api/v3'
    as:
      base-url: 'https://thethings.example.com/api/v3'
    js:
      base-url: 'https://thethings.example.com/api/v3'
    qrg:
      base-url: 'https://thethings.example.com/api/v3'
    edtc:
      base-url: 'https://thethings.example.com/api/v3'

  oauth:
    client-id: 'console'
    client-secret: 'console'          # choose or generate a secret (*)

Does anyone have an idea how to fix the issue ?

You cannot do that if you want to use Let’s Encrypt. Instead, you’ll need to replace example.com with a domain that you actually own, and then either make that publicly accessible so Let’s Encrypt can access it, or add a specific DNS entry to allow Let’s Encrypt to validate your ownership.

Thanks for you answer arjanvanb. I’m gonna try this out.

[EDIT]

I have some minor issues with certificates but I was wondering why is it not working when using regular http ?

If I connect to the web console via HTTP it is not working properly either…