Skip to content

Latest commit

Β 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ”₯ Emberwall

Buildroot from scratch Rust Linux hardened nftables default-deny license MIT

Hardened, minimal IoT/OT security Linux β€” built from scratch with Buildroot. Ships the Rust-native sentinel scanner + secrets vault. A secure MQTT edge gateway.

Emberwall live demo: silent boot, sentinel TCP/UDP/Modbus scan, secrets vault, and MQTT gateway.

Emberwall is not based on any existing distro. It is assembled from source with Buildroot: its own cross-toolchain, a hardened Linux kernel, and a tiny immutable userland β€” no package manager, a few MB in size. Every tool inside is chosen; nothing is incidental. It exists to be the hardened edge gateway for the IoT pipelines in my other projects.


At a glance

What it is A whole Linux distribution assembled from source with Buildroot β€” its own cross-toolchain, a hardened kernel, and an immutable userland of a few MB with no package manager.
The one idea Every tool inside was chosen. Nothing is incidental, because nothing arrived as a dependency of something else β€” which is the property a general-purpose distro cannot give you at the edge.
What it ships sentinel, a ~0.5 MB static Rust binary that folds a port scanner and a secrets vault into one hardened CLI β€” the work from pyscan and aegisvault collapsed into a single tool with no runtime.
Where it sits The gateway tier, deliberately not the dashboard tier. Node-RED, InfluxDB and Grafana are heavy Go and Node services; putting them on a hardened edge node defeats the point of hardening it.
Hardened PIE, full RELRO, SSP-strong, FORTIFY_SOURCE=2 Β· KASLR, strict RWX, hardened usercopy, yama + lockdown LSMs, no /dev/mem Β· nftables default-deny, dropbear with no root login
Targets x86-64 and ARM64 Β· live ISO, workstation, or locked appliance β€” five defconfigs
Try it Build the ISO, boot it in QEMU, log in as root / sentinel, type sentinel-demo

Contents β€” Highlights Β· Where it fits Β· sentinel Β· Quick start Β· Variants Β· Hardening Β· Build flow Β· Layout Β· Status


✨ Highlights

  • Rust-native tooling β€” the sentinel binary (~0.5 MB, static) unifies a port scanner and a secrets vault into one hardened CLI.
  • OT/ICS aware β€” Modbus, S7comm, IEC-104, DNP3, BACnet, EtherNet/IP, plus IoT (MQTT, CoAP, LoRaWAN) β€” TCP and UDP.
  • Hardened by default β€” PIE/RELRO/SSP/FORTIFY, KASLR, lockdown+yama LSMs, restrictive sysctl, nftables default-deny, dropbear without root login.
  • IoT gateway ready β€” Mosquitto (broker + clients + bridge), WireGuard, Chrony, CAN/IΒ²C tooling.
  • Multi-target β€” x86-64 and ARM64; live ISO, workstation, or locked appliance.

πŸ›°οΈ Where it fits

Emberwall is the hardened edge gateway, not the dashboard tier. For a sensor project like solar-weather-station:

flowchart LR
    subgraph EDGE["🌱 Edge (field)"]
        S["ESP32 + sensors<br/>(temp Β· hum Β· lux Β· batt)"]
        B["LoRa→MQTT bridge"]
        S -- "LoRa P2P" --> B
    end

    subgraph GW["πŸ”₯ Emberwall (hardened gateway)"]
        M["mosquitto<br/>MQTT broker"]
        F["nftables<br/>default-deny"]
        SN["sentinel<br/>scan Β· vault"]
        B -- "MQTT wx/#" --> M
        M --- F
        M --- SN
    end

    subgraph SRV["πŸ–₯️ Server / Raspberry Pi"]
        NR["Node-RED"] --> IDB["InfluxDB"] --> GRA["Grafana"]
    end

    M -- "WireGuard (encrypted)" --> NR
Loading

The Node-RED / InfluxDB / Grafana stack runs on that server or a Raspberry Pi β€” deliberately not on the minimal node (they are heavy Go/Node services; putting them on a hardened edge node defeats its purpose). Suggested topic contract: wx/<node-id>/reading β†’ {"tempC":21.4,"hum":58,"batt":3.9,"lux":12000}.


🧰 sentinel β€” the built-in Rust tool

sentinel scan <ip> [--ports top|1-1024|22,80,502] [--udp] [--modbus]
sentinel vault encrypt|decrypt [--input F] [--output F]
  • scan β€” concurrent TCP-connect scanning with OT/ICS + IoT service recognition, UDP probing (real CoAP /.well-known/core probe) and a Modbus/TCP identification probe. A Rust port of the core of pyscan.
  • vault β€” secrets encryption with argon2id + XChaCha20-Poly1305, secrets zeroized in memory. The Rust crypto core of AegisVault as a native binary.

Hexagonal design: domain (services, modbus) / application (tcp, udp) / adapters (ui, vault). Built as a Buildroot cargo-package, cross-compiled static, zero C dependencies.

flowchart TB
    CLI["CLI / main.rs<br/>(arg parsing)"]
    subgraph APP["Application"]
        TCP["tcp engine<br/>(concurrent connect)"]
        UDP["udp engine<br/>(CoAP probe)"]
    end
    subgraph DOM["Domain"]
        SVC["services<br/>(OT/IoT ports)"]
        MOD["modbus<br/>(MBAP probe)"]
        VLT["vault<br/>(argon2id + XChaCha20)"]
    end
    subgraph ADP["Adapters"]
        UI["ui (amber output)"]
    end
    CLI --> TCP & UDP & VLT
    TCP --> SVC & MOD
    UDP --> SVC
    TCP & UDP & VLT --> UI
