Skip to content

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 ██████╗ ██╗██╗   ██╗██╗ ██████╗███████╗
██╔════╝ ██║██║   ██║██║██╔════╝██╔════╝
██║      ██║██║   ██║██║██║     ███████╗
██║      ██║╚██╗ ██╔╝██║██║     ╚════██║
╚██████╗ ██║ ╚████╔╝ ██║╚██████╗███████║
 ╚═════╝ ╚═╝  ╚═══╝  ╚═╝ ╚═════╝╚══════╝

Civilian ICS node software — private mesh messaging for teams, communities, and organizations
Built by @mrdulasolutions


CivICS is the civilian node and operator console for closed ICS networks. Each device holds its own cryptographic identity. Teams message one-to-one or in groups after they join a private hub — a path your organization issues, not a public chat network.

CivICS does not ship a public hub and does not pin a vendor endpoint. You host the hub (LAN, VPS, or cloud) and issue Mesh + Dest yourself.

Device  ──TCP 4242──►  Private hub (yours)
 Operator UI              Mesh + Dest you issue
 (localhost:8080)         Console stays on loopback

Quick start

What you need

Requirement Notes
Docker Desktop or engine with Compose v2
ICS Transport daemon (Apache-2.0). Docker build context.
MMF Message format (Apache-2.0). Docker build context.
A hub card Mesh host:port + Dest (32 hex) from your administrator

Run a node

git clone https://github.com/mrdulasolutions/CivICS.git
cd CivICS
cp .env.example .env   # optional
docker compose up --build -d

Point ICS_CONTEXT and MMF_CONTEXT at your ICS and MMF checkouts if they are not the default nested paths (../../ICS, ../../MMF). A sibling clone (~/mesh/CivICS next to ICS and MMF) uses ICS_CONTEXT=../ICS MMF_CONTEXT=../MMF. Continue on a Linux host: docs/LINUX-BOX.md.

Surface Address
Operator console http://127.0.0.1:8080
Second local node http://127.0.0.1:8081
Third local node http://127.0.0.1:8082
Mesh TCP host port 4242 (lab bind defaults to 127.0.0.1)
  1. Open the console → This device. Set name, unit, device type, and station. Save identity.
  2. Join a hub (recommended) or call a peer.
  3. Click Make visible on every device that should appear to others.
  4. Open Messages. A spoke can message a dest the hub has heard even if those two spokes never called each other on TCP. The third console on 8082 is for that hub-relay check.

Full walkthrough: wiki · Getting started.

Connect to a private hub

Your administrator issues a hub card. CivICS never hardcodes a hub.

Mesh: hub.example.com:4242
Dest: <32 hex characters>

On the device:

  1. SetupHosted hub.
  2. Paste the card, or fill Mesh and Dest. Directory is optional.
  3. Call that hub, then Make visible.

Direct device call

For a nearby peer without a hub: SetupCall a device → paste their TCP address (port 4242 unless specified) → Make visible on both sides.

Direct calls are for lab, local, or point-to-point use. They are not a substitute for a private hub in operational traffic.

Features

Identity

  • Each node has a dest (32-hex message address) that persists with its Docker volume
  • Profile fields (name, unit, device type, station) are what others see
  • docker compose down keeps identity; docker compose down -v mints a new device

Mesh

  • ICS TCP (HDLC framing, port 4242) plus AutoInterface UDP 29716 on the compose network (ICS_AUTO_PORT=0 to disable). Lab compose sets ICS_IFAC=civics-lab. Real LAN, USB radio, and BlueZ: docs/LINUX-BOX.md
  • Share cards: Mesh + Dest for onboarding
  • Public community meshes (*.reticulum.network and listed public hubs) are blocked

Console

  • Home / Messages / Setup
  • Operator UI bound to localhost by default
  • Groups are created on Messages. ICS rooms are 1:1 dest send, not MeshChat rooms.

Hubs

  • Join any private hub your organization operates
  • Self-host with compose.hub.yaml
  • Example AWS automation under infra/aws/ — not a hosted tenant

Self-host a hub

Keep the operator console on loopback. Issue Mesh + Dest from that hub’s share card.

cp .env.hub.example .env.hub
docker compose -f compose.hub.yaml --env-file .env.hub up --build -d

