# Lantern Mesh

Lantern Mesh is a community-operated mesh-network ISP platform for connecting homes, small businesses, and public spaces through participant-hosted wireless nodes. It provides automated node provisioning, peer discovery, encrypted routing, subscriber management, service monitoring, and an optional gateway for upstream internet access.

Lantern Mesh is designed for neighborhood networks and local cooperatives. It is not a substitute for radio-frequency planning, electrical safety work, or compliance with local telecommunications regulations.

## Features

- Automatic peer discovery and encrypted node-to-node links
- Multi-hop routing with gateway failover
- Subscriber plans, quotas, and captive-portal onboarding
- Bandwidth shaping and fair-use policies
- Health checks, latency metrics, and topology reporting
- DNS forwarding with configurable community zones
- IPv4 NAT and native or tunneled IPv6 support
- Prometheus-compatible metrics
- Role-based administration
- Configuration through YAML files and environment variables
- Support for containerized controllers and OpenWrt-based nodes

## Architecture

A deployment has three main components:

- **Controller:** Maintains node, subscriber, and policy state.
- **Gateway:** Connects the mesh to one or more upstream internet providers.
- **Node agent:** Runs on each participating router and manages encrypted links, routing, and telemetry.

Mesh traffic continues to route locally if the controller or upstream connection becomes temporarily unavailable. Internet access requires at least one reachable gateway.

## Requirements

### Controller

- Linux host or virtual machine
- Docker 24+ with Docker Compose v2
- 2 CPU cores and 2 GB RAM for a small deployment
- PostgreSQL 15+
- A stable hostname with TLS
- UDP port `51820` reachable by mesh nodes

### Nodes

- OpenWrt 23.05+ or a supported Debian-based system
- 128 MB RAM minimum
- One wireless interface for mesh backhaul
- A separate access-point interface or VLAN for subscribers
- Accurate system time

Production installations should use outdoor-rated hardware, grounded mounts, surge protection, and an installation plan reviewed by a qualified local technician.

## Installation

Clone the repository and create a local configuration:

```bash
git clone https://github.com/lantern-mesh/lantern-mesh.git
cd lantern-mesh
cp .env.example .env
cp config/lantern.example.yml config/lantern.yml
```

Set a database password and application secret in `.env`:

```dotenv
POSTGRES_PASSWORD=replace-with-a-strong-password
LANTERN_SECRET_KEY=replace-with-at-least-32-random-bytes
LANTERN_CONFIG=/etc/lantern/lantern.yml
```

Generate a secret with:

```bash
openssl rand -base64 48
```

Start the controller:

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

Run the initial database migration and create an administrator:

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

The administration interface is available at `http://localhost:8080` by default. Configure a reverse proxy and TLS before exposing it outside a trusted management network.

### Installing a node

Create a one-time enrollment token:

```bash
docker compose exec controller lantern node token create \
  --name maple-street-01 \
  --expires-in 30m
```

On a supported node, install the agent and enroll it:

```bash
curl -fsSL https://packages.lanternmesh.example/install.sh | sh

sudo lantern-node enroll \
  --controller https://mesh.example.net \
  --token "TOKEN_FROM_CONTROLLER"
```

Review the generated node configuration, then enable the service:

```bash
sudo systemctl enable --now lantern-node
sudo lantern-node status
```

Enrollment tokens are single-use. Do not place them in shell history, shared chat rooms, or persistent provisioning images.

## Usage

### Check network health

```bash
docker compose exec controller lantern status
```

Example output:

```text
Controller: healthy
Nodes:      18 online, 1 degraded, 2 offline
Gateways:   2 online
Subscribers: 146 active
```

### List nodes

```bash
docker compose exec controller lantern node list
```

### Inspect a route

```bash
docker compose exec controller lantern route trace maple-street-01 library-gateway
```

### Add a subscriber plan

```bash
docker compose exec controller lantern plan create community-basic \
  --download 25mbit \
  --upload 10mbit \
  --monthly-quota 500GB
```

### Create a subscriber

```bash
docker compose exec controller lantern subscriber create \
  --name "Example Household" \
  --plan community-basic
```

The command returns an onboarding code that can be entered through the captive portal.

### View logs

```bash
docker compose logs -f controller
```

On a node:

```bash
sudo journalctl -u lantern-node -f
```

## Configuration

The controller reads `/etc/lantern/lantern.yml` by default. Environment variables override file values and use the `LANTERN_` prefix with double underscores for nested keys. For example, `LANTERN_HTTP__PORT=9090` overrides `http.port`.