Loading

πŸš€ Quick start (live ISO)

Host requirements (Ubuntu):

sudo apt install -y build-essential git wget cpio unzip rsync bc \
  libncurses-dev file python3 libelf-dev libssl-dev flex bison \
  mtools dosfstools qemu-system-x86
sudo update-alternatives --install /usr/bin/install install /usr/bin/gnuinstall 100 || true

Build the bootable ISO:

git clone https://gitlab.com/buildroot.org/buildroot.git
cd buildroot
make BR2_EXTERNAL=/path/to/emberwall emberwall_live_x86_64_defconfig
make -j$(nproc)
# β†’ output/images/rootfs.iso9660   (hybrid: also dd-able to USB)

Run it (QEMU windowed, or attach the ISO to a VirtualBox VM):

/path/to/emberwall/board/emberwall/x86_64/run-qemu-iso.sh
# login: root / sentinel   β†’   type: sentinel-demo

Write to USB and boot on real hardware:

sudo dd if=output/images/rootfs.iso9660 of=/dev/sdX bs=4M status=progress conv=fsync

Rust dependencies are vendored in package/sentinel/src/vendor/, so the build works offline. Full guide: docs/BUILD.md Β· diagrams: docs/DIAGRAMS.md.


πŸ—ΊοΈ Variants

flowchart TB
    EXT["BR2_EXTERNAL<br/>(one source tree)"]
    EXT --> L["live<br/>rootfs.iso9660<br/>(boot / USB)"]
    EXT --> W["workstation<br/>ext4 + cpio<br/>(analyst)"]
    EXT --> A["appliance<br/>squashfs (RO)<br/>(locked node)"]
    L --> AR1["x86-64"]
    W --> AR2["x86-64 Β· ARM64"]
    A --> AR3["x86-64 Β· ARM64"]
Loading
defconfig Arch Output Use
emberwall_live_x86_64 x86-64 rootfs.iso9660 Live ISO (boot / USB)
emberwall_workstation_x86_64 x86-64 ext4 + cpio Analyst workstation
emberwall_workstation_aarch64 ARM64 ext4 Same, on SBC / QEMU virt
emberwall_appliance_x86_64 x86-64 squashfs (RO) Locked IoT node
emberwall_appliance_aarch64 ARM64 squashfs (RO) Locked IoT node (ARM)

πŸ”’ Hardening

Toolchain: PIE, full RELRO, SSP-strong, FORTIFY_SOURCE=2. Kernel: KASLR, strict RWX, hardened usercopy, init-on-alloc/free, yama+lockdown LSMs, no /dev/mem, netfilter/nftables. Runtime: restricted ptrace/kptr/dmesg, hardened BPF, anti-spoofing sysctl, nftables default-deny input, dropbear without root login.

Planned for production appliances: dm-verity read-only root, verified boot, signed A/B OTA (swupdate).


πŸ—οΈ Build flow

flowchart LR
    SRC["emberwall<br/>(BR2_EXTERNAL)"] --> BR["Buildroot<br/>make defconfig"]
    BR --> TC["cross toolchain<br/>+ hardened kernel<br/>+ rootfs"]
    TC --> RUST["sentinel<br/>(cargo, vendored)"]
    RUST --> IMG["output/images/<br/>rootfs.iso9660"]
    IMG --> QEMU["QEMU / VirtualBox"]
    IMG --> USB["dd β†’ USB β†’ real HW"]
Loading

πŸ“ Layout

emberwall/
β”œβ”€β”€ configs/                 # defconfigs (5 variants)
β”œβ”€β”€ board/emberwall/         # overlay, kernel/sysctl hardening, QEMU + demo scripts
β”œβ”€β”€ package/
β”‚   β”œβ”€β”€ sentinel/            # the Rust tool (source + vendored deps)
β”‚   β”œβ”€β”€ pyscan/              # optional Python packages (opt-in)
β”‚   └── aegisvault/
β”œβ”€β”€ docs/                    # BUILD.md Β· DIAGRAMS.md Β· demo.gif
└── external.desc / external.mk / Config.in

πŸ“Š Status

The distribution builds and boots today: five defconfigs across x86-64 and ARM64, a hardened kernel, the immutable userland, sentinel compiled from vendored sources, and a live ISO that is also dd-able to USB.

Still open, and all of it belongs to the same theme β€” making an appliance you can trust after it leaves your hands:

  • dm-verity read-only root, so a modified rootfs fails to mount rather than booting quietly.
  • Verified boot, so the kernel that runs is the kernel that was signed.
  • Signed A/B OTA via swupdate, so an update that fails rolls back instead of bricking a device in the field.

Until those land, Emberwall is hardened against what happens while it runs, not against someone who can rewrite its storage offline.


Part of a larger body of work β€” see my profile for the full edge β†’ gateway β†’ dashboard picture.

MIT Β© Zoel Arias ManchΓ³n

About

πŸ”₯ Hardened, minimal IoT/OT security Linux built from scratch with Buildroot. Ships the Rust-native `sentinel` scanner + secrets vault. Secure MQTT edge gateway.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages