Advertisement
Guest User

tts-open-source-guide.md

a guest
Dec 4th, 2020
473
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.91 KB | None | 0 0
  1. Installing The Things Stack open source with custom certificates is a complex task with quite a few configuration settings. As of November 2020, the [official guide](https://thethingsstack.io/getting-started/installation/) does not describe all the steps needed, so this page will serve as a complete guide.
  2.  
  3. # Prerequisites
  4. - A server with a recommended 4 virtual CPUs and 16GB RAM running Docker and Docker Compose*
  5. - DNS record pointing to your computer's IP address. If hosting privately, you can just use the private IP address (this probably looks like 10.x.x.x or 192.168.x.x).
  6. - Install [docker](https://docs.docker.com/engine/install/ubuntu/) and [docker-compose](https://docs.docker.com/compose/install/#install-compose)
  7.  
  8. ```
  9. sudo apt-get update
  10. sudo apt-get install \
  11. apt-transport-https \
  12. ca-certificates \
  13. curl \
  14. gnupg-agent \
  15. software-properties-common
  16. curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  17. sudo add-apt-repository \
  18. "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
  19. $(lsb_release -cs) \
  20. stable"
  21. sudo apt-get update
  22. sudo apt-get install docker-ce docker-ce-cli containerd.io
  23. sudo usermod -aG docker $USER
  24.  
  25. sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  26. sudo chmod +x /usr/local/bin/docker-compose
  27. ```
  28.  
  29. - Install go
  30.  
  31. ```
  32. sudo snap install go --classic
  33. ```
  34.  
  35. - Install `cfssl` and `cfssljson`:
  36.  
  37. ```
  38. go get -u github.com/cloudflare/cfssl/cmd/cfssl
  39. go get -u github.com/cloudflare/cfssl/cmd/cfssljson
  40. ```
  41.  
  42.  
  43. *Benchmark for 100K devices with 12 confirmed uplinks per day. Your requirements will vary depending on your load and desired redundancy. When testing the installation process (so 0 devices and 0 uploads) I got it running on a 4-core laptop with 4GB of RAM.
  44.  
  45. # Configuration
  46. - Download [ttn-lw-stack-docker.yml](https://thethingsstack.io/getting-started/installation/configuration/ttn-lw-stack-docker-open-source.yml) and [docker-compose.yml](https://thethingsstack.io/getting-started/installation/configuration/docker-compose-open-source.yml). Note that `.yml != .yaml`, so don't get smart and change the file extension because it will throw something off somewhere.
  47. - Create a directory structure. I'm putting everything in a directory called `tts`
  48.  
  49. ```
  50. mkdir tts
  51. mkdir -p tts/config/stack
  52. mv ttn-lw-stack-docker-open-source.yml tts/config/stack/ttn-lw-stack-docker.yml
  53. mv docker-compose-open-source.yml tts/docker-compose.yml
  54. ```
  55.  
  56. If you run `tree tts` you should see the following:
  57.  
  58. ```
  59. tts
  60. ├── config
  61. │ └── stack
  62. │ └── ttn-lw-stack-docker.yml
  63. └── docker-compose.yml
  64. ```
  65.  
  66. - Configure your Docker containers by editing `docker-compose.yml`.
  67. - Replace all instances of `thethings.example.com` with the IP address of your host machine. You can leave `127.0.0.1` in the redis, postgres and CockroachDB sections.
  68. - If using postgres, comment out the Cockroachdb stuff and uncomment the postgres stuff (there are 3 places: container definition, stack dependency, and a stack env variable)
  69. - Uncomment the sections on secrets at the bottom of the file
  70. - Add additional environment variables as described in [this github issue](https://github.com/TheThingsNetwork/lorawan-stack/issues/1230). Note that some of the variables mentioned in that issue overlap with config settings in `ttn-lw-stack-docker.yml`, so I have not repeated them here. The environment variables I have set are as follows:
  71.  
  72. ```
  73. environment:
  74. TTN_LW_BLOB_LOCAL_DIRECTORY: /srv/ttn-lorawan/public/blob
  75. TTN_LW_REDIS_ADDRESS: redis:6379
  76. # If using CockroachDB:
  77. # TTN_LW_IS_DATABASE_URI: postgres://root@cockroach:26257/ttn_lorawan?sslmode=disable
  78. # # If using PostgreSQL:
  79. TTN_LW_IS_DATABASE_URI: postgres://root:root@postgres:5432/ttn_lorawan?sslmode=disable
  80.  
  81. TTN_LW_APPLICATION_SERVER_GRPC_ADDRESS: 192.168.x.x:8884
  82. TTN_LW_DEVICE_TEMPLATE_CONVERTER_GRPC_ADDRESS: 192.168.x.x:8884
  83. TTN_LW_GATEWAY_SERVER_GRPC_ADDRESS: 192.168.x.x:8884
  84. TTN_LW_IDENTITY_SERVER_GRPC_ADDRESS: 192.168.x.x:8884
  85. TTN_LW_JOIN_SERVER_GRPC_ADDRESS: 192.168.x.x:8884
  86. TTN_LW_NETWORK_SERVER_GRPC_ADDRESS: 192.168.x.x:8884
  87. TTN_LW_OAUTH_SERVER_ADDRESS: https://192.168.x.x:8885/oauth
  88. ```
  89.  
  90. - Configure The Things Stack by editing `config/stack/ttn-lw-stack-docker.yml`.
  91. - Replace all instances of `thethings.example.com` with the IP address of your host machine.
  92. - Uncomment the custom certs and comment out let's encrypt
  93. - Add port `8885` to most the urls specified below. There may be other urls which require ports to be specified (such as those for `dcs`).
  94. - `is.email.network.console-url`
  95. - `is.email.network.identity-server-url`
  96. - Every url nested under `console`
  97. - Change the console secret to a new value (optional)
  98. - Compare your configured files against the sample files listed at the bottom of this page
  99. - See the [official guide](https://thethingsstack.io/getting-started/installation/configuration/) for further configuration if necessary.
  100. - If you are not using https, replace all instances of https in the configuration files with http. You will also need to change any port numbers that you've specified in URLs from `888x` to `188x`.
  101.  
  102. # Certificates from a Custom Certificate Authority
  103. If you are not using https, you can skip this step. As of 4 Dec 2020, I have not yet tested if the system works fully without https, but it should be possible. Note that there are additional configuration instructions in this guide that you must follow if you are not using https.
  104.  
  105. - Create `ca.json`:
  106.  
  107. ```
  108. {
  109. "names": [
  110. {"C": "NL", "ST": "Noord-Holland", "L": "Amsterdam", "O": "The Things Demo"}
  111. ]
  112. }
  113. ```
  114.  
  115. - Create `cert.json`, using your host machine IP:
  116.  
  117. ```
  118. {
  119. "hosts": ["192.168.x.x"],
  120. "names": [
  121. {"C": "NL", "ST": "Noord-Holland", "L": "Amsterdam", "O": "The Things Demo"}
  122. ]
  123. }
  124. ```
  125.  
  126. - Generate cert and cert authority and add the relevant files to your project:
  127.  
  128. ```
  129. cfssl genkey -initca ca.json | cfssljson -bare ca
  130. cfssl gencert -ca ca.pem -ca-key ca-key.pem cert.json | cfssljson -bare cert
  131. mv cert-key.pem tts/key.pem
  132. mv cert.pem tts/cert.pem
  133. mv ca.pem tts/ca.pem
  134. ```
  135.  
  136. - You can remove any other generated files (`ca-key.pem, ca.csr, ca.json, cert.csr, cert.json`); you don't need them. Your project directory should look like this:
  137.  
  138. ```
  139. tts
  140. ├── ca.pem
  141. ├── cert.pem
  142. ├── config
  143. │ └── stack
  144. │ └── ttn-lw-stack-docker.yml
  145. ├── docker-compose.yml
  146. └── key.pem
  147. ```
  148.  
  149. - Add `ca.pem` to the cert store on any machines that will be accessing the stack. Note that browsers often have their own cert stores, and the cert store location will of course be different on windows. You will also need to add the cert authority to your actual stack container once it is running.
  150.  
  151. ```
  152. sudo cp ca.pem /usr/local/share/ca-certificates/ca.crt
  153. sudo update-ca-certificates
  154. ```
  155.  
  156. # Running The Things Stack
  157. - Pull docker images
  158.  
  159. ```
  160. docker-compose pull
  161. ```
  162.  
  163. - Initialise db
  164.  
  165. ```
  166. docker-compose run --rm stack is-db init
  167. ```
  168.  
  169. - Create an admin user
  170.  
  171. ```
  172. docker-compose run --rm stack is-db create-admin-user \
  173. --id admin \
  174. --email your@email.com --password password
  175. ```
  176.  
  177. - Register command line and web console with oauth. If you are not using https, change these urls to `http` and replace port `8885` with `1885`.
  178.  
  179. ```
  180. docker-compose run --rm stack is-db create-oauth-client \
  181. --id cli \
  182. --name "Command Line Interface" \
  183. --owner admin \
  184. --no-secret \
  185. --redirect-uri "local-callback" \
  186. --redirect-uri "code"
  187.  
  188. docker-compose run --rm stack is-db create-oauth-client \
  189. --id console \
  190. --name "Console" \
  191. --owner admin \
  192. --secret console # use the console secret specified in ttn-lw-stack-docker.yml \
  193. --redirect-uri "https://192.168.x.x/console/oauth/callback" \
  194. --redirect-uri "/console/oauth/callback" \
  195. --logout-redirect-uri "https://192.168.x.x/console" \
  196. --logout-redirect-uri "/console"
  197. ```
  198.  
  199. - Launch
  200.  
  201. ```
  202. docker-compose up -d
  203. ```
  204.  
  205. # Using the Stack
  206. - As promised, we are going to copy the cert auth into our stack. Yes, this could be done automatically by mounting the file like the we did for the config yaml but I've not worked out how to do that.
  207.  
  208. ```
  209. cat ca.pem # copy the contents into your cliboard or something
  210. docker exec -it -u 0 tts_stack_1 /bin/sh # shell into the container as root
  211. echo 'PASTE_CERT_CONTENTS_HERE' > /usr/local/share/ca-certificates/ca.crt
  212. update-ca-certificates
  213. ```
  214.  
  215. - We can now log in and use the stack
  216.  
  217. ```
  218. ttn-lw-cli login --callback=false # as prompted, open your browser and paste the token back into the terminal
  219. ```
  220.  
  221. # Stopping the stack
  222. If you don't have other docker processes running, you can just blow everything away with the commands below. If you have other processes running you probably know how to handle them.
  223.  
  224. ```
  225. docker stop $(docker ps -aq)
  226. docker rm $(docker ps -aq)
  227. ```
  228.  
  229. # Appendix: Sample yaml files
  230. ## docker-compose.yml
  231.  
  232. ```
  233. version: '3.7'
  234. services:
  235.  
  236. # If using CockroachDB:
  237. # cockroach:
  238. # # In production, replace 'latest' with tag from https://hub.docker.com/r/cockroachdb/cockroach/tags
  239. # image: cockroachdb/cockroach:latest
  240. # command: start-single-node --http-port 26256 --insecure
  241. # restart: unless-stopped
  242. # volumes:
  243. # - ${DEV_DATA_DIR:-.env/data}/cockroach:/cockroach/cockroach-data
  244. # ports:
  245. # - "127.0.0.1:26257:26257" # Cockroach
  246. # - "127.0.0.1:26256:26256" # WebUI
  247.  
  248. # If using PostgreSQL:
  249. postgres:
  250. image: postgres
  251. restart: unless-stopped
  252. environment:
  253. - POSTGRES_PASSWORD=root
  254. - POSTGRES_USER=root
  255. - POSTGRES_DB=ttn_lorawan
  256. volumes:
  257. - ${DEV_DATA_DIR:-.env/data}/postgres:/var/lib/postgresql/data
  258. ports:
  259. - "127.0.0.1:5432:5432"
  260.  
  261. redis:
  262. # In production, replace 'latest' with tag from https://hub.docker.com/_/redis?tab=tags
  263. image: redis:latest
  264. command: redis-server --appendonly yes
  265. restart: unless-stopped
  266. volumes:
  267. - ${DEV_DATA_DIR:-.env/data}/redis:/data
  268. ports:
  269. - "127.0.0.1:6379:6379"
  270.  
  271. stack:
  272. # In production, replace 'latest' with tag from https://hub.docker.com/r/thethingsnetwork/lorawan-stack/tags
  273. image: thethingsnetwork/lorawan-stack:latest
  274. entrypoint: ttn-lw-stack -c /config/ttn-lw-stack-docker.yml
  275. command: start
  276. restart: unless-stopped
  277. depends_on:
  278. - redis
  279. # If using CockroachDB:
  280. # - cockroach
  281. # If using PostgreSQL:
  282. - postgres
  283. volumes:
  284. - ./blob:/srv/ttn-lorawan/public/blob
  285. - ./config/stack:/config:ro
  286. # If using Let's Encrypt:
  287. # - ./acme:/var/lib/acme
  288. environment:
  289. TTN_LW_BLOB_LOCAL_DIRECTORY: /srv/ttn-lorawan/public/blob
  290. TTN_LW_REDIS_ADDRESS: redis:6379
  291. # If using CockroachDB:
  292. # TTN_LW_IS_DATABASE_URI: postgres://root@cockroach:26257/ttn_lorawan?sslmode=disable
  293. # # If using PostgreSQL:
  294. TTN_LW_IS_DATABASE_URI: postgres://root:root@postgres:5432/ttn_lorawan?sslmode=disable
  295.  
  296. TTN_LW_APPLICATION_SERVER_GRPC_ADDRESS: 192.168.x.x:8884
  297. TTN_LW_DEVICE_TEMPLATE_CONVERTER_GRPC_ADDRESS: 192.168.x.x:8884
  298. TTN_LW_GATEWAY_SERVER_GRPC_ADDRESS: 192.168.x.x:8884
  299. TTN_LW_IDENTITY_SERVER_GRPC_ADDRESS: 192.168.x.x:8884
  300. TTN_LW_JOIN_SERVER_GRPC_ADDRESS: 192.168.x.x:8884
  301. TTN_LW_NETWORK_SERVER_GRPC_ADDRESS: 192.168.x.x:8884
  302. TTN_LW_OAUTH_SERVER_ADDRESS: https://192.168.x.x:8885/oauth
  303.  
  304. ports:
  305. # If deploying on a public server:
  306. - "80:1885"
  307. - "443:8885"
  308. - "1881:1881"
  309. - "8881:8881"
  310. - "1882:1882"
  311. - "8882:8882"
  312. - "1883:1883"
  313. - "8883:8883"
  314. - "1884:1884"
  315. - "8884:8884"
  316. - "1885:1885"
  317. - "8885:8885"
  318. - "1887:1887"
  319. - "8887:8887"
  320. - "1700:1700/udp"
  321.  
  322. # If using custom certificates:
  323. secrets:
  324. - ca.pem
  325. - cert.pem
  326. - key.pem
  327.  
  328. # If using custom certificates:
  329. secrets:
  330. ca.pem:
  331. file: ./ca.pem
  332. cert.pem:
  333. file: ./cert.pem
  334. key.pem:
  335. file: ./key.pem
  336. ```
  337.  
  338. ## ttn-lw-stack-docker.yml
  339.  
  340. ```
  341. # Identity Server configuration
  342. # Email configuration for "192.168.x.x"
  343. is:
  344. email:
  345. sender-name: 'The Things Stack'
  346. sender-address: 'noreply@192.168.x.x'
  347. network:
  348. name: 'The Things Stack'
  349. console-url: 'https://192.168.x.x:8885/console'
  350. identity-server-url: 'https://192.168.x.x:8885/oauth'
  351.  
  352. # If sending email with Sendgrid
  353. # provider: sendgrid
  354. # sendgrid:
  355. # api-key: '...' # enter Sendgrid API key
  356.  
  357. # If sending email with SMTP
  358. # provider: smtp
  359. # smtp:
  360. # address: '...' # enter SMTP server address
  361. # username: '...' # enter SMTP server username
  362. # password: '...' # enter SMTP server password
  363.  
  364. # Web UI configuration for "192.168.x.x":
  365. oauth:
  366. ui:
  367. canonical-url: 'https://192.168.x.x/oauth'
  368. is:
  369. base-url: 'https://192.168.x.x/api/v3'
  370.  
  371. # HTTP server configuration
  372. http:
  373. cookie:
  374. block-key: '' # generate 32 bytes (openssl rand -hex 32)
  375. hash-key: '' # generate 64 bytes (openssl rand -hex 64)
  376. metrics:
  377. password: 'metrics' # choose a password
  378. pprof:
  379. password: 'pprof' # choose a password
  380.  
  381. # If using custom certificates:
  382. tls:
  383. source: file
  384. root-ca: /run/secrets/ca.pem
  385. certificate: /run/secrets/cert.pem
  386. key: /run/secrets/key.pem
  387.  
  388. # Let's encrypt for "192.168.x.x"
  389. #tls:
  390. # source: 'acme'
  391. # acme:
  392. # dir: '/var/lib/acme'
  393. # email: 'you@192.168.x.x'
  394. # hosts: ['192.168.x.x']
  395. # default-host: '192.168.x.x'
  396.  
  397. # If Gateway Server enabled, defaults for "192.168.x.x":
  398. gs:
  399. mqtt:
  400. public-address: '192.168.x.x:1882'
  401. public-tls-address: '192.168.x.x:8882'
  402. mqtt-v2:
  403. public-address: '192.168.x.x:1881'
  404. public-tls-address: '192.168.x.x:8881'
  405.  
  406. # If Gateway Configuration Server enabled, defaults for "192.168.x.x":
  407. gcs:
  408. basic-station:
  409. default:
  410. lns-uri: 'wss://192.168.x.x:8887'
  411. the-things-gateway:
  412. default:
  413. mqtt-server: 'mqtts://192.168.x.x:8881'
  414.  
  415. # Web UI configuration for "192.168.x.x":
  416. console:
  417. ui:
  418. canonical-url: 'https://192.168.x.x:8885/console'
  419. is:
  420. base-url: 'https://192.168.x.x:8885/api/v3'
  421. gs:
  422. base-url: 'https://192.168.x.x:8885/api/v3'
  423. ns:
  424. base-url: 'https://192.168.x.x:8885/api/v3'
  425. as:
  426. base-url: 'https://192.168.x.x:8885/api/v3'
  427. js:
  428. base-url: 'https://192.168.x.x:8885/api/v3'
  429. qrg:
  430. base-url: 'https://192.168.x.x:8885/api/v3'
  431. edtc:
  432. base-url: 'https://192.168.x.x:8885/api/v3'
  433.  
  434. oauth:
  435. authorize-url: 'https://192.168.x.x:8885/oauth/authorize'
  436. token-url: 'https://192.168.x.x:8885/oauth/token'
  437. logout-url: 'https://192.168.x.x:8885/oauth/logout'
  438. client-id: 'console'
  439. client-secret: 'console' # choose or generate a secret
  440.  
  441. # If Application Server enabled, defaults for "192.168.x.x":
  442. as:
  443. mqtt:
  444. public-address: 'https://192.168.x.x:1883'
  445. public-tls-address: 'https://192.168.x.x:8883'
  446. webhooks:
  447. downlink:
  448. public-address: '192.168.x.x:1885/api/v3'
  449.  
  450. # If Device Claiming Server enabled, defaults for "192.168.x.x":
  451. dcs:
  452. oauth:
  453. authorize-url: 'https://192.168.x.x/oauth/authorize'
  454. token-url: 'https://192.168.x.x/oauth/token'
  455. logout-url: 'https://192.168.x.x/oauth/logout'
  456. client-id: 'device-claiming'
  457. client-secret: 'device-claiming' # choose or generate a secret
  458. ui:
  459. canonical-url: 'https://192.168.x.x/claim'
  460. as:
  461. base-url: 'https://192.168.x.x/api/v3'
  462. dcs:
  463. base-url: 'https://192.168.x.x/api/v3'
  464. is:
  465. base-url: 'https://192.168.x.x/api/v3'
  466. ns:
  467. base-url: 'https://192.168.x.x/api/v3'
  468. ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement