Lorawan-stack: 在我们的入门指南中添加故障排除部分

创建于 2020-04-12  ·  31评论  ·  资料来源: TheThingsNetwork/lorawan-stack

概括

比如#2352。 在入门指南中添加故障排除部分,以解决遵循入门指南时可能出现的常见问题。

我们为什么需要这个 ?

使文档对新用户更友好。

什么已经存在? 你现在看到了什么?

没有故障排除部分。

缺什么? 你要看什么?

入门指南末尾的故障排除部分,供用户查找常见问题,以及解决问题的原因和简单步骤。

您打算如何记录这一点?

我们的文档通常应该简单易懂。 但是,有一个故障排除部分,带有特定的错误消息和修复它们的说明,对于新用户可能会非常有帮助。

你可以自己做这个并提交一个拉请求吗?

是的

shared documentation

最有用的评论

大家好,

在 ubuntu 上安装 TTN 3.7 时我遇到了类似的问题。

我遵循了 fox27374 的指南(https://github.com/fox27374/lora-stack),但仍然有问题。
我的安装是在 VM 和 Ubuntu 上。 我使用自签名证书进行本地开发。

我仍然坚持这个错误。 《拒绝兑换代币》
先感谢您,

所有31条评论

嗨,这绝对是一个大拇指。 在遵循指南时,我遇到了一些问题和未解决的问题。 目前我被这个错误困住了。 也许您也可以在文档中指出这一点?
image

@fox27374你能打开浏览器开发者工具并粘贴window.PAGE_DATA值吗? 您可以在看到此错误时在浏览器控制台中输入它。

此外,您是否遵循了入门指南中的所有步骤,即创建控制台 OAuth 客户端?

你好,
这是 window.PAGE_DATA 以及我用于创建 oauth 客户端的命令。 值得一提的是,我使用自己的证书(由实验室 CA 签名)。

数据
window.PAGE_DATA = { "error": { "code": 7, "message": "error:pkg/web/oauthclient:exchange (token exchange refused)", "details": [{ "@type": "type.googleapis.com/ttn.lorawan.v3.ErrorDetails", "namespace": "pkg/web/oauthclient", "name": "exchange", "message_format": "token exchange refused", "code": 7 }] } };

命令
docker-compose run --rm stack is-db create-oauth-client --id console --name "Console" --owner admin --secret "SM2CE7335KDAIILCA76KETRHDQTTDAQTDJHBSL6RCOX3WFZFDZ4Q" --redirect-uri "https://lora01.ntslab.loc/console/oauth/callback" --redirect-uri "/console/oauth/callback"

非常感谢!
干杯,
丹尼尔

@fox27374感谢您提供更多信息。

配置的 OAuth URL 是什么,即您配置的/token URL? 您可以编辑敏感内容。

假设您通过 Docker 运行 The Things Stack,您能否确认lora01.ntslab.loc在 Docker 容器中解析?

你好,

感谢您的回复并在这里帮助我。 内容尚不合理,它现在是一个实验室设置,作为对未来生产环境的测试。 我想摆脱 Actility 服务器 :)

是的,我通过 Docker 在 Linux 服务器上运行 TTN 堆栈。 lora01.ntslab.loc在 hosts 文件中配置,因此名称解析应该可以工作。

/token URL 是:
令牌网址:' https://lora01.ntslab.loc/oauth/token '

如果您需要更多信息,可以直接查看docker-compose.yml和 ttn -lw-stack.yml文件。 我还使用启动脚本进行初始化( start.sh )。

先感谢您,
丹尼尔

@fox27374

是的,我通过 Docker 在 Linux 服务器上运行 TTN 堆栈。 lora01.ntslab.loc在 hosts 文件中配置,因此名称解析应该可以工作。

你的意思是你机器的/etc/hosts文件吗? 这不会影响运行堆栈的 Docker 容器,这可能是您看到的问题的根源。

您可以使用以下命令进行检查:

$ docker-compose stack exec nc -z lora01.ntslab.loc

您应该会看到类似于nc: bad address 'lora01.ntslab.loc'的内容。

您可以尝试在 docker-compose.yaml 中添加extra_hosts部分,如下所示:

# docker-compose.yaml
services:
  # ...
  stack:
    # ...
    extra_hosts:
      - "lora01.ntslab.loc:YOUR_IP_ADDRESS"
    # ...

并以docker-compose up -d重新启动

然后主机名解析应该可以工作。 (但是,如果YOUR_IP_ADDRESS类似于127.0.0.1 ,那么您可能仍然会遇到一些错误)

嗨@neoaggelos
谢谢你的信息。 我删除了主机条目并直接在 DNS 服务器上设置 IP/主机名。 此外,我在 docker-compose.yml 中添加了“extra_hosts”条目。
恐怕,错误仍然存​​在。

