LoginSignup
5
3

More than 1 year has passed since last update.

ESP32(M5Stack Basic)上でWireGuardを使用したMQTT実装サンプル

Posted at

このエントリーはNGINXのStreamモジュールでMQTT <=> MQTTS変換をしてAWS IoT Coreへ接続するにおける、MCUとProxy間を WireGuard で保護するアーキテクチャの解説です。

ESP32(M5Stack Basic)上でWireGuardを使用したMQTT実装サンプル

mqtt_on_wireguard.ino
/*
   Copyright 2021 Kohei "Max" MATSUSHITA.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
#include <M5Stack.h>

#include <WiFi.h>
char WIFI_SSID[] = "{YOUR_WIFI_SSID}";
char WIFI_PASSWORD[] = "{YOUR_WIFI_PASS}";
WiFiClient net;

#include <WireGuard-ESP32.h>
static WireGuard wg;
char private_key[] = "{YOUR [Interface] PrivateKey}"; // [Interface] PrivateKey
IPAddress local_ip(192, 168, 200, 254);               // [Interface] Address
char public_key[] = "{YOUR [Peer] PublicKey}";        // [Peer] PublicKey
char endpoint_address[] = "{YOUR [Peer] Endpoint}";   // [Peer] Endpoint
int endpoint_port = 11010;                            // [Peer] Endpoint

#include <PubSubClient.h>
PubSubClient mqtt = PubSubClient(net);

#define THING_NAME      "M5StackBasic0"
#define ENDPOINT        "beam.soracom.io"
#define PORT             (1883)
#define PUBLISH_TOPIC   "demo0/via_beam"

void connectToNetwork() {
    Serial.print("Connecting to Wi-Fi: ");
    WiFi.mode(WIFI_STA);
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    while (WiFi.status() != WL_CONNECTED){
        delay(200);
        Serial.print(".");
    }
    Serial.println("done.");
}

void connectToWireGuard() {
    Serial.print("Adjusting system time: ");
    configTime(9 * 60 * 60, 0, "ntp.jst.mfeed.ad.jp", "ntp.nict.jp", "time.google.com");
    delay(3000); // Wait for adjust
    Serial.println("done.");
    Serial.print("Connect to SORACOM Arc (WireGuard):");
    wg.begin(local_ip, private_key, endpoint_address, public_key, endpoint_port);
    Serial.println("done.");
}

void connectToMQTTS() {
    Serial.print("Connecting to MQTTS broker via SORACOM Beam(Proxy): ");
    mqtt.setServer(ENDPOINT, PORT);
    while (!mqtt.connect(THING_NAME)) {
        Serial.print(".");
        delay(200);
    }
    Serial.println("Connected!");
}

void setup() {
    Serial.begin(115200);
    connectToNetwork();
    connectToWireGuard();
    connectToMQTTS();
}

void publishMessage() {
    char payload[512];
    sprintf(payload, "{\"time\": %lu}", millis());
    mqtt.publish(PUBLISH_TOPIC, payload);
}

#define LOOP_INTERVAL_MS (10000)
void loop() {
    Serial.println("loop");
    publishMessage();
    unsigned long next = millis();
    while (millis() < next + LOOP_INTERVAL_MS) {
        mqtt.loop();
    }
}

利用可能なサーバー側の構成

サーバー上にWireGuardサーバーとNGINXによるMQTT/MQTTS中継サーバーを構築した環境、もしくはSORACOM ArcとSORACOM Beamの組み合わせで利用できます。

SORACOM Arcはいわゆる「マネージドWireGuardサーバー」サービス、SORACOM BeamはMQTT等のプロトコル変換/転送サービスです。

独自でサーバーを構築する場合

SORACOM プラットフォームを利用する場合

独自でサーバーを構築する場合のNGINX設定はNGINXのStreamモジュールでMQTT <=> MQTTS変換をしてAWS IoT Coreへ接続するをご覧ください。
WireGuardについては公式のマニュアルをご確認ください。

SORACOM プラットフォームについてはSORACOM Arcのユーザードキュメント並びにSORACOM Beamのユーザードキュメントをご覧ください。

フットプリント比較

同等の実装でMQTT+TLS、MQTT+WireGuard、MQTTのみでフットプリントを比較しました。

フラッシュメモリ RAM
MQTT+TLS 911,762 40,456
MQTT+WireGuard 779,158 41,120
MQTTのみ 748,302 39,912

MQTT+WireGuardは、MQTT+TLSと比較してフラッシュメモリを 141KBも節約できます。MQTTのみから+30KBでVPNが張れるとも言えます。

確認環境

  • Arduino IDE 1.18.6
  • M5Stack Basic
    • ボード定義: ESP32(1.0.6)
    • ライブラリ: M5Stack(0.3.6)

あとがき

EoT

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3