# OpenMesh ISP

OpenMesh ISP is an open-source platform for operating a community-owned mesh network. It combines node provisioning, routing, subscriber management, service monitoring, and a lightweight customer portal into one deployable stack.

The project is designed for neighborhoods, cooperatives, rural broadband groups, and disaster-response teams that use community gateways and wireless mesh nodes to share reliable internet access.

> **Project status:** Beta. OpenMesh ISP is suitable for lab and pilot deployments. Review the security, regulatory, and operational requirements in your region before serving public traffic.

## Features

- Automatic mesh-node discovery and enrollment
- WireGuard tunnels between trusted nodes and gateways
- Support for Babel and BATMAN-adv routing
- Subscriber plans, quotas, and service suspension
- Captive portal and voucher-based guest access
- Gateway health, latency, and bandwidth monitoring
- Prometheus metrics and Grafana dashboards
- Role-based access for operators and volunteers
- Configuration backups and audit logs
- REST API for provisioning and automation
- Docker Compose deployment for small installations
- PostgreSQL and Redis-backed control plane

## Architecture

A typical deployment contains:

- **Controller:** Stores configuration, provisions nodes, and exposes the operator dashboard and API.
- **Gateway:** Connects the mesh to an upstream internet provider and applies subscriber policies.
- **Node agent:** Runs on each mesh router and reports health, neighbors, and route information.
- **Portal:** Provides subscriber login, usage information, and guest access.
- **Monitoring stack:** Collects metrics and alerts operators when nodes or gateways fail.

The controller does not forward subscriber traffic. If the controller becomes unavailable, provisioned nodes continue routing with their last known configuration.

## Requirements

For the controller:

- Linux host with 2 CPU cores and 4 GB RAM
- Docker Engine 25 or later
- Docker Compose v2
- A DNS name with ports `80` and `443` reachable
- SMTP credentials for account invitations and alerts

For mesh nodes:

- OpenWrt 23.05 or later
- At least 16 MB flash and 128 MB RAM
- `wireguard-tools`
- `babeld` or `kmod-batman-adv`
- Accurate system time through NTP

## Installation

Clone the repository and create a local environment file:

```bash
git clone https://github.com/openmesh-isp/openmesh.git
cd openmesh
cp .env.example .env
```

Generate application secrets:

```bash
./scripts/generate-secrets
```

Edit `.env` and set the public hostname, administrator email, and mail server credentials. Then start the stack:

```bash
docker compose up -d
```

Run the initial database migration and create an administrator:

```bash
docker compose exec controller openmesh migrate
docker compose exec controller openmesh admin create
```

Open `https://mesh.example.org` and sign in with the administrator account.

To check the deployment:

```bash
docker compose ps
docker compose exec controller openmesh doctor
```

## Usage

### Add a gateway

Create a gateway enrollment token:

```bash
docker compose exec controller openmesh gateway create \
  --name north-gateway \
  --site northside
```

Install the agent on the gateway and enroll it using the token returned by the command:

```bash
curl -fsSL https://mesh.example.org/install-agent.sh | sh
sudo openmesh-agent enroll --token om_enroll_xxxxxxxxx
```

Approve the gateway in **Network → Pending Devices** before enabling subscriber traffic.

### Add a mesh node

Create a node token from the dashboard or CLI:

```bash
docker compose exec controller openmesh node token create \
  --site northside \
  --expires 30m
```

On an OpenWrt node:

```bash
opkg update
opkg install openmesh-agent wireguard-tools babeld
openmesh-agent enroll --controller https://mesh.example.org \
  --token om_enroll_xxxxxxxxx
```

Once approved, the controller distributes routing, radio, DNS, and gateway-selection settings to the node.

### Create a subscriber

```bash
docker compose exec controller openmesh subscriber create \
  --name "Alex Morgan" \
  --email alex@example.net \
  --plan community-25
```

Assign the subscriber's router or device from the dashboard. Policies are applied at the active gateway during the next synchronization cycle.

### Inspect network health

```bash
docker compose exec controller openmesh node list
docker compose exec controller openmesh gateway status
docker compose exec controller openmesh routes inspect --site northside
```

Prometheus metrics are available at `/metrics` when enabled. The bundled Grafana instance is exposed only on the internal Docker network by default.