我在容器中启动了 ash shell 并检查了 dns 分辨率:

$ nslookup lora01.ntslab.loc
Name:      lora01.ntslab.loc
Address 1: 172.24.89.120 lora01.ntslab.loc

所以这看起来不错。 在错误消息令牌交换被拒绝之后,我们可以为 oauth 令牌交换启用任何进一步的调试吗? 很抱歉让您忙于这个......
谢谢

顺便说一句,似乎其他人也有同样的问题

嗨@neoaggelos
谢谢你的信息。 我删除了主机条目并直接在 DNS 服务器上设置 IP/主机名。 此外,我在 docker-compose.yml 中添加了“extra_hosts”条目。

嗯,通过正确的 DNS 配置,您不必设置extra_hosts

恐怕,错误仍然存​​在。

我在容器中启动了 ash shell 并检查了 dns 分辨率:

$ nslookup lora01.ntslab.loc
Name:      lora01.ntslab.loc
Address 1: 172.24.89.120 lora01.ntslab.loc

172.24.89.120来自 Docker 创建的网络,这也可能是失败的原因。

所以这看起来不错。 在错误消息令牌交换被拒绝之后,我们可以为 oauth 令牌交换启用任何进一步的调试吗? 很抱歉让您忙于这个......
谢谢

尝试清除您的 cookie,并从干净的浏览器会话中尝试。 此外,确保从容器中的外壳cat /var/run/secrets/cert.pemcat /var/run/secrets/key.pem堆栈中正确读取证书应该足以检查该证书。

无关; 您是否尝试在 localhost 上设置堆栈? 你成功了吗?

你好,

对不起,我没有提到 172.24.89.120 是实验室服务器本身的 IP 地址。 码头地址是 172.9.0.X

我在私人模式下使用浏览器进行所有测试,因此不涉及 cookie。 “thethings”用户可以读取密钥和证书:

/ $ whoami
thethings

/ $ cat /var/run/secrets/key.pem 
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC7IjZoBd2Mu4Ev
AYDrEh6mBWYw5cRDA02F10OQpbQbm6RigFbODM2owGRyCkkZfAUL2VV9xl5TzdMl
I6IecaA7/F7TpciuiJHmnfRVAbDlPI6EJYybdrU7tmfdeWc/ThuVVNolJFUeap+T
OIzv9MkGbBAF19ju4PJel6z3ef+NUhc5LKfjVQZeieQULX2b9+Hpd4ySdR2Nfzdt
......

我会尝试将设置更改为 localhost 并随时通知您。

对不起,我没有提到 172.24.89.120 是实验室服务器本身的 IP 地址。 码头地址是 172.9.0.X

但是你可以从容器内部curl https://lora01.ntslab.loc吗? 如果不是,报告的错误是什么?

你好,

好像我们明白了。 卷曲提示是一个很好的提示。 这表明 ca.pem 不在受信任的证书存储中:

/ # curl https://lora01.ntslab.loc
curl: (60) SSL certificate problem: self signed certificate in certificate chain

所以我将 ca.pem 证书复制到 /usr/local/share/ca-certificates/

/ $ ls -la /usr/local/share/ca-certificates/ca.pem 
-rw-r--r--    1 thething thething      1310 Apr 14 11:36 /usr/local/share/ca-certificates/ca.pem

通过将其添加到 docker-compose.yml 文件的卷部分:

volumes:
      - "./data/blob:/srv/ttn-lorawan/public/blob"
      - "./config/stack:/config:ro"
      - "./config/stack/cert/ca.pem:/usr/local/share/ca-certificates/ca.pem"

现在我可以登录控制台并且所有证书都是可信的。 惊人的!

这是将受信任的根证书添加到 TTN 容器的最佳/预期方式吗?

很抱歉过早地欣喜若狂。 似乎身份验证令牌仍在数据库中,这就是一切正常的原因。 容器启动后,我需要运行此命令以将 ca.pem 证书添加到受信任的存储中:

docker exec -it --user root ttn-server_stack_1 /usr/sbin/update-ca-certificates

然后 oauth 客户端能够获取令牌并将其存储在数据库中。 我现在可以工作,但这不应该是我猜的最终解决方案。 有任何想法吗?
非常感谢!

@fox27374太好了,您找到了原因。 想出一个干净的解决方案总是一个好的开始。

堆栈尊重您的 CA 的文件名TTN_LW_TLS_ROOT_CA (或tls.root-ca )。 见https://thethingsstack.io/v3.7.0/reference/configuration/the-things-stack/

@johanstokking :我将以下内容添加到 docker-compose.yml

