Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLI Auth Error - Following Change to TLS Redirection in Config #2965

Closed
ZeroSum24 opened this issue Jul 23, 2020 · 3 comments
Closed

CLI Auth Error - Following Change to TLS Redirection in Config #2965

ZeroSum24 opened this issue Jul 23, 2020 · 3 comments
Assignees
Labels
bug Something isn't working ui/cli This is related to ttn-lw-cli
Milestone

Comments

@ZeroSum24
Copy link

ZeroSum24 commented Jul 23, 2020

Summary

Using ttn-lw-cli v3.8.7 I'm unable to run console commands against a self-managed TTN v3.8.7 deployment. This was working previously and has since stopped following the addition of the http.redirect-to-tls flag in the deployment configuration.

The console is still accessible and working as expected. I am not sure if this is a bug or a system configuration issue. Either way your help would be much appreciated!

Steps to Reproduce

  1. Install dockerised TTN deployment on a remote server with a Let's Encrypt certificate
  2. Follow the getting started guide on setting up the deployment, adding in the http.redirect-to-tls flag, set to true
  3. Install the ttn-lw-cli toolset on another machine, and point the CLI to use the server domain
  4. Try to run a command using the setup ttn-lw-cli toolset

ttn-lw-stack.yml - Server:

# Identity Server configuration
 is:
  # Email configuration for "REMOVED"
   email:
     sender-name: 'The Things Stack'
     sender-address: 'noreply@REMOVED'
     network:
       name: 'TTN-stack'
       console-url: 'https://REMOVED/console'
       identity-server-url: 'https://REMOVED/oauth'

 # Web UI configuration for "REMOVED":
   oauth:
      ui:
        canonical-url: 'https://REMOVED/oauth'
        is:
          base-url: 'https://REMOVED/api/v3'

 # HTTP server configuration
 http:
   cookie:
     block-key: 'REMOVED'                # generate 32 bytes (openssl rand -hex 32)
     hash-key: 'REMOVED'                 # generate 64 bytes (penssl rand -hex 64)
   metrics:
     password: 'REMOVED'               # choose a password
   pprof:
     password: 'REMOVED'                 # choose a password
   redirect-to-tls: 'true'

# Let's encrypt for "REMOVED"
 tls:
   source: 'acme'
   acme:
     dir: '/var/lib/acme'
     email: 'REMOVED'
     hosts: ['REMOVED']
     default-host: 'REMOVED'

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

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

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

  oauth:
    authorize-url: 'https://REMOVED/oauth/authorize'
    token-url: 'https://REMOVED/oauth/token'
    client-id: 'console'
    client-secret: 'console'          # choose or generate a secret

ttn-lw-cli config -- Server:

                   --allow-unknown-hosts="false"
              --application-server-enabled="true"
         --application-server-grpc-address="localhost:8884"
                                      --ca=""
                                  --config="/home/ttn/ttn-stack-v3/config/stack/.ttn-lw-cli.yml,/home/ttn/snap/ttn-lw-stack/192/.ttn-lw-cli.yml,/home/ttn/snap/ttn-lw-stack/192/.config/.ttn-lw-cli.yml"
                          --credentials-id=""
     --device-claiming-server-grpc-address="localhost:8884"
  --device-template-converter-grpc-address="localhost:8884"
                           --dump-requests="false"
                  --gateway-server-enabled="true"
             --gateway-server-grpc-address="localhost:8884"
            --identity-server-grpc-address="localhost:8884"
                            --input-format="json"
                                --insecure="false"
                     --join-server-enabled="true"
                --join-server-grpc-address="localhost:8884"
                               --log.level="info"
                  --network-server-enabled="true"
             --network-server-grpc-address="localhost:8884"
                    --oauth-server-address="https://localhost:443/oauth"
                           --output-format="json"
          --qr-code-generator-grpc-address="localhost:8884"

