IoT SAFE チュートリアル¶
本ドキュメントは、Applet ConsoleおよびIoT SAFEアプレット搭載のアプレットSIMで提供されるIoT SAFE機能を用いて、IoT機器とサーバーがVPNで通信できるシステムを構築することで、IoT SAFEの使用方法に対する理解を深めていただくことを目的としています。
注釈
本ドキュメントの内容は、あくまでもシステムの構築方法をご理解いただくためのものです。そのまま、本番環境に適用できるものではありません。
システムイメージ¶
本ドキュメントで構築するシステムのイメージは、以下の通りです。
この構成は、IoT機器にサービスを提供するIoTサーバーを構築、IoT機器向けのサービス(Webサーバー)を起動します。IoT機器からそのIoTサーバーに対し、IoT SAFEを使用した相互に認証されたmTLS(Mutual TLS)通信によるVPN通信路を確立し、セキュアな通信を行います。
注釈
mTLS(Mutual TLS)とは
一般的なTLS(Transplort Layer Security)は、不特定多数のクライアントがインターネット上の信頼できるサーバーに接続することを想定しているため、クライアントはサーバーの身元確認を行いますが、サーバーはクライアントの身元確認を行いません。
mTLSは、この一般的なTLSの仕組みに加え、サーバーによるクライアントの身元確認を行い、相互(Mutual)に認証する仕組みです。
IoT環境のように信頼できない機器の接続が許されない環境において、サーバーから信頼できるIoT機器(クライアント)のみ接続を許可することで、高度なセキュリティを確保することができます。
mTLSにIoT SAFEを使用するメリット
リソースの限られるIoT機器において、安全、低コストかつ容易に鍵を生成・管理することが難しい場合が多くあります。
IoT SAFEは、SIMの安全かつ安価なメリットを生かし、IoT機器にもサーバーと同様の認証の仕組みをご提供します。
システム構成要素¶
Applet Console¶
IoT SAFEアプレットのOTAインストール(セルラー網経由のインストール)、鍵の管理などIoT SAFEに関わる操作、管理機能を提供します。
また、IoT SAFEを使用したmTLS(Mutual TLS)を使用したVPN接続に必要なCA、OpenVPN機能を提供します。
IoT SAFEアプレット¶
アプレットSIMで動作するアプレット(小さいプログラム)の一種で、IoT SAFE機能を提供します。
注釈
IoT SAFEの概要は、 IoT SAFE をご確認ください。
通信モジュール¶
SIMを装着することで、セルラー網に接続し、通信を行うことができるモジュールです。通常のSIMの代わりにアプレットSIMを装着することで、アプレットから通信モジュールが提供する機能を利用することができます。
I-O DATA UD-USC1
Soracom Onyx
など
注釈
IoT SAFEアプレットの動作確認状況は、 端末動作確認一覧 をご確認ください。
IoT機器¶
上記の通信モジュールが装着でき、IoT SAFE Clientが動作するIoT機器です。
IoT機器名 |
ディストリビューション |
バージョン |
|---|---|---|
Raspberry Pi 4または5 |
Raspberry Pi OS |
12(bookworm) または 13(trixie) |
PC |
Debian |
12(bookworm) または 13(trixie) |
PC |
Ubuntu |
24.04(Noble Numbat) |
IoTサーバー¶
OpenVPNクライアントおよびIoT機器向けサービスが稼働するサーバーです。以下が一例です。
ディストリビューション |
バージョン |
|---|---|
Ubuntu |
24.04(Noble Numbat) |
Windows |
11 |
注釈
OpenSSL 3.0.7以上、OpenVPNが稼働するOSであれば、特に制限はありません。
本ドキュメントの検証では、VMや作業用のWindows PCで代用可能です。
前提条件¶
構築するシステムの前提条件は、以下の通りです。
Applet Consoleが提供するCA機能、OpenVPNサーバー機能を使用。
OpenVPNサーバーが構成するプライベートネットワークサブネットは、「192.168.100.0/24」を設定。
IoT機器にサービスを提供するサーバーは、VMで起動。インターネットに接続。
IoTサーバーのOpenVPNのサブネット内でのIPアドレスは、「192.168.100.100/24」に固定。
IoTサーバーが提供するサービスとして、IoTサーバー上でWebサーバーを起動。
IoT機器に通信モジュールを接続し、通信モジュールには、アプレットSIMを装着。
アプレットSIMが装着された通信モジュール経由で、IoT機器はインターネットに接続。
構築作業の流れ¶
- 1. CA、OpenVPNサーバーの有効化
Applet ConsoleでCA、OpenVPNサーバーを有効にします。
- 2. IoTサーバーからVPN通信を確立
IoTサーバーからApplet Console上のOpenVPNサーバーに接続し、VPN通信を確立します。
- 3. IoT機器からVPN通信を確立
IoT機器からApplet Console上のOpenVPNサーバーに接続し、VPN通信を確立します。
注釈
この作業は、IoT SAFEアプレットとIoT SAFE Clientを使用することにより、ほぼ自動で行われます。
- 4. VPN通信路を経由して、IoT機器からサービスに接続
IoTサーバーでIoT機器向けサービス(今回は、Webサーバー)を起動し、VPN通信路を経由して、IoT機器からサービスに接続します。
構築作業の詳細¶
ここでは、前述の 構築作業の流れ でご説明した作業の詳細をご説明します。
注釈
Applet Consoleでの作業は、特に記載がない場合、「ADMINロール」ユーザーで実施してください。
Applet Consoleでは、機能によっては、本ドキュメントの記載より詳細な設定も可能です。詳細設定は、 applet_applet_console をご確認ください。
1. CA、OpenVPNサーバーの有効化¶
Applet ConsoleでCA、OpenVPNサーバーを有効にします。
作業手順¶
- CAを有効化
注釈
後述作業関連のマニュアル記載場所: CA利用設定
【Applet Console】「設定」メニュー>「IoT SAFE」タブ>「PrivateCA」ボタンをクリックし、「PrivateCA」画面に遷移します。
【Applet Console】「PrivateCA」画面の「Applet ConsoleのCAを利用する」トグルをONにし、CA機能を有効にします。
- CAの識別情報を設定
注釈
「PrivateCA」の「識別情報」は、CAの基本情報です。
注釈
後述作業関連のマニュアル記載場所: CA設定の編集
【Applet Console】「識別情報」の「編集」ボタンをクリックします。
【Applet Console】「CA設定の編集」内の情報を適宜編集し、「保存」ボタンをクリックします。
- 識別情報テンプレートを設定
注釈
「識別情報テンプレート」は、IoT SAFEアプレットがクライアント証明書を自動生成する際の基本情報です。変更が必要な場合は、以下の操作を実行します。
アプレットSIMに証明書情報が存在しない場合、自動作成されるクライアント証明書の「Common Name」には「{識別情報テンプレートのCommon Name}-{アプレットSIMのICCID}」が設定されます。
注釈
後述作業関連のマニュアル記載場所: 識別情報テンプレートの編集
【Applet Console】「設定」メニュー >「IoT SAFE」タブ > 「識別情報テンプレート」ボタンをクリックします。
【Applet Console】「識別情報」画面が表示されますので、「編集」ボタンをクリックします。
【Applet Console】「識別情報テンプレート編集」モーダルが表示されますので、適宜修正し、「保存」ボタンをクリックします。
- OpenVPNサーバーを有効化
注釈
後述作業関連のマニュアル記載場所: OpenVPNの設定
【Applet Console】「設定」メニュー>「IoT SAFE」タブ>「OpenVPN設定」ボタンをクリックし、「OpenVPN設定」画面に遷移します。
【Applet Console】「OpenVPN」画面の「サーバー1」タブの「サーバーサブネット(CIDR)」テキストフィールドに「192.168.100.0/24」と入力し、「設定を保存」ボタンをクリックします。
【Applet Console】「サーバーステータス」の右端に表示される「サーバー起動」ボタンをクリックし、OpenVPNサーバーを起動します。しばらくすると「サーバーステータス」が「実行中」に変化します。
2. IoTサーバーからVPN通信を確立¶
IoTサーバーからApplet Console上のOpenVPNサーバーに接続し、VPN通信を確立します。
作業手順¶
- 関連パッケージをインストール
【IoTサーバー】IoTサーバーにログインします。
- 【IoTサーバー】IoTサーバーにOpenVPNパッケージをインストールします。
Ubuntuの場合
$ sudo apt update ... $ sudo apt install openvpn ... $
Windowsの場合
PS> winget install OpenSSL ... PS> winget install OpenVPN ... PS>
注釈
Windows版OpenVPNをインストールすると「OpenVPN GUI」がインストールおよび起動されますが、本手順では使用しません。
OpenVPNインストール後に表示されるタスクトレイの「OpenVPN GUI」アイコンをクリックし、「起動」>「Windows起動時に開始(L)」チェックボックスのチェックを外し、「OK」をクリックしてください。
その後、タスクトレイの「OpenVPN GUI」アイコンを右クリックして、「終了」をクリックしてください。
- 鍵を生成
- 【IoTサーバー】秘密鍵を作成します。
Ubuntuの場合
$ openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1 -out client.pem $ ls client.pem $ cat client.pem -----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgQQdHte+/OFY4KgB3 ... ttD1imHKdUqy/2np4l6J72erwwBUs6naeoP9iL7PZSDhEhVv7TB8YTsx -----END PRIVATE KEY----- $
Windowsの場合
PS> & "C:\Program Files\OpenSSL-Win64\bin\openssl.exe" genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1 -out client.pem PS> dir Directory: C:\Users\xxx\Documents\yyy\openvpn Mode LastWriteTime Length Name ---- ------------- ------ ---- -a--- 2026/04/15 13:03 246 client.pem PS> type .\client.pem -----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgANe7KVxi9t1GE6/t ... 5My9jBFDXMXQ8jW4dHD8RUOH77i6xbWI80APSUbpBeM4a1qyTeNYne5w -----END PRIVATE KEY----- PS>
注釈
「-algorithm」や「-pkeyopt」は、適宜ご希望のものを指定してください。
秘密鍵は他者に公開できません。漏洩しないよう管理してください。
- CSRを生成・送信
- 【IoTサーバー】CSRを生成します。
Ubuntuの場合
$ openssl req -new -key client.pem -out client.csr You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:JP State or Province Name (full name) [Some-State]:Tokyo Locality Name (eg, city) []:Chiyoda-Ku Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Corp. Organizational Unit Name (eg, section) []:IT Department Common Name (e.g. server FQDN or YOUR name) []:xxx.example.com Email Address []:foo@example.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: $ ls client.csr client.pem $ cat client.csr -----BEGIN CERTIFICATE REQUEST----- MIIBVzCB/wIBADCBnDELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRva3lvMRMwEQYD ... ncVytNSKnB9aNa4= -----END CERTIFICATE REQUEST----- $
Windowsの場合
PS> & "C:\Program Files\OpenSSL-Win64\bin\openssl.exe" req -new -key client.pem -out client.csr You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:JP State or Province Name (full name) [Some-State]:Tokyo Locality Name (eg, city) []:Chiyoda-Ku Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Corp. Organizational Unit Name (eg, section) []:IT Department Common Name (e.g. server FQDN or YOUR name) []:yyy.example.com Email Address []:bar@example.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: PS> type .\client.csr -----BEGIN CERTIFICATE REQUEST----- MIIBVzCB/wIBADCBnDELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRva3lvMRMwEQYD ... GSy7ZJPU/4P38bg= -----END CERTIFICATE REQUEST----- PS>
注釈
「Common Name」は、OpenVPN接続するIoT機器、IoTサーバーで重複できません。
必ずユニークなものを指定してください。
- クライアント証明書を生成・返信
注釈
後述作業関連のマニュアル記載場所: CAを用いた署名
【Applet Console】「設定」メニュー>「IoT SAFE」タブ>「PrivateCA」ボタンをクリックすると、「PrivateCA」画面が表示されます。
【Applet Console】「PrivateCA」画面の「署名」ボタンをクリックし、「CSR入力」モーダルを表示します。
【Applet Console】 作成したCSRファイル「client.csr」をテキストエディターなどで開き、内容を「CSR入力」モーダルにコピー&ペーストし、「プレビュー」ボタンをクリックします。
- 「CSRサブジェクトプレビュー」モーダルが表示されます。問題なければ、「署名」ボタンをクリックします。
注釈
「Common Name」が存在しないとエラーとなります。「Common Name」を含んだCSRを作成・入力してください。
【Applet Console、IoTサーバー】クライアント証明書ファイル「signed-xxxxx.cert」が生成されます。「名前を付けて保存」ダイアログが表示されますので、適当な場所に保存します。
【IoTサーバー】ルート証明書ファイル 「signed-xxxxx.cert」をIoTサーバーの秘密鍵やCSRが保存されているディレクトリーにコピーします。
- ルート証明書をダウンロード
注釈
後述作業関連のマニュアル記載場所: ルート証明書ダウンロード
【Applet Console】「PrivateCA」画面の「ルート証明書をダウンロード」ボタンをクリックします。
【Applet Console】ルート証明書ファイル「root-xxxxx.cert」が生成されます。「名前を付けて保存」ダイアログが表示されますので、適当な場所に保存します。
【IoTサーバー】ルート証明書ファイル「root-xxxxx.cert」をIoTサーバーの秘密鍵やCSRが保存されているディレクトリーにコピーします。
- 固定IPを割り当て
注釈
後述作業関連のマニュアル記載場所: IPアドレス固定設定
【Applet Console】「PrivateCA」画面の「証明書署名履歴」で「デバイスタイプ」が「non-sim」で、「CSRサブジェクト」の「CN」が、作成したCSRの「Common Name」と一致する証明書のチェックボックスをクリックし、選択します。
【Applet Console】「IPアドレス固定設定」ボタンをクリックします。
【Applet Console】「IPアドレス固定設定」モーダルが表示されます。「サーバー1」タブを選択し、「割り当てIPアドレス」テキストフィールドに固定IPアドレス「192.168.100.100」を入力し、「IPアドレスを固定」ボタンをクリックします。
【Applet Console】「IPアドレス固定設定」の「サーバー1」タブで「既にIPアドレスが固定されています」メッセージを確認し、「キャンセル」をクリックします。
【Applet Console】「証明書署名履歴」の一覧でも固定IPアドレスが割り振られていることが確認できます。
- 設定ファイルをダウンロード
注釈
後述作業関連のマニュアル記載場所: クライアント設定ファイルをダウンロード
【Applet Console】「設定」メニュー>「IoT SAFE」タブ>「OpenVPN設定」ボタンをクリックすると、「OpenVPN設定」画面が表示されます。
【Applet Console】「OpenVPN設定」画面の「クライアント設定ファイルをダウンロード」ボタンをクリックします。
【Applet Console、IoTサーバー】クライアント設定ファイル「client_<環境名>_server<番号>_xxxxx.ovpn」が生成されます。「名前を付けて保存」ダイアログが表示されますので、適当な場所に保存します。
【IoTサーバー】ルート証明書ファイル「client_<環境名>_server<番号>_xxxxx.ovpn」をIoTサーバーの秘密鍵やCSRが保存されているディレクトリーにコピーします。
- VPN接続を確立
- 【IoTサーバー】OpenVPNサーバー接続に必要なファイルを確認します。
Ubuntuの場合
$ ls client.csr client.pem client_xxxxx_server1_xxxxx.ovpn root-xxxxx.cert signed-xxxxx.cert $
Windowsの場合
PS> dir Directory: C:\Users\xxx\Documents\yyy\openvpn Mode LastWriteTime Length Name ---- ------------- ------ ---- -a--- 2026/XX/XX XX:XX 301 client_xxxxx_server1_xxxxx.ovpn -a--- 2026/XX/XX XX:XX 552 client.csr -a--- 2026/XX/XX XX:XX 246 client.pem -a--- 2026/XX/XX XX:XX 1488 root-xxxxx.cert -a--- 2026/XX/Xx XX:XX 1237 signed-xxxxx.cert PS>
- 【IoTサーバー】ファイル名を変更します。
Ubuntuの場合
$ mv singed-xxxxx.cert client_cert.pem $ mv root-xxxxx.cert ca.cert
Windowsの場合
PS> ren .\signed-xxxxx.cert .\client_cert.pem PS> ren .\root-xxxx.cert .\ca.cert
- 【IoTサーバー】VPN接続を確立します。ログより「tun0」が生成され、IPアドレス「192.168.100.100/24」が割り振られたことが確認できます。
Ubuntuの場合
$ sudo openvpn --config ./client_xxxxx_server1_xxxxx.ovpn ... 2026-XX-XX XX:XX:XX TUN/TAP device tun0 opened 2026-XX-XX XX:XX:XX net_iface_mtu_set: mtu 1500 for tun0 2026-XX-XX XX:XX:XX net_iface_up: set tun0 up 2026-XX-XX XX:XX:XX net_addr_v4_add: 192.168.100.100/24 dev tun0 2026-XX-XX XX:XX:XX Initialization Sequence Completed
Windowsの場合
注釈
コマンドを実行するPowerShellは、「管理者として実行」してください。
PS> & "C:\Program Files\OpenVPN\bin\openvpn.exe" --config .\client_xxxxx_server1_xxxxx.ovpn ... 2026-XX-XX XX:XX:XX ovpn-dco device [OpenVPN Data Channel Offload] opened 2026-XX-XX XX:XX:XX NETSH: C:\WINDOWS\system32\netsh.exe interface ip set address 78 static 192.168.100.100 255.255.255.0 store=active 2026-XX-XX XX:XX:XX NETSH: C:\WINDOWS\system32\netsh.exe interface ip delete dns 78 all 2026-XX-XX XX:XX:XX NETSH: C:\WINDOWS\system32\netsh.exe interface ip delete wins 78 all 2026-XX-XX XX:XX:XX IPv4 MTU set to 1500 on interface 78 using SetIpInterfaceEntry() 2026-XX-XX XX:XX:XX Initialization Sequence Completed
3. IoT機器からVPN通信を確立¶
IoT機器からApplet Console上のOpenVPNサーバーに接続し、VPN通信を確立します。
作業手順¶
- IoT SAFEアプレットをOTAインストール
注釈
後述作業関連のマニュアル記載場所: 「SIM」メニューの操作
【Applet Console】「SIM」メニューをクリックするとSIM一覧が表示されますので、IoT SAFEアプレットをインストールするSIMのICCIDをクリックします。
【Applet Console】 SIM詳細画面を表示されますので、SIM詳細画面の「アプレット」項目の右に表示される「OTA実行」ボタンをクリックします。
【Applet Console】「OTA実行」モーダルが表示されますので、「インストール」ラジオボタンを選択し、「Applet種別」セレクトボックスで「IoT SAFE」を選択します。
【Applet Console】「Applet名」セレクトボックスが表示されますので、インストールしたいアプレットを選択し、「確認」ボタンをクリックします。
- 【Applet Console】「OTA実行の確認」モーダルが表示されますので、「送信」ボタンをクリックします。
注釈
OTAインストールを実行すると、既にアプレットSIMにインストールされているアプレットはアンインストールされ、今回指定したIoT SAFEアプレットがインストールされます。
この際、既にインストールされていたIoT SAFEアプレットが保持していた鍵や証明書はSIM内から削除され、新たな鍵、証明書が生成されます。
【Applet Console】「アプレット」の「 OTA(Applet)」項目が「Install: Ready」となり、インストール待ち状態になります。しばらくするとIoT機器側からポーリングされるとインストールが開始されます。
【Applet Console】しばらくすると画面上部に表示されるベルアイコンに通知バッチが表示されますので、ベルアイコンをクリックし、表示されるドロップダウンリストから、「OTA」タブを選択します。
- 【Applet Console】「OTA」タブのリスト表示から該当のICCIDで「Type」が「IoT SAFE」、「Status」が「Install Succeeded」のメッセージをクリックします。
注釈
ベルアイコンをクリックし、表示されるリストでメッセージの背景色が着色されているメッセージが、現在表示しているSIM詳細画面のICCIDと一致するメッセージです。
誤ったICCIDのメッセージ(背景色が白色のメッセージ)をクリックすると、別のICCIDのSIM詳細画面に遷移してしまいます。
誤って、別のICCIDのSIM詳細画面に遷移し、確認や操作を行わないようご注意ください。
【Applet Console】SIM詳細画面に戻り、「アプレット」の「OTA(Applet)」項目が「Install: Succeeded」に変化し、SIMへのIoT SAFEアプレットのインストールが完了したことが確認できます。
- 鍵を生成
注釈
IoT SAFEアプレットインストール後、自動実行されます。
- CSRを生成・送信
注釈
IoT SAFEアプレットインストール後、自動実行されます。
- クライアント証明書を生成・返信
注釈
IoT SAFEアプレットインストール後、自動実行されます。
自動生成された鍵や証明書は、下記の手順で確認します。
注釈
後述作業関連のマニュアル記載場所: 「IoT SAFE」メニューの操作
【Applet Console】「IoT SAFE」メニューをクリックするとIoT SAFEアプレットがインストールされたSIM一覧が表示されますので、該当のICCIDをクリックします。
- 【Applet Console】IoT SAFE詳細画面が表示されますので、「クライアント証明書一覧」の一覧に「ラベル」が「template」という行が表示され、「ステータス(キーペア)」が「ReadPublicKey: Succeeded」、「ステータス(CSR)」が「ReadCSR: Succeded」、「ステータス(クライアント証明書)」が「DeliveryClientCert: Succeeded」となっていることを確認します。
注釈
上記の状態になっていない場合、まだ証明書生成動作が完了していないか、表示情報が更新されていない可能性があります。しばらく動作完了を待ち、適宜表示画面を更新してください。
画面表示更新は、ベルアイコン>「IoT SAFE」タブをクリックし、表示されるメッセージをクリックすることで行えます。
【Applet Console】「クライアント証明書一覧」の一覧に「ラベル」が「template」という行の「ID」の番号をクリックします。
- 【Applet Console】「ラベル」が「template」の証明書情報が表示されます。実際の証明書情報は、「PEM形式データ」項目に表示されます。
注釈
「PEM形式データ」に表示された「公開鍵」、「CSR」はアプレットSIMのIoT SAFEアプレットで生成されたもの、「クライアント証明書」はCSRを基にApplet ConsoleのCAで生成・署名されたものです。
- 関連パッケージをインストール
-
【Applet Console、ROOTロールユーザー】ROOTロールを持つユーザーでログインします。
- 【Applet Console、ROOTロールユーザー】「設定」メニュー>「API」タブをクリックします。
注釈
「API」タブを表示するには、ROOTロールのユーザーでログインする必要があります。
【Applet Console、ROOTロールユーザー】「API IDとSecretの生成」項目で、「Generate ID & Screet」をクリックすると「本当に発行しますか?」モーダルが表示されますので、「生成」ボタンをクリックします。
- 【Applet Console、ROOTロールユーザー】新たに生成された、「API ID」と「Secret」のコピーアイコンをクリックし、データをコピーし、保管します。
注釈
「API ID」と「Secret」は、漏洩しないよう厳重に保管してください。 ここでは、仮に、「API ID」を「API_ID_XX」、「Secret」を「secretXXXXX」とします。
【Applet Console、ROOTロールユーザー】ROOTロールを持ちユーザーでログアウトします。
【Applet Console】「設定」メニュー>「IoT SAFE」タブ >「IoT SAFE Client」ボタンをクリックします。
【Applet Console】「IoT SAFE Clientのインストール」画面が表示されますので、「インストール」項目の「コピー」ボタンをクリックします。
【Applet Console】クリップボードにIoT SAFE Clientのインストール用シェルスクリプトがコピーされますので、テキストエディタにペーストします。
【IoT機器】テキストエディタで「your-api-id」と「your-api-secret」を先ほど取得した「API_ID_XX」、「secretXXXXX」に書き換えます。
- 【IoT機器】作成したスクリプトを実行します。
$ API_ID='API_ID_XX' API_SECRET='secretXXXXX' URL="https://iot-safe.api.demo0.sim-applet.com/v1/openapi/client/install.sh" sh -c '(curl -s -H "api_id: ${API_ID}" -H "api_secret: ${API_SECRET}" ${URL} | bash)'
- 【IoT機器】スクリプト実行中に以下のような「API_ID」、「API_SECRET」をIoT機器のローカルに保存してよいかを確認するメッセージが表示されます。「y」を入力します。
Step 2: Configuring iotsafe-client... Do you want to save API credentials to ~/.iotsafe/ for future use? This allows running commands without specifying credentials each time. Save credentials? (y/N): y <Enter>
注釈
「API_ID」、「API_SECRET」といったクレデンシャル情報をIoT機器のローカルディレクトリに保管することを懸念される場合、ここで「n」を選択し、クレデンシャル情報を保存しないことも可能です。
その際は、「iotsafe-client」の一部コマンド実行にあたり、直接コマンドラインにクレデンシャル情報を指定、または環境変数でクレデンシャル情報を指定する必要があります。
本ドキュメントでは、操作を簡略化するために、クレデンシャル情報をローカルへの保存を選択しますが、ローカルへの保存を推奨するものではありません。
- 【IoT機器】OSを再起動します。
$ sudo reboot
- 【IoT機器】通信モジュールの認識、IoT SAFE関連デバイスファイルの認識、通信モジュールでのネットワーク接続を確認します。以下に正常認識された場合の例を示します。
I-O DATA UD-USC1の場合
$ lsusb ... Bus 003 Device 010: ID 05c6:f622 Qualcomm, Inc. UD-USC1 ... $ ls -l /dev/ttyUSB* crw-rw---- 1 root dialout 188, 0 XXX XX XX:XX /dev/ttyUSB0 crw-rw---- 1 root dialout 188, 1 XXX XX XX:XX /dev/ttyUSB1 crw-rw---- 1 root dialout 188, 2 XXX XX XX:XX /dev/ttyUSB2 crw-rw---- 1 root dialout 188, 3 XXX XX XX:XX /dev/ttyUSB3 $ ip addr show ... X: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000 link/ether XX:XX:XX:XX:XX:XX brd ff:ff:ff:ff:ff:ff inet 192.168.8.XXX/24 brd XXX.192.168.8.255 scope global dynamic noprefixroute usb0 valid_lft 79993sec preferred_lft 79993sec inet6 XXXX::XXXX:XXXX:XXXX:XXXX/64 scope link noprefixroute valid_lft forever preferred_lft forever $ ping -I usb0 example.com ...
注釈
UD-USC1は、RNDISデバイスのため、特に明示的な設定を必要とせず、インターネット接続デバイスとして認識されます。
Soracom Onyxの場合
$ lsusb ... Bus 003 Device 007: ID 2c7c:0125 Quectel Wireless Solutions Co., Ltd. EC25 LTE modem ... $ ls -l /dev/ttyUSB* crw-rw---- 1 root dialout 188, 0 XXX XX XX:XX /dev/ttyUSB0 crw-rw---- 1 root dialout 188, 1 XXX XX XX:XX /dev/ttyUSB1 crw-rw---- 1 root dialout 188, 2 XXX XX XX:XX /dev/ttyUSB2 crw-rw---- 1 root dialout 188, 3 XXX XX XX:XX /dev/ttyUSB3 $ ip addr show ... X: wwan0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000 link/none inet XXX.XXX.XXX.XXX/29 brd XXX.XXX.XXX.255 scope global noprefixroute wwan0 valid_lft forever preferred_lft forever $ ping -I wwan0 example.com ...
注釈
通信モジュールによっては、インターネット接続を行うための設定が必要な場合がありますが、本ドキュメントでは解説しません。
通信モジュール経由でインターネット接続し、その経路をVPN接続経路とする場合、NetworkManagerなどで適切な設定を行ってください。
- ルート証明書をダウンロード
注釈
IoT SAFE ClientのVPN接続確立処理内で自動実行されます。
- 設定ファイルをダウンロード
注釈
IoT SAFE ClientのVPN接続確立処理内で自動実行されます。
- VPN接続を確立
- 【IoT機器】OpenVPNクライアントの状態を確認します。
$ iotsafe-client vpn status Auto-start: disabled VPN is disconnected $
- 【IoT機器】OpenVPNクライアントを起動します。
注釈
OpenVPNクライアント起動の前に別コンソールで以下のコマンドを実行しておくと、VPNの接続動作が確認しやすくなります。
エラー発生時の原因特定にも役立ちます。
$ iotsafe-client vpn logs -f ...
$ iotsafe-client vpn start Starting VPN service... ✓ VPN service started successfully Run 'iotsafe-client vpn status' to check connection status $
- 【IoT機器】OpenVPNクライアントの起動を確認します。
$ iotsafe-client vpn status Auto-start: disabled VPN is connected VPN IP(tun0): 192.168.100.XXX $
注釈
「192.168.100.XXX」の「XXX」の部分は、自動割り当てのため、変動します。
IPアドレス取得に、多少時間がかかることがあります。
注釈
「iotsafe-client vpn logs -f」を実行したコンソールには以下のようなメッセージが表示されます。
... XXX XX XX:XX:XX XXXXXX iotsafe-vpn[1612]: 2026-XX-XX XX:XX:XX TCP/UDP: Preserving recently used remote address: [AF_INET> XXX XX XX:XX:XX XXXXXX iotsafe-vpn[1612]: 2026-XX-XX XX:XX:XX UDPv4 link local: (not bound) XXX XX XX:XX:XX XXXXXX iotsafe-vpn[1612]: 2026-XX-XX XX:XX:XX UDPv4 link remote: [AF_INET]XXX.XXX.XXX.XXX:1194 XXX XX XX:XX:XX XXXXXX iotsafe-vpn[1612]: 2026-XX-XX XX:XX:XX [IoTSAFE-OpenVPN] Peer Connection Initiated with [AF_INET]> XXX XX XX:XX:XX XXXXXX iotsafe-vpn[1612]: 2026-XX-XX XX:XX:XX TUN/TAP device tun0 opened XXX XX XX:XX:XX XXXXXX iotsafe-vpn[1612]: 2026-XX-XX XX:XX:XX net_iface_mtu_set: mtu 1500 for tun0 XXX XX XX:XX:XX XXXXXX iotsafe-vpn[1612]: 2026-XX-XX XX:XX:XX net_iface_up: set tun0 up XXX XX XX:XX:XX XXXXXX iotsafe-vpn[1612]: 2026-XX-XX XX:XX:XX net_addr_v4_add: 192.168.100.XXX/24 dev tun0 XXX XX XX:XX:XX XXXXXX iotsafe-vpn[1612]: 2026-XX-XX XX:XX:XX Initialization Sequence Completed
- 【IoT機器】必要に応じて、OS起動時にOpenVPNクライアントが自動起動するように設定します。
$ iotsafe-client vpn enable Enabling VPN service auto-start... Created symlink '/etc/systemd/system/multi-user.target.wants/iotsafe-vpn.service' → '/etc/systemd/system/iotsafe-vpn.service'. ✓ VPN service will start automatically on boot $ iotsafe-client vpn status Auto-start: enabled VPN is connected VPN IP(tun0): 192.168.100.XXX $
- 【IoT機器】IoT機器からIoTサーバーへの疎通を確認します。
$ ping 192.168.100.100注釈
パーソナルファイアウォール(Windowsの場合、「Microsoft Defender ファイアウォール」など)が有効な場合、Pingの応答がない場合があります。
応答がない場合、一時的なパーソナルファイアウォールの無効化やルール追加を行ってください。
4. VPN通信路を経由して、IoT機器からサービスに接続¶
IoTサーバーでIoT機器向けサービス(今回は、Webサーバー)を起動、VPN通信路を経由し、IoT機器からサービスに接続します。
作業手順¶
- 【IoTサーバー】Webサーバーを起動します。
Ubuntuの場合
$ echo "<h1>Hello World</h1>" > index.html $ python3 -m http.server 8080 ...
Windowsの場合
注釈
コマンドを実行するPowerShellは、「管理者として実行」してください。
PS> Set-Content server.ps1 @' $listener = [System.Net.HttpListener]::new() $listener.Prefixes.Add("http://*:8080/") $listener.Start() Write-Host "Listening on http://*:8080/ (Ctrl+C to stop)" try { while ($true) { $task = $listener.GetContextAsync() while (-not $task.IsCompleted) { Start-Sleep -Milliseconds 100 } $context = $task.Result $response = $context.Response $body = "<h1>Hello World</h1>" $buffer = [System.Text.Encoding]::UTF8.GetBytes($body) $response.ContentLength64 = $buffer.Length $response.OutputStream.Write($buffer, 0, $buffer.Length) $response.OutputStream.Close() } } finally { $listener.Stop() $listener.Close() } '@ PS> .\server.ps1
- 【IoT機器】IoT機器からIoTサーバーのWebサーバーに接続します。「<h1>Hello World</h1>」の文字列が表示されれば成功です。
$ curl -i http://192.168.100.100:8080/ HTTP/1.0 200 OK Server: SimpleHTTP/0.6 Python/3.XX.XX Date: XXX, XX XXX 2026 XX:XX:XX GMT Content-type: text/html Content-Length: 21 Last-Modified: XXX, XX XXX 2026 XX:XX:XX GMT <h1>Hello World</h1>