OCIでThingsBoardを使ってIoTデバイスデータを見える化(SSL対応)

1. はじめに

本記事では、Oracle Cloud Infrastructure (OCI)とThingsBoardを組み合わせて、IoTデバイスデータの見える化システムを構築する方法をご紹介します。

OCIの無料枠を活用することも可能なのですが、今回は無料枠を獲得できず有料枠での実装になりましたが、ThingsBoardのCommunity Editionを導入することで、コストを抑えつつ高機能なIoTプラットフォームを実現できます。さらに、SSL対応やテレメトリーデータの加工など、実用的な設定方法も解説します。

2. Oracle Cloud Infrastructure (OCI) とは

Oracle Cloud Infrastructure(OCI)は、高速で信頼性の高いクラウド環境を提供し、企業が必要とするアプリケーションやワークロードをサポートする多彩な機能を備えたエンタープライズクラウドサービスです。クラウドネイティブからエンタープライズITまであらゆるワークロードに対応しており、高いパフォーマンス、高い信頼性、高いコスト優位性を特長としています。

特に無料枠(Oracle Cloud Free Tier)では、他のクラウドサービスと比較して非常に寛大なリソース(4CPU/24GBメモリ/4Gbps帯域)を無期限で提供しており、クラウド学習や小規模なシステム運用に最適です。

2.1. Always Free(無期限無料)サービス

OCIでは、期間の制限なく以下のサービスを無料で利用することができます。

コンピュート

__

Warning

Ampere A1 Computeインスタンス のVM.Standard.A1.Flexはどこのリージョンも不足しているようで、生成時にエラーが表示されます。何度もリトライすれば生成可能(自動リトライするスクリプトを公開している方もいる)のようですが、今回は諦めました。

ストレージ

データベース

3. ThingsBoardとは

ThingsBoardは、IoTデバイスの管理とデータの可視化を可能にするオープンソースのIoTプラットフォームです。このプラットフォームは、デバイスの接続性、データ収集、処理、そして視覚化までを一貫して提供し、IoTソリューションの開発と展開を大幅に簡素化します。
ThingsBoardの大きな魅力の一つは、Community Editionが完全に無料で利用できることです。このエディションは Apache 2.0 ライセンスの下で提供されており、個人利用だけでなく商用利用も可能です。

Warning

Community Editionは機能が限定されるため、本格的に運用するためには有料ですがCloudかProfessional Editionを利用する必要がある可能性が高いです。
ThingsBoradではデバイスごとにテレメトリアップロードAPIが異なるため、別のAPIを生成しデバイスごとのテレメトリアップロードAPIに変換する処理が必要になる場合があります。Professional EditionであればHTTPインテグレーションで対応できる可能性があります。(未確認)
今回はCommunity Editionを利用するため、別の処理で対応します。

3.1. 主な特徴

3.2. データの可視化

ThingsBoardの強みの一つは、データの可視化機能です。以下のような機能により、IoTデバイスから収集したデータを効果的に表示し、分析することができます:

ThingsBoardは、IoTプロジェクトを始めるための優れた選択肢です。無料で利用できる豊富な機能セットと、直感的なデータ可視化ツールにより、IoTデータの価値を最大限に引き出すことができます。スマートエネルギー、産業用IoT、スマートビルディングなど、さまざまな分野で活用されており、IoTソリューションの迅速な開発と展開を支援します。

4. OCIにインスタンスを作成

下記ページにあるようにThingsBoard Marketplace イメージからインスタンスを生成する方法もありますが、このイメージのThingsBoardのバージョンは、3.6.4であり少し古いバージョンのため、今回はUbuntu24.04のインスタンスを生成しDockerでThingsBoardを稼働します。

4.1. パブリックIPアドレスの予約

インスタンスにアクセスするために、パブリックIPアドレスが必要になります。インスタンス生成時に自動割り当てすることも可能ですが、事前にパブリックIPアドレスを予約しておき、そのIPアドレスを生成したインスタンスに割当ます。

[ネットワーキング] - [予約済パブリックIP] - [パブリックIPアドレスの予約]

4.2. インスタンス作成

[コンピュート] - [インスタンス] - [インスタンスの作成]

以上の設定でインスタンスを作成します。

Warning

このシェイプはAlways Free対象ではないためコスト管理には注意してください。

4.3. 予約済IPアドレス割り当て

インスタンスの作成が完了すると自動的に起動します。インスタンスの詳細画面の左側の下部に[アタッチされたVNIC]という項目があるので、それをクリックします。

画面下部に「アタッチされたVNIC」というリストがあり、すでに自動生成されたVNICがあるため名前をクリックします。

画面左下部の[リソース] - [メトリック] - [IPv4アドレス]をクリックします。

IPv4 アドレスのリストがあるため、編集します。

パブリックIPタイプ
[予約済パブリックIP] - [既存の予約済IPアドレスの選択] - [事前に予約していたIPアドレスを選択]

4.4. ネットワーク・セキュリティ・グループ 作成

[ネットワーキング] - [仮想クラウド・ネットワーク] - VCNの名前をクリック - [ネットワーク・セキュリティ・グループ] - [ネットワーク・セキュリティ・グループの作成]

同様に、ポート80、443も追加します。

ネットワーク・セキュリティ・グループを作成したら、インスタンスの詳細画面にて、ネットワーク・セキュリティ・グループ を編集状態にし、作成したネットワーク・セキュリティ・グループを割り当てます。

以上の設定により、ダウンロードしたSSH キーを使いパブリックIPアドレスに接続することでログインできます。
ユーザ名は「ubuntu」(インスタンスの詳細画面で確認可能)

