Lorawan-stack: ๋‹ค๋ฅธ ์œ„์น˜์— ์„œ๋ฒ„ ์„ค์น˜ ์ง€์›

์— ๋งŒ๋“  2020๋…„ 01์›” 07์ผ  ยท  31์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: TheThingsNetwork/lorawan-stack

์š”์•ฝ


TTN Network Server, Application Server, Join Server๋ฅผ ๋ณ„๋„๋กœ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋งค์šฐ ์œ ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ ๊ฐ€์ด๋“œ์—์„œ๋Š” ttn-lw-stack all-in-one ์„ค์น˜ ์ง€์นจ๋งŒ ์ฐพ์•˜์ง€๋งŒ ์„œ๋กœ ๋‹ค๋ฅธ ํ™˜๊ฒฝ์—์„œ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋„๋ก ํ•˜๋ ค๋ฉด ๊ฐ ์„œ๋ฒ„๋ฅผ ๋ณ„๋„๋กœ ์„ค์น˜ํ•˜๋Š” ์˜ต์…˜์ด ์—†์Šต๋‹ˆ๋‹ค.
...

์ด๊ฒƒ์ด ์™œ ํ•„์š”ํ•ฉ๋‹ˆ๊นŒ?


์ด๊ฒƒ์€ ๋ฐฐํฌ๋ฅผ ์œ„ํ•œ ์œ ์—ฐํ•œ ๋ฐฉ๋ฒ•์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ํ›Œ๋ฅญํ•œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ๊ฒŒ์ดํŠธ์›จ์ด์— 3๊ฐœ์˜ ์„œ๋ฒ„(NS, AS, JS)๋ฅผ ๋ชจ๋‘ ์„ค์น˜ํ•˜๋„๋ก ์„ ํƒํ•˜๊ฑฐ๋‚˜ JS๊ฐ€ ์žˆ๋Š” ๋‹ค๋ฅธ ์„œ๋ฒ„๋ฅผ ์„ ํƒํ•˜๊ณ  ๊ฒŒ์ดํŠธ์›จ์ด์— NS ๋ฐ AS๋งŒ ์œ ์ง€ํ•˜์—ฌ ์—ฌ๋Ÿฌ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ์ค‘์•™ ์ง‘์ค‘์‹์œผ๋กœ ์›๊ฒฉ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—.
...

์ด๋ฏธ ๊ฑฐ๊ธฐ์— ๋ฌด์—‡์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์ง€๊ธˆ ๋ฌด์—‡์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?


์ง€๊ธˆ์€ 3๊ฐœ์˜ ์„œ๋ฒ„(NS, AS ๋ฐ JS)๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•˜๋Š” ttn-lw-stack์„ ์„ค์น˜ํ•˜๋Š” ๋ฐฉ๋ฒ•๋งŒ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
...

์—†์–ด์ง„ ๋ฌผ๊ฑด ์žˆ์–ด์š”? ๋ญ๋ฅผ๋ณด๊ณ  ์‹ถ์œผ์„ธ์š”?


NS, AS, JS๋ฅผ ํ•˜๋‚˜์˜ ์„ค์น˜/ํŒจํ‚ค์ง€์— ๋ชจ๋‘ ์„ค์น˜ํ•˜๋Š” ๋Œ€์‹  ๋ณ„๋„๋กœ ์„ค์น˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
...

์ด๊ฒƒ์„ ๋ฌธ์„œํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์–ด๋–ป๊ฒŒ ์ œ์•ˆํ•ฉ๋‹ˆ๊นŒ?


์‹œ์ž‘ํ•˜๊ธฐ ๊ฐ€์ด๋“œ์— ์ถ”๊ฐ€ํ•˜์„ธ์š”.
...

์ด ์ž‘์—…์„ ์ง์ ‘ ์ˆ˜ํ–‰ํ•˜๊ณ  Pull Request๋ฅผ ์ œ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?


