HALO/v0.1.0/GET STARTED

Getting started

This page takes you from bare hardware to a running HALO network with one gateway and one node. A HALO network has exactly one gateway — the control-plane and mesh exit point — and one or more nodes peered to it over HaLow.

Prerequisites

  • A Raspberry Pi 4B (or compatible ARM board) for the gateway, with upstream connectivity on eth0.
  • One or more Pi-class boards for nodes, each with a Morse Micro HaLow radio.
  • A HALO .img.gz image. Build it on a Pi with the pi-gen builder in deploy/image/ — do not build the image on Windows, where path handling corrupts the build.
  • A workstation to flash the image and reach the gateway over LAN.

Flash and first boot

Write the image to each board's SD card and boot it.

bash
zcat halo-<version>.img.gz | sudo dd of=/dev/sdX bs=4M status=progress conv=fsync

The image carries all five binaries (gateway-api, halo-agent, halo-mesh, halo-field, haloctl), the custom wpa_supplicant, mesh scripts, the frontend, nginx, dnsmasq, wireguard-tools, and gpsd. A first-boot provisioner reads halo.toml from the FAT32 boot partition and enables services according to the node role.

Role-based service enablement decides what comes up:

  • Gateway nodes start nginx and gateway-api.
  • Remote nodes start halo-field on port 80.

halo-mesh is the root dependency. If systemctl is-enabled halo-mesh returns disabled, no HALO services start on boot. Always verify it is enabled after any hardware change.

Bring up the gateway

On the gateway, run the interactive setup wizard. It prompts for node name and ID, role, mesh SSID/PSK/country/channel, and admin credentials, then writes /etc/halo/config.yaml.

bash
haloctl setup

Confirm the gateway is healthy. Every check should report PASS.

bash
haloctl gateway-health

A healthy gateway shows halo-mesh, gateway-api, and halo-agent active, wlan0 in mesh point mode, a bat0 address on 10.41.0.0/24, a wg0 address on 10.42.0.0/24, and a recent WireGuard handshake.

Reach HALO Portal

HALO Portal is served by nginx on port 80 of the gateway. Open it in a browser and log in.

text
http://<gateway-lan-ip>/

Default credentials are admin / ethrx. On first login the gateway forces an admin password change. The API itself listens on port 8080; nginx proxies it and the WebSocket stream behind port 80.

Join the first node

Node onboarding is automatic. A node boots, joins the 802.11s mesh, peers with the gateway, and acquires a bat0 address via DHCP. It then registers a WireGuard key and starts reporting:

  1. The node peers with the gateway over HaLow and gets an underlay IP on 10.41.0.0/24.
  2. It calls POST /v1/mesh/wg-register, exchanges WireGuard keys, and receives an overlay IP on 10.42.0.0/24.
  3. The agent authenticates and runs a heartbeat loop, posting telemetry every 5 seconds.
  4. The node appears in the topology and on the dashboard.

From the gateway you can list known nodes and confirm reachability.

bash
haloctl gateway-peers

If a node needs admin approval before it is trusted, approve it from the gateway.

bash
haloctl admin list
haloctl admin approve <registration-id>

Verify the mesh

Check the full node status dashboard on any device.

bash
haloctl status

From a remote node, confirm it can reach the gateway through the mesh.

bash
haloctl remote-diag

SSH over the WireGuard overlay (10.42.0.x) is unreliable during banner exchange. Prefer LAN IPs when available, or use curl http://10.42.0.2:80/api/diag from the gateway as a diagnostic fallback — halo-field always responds even when SSH does not.

Where to go next