## Configuration

Application settings are loaded from `.env`. Network and site settings are stored in `config/network.yaml`.

### Environment variables

| Variable | Required | Default | Description |
| --- | --- | --- | --- |
| `OPENMESH_PUBLIC_URL` | Yes | — | Public HTTPS URL of the controller |
| `OPENMESH_SECRET_KEY` | Yes | — | Secret used to sign sessions and tokens |
| `OPENMESH_DATABASE_URL` | Yes | — | PostgreSQL connection string |
| `OPENMESH_REDIS_URL` | Yes | — | Redis connection string |
| `OPENMESH_ADMIN_EMAIL` | Yes | — | Initial operator email |
| `OPENMESH_SMTP_URL` | No | — | SMTP connection URL for email delivery |
| `OPENMESH_ENROLLMENT_TTL` | No | `30m` | Default lifetime of enrollment tokens |
| `OPENMESH_METRICS_ENABLED` | No | `true` | Exposes Prometheus metrics |
| `OPENMESH_LOG_LEVEL` | No | `info` | Logging level |
| `OPENMESH_TRUSTED_PROXIES` | No | — | Comma-separated reverse-proxy addresses |

### Network configuration

Example `config/network.yaml`:

```yaml
network:
  name: Northside Community Mesh
  domain: mesh.example.org
  management_cidr: 10.64.0.0/16
  subscriber_cidr: 10.80.0.0/14
  dns:
    servers:
      - 1.1.1.1
      - 9.9.9.9

routing:
  protocol: babel
  metric: etx
  gateway_selection: lowest-cost
  convergence_interval: 30s

wireguard:
  listen_port: 51820
  persistent_keepalive: 25s
  rotate_keys_every: 90d

sites:
  northside:
    channel_2ghz: 6
    channel_5ghz: 149
    mesh_ssid: openmesh-backhaul
    client_ssid: Northside Community WiFi
    minimum_signal_dbm: -78

plans:
  community-25:
    download_mbps: 25
    upload_mbps: 10
    monthly_quota_gb: 500
  community-100:
    download_mbps: 100
    upload_mbps: 25
    monthly_quota_gb: 1000
```

Validate changes before applying them:

```bash
docker compose exec controller openmesh config validate
docker compose exec controller openmesh config apply
```

Configuration updates are staged first. Operators can review the affected nodes and gateways before confirming rollout.

## Backups

Create a backup of the database and controller configuration:

```bash
./scripts/backup ./backups
```

Restore from a backup:

```bash
docker compose down
./scripts/restore ./backups/openmesh-YYYYMMDD-HHMMSS.tar.gz
docker compose up -d
```

Store backups outside the controller host and test restoration regularly.

## Upgrading

Pull the latest release and review its migration notes:

```bash
git fetch --tags
git checkout v1.4.0
docker compose pull
docker compose run --rm controller openmesh migrate
docker compose up -d
```

Back up the deployment before upgrading. Avoid deploying unreleased branches to production gateways.

## Security

- Use HTTPS for all controller and enrollment traffic.
- Keep management interfaces on a separate VLAN.
- Rotate enrollment tokens and WireGuard keys regularly.
- Restrict SSH access to operator networks.
- Do not expose PostgreSQL, Redis, Prometheus, or Grafana directly to the internet.
- Review gateway firewall and abuse-handling policies before activating subscribers.
- Report vulnerabilities privately to `security@openmesh.example.org`.

## Troubleshooting

View controller and agent logs:

```bash
docker compose logs -f controller
sudo journalctl -u openmesh-agent -f
```

Run node diagnostics:

```bash
sudo openmesh-agent doctor
sudo openmesh-agent neighbors
sudo openmesh-agent routes
```

If a node loses controller connectivity, confirm that DNS, NTP, and outbound HTTPS work. Routing may remain operational while configuration synchronization is unavailable.

## Contributing

Contributions from network operators, radio enthusiasts, developers, and technical writers are welcome. Open an issue before making significant architectural changes, and include tests for changes that affect provisioning, routing, or subscriber policy.

By participating, you agree to follow the project Code of Conduct.

## License

OpenMesh ISP is licensed under the GNU Affero General Public License v3.0. See `LICENSE` for details.