# VeloraMesh Ubuntu Server Install

Run these commands from this extracted package on the Ubuntu server.

## Easiest Guided Setup

```bash
sudo bash ./manage-veloramesh-server.sh
```

Choose one of the role-aware install flows:

```text
1) All-in-one API + Edge install/update
2) API-only install/update
3) Edge-only install/update
4) Fresh/reset by role
```

Use `All-in-one` for labs, personal networks, and the fastest single-host setup.

Use `API-only` on the control-plane host when the UDP edge will run on another machine.

Use `Edge-only` on the UDP discovery host. This role installs no control-plane database, TLS private key, join secret, membership-ticket key, network admin authority, or API service.

Choose `Fresh/reset by role` when you intentionally want to delete all VeloraMesh data on the current host, reinstall only the selected role, attach required keys/TLS files, optionally create the first network for API roles, and start the matching service set from one menu flow.

The server package contains two binaries and two systemd services:

```text
/opt/veloramesh/veloramesh-server  # HTTPS control-plane API, default :2053
/opt/veloramesh/veloramesh-edge    # UDP discovery edge, default :3478/udp
```

You do not install UDP discovery from a second package. The same package can install all-in-one, API-only, or Edge-only. The operational difference is which service is installed on each host and which firewall port is opened.

The guided manager prompts for local bind host and port separately according to the selected role. Press Enter to bind on all interfaces and use the packaged ports, or enter deployment-specific local host/port values to avoid a fixed public footprint. Do not enter public URLs or DNS names here; public API/edge hostnames are entered by clients during client install.

Bind examples:

```text
Local API bind host/port:    blank + 2053, localhost + 2053, or 127.0.0.1 + 2053
Local edge UDP host/port:    blank + 3478, localhost + 3478, or 0.0.0.0 + 3478
Client API host/port:        api.example.com + 2053
Client edge host/port:       edge.example.com + 3478
```

API and all-in-one setup also asks for the default virtual IPv4 CIDR used by newly created networks. Press Enter for `10.253.0.0/16`, or choose another private pool inside `10.0.0.0/8` or `172.16.0.0/12` with a `/16` through `/24` prefix. Avoid ISP CGNAT `100.64.0.0/10`, common home LAN `192.168.0.0/16`, public ranges, and tiny pools. The admin menu can override this per network at creation time; existing network CIDRs are intentionally not changed in v1.

The guided flow prompts for the Let's Encrypt certificate/key paths. The default paths are:

```text
/etc/letsencrypt/live/veloramesh.com/fullchain.pem
/etc/letsencrypt/live/veloramesh.com/privkey.pem
```

Set `VELORAMESH_TLS_CERT_NAME=<cert-name>` before running the manager to change that default without typing full paths.

If a TLS file path is wrong, the manager reports the missing file and offers to retry. Join secrets entered through the manager must be 24-256 characters and are confirmed before network creation or rotation.

## Manual Install Or Update

```bash
sudo bash ./install-veloramesh-server.sh --role all --api-bind :2053 --edge-bind :3478 --default-virtual-ipv4-cidr 10.253.0.0/16 --no-start
sudo install -o root -g veloramesh -m 0644 /etc/letsencrypt/live/<certificate-name>/fullchain.pem /etc/veloramesh/tls/fullchain.pem
sudo install -o root -g veloramesh -m 0640 /etc/letsencrypt/live/<certificate-name>/privkey.pem /etc/veloramesh/tls/privkey.pem
sudo systemctl enable --now veloramesh-server veloramesh-edge
```

For an API-only host:

```bash
sudo bash ./install-veloramesh-server.sh --role api --api-bind :2053 --default-virtual-ipv4-cidr 10.253.0.0/16 --no-start
sudo install -o root -g veloramesh -m 0644 /etc/letsencrypt/live/<certificate-name>/fullchain.pem /etc/veloramesh/tls/fullchain.pem
sudo install -o root -g veloramesh -m 0640 /etc/letsencrypt/live/<certificate-name>/privkey.pem /etc/veloramesh/tls/privkey.pem
sudo systemctl enable --now veloramesh-server
sudo install -m 0600 -o "$USER" -g "$USER" /var/lib/veloramesh/edge-ticket.key ./edge-ticket.key
```

