# Meshtastic Node Setup & Web Client Integration This repository maintains the firmware build artifacts, local CA TLS provisioning, device configuration backups, and Kubernetes deployment integration for the local Meshtastic node. --- ## 1. Hardware & Network Overview * **Hardware**: Heltec WiFi LoRa 32 (V4) / ESP32-S3 (16MB Flash, 2MB PSRAM, 0.96" OLED display) * **Node MAC**: `f8:5b:1b:a1:bc:60` (Node ID: `!1ba1bc60`, Name: `Meshtastic bc60`) * **Firmware Base**: Meshtastic `v2.7.26.54e0d8d` * **Network Connectivity**: * Wi-Fi DHCP IP: `192.168.20.140` * mDNS Hostname: `meshtastic.local` * TCP Port 4403: Meshtastic Protobuf API (CLI and internal RPC) * TCP Port 443: Native HTTPS server serving `/api/v1/fromradio` and `/api/v1/toradio` with CORS enabled --- ## 2. Architecture & Challenges Solved ### A. Mixed Content & Browser Security The self-hosted Meshtastic Web Client runs on Kubernetes at `https://meshtastic-web.ericxliu.local` via internal Nginx ingress with TLS. Because the Web Client is a client-side Single Page Application (SPA), the browser makes direct API requests to the radio on LAN: * **Mixed Content Blocking**: The browser forbids plain HTTP calls from an HTTPS origin. * **Self-Signed TLS Rejection**: Stock Meshtastic firmware generates a self-signed certificate (`CN=meshtastic.local, O=Meshtastic`), which browsers reject with `NET::ERR_CERT_AUTHORITY_INVALID`. ### B. Custom Local CA Provisioning * A leaf certificate and private key were issued for `DNS:meshtastic.local` and `DNS:*.meshtastic.local` by Eric's private root CA (`ericxliu.local`, trusted in macOS Keychain). * Stock Meshtastic stores its HTTPS key and certificate in ESP32 NVS preferences under the `MeshtasticHTTPS` namespace (`PK` and `cert`). * The custom firmware in [`firmware-custom/`](./firmware-custom/) writes the DER-encoded CA-signed certificate and key directly into these NVS keys on startup. Because stock Meshtastic checks for existing keys before generating a self-signed pair, this CA certificate survives future upgrades. ### C. Handshake Latency & Web Client Timeout * **Handshake Bottleneck**: In stock firmware (`WebServer.cpp`), `IDLE_INTERVAL_MS` was set to `1000ms`. The multi-round-trip TLS handshake plus 2048-bit RSA computation took **~4.5 to 5.4 seconds**. * **Hardcoded Client Timeout**: The official web client bundle (`apps/web/src/pages/Connections/utils.ts`) had a hardcoded `2500ms` timeout on `testHttpReachable`. Every test attempt was aborted at 2.5s, marking the device as "Not reachable". * **The Fix**: 1. Reduced `IDLE_INTERVAL_MS` in firmware to `50ms` (dropping handshake and response time to **~1.34 seconds**). 2. In [`k8s-flux`](https://github.com/eric-x-liu/k8s-flux), added an `initContainer` in `apps/myapp/meshtastic-web/release.yaml` that patches `testHttpReachable` timeout in the bundle from `t=2500` to `t=15000` (15s). --- ## 3. Directory Layout ``` . ├── README.md ├── certs/ │ ├── meshtastic.local.crt # Signed leaf certificate (valid to Oct 2027) │ └── meshtastic.local.csr # Certificate Signing Request ├── firmware-custom/ │ ├── firmware-heltec-v4-2.7.26.54e0d8d.bin # Custom app0 image with CA cert + 50ms loop │ ├── firmware-heltec-v4-2.7.26.54e0d8d.factory.bin # Full factory image (bootloader + part + app) │ ├── MeshtasticTlsCertificate.h # DER cert & key header embedded into build │ └── patches/ │ └── WebServer.cpp.patch # Diff applied to stock v2.7.26.54e0d8d ├── firmware-2.7.26/ # Stock vendor 2.7.26 firmware binaries │ ├── firmware-heltec-v4-2.7.26.54e0d8d.factory.bin │ ├── firmware-heltec-v4-2.7.26.54e0d8d.mt.json │ ├── littlefs-heltec-v4-2.7.26.54e0d8d.bin │ └── mt-esp32s3-ota.bin ├── backups/ │ ├── aideepen-lora-v4-factory-f85b1ba1bc60.bin # Original factory 16MB flash dump │ └── nvs_backup_before_flash.bin # Live NVS partition backup (0x9000, 20KB) ├── docs/ │ └── 91Qt4C5SZBL.pdf # Heltec V4 board schematic and pinouts └── scripts/ ├── flash_custom_firmware.sh # Flash custom firmware to app0 over USB └── backup_nvs.sh # Backup device NVS partition over USB ``` --- ## 4. Maintenance & Operations ### Flash Custom Firmware via USB Connect the Heltec V4 via USB-C: ```bash ./scripts/flash_custom_firmware.sh /dev/cu.usbmodem1101 ``` Or directly with `esptool`: ```bash esptool --port /dev/cu.usbmodem1101 --baud 921600 write_flash 0x10000 firmware-custom/firmware-heltec-v4-2.7.26.54e0d8d.bin ``` ### Backup NVS Configuration ```bash ./scripts/backup_nvs.sh /dev/cu.usbmodem1101 ``` ### Verify TLS Handshake & API Endpoints Verify certificate validity using macOS system trust: ```bash # Must verify without -k / insecure flags curl -v https://meshtastic.local/api/v1/fromradio ``` Verify CLI over Wi-Fi: ```bash meshtastic --host meshtastic.local --info ``` ### Accessing the Web Client 1. Open **[https://meshtastic-web.ericxliu.local](https://meshtastic-web.ericxliu.local)**. 2. Select **HTTP** connection and set URL to `meshtastic.local` (with **Use HTTPS** enabled). 3. Connection tests complete in ~1.3s and save cleanly.