ํ˜„์žฌ๋กœ์„œ๋Š” ์ด๊ฒƒ์ด ์ด๋ฏธ ๋ถ€๋ถ„์ ์œผ๋กœ ๊ตฌํ˜„๋˜์—ˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์œผ๋ฉฐ ์•„๋งˆ๋„ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ๋‚˜๋ณด๋‹ค ๋” ํšจ์œจ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๊ณ  ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
...

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]

์ด๋Ÿฌํ•œ ์„œ๋น„์Šค๊ฐ€ ๋™์ผํ•œ ํด๋Ÿฌ์Šคํ„ฐ ๋ฐ ์„œ๋ธŒ๋„ท์˜ ์ผ๋ถ€์ธ ๊ฒฝ์šฐ ๊ตฌ์„ฑ ์š”์†Œ๋‹น ์„œ๋น„์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์€ ๊ทธ๋ฆฌ ์–ด๋ ต์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ง€๊ธˆ์€ ์ด ๋ฌธ์ œ์˜ ๋ฒ”์œ„๋ฅผ ๋‹ค์Œ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ง€์นจ์œผ๋กœ ์ง€์ •ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋…๋ฆฝ ์‹คํ–‰ํ˜• Identity Server ์„ค์น˜
  • ๋…๋ฆฝ ์‹คํ–‰ํ˜• ๊ฐ€์ž… ์„œ๋ฒ„ ์„ค์น˜
  • ๋…๋ฆฝํ˜• ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ์ดํŠธ์›จ์ด ์„œ๋ฒ„, ๋„คํŠธ์›Œํฌ ์„œ๋ฒ„ ๋ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์™€ ํ•จ๊ป˜ ๋ผ์šฐํŒ… ํด๋Ÿฌ์Šคํ„ฐ ์„ค์น˜

@johanstokking ๊ท€ํ•˜์˜ ์‘๋‹ต๊ณผ ๋ฐฑ๋กœ๊ทธ์— ๋ฌธ์ œ๋ฅผ ์ถ”๊ฐ€ํ•ด ์ฃผ์…”์„œ ๋Œ€๋‹จํžˆ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ๋™์•ˆ, ๋‹น์‹ ์ด ์ด๊ฒƒ์„ ๋„์™€์ค„ ์ˆ˜ ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ช…๋ น์œผ๋กœ ์กฐ์ธ ์„œ๋ฒ„๋ฅผ ๋‹จ๋…์œผ๋กœ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.
ttn-lw-stack start js --cluster.network-server "ns_ip_address" --cluster.application-server "as_ip_address"

๋‚ด๊ฐ€ ์•Œ ์ˆ˜์—†๋Š” ๊ฒƒ์€ Join ์„œ๋ฒ„๊ฐ€ Join_Req๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ์ง€์ •๋œ ๋„คํŠธ์›Œํฌ ์„œ๋ฒ„์— Join_Ans๋ฅผ ์ž๋™์œผ๋กœ ๋ณด๋‚ผ ํฌํŠธ์ž…๋‹ˆ๋‹ค.

๋‹ค์‹œ ํ•œ๋ฒˆ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

@zamashal ์‚ฌ์‹ค JS๋Š” ์„œ๋ฒ„์ด๊ณ  NS์™€ AS๋Š” ํด๋ผ์ด์–ธํŠธ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ NS ๋ฐ AS์—์„œ JS ํด๋Ÿฌ์Šคํ„ฐ ์ฃผ์†Œ๋ฅผ ๊ตฌ์„ฑํ•˜์‹ญ์‹œ์˜ค. ๋”ฐ๋ผ์„œ ๊ฐœ๋ณ„ ๊ตฌ์„ฑ ์š”์†Œ์ด์ง€๋งŒ ๋™์ผํ•œ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋™์ผํ•œ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ์„œ๋กœ๋ฅผ ์‹ ๋ขฐํ•˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์œ„ํ•ด ์„ค๊ณ„๋œ ํด๋Ÿฌ์Šคํ„ฐ ์ธ์ฆ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์—์ง€์— GS, NS ๋ฐ AS๋ฅผ ๋ฐฐํฌํ•˜๊ณ  ํด๋ผ์šฐ๋“œ์— JS๋ฅผ ๋ฐฐํฌํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ๊ทธ๋ ‡์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๊ฒฝ์šฐ ์ง€์›๋˜๋Š” LoRaWAN ๋ฐฑ์—”๋“œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด interop์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด NS๋Š” TLS ํด๋ผ์ด์–ธํŠธ ์ธ์ฆ์„ ํ†ตํ•ด JS์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