......
    secrets:
      - cert.pem
      - key.pem
      - ca.pem

secrets:
  cert.pem:
    file: config/stack/cert/cert.pem
  key.pem:
    file: config/stack/cert/key.pem
  ca.pem:
    file: config/stack/cert/ca.pem

这样,证书文件在/run/secrets/var/run/secrets的容器中可用。 我在容器中检查了这个直接。

我添加了
TTN_LW_TLS_ROOT_CA: "/var/run/secrets/ca.pem"
docker-compose.yml文件。 错误仍然存​​在。 我还尝试将其添加到ttn-lw-stack.yml

tls:
  source: "file"
  root-ca: "/var/run/secrets/ca.pem"
  certificate: "/var/run/secrets/cert.pem"
  key: "/var/run/secrets/key.pem"

这里也一样。 我仍然得到错误。 可能是某些应用程序,尤其是 oauth 客户端使用操作系统内部受信任的根证书吗? 因为只要我将 ca.pem 添加到受信任的根证书,一切正常。
谢谢,丹尼尔

抄送@adriansmares

你好,这里有消息吗? 我尝试使用 strace 调试对受信任的根证书的访问,但没有成功。

@fox27374你能验证这是否有效吗?

$ curl -cacert /var/run/secrets/ca.pem https://lora01.ntslab.loc

@adriansmares看起来我们需要两件事;

  1. 报告潜在的错误原因,可能是原因属性,因为它是net错误或其他 stdlib
  2. 验证我们在 OAuth 客户端中尊重tls.root-ca

嗨,大家好,

我遇到了同样的 403 错误,在 Vagrant 盒子(带有虚拟盒子)中使用 docker 运行 TTN 堆栈 v3。 - 只是一个沙箱供我创建 Saltstack 配方。

考虑到我处理了 DNS,我尝试了很多方法。

  • 使用自签名证书
  • 重用由 TTN 堆栈在 VPS 上使用letsencrypt创建的一些现有证书。
  • 一个一个地尝试了所有insecure配置

对我来说这不是root-ca的问题,我不知道它是什么。 我们应该为此打开另一个问题吗?

但是有一个问题:据您所知,是否可以在没有 TLS的情况下对其进行配置,仅用于 Vagrant 框中的开发目的? 如果是这样,请您给我一些指示吗?

我可以确认,在我的 VPS 上,它可以与letsencrypt一起正常工作,这当然是我们在生产中所拥有的。

谢谢。

添加c/shared因为它可能不是配置的东西

您好,抱歉回复晚了。 我可以验证 curl 仅适用于 --cacert 参数,因为 ca.pem 证书未安装在受信任的根证书中:

/ $ whoami
thethings
/ $ curl https://lora01.ntslab.loc
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
/ $ curl --cacert /var/run/secrets/ca.pem https://lora01.ntslab.loc
/ $ 

请检查 OAuth 客户端是否遵守 TLS 配置

如果您在堆栈前面使用 nginx,则 nginx 必须处理所有 ssl/tls。

这是 nginx 的配置:

nginx.conf

stream {
    include stream_conf.d/*.conf;
}

stream_conf.d/mqtt.conf

log_format mqtt '$remote_addr [$time_local] $protocol $status $bytes_received '
                '$bytes_sent $upstream_addr';

upstream ttn1 {
    server stack-ip:1881;
    zone tcp_mem 64k;
}
upstream ttn2 {
    server stack-ip:1882;
    zone tcp_mem 64k;
}
upstream ttn3 {
    server stack-ip:1883;
    zone tcp_mem 64k;
}

server {
    listen 8881 ssl; # MQTT secure port
    preread_buffer_size 1k;

    ssl_certificate /etc/letsencrypt/live/FQDN/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/FQDN/privkey.pem; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ssl_session_cache   shared:SSL:128m; # 128MB ~= 500k sessions
    ssl_session_tickets on;
    ssl_session_timeout 8h;

    proxy_pass ttn1;
    proxy_connect_timeout 1s;
}

server {
    listen 8882 ssl; # MQTT secure port
    preread_buffer_size 1k;

    ssl_certificate /etc/letsencrypt/live/FQDN/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/FQDN/privkey.pem; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ssl_session_cache   shared:SSL:128m; # 128MB ~= 500k sessions
    ssl_session_tickets on;
    ssl_session_timeout 8h;

    proxy_pass ttn2;
    proxy_connect_timeout 1s;


server {
    listen 8883 ssl; # MQTT secure port
    preread_buffer_size 1k;

    ssl_certificate /etc/letsencrypt/live/FQDN/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/FQDN/privkey.pem; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ssl_session_cache   shared:SSL:128m; # 128MB ~= 500k sessions
    ssl_session_tickets on;
    ssl_session_timeout 8h;

    proxy_pass ttn3;
    proxy_connect_timeout 1s;
}

server {
    listen 1881; # MQTT secure port
    preread_buffer_size 1k;

    proxy_pass ttn1;
    proxy_connect_timeout 1s;
}

server {
    listen 1882; # MQTT secure port
    preread_buffer_size 1k;

    proxy_pass ttn2;
    proxy_connect_timeout 1s;
}

server {
    listen 1883; # MQTT secure port
    preread_buffer_size 1k;

    proxy_pass ttn3;
    proxy_connect_timeout 1s;
}

你需要在你的站点配置中为所有端口(PORT=1884、1885、1887):

server {
        server_name FQDN;

        location / {
                proxy_pass      http://stack-ip:PORT;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-Host $server_name;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "Upgrade";
                proxy_buffering off;
        }

       listen [::]:PORT ipv6only=on; # managed by Certbot
       listen PORT; # managed by Certbot
}

这适用于端口(PORT/PORTSSL=1885/443、1884/8884、1887/8887):

server {

        server_name FQDN;

        location / {
                proxy_pass      http://stack-ip:PORT;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-Host $server_name;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "Upgrade";
                proxy_buffering off;
        }

        listen [::]:PORTSSL ssl ipv6only=on; # managed by Certbot
        listen PORTSSL ssl; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/FQDN/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/FQDN/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

如您所见,我正在使用让我们加密。

非常感谢@wasn-eu!

这对于#1760 也很有用。

大家好,

在 ubuntu 上安装 TTN 3.7 时我遇到了类似的问题。

我遵循了 fox27374 的指南(https://github.com/fox27374/lora-stack),但仍然有问题。
我的安装是在 VM 和 Ubuntu 上。 我使用自签名证书进行本地开发。

我仍然坚持这个错误。 《拒绝兑换代币》
先感谢您,

@ramampiandra

正如我在 Slack 聊天中所写,要使整个工作正常进行,您需要以下内容:

  • TLS 流量的证书:cert.pem
  • 对应的私钥:key.pem
  • 颁发 cert.pem 的 CA 证书:ca.pem

请确保证书正确无误:

证书.pem

openssl x509 -in cert.pem -text -noout | grep -A 1 Identifier
            X509v3 Subject Key Identifier:
                26:78:63:90:E7:1C:09:B7:DA:B3:7D:81:F0:DE:47:6B:AE:16:58:79
            X509v3 Authority Key Identifier:
                keyid:86:32:F5:56:44:21:EC:E3:2A:D9:5F:6E:87:82:7A:67:C2:F1:77:E8

卡佩姆

openssl x509 -in ca.pem -text -noout | grep -A 1 Identifier
            X509v3 Subject Key Identifier:
                86:32:F5:56:44:21:EC:E3:2A:D9:5F:6E:87:82:7A:67:C2:F1:77:E8

确保 cert.pem 中的颁发机构密钥标识器与 ca.pem 中的主题密钥标识器相同。

在堆栈启动并且所有 docker 容器都启动后,运行以下命令(将“ttn-server_stack_1”调整为您的 TTN 容器的名称):
docker exec -it --user root ttn-server_stack_1 /usr/sbin/update-ca-certificates
这将在容器中安装 ca.pem 证书并将其添加到受信任的证书中。

之后,直接登录到您的容器并测试证书是否有效:

docker-compose exec stack "/bin/ash"
curl https://YOURSERVER.YOUR.DOMAIN

您不应该看到任何结果或错误 - 这意味着您的证书是受信任的。

我希望这有帮助,
干杯

因此,在详细研究了这一点之后,我能够重现并确认确实存在我们的 OAuth 流程不尊重 TLS 配置(特别是根证书)的问题,从而导致令牌交换失败。

我目前正在做一个 PR 来解决这个问题,这个问题应该会在今天晚些时候登陆。

@kschiffer太棒了,谢谢你看这个。 请随时通知我,以便我可以帮助您进行测试。

你好! 还有另一种解决方法,可以暂时解决这个问题?

@dgraposo这应该在 3.8.1 中修复

我现在将关闭此问题,因为焦点转移到“令牌交换被拒绝”问题,该问题已通过 #2511 解决,可以通过 #2521 进一步跟进。 我怀疑这是添加故障排除部分的最大原因。

这个问题对于讨论它的最初目的已经不是很有用了。 如果我们认为仍然需要故障排除部分,我建议在适当的范围内重新打开。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

bafonins picture bafonins  ·  5评论

w4tsn picture w4tsn  ·  6评论

adriansmares picture adriansmares  ·  9评论

johanstokking picture johanstokking  ·  8评论

kschiffer picture kschiffer  ·  4评论