$30 off During Our Annual Pro Sale. View Details »

ESP32でSORACOM Arcつないでみた

ESP32でSORACOM Arcつないでみた

SORACOM UG Online #6 で発表した、ESP32でSORACOM Arcつないでみたの発表資料です。

Kenta IDA

July 27, 2021
Tweet

More Decks by Kenta IDA

Other Decks in Programming

Transcript

  1. ESP32で
    SORACOM Arcつないでみた
    SORACOM UG ONLINE #6 2021/07/27
    Kenta Ida (@ciniml)

    View Slide

  2. 自己紹介
    •井田 健太 (@ciniml)
    •仕事:FPGAの論理設計
    •使用言語:C++, SystemVerilog, Rust, C#
    •組込みRust本の1割くらい書きました
    (サンプルアプリ作ったり、デバッガ試したり)→
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた 2

    View Slide

  3. SORACOM Discovery 2021 Online 当日
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた
    •SORACOM Arcが発表された
    • WireGuardによるVPNにて
    インターネットからSORACOMサービスに接続
    •ESP32等で接続できるとおもしろいのでは?
    • ESP32: EspressifのWiFi+BT付きマイコン
    •ESP32向けWireGuard実装を探したが見つからず放置
    3

    View Slide

  4. およそ2週間後くらい facebookにて
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた 4

    View Slide

  5. およそ2週間後くらい facebookにて
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた
    これは煽りに違いない
    やれってことですね!
    5

    View Slide

  6. もうちょっとくわしく
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた
    •lwIP(組込み向けIPスタック)向けWireGuard実装あり!
    • https://github.com/smartalock/wireguard-lwip
    • 3条項BSDライセンス
    •ESP-IDF (ESP32公式フレームワーク) もlwIP使用
    • Arduino core for the ESP32も同じ
    •動かせるのでは?
    6

    View Slide

  7. 調整してみた結果をTweet
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた 7

    View Slide

  8. やっぱばれた
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた 8

    View Slide

  9. どういうこと?
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた

    100.127.100.127
    (pong.soracom.io)
    からのping応答
    →SORACOM
    サービスにつながってる
    ESP-IDFの標準ログフォーマット
    (つまりESP32で動いている)
    9

    View Slide

  10. 動かすためにやったこと(1)
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた
    •WireGuard for lwIPのIPv6有効版lwIP対応
    • 基本的に ipaddr_t を使うように修正
    • IPv4が必要な部分は適宜変換関数・マクロを呼ぶように修正
    10

    View Slide

  11. ビルド通った!
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた
    •ビルド通ったので動かしてみた
    •試しに自宅VPN用のWireGuardに接続
    •つながった!
    • が、Endpointにしかpingが届かない
    • VPN接続先ネットワーク内のホストに到達できず…
    •なんでだ?
    ESP32
    スマート
    フォン
    WireGuard
    Endpoint
    (RPi4)
    インターネット
    他のホスト
    11

    View Slide

  12. 動かすためにやったこと(2)
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた
    •アプリ送信データがWiFiに直接流れる…
    •lwIPはルーティング機構が存在しない
    • netif指定でsend: netif経由で送信
    • それ以外: デフォルトnetif経由で送信
    •WireGuard netifをデフォルトに変更
    アプリ
    WireGuard
    netif
    WiFi
    netif
    send
    udp_sendto
    修正前: デフォルト=WiFi
    アプリ
    WireGuard
    netif
    WiFi
    netif
    udp_sendto_netif(WiFi)
    send
    修正前: デフォルト=WireGuard
    12

    View Slide

  13. 動かすためにやったこと(3)
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた
    •WireGuardのハンドシェークは現在時刻を使用している
    •要求受信側はハンドシェーク時の時刻が
    前回より進んでいない場合ハンドシェーク拒否
    • RTCでの時刻保持やNTPでの時刻同期が必要
    •今回はNTPで時刻同期するようにして対応
    • ESP32 ArduinoではconfigTime関数呼び出すだけ
    13

    View Slide

  14. もうちょっと応用例
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた
    •pingは面白くないのでHarvest Dataにデータ投げる例
    ESP32
    uptime (起動後経過時間) [ms]
    count (送信回数)
    64[bit] = 8[byte]
    2つ
    =16[byte]
    バイナリ
    {
    "uptime":1016378,
    "count":201,
    "imsi":"...",
    "name":"",
    "location":null,
    "timestamp":1627205656599
    }
    OrbitでJSONに変換 Harvest Dataに投入
    14

    View Slide

  15. もうちょっと応用例
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた
    •Harvestで結果確認
    15

    View Slide

  16. Arduino Library化
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた
    •WireGuard IF部分を
    ESP32用にArduino Library化
    •Arcでuptime送信サンプル付き
    16

    View Slide

  17. Arduino Library化
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた
    • 使い方は簡単
    • WireGuard型変数宣言
    • NTP時刻調整
    • WireGuard::begin呼び出し
    • ArcのJSONに含まれている
    接続情報を引数で渡す
    • あとはWiFi同様に
    通信処理を記述
    // WireGuard configuration --- UPDATE this configuration from JSON
    char private_key[] = "(Private Key) "; // [Interface] PrivateKey
    IPAddress local_ip(1,2,3,4); // [Interface] Address
    char public_key[] = "(Public Key)"; // [Peer] PublicKey
    char endpoint_address[] = "link.arc.soracom.io"; // [Peer] Endpoint
    int endpoint_port = 11010; // [Peer] Endpoint
    ...
    static WireGuard wg;
    static HTTPClient httpClient;
    void setup()
    {
    Serial.begin(115200);
    Serial.println("Connecting to the AP...");
    WiFi.begin(ssid, password);
    while( !WiFi.isConnected() ) {
    delay(1000);
    }
    Serial.println("Adjusting system time...");
    configTime(9 * 60 * 60, 0, "ntp.jst.mfeed.ad.jp", "ntp.nict.jp",
    "time.google.com");
    Serial.println("Connected. Initializing WireGuard...");
    wg.begin(
    local_ip,
    private_key,
    endpoint_address,
    public_key,
    endpoint_port);
    }
    17

    View Slide

  18. 現状の課題(1/2)
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた
    •乱数生成処理の妥当性
    • WireGuard for lwIPではサンプルでrand()を使って実装
    • 必ず置き換えるようにとコード中にコメントあり
    • randは容易に推測可能なため
    •とりあえずESP32のハードウェア乱数
    + mbedTLSのCTR-DRBG実装で乱数生成を実装
    •専門ではないのでこれでいいのかよくわからん…
    • だれか詳しい人おしえてください。
    18

    View Slide

  19. 現状の課題(2/2)
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた
    •WireGuard接続情報はスケッチにハードコード
    • 真面目に使うなら暗号化NVSに保存などが必要
    19

    View Slide

  20. 未確認事項
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた
    •通信パフォーマンスがどれくらいか不明
    • 余裕があったらiperfサンプルあたり動かしたい
    • ESP32向け最適化の余地があるかも
    20

    View Slide

  21. ソースコードなど
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた
    •https://github.com/ciniml/WireGuard-ESP32-Arduino
    •https://github.com/ciniml/ESP32_WireGuard
    21

    View Slide

  22. おしまい
    2021/7/27
    ESP32 SORACOM Arc
    で つないでみた 22

    View Slide