Lorawan-stack: 支持在不同位置安装服务器

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

概括


能够分别安装 TTN 网络服务器、应用程序服务器和加入服务器将非常有帮助。 目前在指南中,我只找到了安装 ttn-lw-stack 多合一的说明,但如果您希望它们在不同的环境中一起工作,则没有单独安装每个服务器的选项。
...

我们为什么需要这个 ?


这是一个很棒的功能,可以实现灵活的部署方法。 你可以选择把3台服务器(NS、AS、JS)都安装在网关上,也可以选择另外一台带JS的服务器,只在网关上保留NS和AS,实现多个网关的集中远程管理,等等在。
...

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


现在我只看到一种安装 ttn-lw-stack 的方法,它包括所有 3 个服务器(NS、AS 和 JS)。
...

有什么不见了? 你要看什么?


我希望看到单独安装 NS、AS 和 JS 的说明,而不是将它们全部放在一个安装/包中。
...

你打算如何记录这一点?


将其添加到入门指南中。
...

你能自己做这个并提交一个拉取请求吗?


目前还没有,我不确定这是否已经部分实施,可能有人知道如何比我更有效地做到这一点。
...

documentation

所有31条评论

感谢@zamashal的建议

确实,入门指南目前适用于单进程方法,但您可能已经看到,您可以单独启动组件。 看;

$ ttn-lw-stack start --help
Start The Things Stack

Usage:
  ttn-lw-stack start [is|gs|ns|as|js|console|gcs|dtc|qrg|all]... [flags]

当这些服务属于同一集群和子网时,为每个组件生成服务并不是很困难。

我现在将这个问题的范围界定为如何操作的说明;

  • 安装独立的身份服务器
  • 安装独立的加入服务器
  • 安装具有使用独立服务的网关服务器、网络服务器和应用程序服务器的路由集群

@johanstokking非常感谢您的回复并将问题添加到待办事项中。 与此同时,我想知道你是否可以帮我解决这个问题。 我使用以下命令单独启动了加入服务器:
ttn-lw-stack start js --cluster.network-server "ns_ip_address" --cluster.application-server "as_ip_address"

我想不通的是加入服务器在哪个端口接收 Join_Req 并且它是否会自动将 Join_Ans 发送到指定的网络服务器?

再次感谢!

@zamashal实际上 JS 是服务器,NS 和 AS 是客户端。 所以在NS和AS中配置JS集群地址。 这使得它们在同一个集群中工作,尽管它们是独立的组件。 请注意,这使用了集群身份验证,这是为在同一集群中相互信任的组件而设计的。 如果您在边缘部署 GS、NS 和 AS,而在云中部署 JS,则情况可能并非如此。

在这种情况下,您必须通过 LoRaWAN 后端接口使用互操作,这也受支持。 这允许 NS 通过 TLS 客户端身份验证联系您的 JS。

这分为两部分:配置 NS 以使用您的 JS和使用interop配置配置您的 JS(请参阅--help )。 不幸的是,这还没有完全记录下来。

再次感谢@johanstokking ! 我一直在尝试按照您的解释使此设置正常工作。 有一件事让我很困惑。 在您提供的链接中,有一个关于如何设置与 Semtech Join Server 的互操作性的示例。 但是,我正在尝试使用 TTN Stack 的 Join Server 本身,而不是像 Semtech 或其他外部的东西。 我还需要为configure.ymlexample/js.yml吗? 如果是这样,那会是什么样子?

我已经将我的 NS 配置为使用外部 JS(又名,TTN Stack 的 JS),但是使用加入服务器的端口8886 (Interop/tls)发送 Join_Req,连接被拒绝,尽管JS 似乎正在监听那个端口。

谢谢!

@zamashal这里大概是需要做的事情;

加入服务器互操作配置