JS๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก NS๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ๊ณผ interop ๊ตฌ์„ฑ์œผ๋กœ JS๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค( --help ). ์ด๊ฒƒ์€ ๋ถˆํ–‰ํžˆ๋„ ์•„์ง ์™„์ „ํžˆ ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

@johanstokking ๋‹ค์‹œ ํ•œ๋ฒˆ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค! ๋‚˜๋Š” ๋‹น์‹ ์ด ์„ค๋ช… ํ•œ๋Œ€๋กœ์ด ์„ค์ •์„ ์ž‘๋™ ์‹œํ‚ค๋ ค๊ณ  ๋…ธ๋ ฅํ•ด ์™”์Šต๋‹ˆ๋‹ค. ํ•œ ๊ฐ€์ง€ ํ—ท๊ฐˆ๋ฆฌ๋Š” ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ œ๊ณตํ•œ ๋งํฌ ์— Semtech Join Server์™€์˜ ์ƒํ˜ธ ์šด์šฉ์„ฑ ์„ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์˜ˆ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Semtech ๋˜๋Š” ๊ธฐํƒ€์™€ ๊ฐ™์€ ์™ธ๋ถ€๊ฐ€ ์•„๋‹Œ TTN Stack์˜ Join Server ์ž์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ ํ•ฉ๋‹ˆ๋‹ค. configure.yml ๋ฐ example/js.yml ์— ๋Œ€ํ•œ ๊ตฌ์„ฑ์„ ๊ณ„์† ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ์„๊นŒ?

์™ธ๋ถ€ JS(TTN ์Šคํƒ์˜ JS๋ผ๊ณ ๋„ ํ•จ)์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋„๋ก NS๋ฅผ ์ด๋ฏธ ๊ตฌ์„ฑํ–ˆ์ง€๋งŒ Join_Req๋ฅผ ๋ณด๋‚ด๊ธฐ ์œ„ํ•ด ์กฐ์ธ ์„œ๋ฒ„์˜ ํฌํŠธ 8886 (Interop/tls)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—ฐ๊ฒฐ์ด ๊ฑฐ๋ถ€๋˜์ง€๋งŒ 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 ์ฃผ์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ „์šฉ interop ํฌํŠธ(๊ธฐ๋ณธ๊ฐ’ 8886)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ ์ธ์ฆ์„œ๋ฅผ ๋ฐœ๊ธ‰ํ•˜๋Š” ์‚ฌ์„ค CA๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋“ค์€ NS์— ์˜ํ•ด ์—์ง€์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์กฐ์ธ ์„œ๋ฒ„์—์„œ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ํด๋ผ์ด์–ธํŠธ CA๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด๋Š” NetID๋ณ„๋กœ ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ํ•ญ์ƒ ๊ฐœ์ธ ๋„คํŠธ์›Œํฌ์—์„œ NetID 000000 ๋ฐ 000001 ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ LoRa Alliance์— ๊ฐ€์ž…ํ•˜์—ฌ ์ง์ ‘ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