ttn-lw-stack config -- CLI:

                                       --as.device-kek-label=""
                                    --as.interop.blob.bucket=""
                                      --as.interop.blob.path=""
                                  --as.interop.config-source=""
                                      --as.interop.directory=""
                                             --as.interop.id=""
                                            --as.interop.url=""
                                              --as.link-mode="all"
                                            --as.mqtt.listen=":1883"
                                        --as.mqtt.listen-tls=":8883"
                                    --as.mqtt.public-address="localhost:1883"
                                --as.mqtt.public-tls-address="localhost:8883"
                       --as.webhooks.downlink.public-address="http://localhost:1885/api/v3"
                   --as.webhooks.downlink.public-tls-address=""
                                    --as.webhooks.queue-size="16"
                                        --as.webhooks.target="direct"
                           --as.webhooks.templates.directory=""
                       --as.webhooks.templates.logo-base-url=""
                                 --as.webhooks.templates.url=""
                                       --as.webhooks.timeout="5s"
                                       --as.webhooks.workers="16"
                                    --blob.aws.access-key-id=""
                                         --blob.aws.endpoint=""
                                           --blob.aws.region=""
                                --blob.aws.secret-access-key=""
                                    --blob.aws.session-token=""
                                      --blob.gcp.credentials=""
                                 --blob.gcp.credentials-file=""
                                      --blob.local.directory="./public/blob"
                                             --blob.provider="local"
                                       --cache.redis.address=""
                                      --cache.redis.database="0"
                            --cache.redis.failover.addresses=""
                               --cache.redis.failover.enable="false"
                          --cache.redis.failover.master-name=""
                                     --cache.redis.namespace=""
                                      --cache.redis.password=""
                                     --cache.redis.pool-size="0"
                                             --cache.service=""
                                           --cluster.address=""
                                --cluster.application-server=""
                                     --cluster.crypto-server=""
                                    --cluster.gateway-server=""
                                   --cluster.identity-server=""
                                              --cluster.join=""
                                       --cluster.join-server=""
                                              --cluster.keys=""
                                              --cluster.name=""
                                    --cluster.network-server=""
                                               --cluster.tls="false"
                                                    --config="REMOVED"
                                             --console.mount=""
                               --console.oauth.authorize-url="http://localhost:1885/oauth/authorize"
                                   --console.oauth.client-id="console"
                               --console.oauth.client-secret="console"
                                  --console.oauth.logout-url="http://localhost:1885/oauth/logout"
                                   --console.oauth.token-url="http://localhost:1885/oauth/token"
                                    --console.ui.as.base-url="http://localhost:1885/api/v3"
                                     --console.ui.as.enabled="true"
                                --console.ui.assets-base-url="/assets"
                              --console.ui.branding-base-url=""
                                  --console.ui.canonical-url="http://localhost:1885/console"
                                       --console.ui.css-file="console.css"
                                   --console.ui.descriptions=""
                         --console.ui.documentation-base-url="https://thethingsstack.io/3.8.7"
                                  --console.ui.edtc.base-url="http://localhost:1885/api/v3"
                                   --console.ui.edtc.enabled="true"
                                    --console.ui.gs.base-url="http://localhost:1885/api/v3"
                                     --console.ui.gs.enabled="true"
                                    --console.ui.icon-prefix="console-"
                                    --console.ui.is.base-url="http://localhost:1885/api/v3"
                                     --console.ui.is.enabled="true"
                                        --console.ui.js-file="console.js"
                                    --console.ui.js.base-url="http://localhost:1885/api/v3"
                                     --console.ui.js.enabled="true"
                                       --console.ui.language="en"
                                    --console.ui.ns.base-url="http://localhost:1885/api/v3"
                                     --console.ui.ns.enabled="true"
                                   --console.ui.qrg.base-url="http://localhost:1885/api/v3"
                                    --console.ui.qrg.enabled="true"
                                     --console.ui.sentry-dsn=""
                                      --console.ui.site-name="The Things Stack for LoRaWAN"
                                      --console.ui.sub-title="Management platform for The Things Stack for LoRaWAN"
                                   --console.ui.support-link=""
                                    --console.ui.theme-color=""
                                          --console.ui.title="Console"
                             --device-repository.blob.bucket=""
                               --device-repository.blob.path=""
                           --device-repository.config-source=""
                               --device-repository.directory=""
                                     --device-repository.url=""
                                               --dtc.enabled=""
                                            --events.backend="internal"
                                  --events.cloud.publish-url=""
                                --events.cloud.subscribe-url=""
                                      --events.redis.address=""
                                     --events.redis.database="0"
                           --events.redis.failover.addresses=""
                              --events.redis.failover.enable="false"
                         --events.redis.failover.master-name=""
                                    --events.redis.namespace=""
                                     --events.redis.password=""
                                    --events.redis.pool-size="0"
                               --frequency-plans.blob.bucket=""
                                 --frequency-plans.blob.path=""
                             --frequency-plans.config-source=""
                                 --frequency-plans.directory=""
                                       --frequency-plans.url="https://raw.githubusercontent.com/TheThingsNetwork/lorawan-frequency-plans/master"
                   --gcs.basic-station.allow-cups-uri-update="false"
                         --gcs.basic-station.default.lns-uri="wss://localhost:8887"
          --gcs.basic-station.owner-for-unknown.account-type=""
               --gcs.basic-station.owner-for-unknown.api-key=""
                    --gcs.basic-station.owner-for-unknown.id=""
                 --gcs.basic-station.require-explicit-enable="false"
                                          --gcs.require-auth="true"
               --gcs.the-things-gateway.default.firmware-url="https://thethingsproducts.blob.core.windows.net/the-things-gateway/v1"
                --gcs.the-things-gateway.default.mqtt-server="mqtts://localhost:8881"
             --gcs.the-things-gateway.default.update-channel="stable"
                       --grpc.allow-insecure-for-credentials="false"
                                               --grpc.listen=":1884"
                                           --grpc.listen-tls=":8884"
               --gs.basic-station.fallback-frequency-plan-id=""
                                   --gs.basic-station.listen=":1887"
                               --gs.basic-station.listen-tls=":8887"
                  --gs.basic-station.use-traffic-tls-address="false"
                         --gs.basic-station.ws-ping-interval="30s"
                                                --gs.forward="=00000000/0"
                                         --gs.mqtt-v2.listen=":1881"
                                     --gs.mqtt-v2.listen-tls=":8881"
                                 --gs.mqtt-v2.public-address="localhost:1881"
                             --gs.mqtt-v2.public-tls-address="localhost:8881"
                                            --gs.mqtt.listen=":1882"
                                        --gs.mqtt.listen-tls=":8882"
                                    --gs.mqtt.public-address="localhost:1882"
                                --gs.mqtt.public-tls-address="localhost:8882"
                            --gs.require-registered-gateways="false"
                                  --gs.udp.addr-change-block="1m0s"
                                 --gs.udp.connection-expires="1m0s"
                              --gs.udp.downlink-path-expires="15s"
                                          --gs.udp.listeners=":1700="
                                      --gs.udp.packet-buffer="50"
                                    --gs.udp.packet-handlers="16"
                               --gs.udp.rate-limiting.enable="true"
                             --gs.udp.rate-limiting.messages="10"
                            --gs.udp.rate-limiting.threshold="10ms"
                                 --gs.udp.schedule-late-time="800ms"
                  --gs.update-connection-stats-debounce-time="3s"
                  --gs.update-gateway-location-debounce-time="1h0m0s"
                                     --http.cookie.block-key=""
                                      --http.cookie.hash-key=""
                                        --http.health.enable="true"
                                      --http.health.password=""
                                               --http.listen=":1885"
                                           --http.listen-tls=":8885"
                                     --http.log-ignore-paths=""
                                       --http.metrics.enable="true"
                                     --http.metrics.password=""
                                         --http.pprof.enable="true"
                                       --http.pprof.password=""
                                     --http.redirect-to-host=""
                                      --http.redirect-to-tls="false"
                                         --http.static.mount="/assets"
                                   --http.static.search-path="/usr/local/Cellar/ttn-lw-stack/3.8.7/libexec/public"
                                      --http.trusted-proxies="10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
                                        --interop.listen-tls=":8886"
                      --interop.sender-client-ca.blob.bucket=""
                        --interop.sender-client-ca.blob.path=""
                        --interop.sender-client-ca.directory=""
                           --interop.sender-client-ca.source=""
                              --interop.sender-client-ca.url=""
                                 --interop.sender-client-cas=""
                              --is.auth-cache.membership-ttl="10m0s"
                                           --is.database-uri="postgresql://root@localhost:26257/ttn_lorawan_dev?sslmode=disable"
                              --is.email.network.console-url="http://localhost:1885/console"
                      --is.email.network.identity-server-url="http://localhost:1885/oauth"
                                     --is.email.network.name="The Things Stack for LoRaWAN"
                                         --is.email.provider=""
                                   --is.email.sender-address=""
                                      --is.email.sender-name=""
                                 --is.email.sendgrid.api-key=""
                                 --is.email.sendgrid.sandbox="false"
                                     --is.email.smtp.address=""
                                 --is.email.smtp.connections="0"
                                    --is.email.smtp.password=""
                                    --is.email.smtp.username=""
                            --is.email.templates.blob.bucket=""
                              --is.email.templates.blob.path=""
                              --is.email.templates.directory=""
                               --is.email.templates.includes=""
                                 --is.email.templates.source=""
                                    --is.email.templates.url=""
                              --is.end-device-picture.bucket="end_device_pictures"
                          --is.end-device-picture.bucket-url="/assets/blob/end_device_pictures"
                                            --is.oauth.mount=""
                               --is.oauth.ui.assets-base-url="/assets"
                             --is.oauth.ui.branding-base-url=""
                                 --is.oauth.ui.canonical-url="http://localhost:1885/oauth"
                                      --is.oauth.ui.css-file="oauth.css"
                                  --is.oauth.ui.descriptions=""
                                   --is.oauth.ui.icon-prefix="oauth-"
                                   --is.oauth.ui.is.base-url="http://localhost:1885/api/v3"
                                    --is.oauth.ui.is.enabled="true"
                                       --is.oauth.ui.js-file="oauth.js"
                                      --is.oauth.ui.language="en"
                                    --is.oauth.ui.sentry-dsn=""
                                     --is.oauth.ui.site-name="The Things Stack for LoRaWAN"
                                     --is.oauth.ui.sub-title=""
                                   --is.oauth.ui.theme-color=""
                                         --is.oauth.ui.title=""
                                 --is.profile-picture.bucket="profile_pictures"
                             --is.profile-picture.bucket-url="/assets/blob/profile_pictures"
                           --is.profile-picture.use-gravatar="true"
              --is.user-registration.admin-approval.required="false"
     --is.user-registration.contact-info-validation.required="false"
                  --is.user-registration.invitation.required="false"
                 --is.user-registration.invitation.token-ttl="168h0m0s"
     --is.user-registration.password-requirements.max-length="1000"
     --is.user-registration.password-requirements.min-digits="1"
     --is.user-registration.password-requirements.min-length="8"
    --is.user-registration.password-requirements.min-special="0"
  --is.user-registration.password-requirements.min-uppercase="1"
                                       --js.device-kek-label=""
                                        --js.join-eui-prefix="0000000000000000/0"
                                        --key-vault.provider="static"
                                          --key-vault.static=""
                                                 --log.level="info"
                   --ns.application-uplink-queue.buffer-size="1000"
                                        --ns.cooldown-window="1s"
                                   --ns.deduplication-window="200ms"
                        --ns.default-mac-settings.adr-margin="15"
                   --ns.default-mac-settings.class-b-timeout="1m0s"
                   --ns.default-mac-settings.class-c-timeout="5m0s"
                 --ns.default-mac-settings.desired-rx1-delay="5"
          --ns.default-mac-settings.status-count-periodicity="200"
           --ns.default-mac-settings.status-time-periodicity="24h0m0s"
                                      --ns.dev-addr-prefixes=""
                                       --ns.device-kek-label=""
                        --ns.downlink-priorities.join-accept="highest"
                       --ns.downlink-priorities.mac-commands="highest"
           --ns.downlink-priorities.max-application-downlink="high"
                                    --ns.interop.blob.bucket=""
                                      --ns.interop.blob.path=""
                                  --ns.interop.config-source=""
                                      --ns.interop.directory=""
                                            --ns.interop.url=""
                                                 --ns.net-id="000000"
                                            --pba.cluster-id=""
                                    --pba.data-plane-address=""
                                      --pba.forwarder.enable="false"
                                   --pba.forwarder.token-key=""
                           --pba.forwarder.worker-pool.limit="1024"
                      --pba.home-network.blacklist-forwarder="true"
                        --pba.home-network.dev-addr-prefixes=""
                                   --pba.home-network.enable="false"
                        --pba.home-network.worker-pool.limit="4096"
                                                --pba.net-id="000000"
                                             --pba.tenant-id=""
                                       --pba.tls.certificate=""
                                               --pba.tls.key=""
                                      --pba.tls.key-vault.id=""
                                            --pba.tls.source=""
                                             --redis.address="localhost:6379"
                                            --redis.database="0"
                                  --redis.failover.addresses=""
                                     --redis.failover.enable="false"
                                --redis.failover.master-name=""
                                           --redis.namespace="ttn,v3"
                                            --redis.password=""
                                           --redis.pool-size="0"
                                                --rights.ttl="2m0s"
                                                --sentry.dsn=""
                                     --tls.acme.default-host=""
                                              --tls.acme.dir=""
                                            --tls.acme.email=""
                                           --tls.acme.enable="false"
                                         --tls.acme.endpoint="https://acme-v02.api.letsencrypt.org/directory"
                                            --tls.acme.hosts=""
                                           --tls.certificate="cert.pem"
                                  --tls.insecure-skip-verify="false"
                                                   --tls.key="key.pem"
                                          --tls.key-vault.id=""
                                               --tls.root-ca=""
                                                --tls.source=""