见标志:

      --interop.listen-tls string                                      Address for the interop server to listen on (default ":8886")
      --interop.sender-client-ca.blob.bucket string                    Bucket to use
      --interop.sender-client-ca.blob.path string                      Path to use
      --interop.sender-client-ca.directory string                      OS filesystem directory, which contains sender client CA configuration
      --interop.sender-client-ca.source string                         Source of the sender client CA configuration (static, directory, url, blob)
      --interop.sender-client-ca.url string                            URL, which contains sender client CA configuration

Interop 有自己的专用侦听器,该侦听器使用 TLS 客户端身份验证。 您可以使用与 gRPC 相同的公共 IP 地址并使用专用的互操作端口(默认为 8886)。

您需要一个颁发客户端证书的私有 CA。 这些由 NS 在边缘使用。 您可以在加入服务器中配置受信任的客户端 CA,这是每个 NetID。 您可以随时在您的私有网络中使用 NetIDs 000000000001 ,或者加入 LoRa 联盟,您可以自己获得一个。

interop.sender-client-ca.sourcedirectory并将config.yml放入其中,例如:

# Experimentation
000000: ca-000000.pem

# The Things Network Foundation
#000013: ca-000013.pem

您的私有 CA 进入ca-000000.pem 。 您可以像示例中那样为 TTN NetID 添加 TTN 的 CA,只是为了向您展示这是如何工作的。

网络服务器互操作配置

就像文档化,但实际上你需要的是本地 JS 配置。 这将如下所示:

fqdn: 'thethings.example'
port: 8886
protocol: 'BI1.0'
tls:
  root-ca: 'path/to/clientca.pem'
  certificate: 'path/to/clientcert.pem'
  key: 'path/to/clientkey.pem'

这里, thethings.example是您加入服务器的 FQDN,8886 是您在 JS 互操作中配置的listen-tls的端口。

