Closed TheIronNinja closed 3 years ago
If anyone stumbles upon this issue looking for answers, go here https://www.thethingsnetwork.org/forum/t/thethingsstack-v3-8-7-with-self-signed-certificate-forbidden-token-exchange-refused/38902/15
cc @nejraselimovic
cc @nejraselimovic
Thanks for the insight @johanstokking, and good job @TheIronNinja!
I can confirm that on Ubuntu 18.04 I got rid of Token exchange refused
error that I had with setup that uses localhost
as a hostname and self-signed certificates by doing the following:
TTN_LW_OAUTH_SERVER_ADDRESS: https://localhost:8885/oauth
to environment
in docker-compose.yml
https://thethings.example.com/
occurrences with https://localhost:8885/
in default ttn-lw-stack-docker.yml
file--redirect-uri "https://localhost:8885/console/oauth/callback"
and --logout-redirect-uri "https://localhost:8885/console"
as @TheIronNinja described in TTN forum threadHaving this setup, I only needed to import ca.pem
I created according to this section under Authorities
in my browser to resolve all security warnings.
OK. Do we need to change or clarify the documentation on these points?
OK. Do we need to change or clarify the documentation on these points?
Maybe just a note in troubleshooting section in this case when localhost
and self-signed certs are being used?
I'd add a note saying that if you are not installing the stack on your local machine you need to change those things. In my case I'm not using self-signed certificates so this always applies.
I'd add a note saying that if you are not installing the stack on your local machine you need to change those things. In my case I'm not using self-signed certificates so this always applies.
Oh, I see. But also, I had this problem on my local machine and solved it as I mentioned above. So what we first need here is a good explanation of why this was necessary to make things work in both of our cases, then we can document it properly.
With #3352 the error information for these errors will be returned in window.__ttn_config__.PAGE_DATA.error
and could be shown to the user. @kschiffer already confirmed that this is possible, but he's concerned that this would be "disclosing development information to the user".
I'd add a note saying that if you are not installing the stack on your local machine you need to change those things. In my case I'm not using self-signed certificates so this always applies.
@TheIronNinja if you're not installing the stack on your local machine, you shouldn't need to add these environment variables to your docker-compose.yml
. The configuration options you posted are in our example ttn-lw-config-docker.yml, and if you follow along in the installation instructions they should be set to your server's domain, not localhost. If you configured them as localhost on a remote server, that wouldn't work. It also shouldn't be necessary to specify the port in those parameters, since all TLS requests are redirected in docker-compose.yml
. 8885
is also passed through, so it will work the way you have it, but it isn't necessary
ports:
# If deploying on a public server:
- "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"
TTN_LW_OAUTH_SERVER_ADDRESS
is not a config parameter.
TTN_LW_CONSOLE_UI_AS_BASE_URL: https://mydomain:8885/api/v3
TTN_LW_CONSOLE_UI_IS_BASE_URL: https://mydomain:8885/api/v3
TTN_LW_OAUTH_SERVER_ADDRESS: https://mydomain:8885/oauth # this one is not a real config
TTN_LW_IS_OAUTH_UI_CANONICAL_URL: https://mydomain:8885/oauth
TTN_LW_IS_OAUTH_UI_IS_BASE_URL: https://mydomain:8885/api/v3
TTN_LW_APPLICATION_SERVER_GRPC_ADDRESS: mydomain:8884
TTN_LW_DEVICE_CLAIMING_SERVER_GRPC_ADDRESS: mydomain:8884
@nejraselimovic has a slightly different problem - she's running docker on localhost, and token exchange is failing, i think because if you don't specify the ports, requests WITHIN docker to https://localhost/oauth
become localhost/oauth:443
by default, which is not where the stack is listening.
For @nejraselimovic , changing e.g localhost/oauth
to localhost/oauth:8885
fixed internal redirects inside Docker.
Hi @benolayinka, thanks for the detailed info. I guess I saw the TTN_LW_OAUTH_SERVER_ADDRESS
in some other post and assumed it was correct, but if it doesn't exist then I'll delete it from my config. As for some of the other parameters I know some of them are defined in the ttn-lw-config-docker.yml, but for some reason they are ignored and I only see the changes reflected if I put them in the docker-compose.yml. In fact, I ended up introducing most of the config parameters there just to make sure they have the value I want them to have.
Hi @benolayinka, thanks for the detailed info. I guess I saw the
TTN_LW_OAUTH_SERVER_ADDRESS
in some other post and assumed it was correct, but if it doesn't exist then I'll delete it from my config. As for some of the other parameters I know some of them are defined in the ttn-lw-config-docker.yml, but for some reason they are ignored and I only see the changes reflected if I put them in the docker-compose.yml. In fact, I ended up introducing most of the config parameters there just to make sure they have the value I want them to have.
If the parameters in ttn-lw-config-docker.yml
are ignored we need to figure out why! Can you share your docker-compose.yml
and ttn-lw-config-docker.yml
so that we can try to reproduce the issue?
Sure. This are the contents of the docker-compose.yml:
version: '3.7'
services:
# If using CockroachDB:
cockroach:
image: cockroachdb/cockroach:v20.1.5
command: start --http-port 26256 --insecure
restart: unless-stopped
volumes:
- .env/data/cockroach:/cockroach/cockroach-data
ports:
- 127.0.0.1:26257:26257 # Cockroach
- 127.0.0.1:26256:26256 # WebUI
redis:
image: redis:6.0.8
command: redis-server --appendonly yes
restart: unless-stopped
volumes:
- .env/data/redis:/data
ports:
- 127.0.0.1:6379:6379
stack:
image: thethingsnetwork/lorawan-stack:3.9.4
entrypoint: ttn-lw-stack
command: start
restart: unless-stopped
depends_on:
- redis
- cockroach
volumes:
- ./blob:/srv/ttn-lorawan/public/blob
- ./config/stack:/stack:ro
# If using Let's Encrypt:
- ./acme:/var/lib/acme
environment:
TTN_LW_BLOB_LOCAL_DIRECTORY: /srv/ttn-lorawan/public/blob
TTN_LW_REDIS_ADDRESS: redis:6379
TTN_LW_IS_DATABASE_URI: postgres://root@cockroach:26257/ttn_lorawan?sslmode=disable
# TTN_LW_LOG_LEVEL: DEBUG
TTN_LW_TLS_SOURCE: acme
TTN_LW_TLS_ACME_DIR: /var/lib/acme
TTN_LW_TLS_ACME_EMAIL: REDACTED
TTN_LW_TLS_ACME_HOSTS: MY_DOMAIN
TTN_LW_TLS_ACME_DEFAULT_HOST: MY_DOMAIN
TTN_LW_CONSOLE_OAUTH_AUTHORIZE_URL: https://MY_DOMAIN:8885/oauth/authorize
TTN_LW_CONSOLE_OAUTH_TOKEN_URL: https://MY_DOMAIN:8885/oauth/token
TTN_LW_CONSOLE_UI_CANONICAL_URL: https://MY_DOMAIN:8885/console
TTN_LW_CONSOLE_UI_AS_BASE_URL: https://MY_DOMAIN:8885/api/v3
TTN_LW_CONSOLE_UI_IS_BASE_URL: https://MY_DOMAIN:8885/api/v3
TTN_LW_OAUTH_SERVER_ADDRESS: https://MY_DOMAIN:8885/oauth
TTN_LW_IS_OAUTH_UI_CANONICAL_URL: https://MY_DOMAIN:8885/oauth
TTN_LW_IS_OAUTH_UI_IS_BASE_URL: https://MY_DOMAIN:8885/api/v3
TTN_LW_APPLICATION_SERVER_GRPC_ADDRESS: MY_DOMAIN:8884
TTN_LW_DEVICE_CLAIMING_SERVER_GRPC_ADDRESS: MY_DOMAIN:8884
TTN_LW_DEVICE_TEMPLATE_CONVERTER_GRPC_ADDRESS: MY_DOMAIN:8884
TTN_LW_DEVICE_TEMPLATE_CONVERTER_SERVER_GRPC_ADDRESS: MY_DOMAIN:8884
TTN_LW_GATEWAY_SERVER_GRPC_ADDRESS: MY_DOMAIN:8884
TTN_LW_IDENTITY_SERVER_GRPC_ADDRESS: MY_DOMAIN:8884
TTN_LW_JOIN_SERVER_GRPC_ADDRESS: MY_DOMAIN:8884
TTN_LW_NETWORK_SERVER_GRPC_ADDRESS: MY_DOMAIN:8884
TTN_LW_QR_CODE_GENERATOR_GRPC_ADDRESS: MY_DOMAIN:8884
TTN_LW_AS_MQTT_PUBLIC_ADDRESS: "MY_DOMAIN:1883"
TTN_LW_AS_MQTT_PUBLIC_TLS_ADDRESS: "MY_DOMAIN:8883"
TTN_LW_AS_WEBHOOKS_DOWNLINK_PUBLIC_ADDRESS: "https://MY_DOMAIN:8885/api/v3"
TTN_LW_CONSOLE_OAUTH_LOGOUT_URL: "https://MY_DOMAIN:8885/oauth/logout"
TTN_LW_CONSOLE_UI_EDTC_BASE_URL: "https://MY_DOMAIN:8885/api/v3"
TTN_LW_CONSOLE_UI_GS_BASE_URL: "https://MY_DOMAIN:8885/api/v3"
TTN_LW_CONSOLE_UI_JS_BASE_URL: "https://MY_DOMAIN:8885/api/v3"
TTN_LW_CONSOLE_UI_NS_BASE_URL: "https://MY_DOMAIN:8885/api/v3"
TTN_LW_CONSOLE_UI_QRG_BASE_URL: "https://MY_DOMAIN:8885/api/v3"
TTN_LW_GCS_BASIC_STATION_DEFAULT_LNS_URI: "wss://MY_DOMAIN:8887"
TTN_LW_GCS_THE_THINGS_GATEWAY_DEFAULT_MQTT_SERVER: "mqtts://MY_DOMAIN:8881"
TTN_LW_GS_MQTT_V2_PUBLIC_ADDRESS: "MY_DOMAIN:1881"
TTN_LW_GS_MQTT_V2_PUBLIC_TLS_ADDRESS: "MY_DOMAIN:8881"
TTN_LW_GS_MQTT_PUBLIC_ADDRESS: "MY_DOMAIN:1882"
TTN_LW_GS_MQTT_PUBLIC_TLS_ADDRESS: "MY_DOMAIN:8882"
TTN_LW_IS_EMAIL_NETWORK_CONSOLE_URL: "https://MY_DOMAIN:8885/console"
TTN_LW_IS_EMAIL_NETWORK_IDENTITY_SERVER_URL: "https://MY_DOMAIN:8885/oauth"
ports:
# If deploying on a public server:
- 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
# If using custom certificates:
# secrets:
# - ca.pem
# - cert.pem
# - key.pem
# If using custom certificates:
#secrets:
# ca.pem:
# file: ./ca.pem
# cert.pem:
# file: ./cert.pem
# key.pem:
# file: ./key.pem
And here the contents of the ttn-lw-stack-docker.yml:
# Identity Server configuration
# Email configuration for MY_DOMAIN
is:
email:
sender-name: 'Test name'
sender-address: 'noreply@MY_DOMAIN'
network:
name: 'Test name'
console-url: 'https://MY_DOMAIN/console'
identity-server-url: 'https://MY_DOMAIN/oauth'
# Web UI configuration for MY_DOMAIN:
oauth:
ui:
canonical-url: 'https://MY_DOMAIN/oauth'
is:
base-url: 'https://MY_DOMAIN/api/v3'
# HTTP server configuration
http:
cookie:
block-key: 'REDACTED' # generate 32 bytes (openssl rand -hex 32)
hash-key: 'REDACTED' # generate 64 bytes (openssl rand -hex 64)
metrics:
password: 'REDACTED' # choose a password
pprof:
password: 'REDACTED' # choose a password
redirect-to-tls: 'true'
# Let's encrypt for MY_DOMAIN
#tls:
# source: 'acme'
# acme:
# dir: '/var/lib/acme'
# email: 'REDACTED'
# hosts: ['MY_DOMAIN']
# default-host: 'MY_DOMAIN'
# If Gateway Server enabled, defaults for MY_DOMAIN:
gs:
mqtt:
public-address: 'MY_DOMAIN:1882'
public-tls-address: 'MY_DOMAIN:8882'
mqtt-v2:
public-address: 'MY_DOMAIN:1881'
public-tls-address: 'MY_DOMAIN:8881'
# If Gateway Configuration Server enabled, defaults for MY_DOMAIN:
gcs:
basic-station:
default:
lns-uri: 'wss://MY_DOMAIN:8887'
the-things-gateway:
default:
mqtt-server: 'mqtts://MY_DOMAIN:8881'
# Web UI configuration for HTTPS
console:
ui:
canonical-url: 'https://MY_DOMAIN/console'
is:
base-url: 'https://MY_DOMAIN/api/v3'
gs:
base-url: 'https://MY_DOMAIN/api/v3'
ns:
base-url: 'https://MY_DOMAIN/api/v3'
as:
base-url: 'https://MY_DOMAIN/api/v3'
js:
base-url: 'https://MY_DOMAIN/api/v3'
qrg:
base-url: 'https://MY_DOMAIN/api/v3'
edtc:
base-url: 'https://MY_DOMAIN/api/v3'
oauth:
authorize-url: 'https://MY_DOMAIN/oauth/authorize'
token-url: 'https://MY_DOMAIN/oauth/token'
logout-url: 'https://MY_DOMAIN/oauth/logout'
client-id: 'console'
client-secret: 'console' # choose or generate a secret
# If Application Server enabled, defaults for MY_DOMAIN:
as:
mqtt:
public-address: 'http://MY_DOMAIN:1883'
public-tls-address: 'https://MY_DOMAIN:8883'
webhooks:
downlink:
public-address: 'MY_DOMAIN:1885/api/v3'
Sure. This are the contents of the docker-compose.yml:
version: '3.7' services: stack: image: thethingsnetwork/lorawan-stack:3.9.4 entrypoint: ttn-lw-stack command: start restart: unless-stopped depends_on: - redis - cockroach volumes: - ./blob:/srv/ttn-lorawan/public/blob - ./config/stack:/stack:ro # If using Let's Encrypt: - ./acme:/var/lib/acme
ah, you're missing
services:
stack:
entrypoint: ttn-lw-stack -c /config/ttn-lw-config-docker.yml
If I add that option I get the following log when trying to start the dockers and the service doesn't start:
stack_1 | open /config/stack/ttn-lw-stack-docker.yml: no such file or directory
I've changed the path and the filename to match the ones that I have, which are the ones explained in the Getting Started guide that you linked. Using /config/ttn-lw-config-docker.yml
has the same result though, as well as config/stack/...
and ./config/stack/...
TTN_LW_OAUTH_SERVER_ADDRESS
is not a config parameter.TTN_LW_OAUTH_SERVER_ADDRESS: https://mydomain:8885/oauth # this one is not a real config
I was testing right now and this seems to not be true by the way. This parameter is, at the very least, used when I try to login to the server via the CLI. If I comment the parameter and do a login it tries to send me to localhost
which causes an error since my computer is not running a server, but with the parameter active it sends me to my domain and everything works as explained above.
What is the status here?
@benolayinka is this being addressed with self-signed certs on localhost?
@kschiffer can we show at least the full error for users to see what's going on? I.e. wrong issuer, expired cert, wrong host name?
@kschiffer can we show at least the full error for users to see what's going on? I.e. wrong issuer, expired cert, wrong host name?
Iirc the exact error gets swallowed by the OAuth package, so that has to be addressed first. I'll take another look to see how we can improve the communication there.
@kschiffer that was already addressed by https://github.com/TheThingsNetwork/lorawan-stack/pull/3352
OK, so what is the action item here? @benolayinka @nejraselimovic what is the user experience now?
Even with #3352, the errors are still mostly unhelpful. E.g. I tried authorizing the console using an incorrect client secret and the error I got was client is not authorized to request a token using this method
, which is misleading to say the least. The same error is thrown if the client has not set redirect URIs.
I think these unspecific error messages are a part of the security concept of the specification. See also openshift/osin#169
So I think our best bet here is to improve troubleshooting guides in the doc.
So I think our best bet here is to improve troubleshooting guides in the doc.
OK!
This issue and some others are addressed in https://thethingsstack.io/getting-started/installation/troubleshooting/. Please create issues for specific unaddressed errors
Summary
Missing Authentication reference in the Troubleshooting section of the documentation. https://thethingsstack.io/getting-started/troubleshooting/
...
Why do we need this ?
The text is there but it links to the same page so it's supposed to exist already.
...
What is already there? What do you see now?
Same as above
...
What is missing? What do you want to see?
I've been having trouble with logging in to the Stack console with the message "Forbidden: Token exchange refused". I've tried everything explained in #2521, #2838, #1752, and this has also been talked about in #2353 and #2714. Since this has been a returning problem, a nice troubleshooting guide would be very useful so there would be no need to read a bunch of threads trying to fix it.
...
How do you propose to document this?
Really just a thorough summary of everything that could fix it in an understandable and easy to follow way.
...
Can you do this yourself and submit a Pull Request?
Not really since this should go in the https://thethingsstack.io/getting-started/troubleshooting page
...