5. Ubuntuの初期設定

sudo apt update && sudo apt upgrade -y

5.1. ufwの有効化

sudo ufw limit proto tcp from any to any port 22
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 8080/tcp
sudo ufw enable

設定状態を確認します。

sudo ufw status

5.2. fail2banの設定

sudo apt install fail2ban
fail2ban-client --version
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

fail2banの設定は下記サイトの情報を参考に設定します。

6. Dockerのインストール

下記サイトを参考にインストールします。

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo docker run hello-world

6.1. 非ルートユーザーとしてDockerを管理する

sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
docker run hello-world

7. DockerにThingsBoardをインストール

下記ページを参考にDockerにThingsBoardを構築します。

nano docker-compose.yml
version: '3.0'
services:
  mytb:
    restart: always
    image: "thingsboard/tb-postgres"
    ports:
      - "8080:9090"
      - "1883:1883"
      - "7070:7070"
      - "5683-5688:5683-5688/udp"
    environment:
      TB_QUEUE_TYPE: in-memory
    volumes:
      - ~/.mytb-data:/data
      - ~/.mytb-logs:/var/log/thingsboard
mkdir -p ~/.mytb-data && sudo chown -R 799:799 ~/.mytb-data
mkdir -p ~/.mytb-logs && sudo chown -R 799:799 ~/.mytb-logs
docker compose up -d && docker compose logs -f mytb

これでThingsBoardが起動します。起動までに少し時間がかかります。

起動後は、http:// <パブリックIPアドレス>:8080 にブラウザからアクセスすることで、ログイン画面が表示されます。

8. ThingsBoardの初期設定

http://<パブリックIPアドレス >:8080 にブラウザからアクセスする。

8.1. 初期ユーザーアカウントのパスワードを変更する

ThigsBoardインストール時点で、3つのユーザーが作成されています。
各ユーザーでログインし、初期パスワードを変更します。

8.2. ドメインの割当て

パブリックIP直打ちではなくドメインでアクセスできるようにします。
ドメインはどこから取得したものでも利用できます。今回はXserverドメインにて取得したドメインを利用しました。

下記サイトの情報を参考に設定します。

8.2.1. ゾーンの作成

[ネットワーキング] - [仮想クラウド・ネットワーク] - [DNS管理] - [ゾーン] - [ゾーンの作成]

8.2.2. ネームサーバーの設定

ゾーンを作成すると、ネームサーバーの一覧が表示されるのでメモしておき、ドメインを取得したサービス(今回はXserver ドメイン)の管理画面からネームサーバーを指定します。

8.2.3. DNSレコード設定

作成したゾーンの[レコード]にて[レコードの管理]をクリックし、[レコードの追加]をクリックします。

以上の設定により、http://ドメイン:8080 でThingsBoardにアクセス可能になります。接続可能になるまで、しばらく時間がかかります。(最大48時間)

9. SSL接続設定

ThingsBoardにデータを送信する際、httpでの送信でも可能ですが、SSL対応にしてhttpsでの送信にすることでセキュリティが向上します。
特に、ログイン情報やデバイスのアクセストークンが漏洩するリスクを低減できます。

また、外部から接続する際に、SSL対応していなければ送信できない場合もあります。今回はこれに該当し、1nceからThingsBoardにデータを送信する際にはSSLでなければ送信できません。

よって、ThingsBoardにSSL接続するよう設定します。いくつか方法がありますが、簡単に設定できるnginxのリバースプロキシを利用する方法で設定します。

9.1. Nginx と Certbot をインストール

sudo apt-get install nginx certbot python3-certbot-nginx
``` ```
sudo nano /etc/nginx/sites-available/default

上記ファイルに次の内容を追加します。

server {
    listen 443 ssl;
    server_name あなたのドメイン;

    ssl_certificate /etc/letsencrypt/live/あなたのドメイン/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/あなたのドメイン/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
sudo nginx -t
sudo systemctl restart nginx

Let's Encrypt で証明書を取得します。

sudo certbot --nginx -d あなたのドメイン

証明書の自動更新を設定します。

sudo systemctl status certbot.timer

証明書の自動更新のテスト

sudo certbot renew --dry-run

[:alert type="info" title="Information"]証明書を以前に取得済みで、今回始めてnginxと併用する場合には、自動更新が失敗することがあります。(既にport 80を別プロセスが利用しているというような内容のエラーがでます)
その場合には、/etc/letsencrypt/renewal/ドメイン名.confファイルを編集し、認証方法をnginxに変更します。[:ealert]

[renewalparams]
authenticator = nginx
installer = nginx

以上の設定により、http s://ドメインでThingsBoardにアクセス可能になります。

10. 【オプション】テレメトリーデータの加工

今回は10年間のランニングコストがわずか2000円で使えるIoT専用SIM 1nceを使ってデバイスからデータを送信し、1nceからThingsBoardにデータを転送することで見える化します。
1nceについては、別記事にまとめています。

1nceから外部へWebhookで送信されるデータのフォーマットは次のようなフォーマットです。


{
  "payload": {
    "type":"JSON",
    "value":{
      "humi":57.36629,
      "rain":0,
      "temp":23.034637,
      "press":10.365234,
      "deviceid":1,
      "lux":0
    }
  },
  "received": "1670598749915",
  "id": "xxxxxx",
  "source": "UDP",
  "type": "TELEMETRY_DATA",
  "version": "1.0.0",
  "device": {
    "iccid": "xxxxxx",
    "ip": "xxxxxx",
    "imsi": "xxxxxx"
  }
}