此外, root-ca是(与示例中所说的不同)_server 证书_的根 CA。 这可能是同一个 CA。 如果您使用 NS 已经信任的商业(或 Let's Encrypt)服务器证书,您也可以省略它。

在任一侧 ( log.level=debug ) 启用调试日志,您应该会看到工作正常或不工作的原因。 祝你好运!

此外,如果您完成这项工作,请随时提交拉取请求以记录此内容。 它可能需要一个指南,但参考页面也需要一些爱。

@johanstokking ,我将致力于此,希望一旦我弄明白,我一定会提出拉取请求来更新指南。 非常感谢您的帮助!

@johanstokking - 我希望你一切顺利。 我想告诉你我的进展。 不幸的是,我一直在解决很多错误以使其正常工作,我将在这里与您分享我面临的最新错误。 设置互操作并配置我的网络服务器以在默认端口 8886 上向加入服务器发送加入请求后,我的网络服务器日志中不断出现以下错误:
error="join-request to join-server error: http post error: Post http://js-server_ip:8886: dial tcp js-server_ip:8886: connect: connection refused"

如果我将网络服务器配置为将加入请求发送到 gRPC 服务器的端口 1884,则会在网络服务器日志中收到以下错误:
level=error msg="uplink: processing uplink frame error" ctx_id=f046310d-e528-4dd2-9dcb-6d5c8232a799 error="join-request to join-server error: http post error: Post http://js-server_ip:1884: net/http: HTTP/1.x transport connection broken: malformed HTTP response \"\\x00\\x00\\f\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x05\\x00\\x00@\\x00\\x00\\x03\\x00\\x00\\xff\\xff\""
结合 ttn 堆栈日志中的以下错误:
stack_1 | WARN grpc: Server.Serve failed to create ServerTransport: connection error: desc = "transport: http2Server.HandleStreams received bogus greeting from client: \"POST / HTTP/1.1\\r\\nHost: 1\"" namespace=grpc

我希望您或其他任何人可以帮助我了解如何解决这些错误并了解可能导致此类错误的原因。

再次感谢您一直以来的支持!

加入服务器仅可通过 https 使用。

看起来 NS 也无法通过 DNS 解析js-server_ip

谢谢@johanstokking! 所以是的,事实证明我没有在 docker-compose.yml 中将端口 8886 映射到我的主机。 现在我面临的问题是 TLS 握手错误:

tls: failed to verify client's certificate: x509: certificate signed by unknown authority

一方面,我使用了--tls.insecure-skip-verify标志,但它仍然坚持验证证书并给了我同样的错误。 我认为问题在于我需要信任我的 docker 容器中的证书颁发机构。 我在堆栈中打开了一个 shell,每当我尝试将证书复制到/usr/local/share/ca-certificates/以便机器信任它们时,它都会给我一个Permission denied错误。

我认为--tls.insecure-skip-verify标志应该允许它,但也许你的实现是不同的。 我现在的问题是 docker 容器没有让我选择信任我的自签名证书。 有什么我在那里想念的吗?

客户端证书是否由客户端 CA 配置中定义的SenderID的 CA 之一签名?

这就是加入服务器用来验证客户端证书的内容; 不是系统信任或任何东西。

我试图遵循它,但它与网站上的说明并不完全一致。
我的 config.yml 中有以下内容:

000000: ca-000000.pem
join-servers:
  - file: './example/js.yml'
    join-euis:
    - 'abcd000000000000/16'

然后我把它放到我的 js.yml 中:

fqdn: 'thethings.example'
port: 8886
protocol: 'BI1.0'
tls:
  root-ca: 'path/to/clientca.pem'
  certificate: 'path/to/clientcert.pem'
  key: 'path/to/clientkey.pem'

发件人客户端 CA 尚未记录,我们将作为关闭或替换此问题的一部分进行记录。 请参阅(此处)[ https://github.com/TheThingsNetwork/lorawan-stack/issues/1818#issuecomment -575534345]。 它是一个特殊文件,它有自己的设置来引用该文件:

      --interop.sender-client-ca.blob.bucket string                    Bucket to use
      --interop.sender-client-ca.blob.path string                      Path to use
      --interop.sender-client-ca.directory string                      OS filesystem directory, which contains sender client CA configuration
      --interop.sender-client-ca.source string                         Source of the sender client CA configuration (static, directory, url, blob)
      --interop.sender-client-ca.url string                            URL, which contains sender client CA configuration

所以source需要设置为directory并且您将上述格式的配置放在该文件夹中的config.yml中。 这是与互操作配置不同的目录。

谢谢@johanstokking! 我没有意识到应该在不同的目录中,我终于解决了证书问题,现在从 ttn-stack 调试日志中处理这个错误(我故意掩盖了密钥,但它们是正确的):

stack_1      |   INFO Join not accepted                        dev_eui=0000000000000000 error=error:pkg/redis:not_found (entity not found) join_eui=0000000000000000 method=POST namespace=joinserver/interop remote_addr=gateway_ip:49426 request_id=01E1D3PZ63CQ7VNCE5JE8SDC3J url=/
stack_1      |   INFO Request handled                          duration=2.948762ms error=error:pkg/interop:join_req (join-request failed) error_cause=error:pkg/redis:not_found (entity not found) method=POST namespace=interop remote_addr=gateway_ip:49426 request_id=01E1D3PZ63CQ7VNCE5JE8SDC3J status=400 url=/

注意,gateway_ip 也是 NS 和 AS 所在的地方。

这也是我在 NS 调试日志中看到的:

time="2020-02-18T16:36:52-05:00" level=error msg="uplink: processing uplink frame error" ctx_id=ef20804f-13a8-4f7f-b90e-ce279c1e11ea error="join-request to join-server error: response error, code: JoinReqFailed, description: error:pkg/redis:not_found (entity not found)"

据我所知,该错误似乎是在抱怨我的 docker-compose 的 redis 组件配置错误。 我重新访问了配置教程以确保一切都匹配。 我的配置是这样的:

volumes:
      - ${DEV_DATA_DIR:-.env/data}/redis:/data

所以我继续把它改成这样:

volumes:
    - './data/redis:/data'

然后,我开始看到以下错误,它甚至不允许我运行堆栈:

stack_1      | error:cmd/internal/shared:initialize_identity_server (could not initialize Identity Server)
stack_1      | --- error:pkg/identityserver:db_needs_migration (the database needs to be migrated)
stack_1      | --- pq: database "ttn_lorawan" does not exist

我不确定是否有必要进行此更改,在./data/redis/我只看到一个文件 ``appendonly.aof```,所以似乎我遗漏了一些东西..

我不确定是否有必要进行此更改,在./data/redis/我只看到一个文件 ``appendonly.aof```,所以似乎我遗漏了一些东西..

不,事实上这对 Redis 来说没问题。

您的设备似乎未在加入服务器中注册?

哦,大概就是这个原因。 好吧,我所做的只是使用标志--js.join-eui-prefix但这似乎还不够。 我被困在另一个我一直试图忽略的问题上

我可以通过手动向redis数据库添加行来注册设备吗? 如果有,格式是什么? 这可能会帮助我在此期间继续忽略另一个问题。

我能够访问另一个问题的仪表板并在仪表板上注册设备。 我现在看到一个错误,它说sender unknown我相信这是在抱怨网关未被识别。 我尝试从控制台添加网关,但它仍然显示Disconnected 。 我尝试输入 gateway_ip 和 server_ip 的地址,但两者似乎都没有任何区别。

发件人未知可能意味着终端设备的 NetID 未设置为您的网络服务器的 NetID。 两者都应设置为000000

您可以通过 CLI 使用ttn-lw-cli end-device set <app-id> <dev-id> --net-id=000000设置终端设备的 NetID

我的ttn-lw-cli表现得很奇怪,我只能使用默认选项运行 login 命令,如果我指定任何配置文件或证书颁发机构,我只会得到permission denied 。 我通过更改 chmod 和 chown 尝试了几种绕过权限的方法,我继续得到permission denied 。 如果我只输入ttn-lw-cli login来运行默认配置,我会得到:

Post https://localhost:8885/oauth/token: x509: certificate signed by unknown authority

尽管 docker-compose up 运行良好,没有证书问题或任何其他错误。 知道我可能遗漏了什么可能导致权限被拒绝吗?
谢谢!

你能发布你的服务器和 CLI 配置以及你尝试做的事情吗?

我只是想先用命令sudo ttn-lw-cli login登录,这是我的配置:

# sudo ttn-lw-cli config
                         --allow-unknown-hosts="false"
                  --application-server-enabled="true"
             --application-server-grpc-address="localhost:8884"
                                          --ca=""
                                      --config="/etc/ttn-cli/.ttn-lw-cli.yml,/root/snap/ttn-lw-stack/149/.ttn-lw-cli.yml,/root/snap/ttn-lw-stack/149/.config/.ttn-lw-cli.yml"
                              --credentials-id=""
         --device-claiming-server-grpc-address="localhost:8884"
      --device-template-converter-grpc-address="localhost:8884"
                      --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:8885/oauth"
                               --output-format="json"
              --qr-code-generator-grpc-address="localhost:8884"

因此,运行默认值会给我带来我之前分享的certificate signed by unknown authority错误。 但是由于证书问题,我尝试添加以下选项: sudo ttn-lw-cli login --ca "path/to/ca.pem"但这给了我一个权限被拒绝的错误。

我试图添加以下选项: sudo ttn-lw-cli login --ca "path/to/ca.pem"

这很好。 您也可以将其放在配置文件或环境中。

但这给了我一个权限被拒绝的错误。

在 CLI 或服务器上? 你有日志吗?

我认为服务器错误? 这是我所能看到的:

root<strong i="6">@myserver</strong>:/etc/ttn-cli# sudo ttn-lw-cli login --ca="/etc/ttn-cli/ca.pem" --log.level="debug"
open /etc/ttn-cli/ca.pem: permission denied

我也试图给它chmod 777权限,但仍然得到同样的错误..

我终于能够通过将配置文件添加到/root/snap/ttn-lw-stack/149/.ttn-lw-cli.yml来解决这个问题!

我现在收到certificate signed by unknown authority错误。 ttn-lw-cli工具如何信任证书? 这是完整的日志:

root<strong i="8">@localhost</strong>:/etc/ttn-stack# sudo ttn-lw-cli login --callback=false --config="/root/snap/ttn-lw-stack/149/.ttn-lw-cli.yml" --log.level="debug" --insecure="true" --allow-unknown-hosts="true" --ca="/root/snap/ttn-lw-stack/149/ca.pem"
  WARN Access token expired at 5:17PM
 ERROR Please login with the login command
 DEBUG ccResolverWrapper: sending update to cc: {[{localhost:1884  <nil> 0 <nil>}] <nil> <nil>}
 DEBUG pickfirstBalancer: HandleSubConnStateChange: 0xc00087caa0, {CONNECTING <nil>}
 DEBUG pickfirstBalancer: HandleSubConnStateChange: 0xc00087caa0, {READY <nil>}
 DEBUG Finished unary call                      duration=2.376756ms grpc_method=AuthInfo grpc_service=ttn.lorawan.v3.EntityAccess namespace=grpc
  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=fork/exec /usr/bin/xdg-open: permission denied
  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.JX2QFUHNVVWMEYTTRQ3S4DTGPI5VXBYJWVJQ2ZI.OG5C4HQXGMRQ4LVW7ES4IZRNH2L5OJOING2SWOW74LFLQAYDH64Q
 ERROR Could not exchange OAuth access token    error=Post https://localhost/oauth/token: x509: certificate signed by unknown authority
Post https://localhost/oauth/token: x509: certificate signed by unknown authority

我正在使用与 docker-compose 一起运行的ttn-stack信任的相同 ca.pem。

我通过在ttn-lw-cli配置中使用 http URI 和 http 端口再次解决了登录/证书问题。 当我运行sudo ttn-lw-cli end-device set "mysensor1app" "mysensor1dev" --net-id=000000 --log.level="debug" ,我看到以下内容:

root<strong i="8">@localhost</strong>:/etc/ttn-stack$ sudo ttn-lw-cli end-device set "mysensor1app" "mysensor1dev" --net-id=000000 --log.level="debug"
 DEBUG Using access token (valid until 6:42PM)
 DEBUG ccResolverWrapper: sending update to cc: {[{localhost:1884  <nil> 0 <nil>}] <nil> <nil>}
 DEBUG pickfirstBalancer: HandleSubConnStateChange: 0xc000414730, {CONNECTING <nil>}
  WARN grpc: addrConn.createTransport failed to connect to {localhost:1884  <nil> 0 <nil>}. Err :connection error: desc = "transport: authentication handshake failed: context deadline exceeded". Reconnecting...
 DEBUG pickfirstBalancer: HandleSubConnStateChange: 0xc000414730, {TRANSIENT_FAILURE connection error: desc = "transport: authentication handshake failed: context deadline exceeded"}
 DEBUG pickfirstBalancer: HandleSubConnStateChange: 0xc000414730, {CONNECTING <nil>}
  WARN grpc: addrConn.createTransport failed to connect to {localhost:1884  <nil> 0 <nil>}. Err :connection error: desc = "transport: authentication handshake failed: context deadline exceeded". Reconnecting...

这是我的ttn-lw-cli配置:

                         --allow-unknown-hosts="true"
                  --application-server-enabled="true"
             --application-server-grpc-address="localhost:1884"
                                          --ca="/root/snap/ttn-lw-stack/149/ca.pem"
                                      --config="/etc/ttn-stack/.ttn-lw-cli.yml,/root/snap/ttn-lw-stack/149/.ttn-lw-cli.yml,/root/snap/ttn-lw-stack/149/.config/.ttn-lw-cli.yml"
                              --credentials-id=""
         --device-claiming-server-grpc-address="localhost:1884"
      --device-template-converter-grpc-address="localhost:1884"
                      --gateway-server-enabled="true"
                 --gateway-server-grpc-address="localhost:1884"
                --identity-server-grpc-address="localhost:1884"
                                --input-format="json"
                                    --insecure="true"
                         --join-server-enabled="true"
                    --join-server-grpc-address="localhost:1884"
                                   --log.level="info"
                      --network-server-enabled="true"
                 --network-server-grpc-address="localhost:1884"
                        --oauth-server-address="http://localhost/oauth"
                               --output-format="json"
              --qr-code-generator-grpc-address="localhost:1884"

我认为这可能与我的 http 设置有关,尽管我在登录后收到了INFO Got OAuth access token消息,这似乎表明身份验证成功。

我也开始从docker-compose日志中看到以下错误:

stack_1      |  DEBUG Rejected authentication                  client_id=mqtt_5bc528ca.ae4ea8 error=error:pkg/ttnpb:identifiers (invalid identifiers) error_cause=error:pkg/errors:validation (invalid `application_id`: value does not match regex pattern "^[a-z0-9](?:[-]?[a-z0-9]){2,}$") field=application_id name=ApplicationIdentifiersValidationError namespace=applicationserver/io/mqtt reason=value does not match regex pattern "^[a-z0-9](?:[-]?[a-z0-9]){2,}$" username=
stack_1      |   WARN Failed to setup connection               error=error:pkg/ttnpb:identifiers (invalid identifiers) error_cause=error:pkg/errors:validation (invalid `application_id`: value does not match regex pattern "^[a-z0-9](?:[-]?[a-z0-9]){2,}$") field=application_id name=ApplicationIdentifiersValidationError namespace=applicationserver/io/mqtt reason=value does not match regex pattern "^[a-z0-9](?:[-]?[a-z0-9]){2,}$" remote_addr=172.18.0.1:57472

我无法弄清楚它指的是什么,但我认为它可能会抱怨我添加的相同设备和应用程序,但仍然没有加入传感器。

我现在收到certificate signed by unknown authority错误。 ttn-lw-cli工具如何信任证书?

它使用您通过ca传递的 CA 文件。 该文件应该指向服务器证书(如果它是自签名的)或签署服务器证书的 CA。

这是我的ttn-lw-cli配置:

如果您不想使用 TLS,此配置看起来不错。 但是,服务器是否在其非 TLS 配置中侦听这些地址?

我也开始从docker-compose日志中看到以下错误:

这是一个 MQTT 客户端,使用的用户名不是有效的应用程序 ID。

感谢您的提示! 指向cert.pem而不是ca.pem解决了certificate signed by unknown authority问题。 但是,我仍然收到其他连接错误。 我肯定在监听端口1884

user<strong i="10">@localhost</strong>:/etc/ttn-stack$ sudo netstat -tulpn | grep LISTEN
tcp6       0      0 :::1884                 :::*                    LISTEN      18793/docker-proxy

当我 telnet 到端口 1884 并运行ttn-lw-cli工具时,我还可以看到数据包通过。 所以肯定会发生数据包交换,但调试日志仍然给我以下错误: "transport: authentication handshake failed: context deadline exceeded". Reconnecting...

我终于通过在end-device set命令中添加--insecure标志解决了这个问题!! 看来我在使用 TLS 时遇到了问题,但无论如何我现在都不担心
再次感谢!

我很高兴地通知您,在设置--root-keys.app-key.key--net-idend-device的加入过程成功完成,我开始从独立的终端设备上获取数据。应用服务器! 再次感谢您对我所面临的所有问题的大力帮助!

那太棒了! 如果您能在这里记录您的场景,那将会很棒,这样我们就可以合并它。

也感谢你的动力和成为第一个煎饼。

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

相关问题

johanstokking picture johanstokking  ·  8评论

adriansmares picture adriansmares  ·  9评论

kschiffer picture kschiffer  ·  6评论

johanstokking picture johanstokking  ·  6评论

htdvisser picture htdvisser  ·  9评论