Host production hubs on a network you control. Operator checklist: docs/PRIVATE-HUB.md. Also wiki · Self-hosting.

Security

  • ICS identity (ICS_HOME, /var/lib/civics/ics) plus hub lists, channels, and messages (/var/lib/civics/civics) live on the Docker volume
  • Publish TCP 4242 (and UDP 29716 on Linux LAN) only to networks you intend to peer with. Lab compose binds 4242 to loopback; compose.hub.yaml / compose.lan.yaml open the host. Keep 8080 and 7850 on loopback.
  • Report vulnerabilities: SECURITY.md
./scripts/backup.sh
./scripts/restore.sh backups/<stamp>
CIVICS_DRILL_YES=1 ./scripts/backup-drill.sh   # backup → down -v → restore; same dest
./scripts/drop-saved-peer.sh <host> 4242       # leftover ICS peers.json entry

Architecture

civics-hub / civics-spoke
├── icsd          ICS daemon (TCP 4242, AutoInterface 29716, RPC 7850, ICS_HOME=/var/lib/civics/ics)
├── status_server Operator console + API (HTTP 8080)
├── mesh.py       Peers, dest, MMF messages, hosted hubs
├── ui/           Home, Messages, Setup
└── volume        /var/lib/civics  (not /var/lib/reticulum)

Transport is ICS (Apache-2.0). Messages are MMF (Apache-2.0). CivICS is not TAK Server and does not ship Python rns or lxmf.

See ARCHITECTURE.md and the wiki.

Configuration

Copy .env.example to .env.

Variable Purpose
CIVICS_CALLSIGN Default display name until identity is saved
CIVICS_HOME Data root inside the container (/var/lib/civics; ICS_HOME is $CIVICS_HOME/ics)
CIVICS_ADVERTISE_HOST Host on the share card (LAN, Tailscale, or hub DNS — not 127.0.0.1 for remote peers)
CIVICS_TCP_BIND Host bind for published mesh TCP (lab default 127.0.0.1)
CIVICS_TCP_PORT Published mesh port (container listens on 4242)
ICS_IFAC Shared AutoInterface secret (civics-lab on compose.yaml; unset on hub-only)
ICS_LORA_DEV Optional boot TTY (compose.lora.yaml). Empty = Home → Radio picker.
CIVICS_HTTP_BIND / CIVICS_HTTP_PORT Operator console bind

Hub-only deployments use .env.hub.example. Details: wiki · Configuration.

Documentation

Wiki Operator handbook
ARCHITECTURE.md How the node is put together
docs/PRIVATE-HUB.md Example private-hub runbook
docs/LINUX-BOX.md Continue on Linux: real LAN AutoInterface, then RNode / BlueZ
VERSIONS.md Pinned ICS and MMF SHAs for image rebuilds
ROADMAP.md Later tracks
CONTRIBUTING.md How to change the code
SECURITY.md Vulnerability reporting
CODE_OF_CONDUCT.md Community standards

License

Apache License 2.0. ICS and MMF are Apache-2.0. This image does not ship Python rns or lxmf.

Disclaimer

CivICS is provided AS IS, without warranties or conditions of any kind. See LICENSE.

What this software is. A Docker node and operator console. Transport is ICS. Messages are MMF. Data lives under ICS_HOME / /var/lib/civics, not a Reticulum/rns tree.

What it is not. TAK Server, ATAK, MeshChat, Python rns/lxmf, or a public Reticulum community client. ICS implements the public-domain Reticulum protocol. MMF follows the public LXMF layout. Neither is a fork of those reference packages.

Affiliation. Not affiliated with, endorsed by, or certified by Amazon Web Services, Microsoft, unsigned.io, or TAK product vendors. Reticulum, LXMF, TAK, AWS, and Azure are names of their respective owners.

“Private hub.” A hub you host or procure, reached by Mesh + Dest you issue. It is not a hosted tenant in this repository.

You own the deployment. Hub cards, peering, backups, radio/spectrum, and lawful use are the operator’s. Device types in the console describe the platform a node is on. Contracts can add duties a README cannot waive.


Built by @mrdulasolutions

About

Civilian Version of the Interoperable Communication Service Node Software

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages