# CommonMesh

CommonMesh is an open-source platform for operating a community-owned mesh-network ISP. It helps local groups provision wireless nodes, route subscriber traffic, monitor link health, and manage member access across a resilient, decentralized network.

CommonMesh is designed for neighborhoods, rural cooperatives, emergency networks, and other communities that want to share upstream internet connections without depending on a single local access point.

## Features

- Automatic peer discovery and mesh formation
- IPv4 and IPv6 support
- WireGuard-encrypted links between nodes
- Gateway selection and automatic failover
- Member authentication and service profiles
- Bandwidth limits and fair-use policies
- DNS, DHCP, and captive-portal integration
- Prometheus metrics and health checks
- Web-based network status dashboard
- Configuration through YAML and environment variables
- Runs on standard Linux servers and OpenWrt-compatible routers

## Requirements

### Controller

- Linux
- Docker 24 or later
- Docker Compose v2
- 2 CPU cores
- 2 GB RAM
- A static IP address or resolvable hostname

### Mesh nodes

- OpenWrt 23.05 or later, or Debian 12 or later
- One or more supported wireless interfaces
- WireGuard
- `batman-adv`
- At least 128 MB RAM

## Installation

Clone the repository and create a local configuration file:

```sh
git clone https://github.com/commonmesh/commonmesh.git
cd commonmesh
cp config.example.yaml config.yaml
```

Create the environment file:

```sh
cp .env.example .env
```

Set a secure controller secret:

```sh
openssl rand -hex 32
```

Add the generated value to `.env`:

```dotenv
COMMONMESH_SECRET=replace-with-generated-value
```

Start the controller:

```sh
docker compose up -d
```

Confirm that the services are healthy:

```sh
docker compose ps
curl http://localhost:8080/health
```

The administration dashboard is available at `http://localhost:8080`.

## Usage

### Create an administrator

```sh
docker compose exec controller commonmesh admin create
```

### Register a gateway

Gateways provide upstream internet connectivity to the mesh:

```sh
docker compose exec controller commonmesh gateway add \
  --name community-center \
  --address 10.42.0.1
```

### Generate a node enrollment token

```sh
docker compose exec controller commonmesh node token \
  --name rooftop-west \
  --expires 24h
```

Run the command printed by the controller on the target node. The node will download its configuration, establish an encrypted control connection, and join the mesh.

### View network status

```sh
docker compose exec controller commonmesh status
```

### List nodes

```sh
docker compose exec controller commonmesh node list
```

### Inspect a node

```sh
docker compose exec controller commonmesh node show rooftop-west
```

### View logs

```sh
docker compose logs -f controller
```

## Configuration

CommonMesh reads its main configuration from `config.yaml`. Environment variables override matching YAML values.

```yaml
controller:
  public_url: https://mesh.example.org
  listen_address: 0.0.0.0
  listen_port: 8080

network:
  name: CommonMesh
  mesh_interface: mesh0
  address_pool: 10.42.0.0/16
  ipv6_prefix: fd42:6d65:7368::/48
  routing_protocol: batman-adv
  mtu: 1380

wireguard:
  listen_port: 51820
  persistent_keepalive: 25

dns:
  servers:
    - 1.1.1.1
    - 9.9.9.9
  local_domain: mesh.local

members:
  default_profile: residential
  session_timeout: 24h

profiles:
  residential:
    download_mbps: 50
    upload_mbps: 10
    monthly_transfer_gb: 500

  community:
    download_mbps: 100
    upload_mbps: 25
    monthly_transfer_gb: 2000

gateways:
  selection: lowest-latency
  failover_timeout: 30s

monitoring:
  prometheus_enabled: true
  prometheus_address: 0.0.0.0:9090
  node_offline_after: 5m

logging:
  level: info
  format: json
```

### Environment variables

| Variable | Description | Default |
| --- | --- | --- |
| `COMMONMESH_CONFIG` | Path to the YAML configuration | `/etc/commonmesh/config.yaml` |
| `COMMONMESH_SECRET` | Secret used to sign sessions and enrollment tokens | Required |
| `COMMONMESH_DATABASE_URL` | PostgreSQL connection string | `postgres://commonmesh@db/commonmesh` |
| `COMMONMESH_PUBLIC_URL` | Public controller URL | Value from `config.yaml` |
| `COMMONMESH_LOG_LEVEL` | Logging level | `info` |
| `COMMONMESH_HTTP_PORT` | Controller HTTP port | `8080` |
| `COMMONMESH_METRICS_PORT` | Prometheus metrics port | `9090` |

Restart the controller after changing its configuration:

```sh
docker compose restart controller
```

Validate the configuration before deploying it:

```sh
docker compose exec controller commonmesh config validate
```

## Network Planning

Assign the mesh a private address range that does not overlap with member LANs or upstream networks. Keep management traffic separate from subscriber traffic where supported, and use distinct VLANs for:

- Mesh backhaul
- Node management
- Subscriber access
- Upstream gateway traffic

For production deployments, run the controller behind a TLS-enabled reverse proxy and restrict administrative access with a firewall or VPN.

## Upgrading

Back up the database and configuration:

```sh
docker compose exec db pg_dump -U commonmesh commonmesh > commonmesh.sql
cp config.yaml config.yaml.backup
```

Pull the latest release and apply migrations:

```sh
git pull --ff-only
docker compose pull
docker compose run --rm controller commonmesh migrate
docker compose up -d
```

Review the release notes before upgrading mesh nodes or changing routing protocols.

## Troubleshooting

Check controller and node connectivity:

```sh
commonmesh node diagnose
```

Verify the WireGuard tunnel:

```sh
wg show
```

Inspect the mesh routing table:

```sh
batctl neighbors
batctl originators
```

If a node cannot reach the controller, confirm that DNS, system time, firewall rules, and UDP port `51820` are configured correctly.

## Security

Enrollment tokens grant access to the management network and should be treated as credentials. Use short expiration times, revoke unused tokens, and rotate controller secrets according to your community's security policy.

To report a vulnerability, email `security@commonmesh.example` instead of opening a public issue.

## Contributing

Contributions are welcome. Before submitting a pull request:

1. Open an issue describing significant changes.
2. Add tests for new behavior.
3. Run the test suite with `make test`.
4. Run formatting and static checks with `make lint`.
5. Update the documentation when configuration or operator workflows change.

## License

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