interop.sender-client-ca.source ๋ฅผ directory ํ•˜๊ณ  ์—ฌ๊ธฐ์— 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์ด๊ณ  JS interop์—์„œ ๊ตฌ์„ฑํ•œ listen-tls ์˜ 8886 ํฌํŠธ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ root-ca ๋Š” (์˜ˆ์‹œ์™€ ๋‹ฌ๋ฆฌ) _server ์ธ์ฆ์„œ_์˜ ๋ฃจํŠธ CA์ž…๋‹ˆ๋‹ค. ๋™์ผํ•œ CA์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. NS์—์„œ ์ด๋ฏธ ์‹ ๋ขฐํ•˜๋Š” ์ƒ์šฉ(๋˜๋Š” Let's Encrypt) ์„œ๋ฒ„ ์ธ์ฆ์„œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์–‘์ชฝ์—์„œ ๋””๋ฒ„๊ทธ ๋กœ๊ทธ๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋ฉด( log.level=debug ) ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์„ ๋ณด๊ฑฐ๋‚˜ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋ฅผ ์ถ”์ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ–‰์šด์„ ๋น•๋‹ˆ๋‹ค!

๋˜ํ•œ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ ์ด๋ฅผ ๋ฌธ์„œํ™”ํ•˜๊ธฐ ์œ„ํ•œ ํ’€ ์š”์ฒญ์„ ์ž์œ ๋กญ๊ฒŒ ์ œ์ถœํ•˜์‹ญ์‹œ์˜ค. ๊ฐ€์ด๋“œ๊ฐ€ ํ•„์š”ํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์ฐธ์กฐ ํŽ˜์ด์ง€ ์—๋„ ์•ฝ๊ฐ„์˜ ์‚ฌ๋ž‘์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

@johanstokking , ๋‚˜๋Š” ์ด๊ฒƒ์— ๋Œ€ํ•ด ์ž‘์—…ํ•  ๊ฒƒ์ด๋ฉฐ,

์•ˆ๋…•ํ•˜์„ธ์š” @johanstokking - ๋ชจ๋“  ์ผ์ด ์ž˜ ๋˜๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์ง„ํ–‰ ์ƒํ™ฉ์„ ์•Œ๋ ค๋“œ๋ฆฌ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋ถˆํ–‰ํžˆ๋„, ์ €๋Š” ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๋งŽ์€ ์˜ค๋ฅ˜๋ฅผ ํ•ด๊ฒฐํ•ด ์™”์œผ๋ฉฐ ์—ฌ๊ธฐ์—์„œ ์ œ๊ฐ€ ์ง๋ฉดํ•œ ์ตœ์‹  ์˜ค๋ฅ˜๋ฅผ ๊ณต์œ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. interop์„ ์„ค์ •ํ•˜๊ณ  ๊ธฐ๋ณธ ํฌํŠธ 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

๊ท€ํ•˜ ๋˜๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ์ด๋Ÿฌํ•œ ์˜ค๋ฅ˜๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ดํ•ดํ•˜๊ณ  ๊ทธ๋Ÿฌํ•œ ์˜ค๋ฅ˜์˜ ์›์ธ์ด ๋  ์ˆ˜ ์žˆ๋Š” ์›์ธ์„ ์•„๋Š” ๋ฐ ๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๊ท€ํ•˜์˜ ์ง€์†์ ์ธ ์ง€์›์— ๋‹ค์‹œ ํ•œ ๋ฒˆ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

Join Server๋Š” https๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

NS๊ฐ€ DNS๋ฅผ ํ†ตํ•ด js-server_ip ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@johanstokking ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์˜ˆ, ํฌํŠธ 8886์„ docker-compose.yml์˜ ํ˜ธ์ŠคํŠธ์— ๋งคํ•‘ํ•˜์ง€ ์•Š์€ ๊ฒƒ์œผ๋กœ ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋‚ด๊ฐ€ ์ง๋ฉดํ•œ ๋ฌธ์ œ๋Š” TLS ํ•ธ๋“œ์…ฐ์ดํฌ ์˜ค๋ฅ˜์ž…๋‹ˆ๋‹ค.

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

์šฐ์„  --tls.insecure-skip-verify ํ”Œ๋ž˜๊ทธ๋ฅผ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ์ธ์ฆ์„œ ํ™•์ธ์„ ์š”๊ตฌํ•˜๊ณ  ๋™์ผํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ๋‚ด ๋„์ปค ์ปจํ…Œ์ด๋„ˆ์˜ ์ธ์ฆ ๊ธฐ๊ด€์„ ์‹ ๋ขฐํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์Šคํƒ์— ์…ธ์„ ์—ด์—ˆ๋Š”๋ฐ ์ปดํ“จํ„ฐ์—์„œ ์ธ์ฆ์„œ๋ฅผ ์‹ ๋ขฐํ•˜๊ธฐ ์œ„ํ•ด ์ธ์ฆ์„œ๋ฅผ /usr/local/share/ca-certificates/ ์— ๋ณต์‚ฌํ•˜๋ ค๊ณ  ํ•  ๋•Œ๋งˆ๋‹ค Permission denied ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

--tls.insecure-skip-verify ํ”Œ๋ž˜๊ทธ๊ฐ€ ํ—ˆ์šฉํ–ˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ๊ตฌํ˜„์ด ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋‚ด ๋ฌธ์ œ๋Š” ๋„์ปค ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋‚ด ์ž์ฒด ์„œ๋ช… ์ธ์ฆ์„œ๋ฅผ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์„ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฑฐ๊ธฐ์— ๋‚ด๊ฐ€ ๋ˆ„๋ฝ ๋œ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

ํด๋ผ์ด์–ธํŠธ 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 ์— ๋„ฃ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. interop ๊ตฌ์„ฑ๊ณผ ๋‹ค๋ฅธ ๋””๋ ‰ํ„ฐ๋ฆฌ์ž…๋‹ˆ๋‹ค.

@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์—๋Š” ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

๊ท€ํ•˜์˜ ์žฅ์น˜๊ฐ€ Join Server์— ๋“ฑ๋ก๋˜์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์•„, ์•„๋งˆ ๊ทธ ๋•Œ๋ฌธ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ธ€์Ž„, ๋‚ด๊ฐ€ ํ•œ ๊ฒƒ์€ --js.join-eui-prefix ํ”Œ๋ž˜๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด์ง€๋งŒ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ฌด์‹œํ•˜๋ ค๊ณ  ํ–ˆ๋˜ ๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ์— ๊ฐ‡ํ˜”์Šต๋‹ˆ๋‹ค: ๋ฌธ์ œ 1942

์ˆ˜๋™์œผ๋กœ redis ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ํ–‰์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์žฅ์น˜๋ฅผ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด ํ˜•์‹์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๊ทธ ๋™์•ˆ ๋‹ค๋ฅธ ๋ฌธ์ œ๋ฅผ ๊ณ„์† ๋ฌด์‹œํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ๋ฌธ์ œ์˜ ๋Œ€์‹œ๋ณด๋“œ์— ์•ก์„ธ์Šคํ•˜์—ฌ ๋Œ€์‹œ๋ณด๋“œ์— ์žฅ์น˜๋ฅผ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ sender unknown ๋ผ๋Š” ์˜ค๋ฅ˜๊ฐ€ ํ‘œ์‹œ๋˜๋ฉฐ ๊ฒŒ์ดํŠธ์›จ์ด๊ฐ€ ์ธ์‹๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๋ถˆํ‰ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ฝ˜์†”์—์„œ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  ํ–ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ Disconnected ๋ฉ๋‹ˆ๋‹ค. gateway_ip์™€ server_ip์˜ ์ฃผ์†Œ๋ฅผ ์ž…๋ ฅํ•˜๋ ค๊ณ  ํ–ˆ์ง€๋งŒ ๋‘˜ ๋‹ค ์•„์ง ์•„๋ฌด๋Ÿฐ ์ฐจ์ด๊ฐ€ ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Sender unknown์€ ์ตœ์ข… ์žฅ์น˜์˜ NetID๊ฐ€ ๋„คํŠธ์›Œํฌ ์„œ๋ฒ„์˜ NetID๋กœ ์„ค์ •๋˜์ง€ ์•Š์•˜์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋‘˜ ๋‹ค 000000 ๋กœ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ttn-lw-cli end-device set <app-id> <dev-id> --net-id=000000 ํ•˜์—ฌ CLI๋ฅผ ํ†ตํ•ด ์ตœ์ข… ์žฅ์น˜์˜ NetID๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚ด ttn-lw-cli ๊ฐ€ ์ด์ƒํ•˜๊ฒŒ ์ž‘๋™ํ•˜๊ณ  ๊ธฐ๋ณธ ์˜ต์…˜์œผ๋กœ ๋กœ๊ทธ์ธ ๋ช…๋ น๋งŒ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ตฌ์„ฑ ํŒŒ์ผ์ด๋‚˜ ์ธ์ฆ ๊ธฐ๊ด€์„ ์ง€์ •ํ•˜๋ฉด 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"

๋กœ๊ทธ์ธ ํ›„ ์„ฑ๊ณต์ ์ธ ์ธ์ฆ์„ ๋‚˜ํƒ€๋‚ด๋Š” INFO Got OAuth access token ๋ฉ”์‹œ์ง€๊ฐ€ ์žˆ์—ˆ์ง€๋งŒ ์ด๊ฒƒ์ด ๋‚ด http ์„ค์ •๊ณผ ๊ด€๋ จ์ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ๋‚ด 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 ๋กœ๊ทธ์—์„œ ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ํ‘œ์‹œ๋˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

์œ ํšจํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ID๊ฐ€ ์•„๋‹Œ ์‚ฌ์šฉ์ž ์ด๋ฆ„์œผ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” MQTT ํด๋ผ์ด์–ธํŠธ์ž…๋‹ˆ๋‹ค.

ํžŒํŠธ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๊ฐ€๋ฆฌํ‚ค๋ฉฐ 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

๋˜ํ•œ ํฌํŠธ 1884์— ํ…”๋„ท์„ ์—ฐ๊ฒฐํ•˜๊ณ  ttn-lw-cli ๋„๊ตฌ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ๋ฐ์ดํ„ฐ ํŒจํ‚ท์ด ๋“ค์–ด์˜ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ™•์‹คํžˆ ํŒจํ‚ท ๊ตํ™˜์ด ๋ฐœ์ƒํ•˜์ง€๋งŒ ๋””๋ฒ„๊ทธ ๋กœ๊ทธ๋Š” ์—ฌ์ „ํžˆ ๋‹ค์Œ ์˜ค๋ฅ˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. "transport: authentication handshake failed: context deadline exceeded". Reconnecting...

๋งˆ์นจ๋‚ด --insecure ํ”Œ๋ž˜๊ทธ๋ฅผ end-device set ๋ช…๋ น์— ์ถ”๊ฐ€ํ•˜์—ฌ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค!! TLS์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์ง€๋งŒ ์–ด์จŒ๋“  ์ง€๊ธˆ์€ ๊ฑฑ์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋‹ค์‹œ ํ•œ๋ฒˆ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

๋‚ด๊ฐ€ ๊ทธ ์„ค์ • ํ•œ ํ›„ ์•Œ๋ ค ์˜ค์‹น --root-keys.app-key.key ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ --net-id ์˜์€์„์œ„ํ•œ ๊ณผ์ •์— ์ฐธ์—ฌ end-device ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ ๋‚˜๋Š” ๋…๋ฆฝ์— ์ตœ์ข… ์žฅ์น˜์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๊ธฐ ์‹œ์ž‘ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„! ๋‚ด๊ฐ€ ์ง๋ฉดํ•œ ๋ชจ๋“  ๋ฌธ์ œ๋ฅผ ํ†ตํ•ด ํฐ ๋„์›€์„ ์ฃผ์…”์„œ ๋‹ค์‹œ ํ•œ ๋ฒˆ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

๋Œ€๋‹จํ•ด! ์—ฌ๊ธฐ์— ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋ฌธ์„œํ™”ํ•˜์—ฌ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ •๋ง ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋™๊ธฐ ๋ถ€์—ฌ๋„ ํ•ด์ฃผ์‹œ๊ณ  ์ฒซ ํŒฌ์ผ€์ดํฌ๊ฐ€ ๋˜์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