What do you see now?

ttn-lw-cli login
 ERROR Please login with the login command     
  INFO Opening your browser on https://openstack-floating-193-206.ecdf.ed.ac.uk:443/oauth/authorize?client_id=cli&redirect_uri=local-callback&response_type=code
  INFO After logging in and authorizing the CLI, we'll get an access token for future commands.
  INFO Waiting for your authorization...       
 ERROR Could not exchange OAuth access token    error=oauth2: cannot fetch token: 405 Method Not Allowed
Response: {
  "code": 2,
  "message": "error:pkg/errors/web:unknown (Method Not Allowed)",
  "details": [
    {
      "@type": "type.googleapis.com/ttn.lorawan.v3.ErrorDetails",
      "namespace": "pkg/errors/web",
      "message_format": "Method Not Allowed",
      "attributes": {
        "message": "Method Not Allowed"
      },
      "code": 2
    }
  ]
}

What do you want to see instead?

Ideally, I would like to get authorised and be able to login via the console.

Environment

Both CLI and deployment are running v3.8.7. The deployment and the CLI work as expected when the http.redirect-to-tls flag is set to false or not present. This has also been tested using several different machines against the same deployment, reproducing the error each time (with each CLI running v3.8.7 too)

Can you do this yourself and submit a Pull Request?

Nope, I would happily do so if I could fix it, but with this I very much appreciated your help!

@neoaggelos neoaggelos self-assigned this Jul 23, 2020
@neoaggelos neoaggelos added bug Something isn't working ui/cli This is related to ttn-lw-cli labels Jul 23, 2020
@neoaggelos neoaggelos added this to the July 2020 milestone Jul 23, 2020
@neoaggelos
Copy link
Contributor

neoaggelos commented Jul 23, 2020

Hi @ZeroSum24 , thanks for reporting this issue. Indeed, I was able to reproduce the problem. This has been around since 3.8.0 apparently.

EDIT: As a workaround, until a fix is released, you should be able to login successfully be removing the port number (:443) from the OAuth server address in .ttn-lw-cli.yml.

@ZeroSum24
Copy link
Author

@neoaggelos thanks very much for your help and the quick response! I've applied that workaround on our end which has resolved the issue for the moment.

@neoaggelos
Copy link
Contributor

Should be fixed with #3120

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working ui/cli This is related to ttn-lw-cli
Projects
None yet
Development

No branches or pull requests

3 participants