```yaml
site:
  name: "Lantern Community Network"
  timezone: "America/Toronto"
  contact_email: "noc@example.net"

http:
  address: "0.0.0.0"
  port: 8080
  trusted_proxies:
    - "10.20.0.0/24"

database:
  url: "postgresql://lantern:password@postgres/lantern"
  pool_size: 10

mesh:
  domain: "mesh.example.net"
  address_pool_v4: "10.64.0.0/16"
  address_pool_v6: "fd42:6c61:6e74::/48"
  wireguard_port: 51820
  peer_keepalive_seconds: 25
  route_metric: "latency"
  maximum_hops: 8

dns:
  upstream:
    - "1.1.1.1"
    - "9.9.9.9"
  community_zone: "lantern.internal"
  cache_ttl_seconds: 300

subscriber_network:
  address_pool: "10.96.0.0/16"
  default_plan: "community-basic"
  captive_portal: true
  client_isolation: true

traffic:
  fair_queueing: true
  local_mesh_unmetered: true
  accounting_interval_seconds: 60

telemetry:
  enabled: true
  prometheus_address: "127.0.0.1"
  prometheus_port: 9108
  retain_days: 30

security:
  enrollment_token_ttl: "30m"
  session_ttl: "12h"
  require_mfa_for_admins: true
  allowed_admin_networks:
    - "10.20.0.0/24"
```

### Node configuration

Node settings are stored in `/etc/lantern-node/config.yml`:

```yaml
node:
  name: "maple-street-01"
  location:
    latitude: 43.6532
    longitude: -79.3832
    visibility: "members"

controller:
  url: "https://mesh.example.net"

interfaces:
  mesh: "wlan0"
  subscribers: "br-lan"

radio:
  band: "5ghz"
  channel: 149
  width: "40mhz"
  country_code: "CA"
  transmit_power_dbm: 20

gateway:
  enabled: false
  upstream_interface: "wan"
  advertised_capacity:
    download_mbit: 0
    upload_mbit: 0
```

Radio channels, transmit power, antenna gain, and outdoor operation must comply with the rules for the node's jurisdiction. Set `country_code` correctly on every node.

### Gateway configuration

To advertise a node as an internet gateway:

```yaml
gateway:
  enabled: true
  upstream_interface: "wan"
  nat_ipv4: true
  advertise_default_route: true
  advertised_capacity:
    download_mbit: 500
    upload_mbit: 100
```

Only enable gateway mode when the upstream service agreement permits connection sharing. Apply subscriber isolation and firewall policies before advertising a default route.

## Backups

Back up the database and controller secrets together:

```bash
docker compose exec -T postgres pg_dump -U lantern lantern > lantern-backup.sql
tar -czf lantern-secrets.tar.gz .env config/lantern.yml data/keys
```

Store backups encrypted and test restoration regularly. A database backup without the controller keys cannot restore existing node identities.

## Monitoring

Prometheus metrics are exposed on `127.0.0.1:9108` by default. Useful metrics include:

- `lantern_nodes_online`
- `lantern_peer_latency_seconds`
- `lantern_peer_packet_loss_ratio`
- `lantern_gateway_available`
- `lantern_subscriber_bytes_total`
- `lantern_route_changes_total`

Do not expose the metrics endpoint publicly; topology and subscriber labels may contain sensitive operational information.

## Troubleshooting

Verify controller connectivity:

```bash
sudo lantern-node diagnose controller
```

Check wireless peers:

```bash
sudo lantern-node peer list
```

Run a complete node diagnostic:

```bash
sudo lantern-node diagnose --output diagnostic.tar.gz
```

Diagnostic archives may include IP addresses, node identifiers, and recent logs. Review them before sharing.

If a node repeatedly changes routes, check signal quality, channel congestion, clock synchronization, and overlapping address pools. Avoid increasing transmit power as a first response; antenna placement and channel planning usually have a larger effect.

## Security

- Use TLS for controller access.
- Require multi-factor authentication for administrators.
- Keep management traffic on a separate VLAN or VPN.
- Rotate enrollment tokens and revoke lost nodes immediately.
- Restrict SSH access to trusted administration networks.
- Apply operating-system and router firmware updates promptly.
- Publish clear privacy, retention, acceptable-use, and incident-response policies.
- Collect only the subscriber data needed to operate the network.

To report a vulnerability, email `security@example.net`. Do not open a public issue for undisclosed security problems.

## Contributing

Contributions are welcome from network operators, software developers, technical writers, and community organizers.

Before submitting a pull request:

```bash
make lint
make test
make integration-test
```

Open an issue for major protocol, schema, or deployment changes so they can be discussed with operators before implementation.

## License

Lantern Mesh is released under the GNU Affero General Public License v3.0. See `LICENSE` for details.