Service setup
April 17, 2026 · View on GitHub
Both the central server and the remote agent can be run as systemd services that start on boot and restart on failure. Installers live in scripts/.
Prerequisites
- Repo cloned, venv created, dependencies installed per install.md.
- For the agent: Meshtastic radio on USB, RTL-SDR connected. GPS optional.
- For the server: HackRF / RTL-SDR / BLE / WiFi per your use case, plus the Meshtastic radio if using C2.
Central server
cd ~/code/sigint
sudo ./scripts/install-server.sh
The installer:
- Offers to copy a template from
configs/*.json.exampleintoconfigs/server.json(skip if you've already written one). - Optionally applies a Meshtastic channel URL to the server's radio via
meshtastic --seturl. - Writes
/etc/systemd/system/sigint-server.servicewith the current project path substituted for@PROJECT_DIR@. systemctl enable --now sigint-server.service.
Service details:
- Runs as
root(needed for BLE / WiFi). ExecStart=.../sdr.py server configs/server.json --web— web UI always on, port from config (web_port) or default 8080.Restart=always, RestartSec=5.
Useful commands:
sudo systemctl status sigint-server
sudo systemctl restart sigint-server
journalctl -u sigint-server -f
Remote agent
cd ~/code/sigint
sudo ./scripts/install-agent.sh
The installer prompts for four things:
- Agent ID — short identifier, e.g.
N01. - Meshtastic serial port — full
/dev/serial/by-id/...path recommended. - Meshtastic channel URL (optional) — applied via
--seturlif provided. Leave empty if the radio is already on the shared channel. - GPS serial port (optional) — u-blox or similar NMEA source.
Then it writes configs/agent.json, installs sigint-agent.service, and starts it.
Service details:
- Runs as
root. ExecStart=.../sdr.py agent --config configs/agent.json./var/lib/sigint/holdsstate.json,outbox.db, andscanner/<type>_*.db.Restart=always, RestartSec=5.
Useful commands:
sudo systemctl status sigint-agent
sudo systemctl restart sigint-agent
journalctl -u sigint-agent -f
# Edit the agent config without reinstalling:
sudo $EDITOR configs/agent.json
sudo systemctl restart sigint-agent
Template substitution (@PROJECT_DIR@)
The committed unit files (scripts/sigint-*.service) use @PROJECT_DIR@ as a placeholder for the absolute repo path. Each installer sed-substitutes it to the current project directory when copying the unit into /etc/systemd/system/. That makes the repo path-portable — clone anywhere, run the installer, done.
What the installers don't do
None of them install system packages or Python dependencies. Do that first (install.md). The installer assumes:
venv/bin/python3exists in the project dirpip install -r requirements.txthas been runrtl-sdr,readsb,rtl_ais,multimon-ng,rtl-433, etc. are on PATH as needed
Provisioning a fresh Meshtastic radio
If the radio is on the factory default channel, the server can't hear it and vice versa. Provision with:
venv/bin/meshtastic --port /dev/serial/by-id/usb-<your-radio>-if00 --seturl '<URL>'
The same URL must be set on every node that should join the C2 mesh. install-agent.sh and install-server.sh both run --seturl for you if you paste the URL at the prompt.
Verify:
venv/bin/meshtastic --port /dev/serial/by-id/usb-<your-radio>-if00 --info | grep -A1 "Complete URL"
Un-install
sudo systemctl disable --now sigint-agent # or sigint-server
sudo rm /etc/systemd/system/sigint-agent.service
sudo systemctl daemon-reload
# Optional: remove the config + state
sudo rm -rf /var/lib/sigint configs/agent.json