Copy `./edge-ticket.key` to the edge host over a trusted channel.

For an Edge-only host:

```bash
# When prompted by the guided manager, enter: /tmp/edge-ticket.key
sudo bash ./install-veloramesh-server.sh --role edge --edge-bind :3478 --edge-ticket-key /tmp/edge-ticket.key --no-start
sudo systemctl enable --now veloramesh-edge
sudo rm -f /tmp/edge-ticket.key
```

In guided Edge-only setup, the `Edge ticket key source path` prompt expects the
path to the temporary key file on the edge host, for example
`/tmp/edge-ticket.key`. The installer copies it into
`/var/lib/veloramesh/edge-ticket.key` with service-only permissions.

The low-level installer keeps the existing `/etc/veloramesh/veloramesh.env` and SQLite database when they already exist for API roles. `--role edge` converges the host to the narrow UDP discovery role and removes local API unit/binary material from that host.

During install/update, the installer repairs `/var/lib/veloramesh`, the SQLite store files, and service key files so the `veloramesh` service user can access the preserved data.

The manager menu can install/update the service, perform a fresh reset, attach TLS files, start/restart the service, create/rename/delete networks, rotate join secrets, inspect members/endpoints, remove members, rename/block/unblock devices, backup/restore the store, and reset server data with a backup.

## UDP Edge Checklist

For a one-host lab install, API and edge run on the same Ubuntu host:

```bash
sudo systemctl enable --now veloramesh-server veloramesh-edge
sudo ufw allow 2053/tcp comment "VeloraMesh API"
sudo ufw allow 3478/udp comment "VeloraMesh edge discovery"
```

If you customized ports, open those selected ports instead of the examples above.

Validate both roles:

```bash
/opt/veloramesh/veloramesh-server version
/opt/veloramesh/veloramesh-edge version
sudo systemctl status veloramesh-server --no-pager
sudo systemctl status veloramesh-edge --no-pager
sudo ss -ltnp | grep ':2053'
sudo ss -lunp | grep ':3478'
getent hosts edge.veloramesh.com
```

Clients enter the API host/port and edge host/port separately during guided setup. If `veloramesh-edge` is active but peers cannot discover each other, check UFW, the cloud provider firewall/security group, and that the edge DNS record is DNS-only.

For a split deployment, validate each host separately:

```bash
# API host
sudo systemctl status veloramesh-server --no-pager
sudo ss -ltnp | grep ':2053'

# Edge host
sudo systemctl status veloramesh-edge --no-pager
sudo ss -lunp | grep ':3478'
```

## Deployment Topology

Recommended DNS shape:

```text
www / apex product site: proxied HTTPS
api.<domain>: HTTPS control plane, proxied only after TLS/SPKI/client smoke tests pass
edge.<domain>: UDP discovery edge, DNS-only
```

For a one-host lab, `api.<domain>` and `edge.<domain>` may point to the same Ubuntu host, but `edge.<domain>` must remain DNS-only. For a hardened deployment, run `API-only` and `Edge-only` on separate hosts and copy only `/var/lib/veloramesh/edge-ticket.key` to the edge host. Do not copy the SQLite store, TLS private key, membership-ticket key, or join secrets to the edge host.

## Status

```bash
/opt/veloramesh/veloramesh-server version
/opt/veloramesh/veloramesh-edge version
sudo systemctl status veloramesh-server --no-pager
sudo systemctl status veloramesh-edge --no-pager
sudo ss -ltnp | grep ':2053'
sudo ss -lunp | grep ':3478'
sudo journalctl -u veloramesh-server -u veloramesh-edge -n 100 --no-pager
getent hosts edge.veloramesh.com
```

If you customized listen ports, validate those selected ports instead of `2053` and `3478`.

## Local Admin

List networks:

```bash
sudo /opt/veloramesh/veloramesh-server admin networks list
sudo /opt/veloramesh/veloramesh-server admin networks show -network home
```

Create a network:

```bash
printf '%s' '<network-join-secret>' > ./veloramesh-join.secret
chmod 600 ./veloramesh-join.secret
sudo /opt/veloramesh/veloramesh-server admin networks create -name home -join-secret-file ./veloramesh-join.secret -virtual-ipv4-cidr 10.253.0.0/16
rm ./veloramesh-join.secret
```

Rename a network:

```bash
sudo /opt/veloramesh/veloramesh-server admin networks rename -network home -name new-home
```

List members and their virtual IPs:

```bash
sudo /opt/veloramesh/veloramesh-server admin members list -network home
sudo /opt/veloramesh/veloramesh-server admin members endpoints -network home
```

Rotate the join secret for future joins:

```bash
printf '%s' '<new-network-join-secret>' > ./veloramesh-new-join.secret
chmod 600 ./veloramesh-new-join.secret
sudo /opt/veloramesh/veloramesh-server admin networks rotate-secret -network home -join-secret-file ./veloramesh-new-join.secret
rm ./veloramesh-new-join.secret
```

Set LAN discovery broadcast policy:

```bash
sudo /opt/veloramesh/veloramesh-server admin networks broadcast -network home -mode filtered
sudo /opt/veloramesh/veloramesh-server admin networks broadcast -network home -mode all
```

Use `filtered` for normal operation. Use `all` only for trusted LAN-discovery test rooms where automatic LAN browsers need every UDP broadcast/multicast discovery packet.

Set underlay endpoint policy:

```bash
sudo /opt/veloramesh/veloramesh-server admin networks underlay -network home -mode ipv4-only
sudo /opt/veloramesh/veloramesh-server admin networks underlay -network home -mode dual-stack
sudo /opt/veloramesh/veloramesh-server admin networks endpoint-ttl -network home -seconds 45
```

`ipv4-only` is the default. Use `dual-stack` or `ipv6-only` only when the room intentionally needs IPv6 underlay candidates.

Remove one device from a network:

```bash
sudo /opt/veloramesh/veloramesh-server admin members remove -network home -device '<device-id>'
```

List blocked devices:

```bash
sudo /opt/veloramesh/veloramesh-server admin devices blocked
sudo /opt/veloramesh/veloramesh-server admin devices endpoints -device '<device-id>'
```

Rename a device label:

```bash
sudo /opt/veloramesh/veloramesh-server admin devices rename -device '<device-id>' -name '<new-device-name>'
```

Block or unblock a device:

```bash
sudo /opt/veloramesh/veloramesh-server admin devices block -device '<device-id>' -yes
sudo /opt/veloramesh/veloramesh-server admin devices unblock -device '<device-id>' -yes
```

Backup or restore the local store:

```bash
sudo /opt/veloramesh/veloramesh-server admin store backup -out /var/backups/veloramesh/veloramesh.db
sudo systemctl stop veloramesh-server
sudo /opt/veloramesh/veloramesh-server admin store restore -in /var/backups/veloramesh/veloramesh.db -yes
sudo systemctl start veloramesh-server
```

## Uninstall Or Purge

Use the manager menu:

```bash
sudo bash ./manage-veloramesh-server.sh
```

`Service operations -> Uninstall service, keep config/data` removes installed VeloraMesh services and binaries while preserving `/etc/veloramesh` and `/var/lib/veloramesh`.

`Service operations -> Purge installation and data` removes installed binaries, systemd units, copied TLS files, VeloraMesh config, store, keys, and the service user. It does not touch Let's Encrypt's own certificate directories.