Create MeshCentral workspace
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
# GracePress MeshPress Bridge
|
||||
|
||||
Small local HTTP bridge between WordPress/MeshPress and MeshCentral.
|
||||
|
||||
The bridge runs beside MeshCentral and uses MeshCentral's official `meshctrl` tool to read device groups and devices. WordPress talks to this bridge instead of trying to speak MeshCentral websocket protocol directly.
|
||||
|
||||
## Endpoints
|
||||
|
||||
- `GET /api/health`
|
||||
- `GET /api/status`
|
||||
- `GET /api/self-test`
|
||||
- `GET /api/groups`
|
||||
- `GET /api/users`
|
||||
- `GET /api/events?limit=50`
|
||||
- `GET /api/serverinfo`
|
||||
- `GET /api/devices`
|
||||
- `GET /api/device/:nodeId`
|
||||
- `GET /api/fleet`
|
||||
- `POST /api/push-now`
|
||||
- `POST /api/cache/clear`
|
||||
- `GET /api/link/desktop/:nodeId`
|
||||
- `GET /api/link/terminal/:nodeId`
|
||||
- `GET /api/link/files/:nodeId`
|
||||
- `GET /api/link/:mode/:nodeId?link_mode=both`
|
||||
- `GET /api/agent-links/:groupId`
|
||||
- `POST /api/groups/create`
|
||||
- `POST /api/groups/edit`
|
||||
- `POST /api/groups/remove`
|
||||
- `POST /api/groups/add-user`
|
||||
- `POST /api/groups/remove-user`
|
||||
- `POST /api/invite-link`
|
||||
- `POST /api/device/message`
|
||||
- `POST /api/device/toast`
|
||||
- `POST /api/action`
|
||||
|
||||
All endpoints require `Authorization: Bearer TOKEN`. If `MESHPRESS_BRIDGE_TOKEN` is empty, protected requests are rejected.
|
||||
|
||||
`/api/action` is intentionally locked down for now. It returns a clear unsupported-command response until each broad remote-command workflow is whitelisted and tested.
|
||||
|
||||
Provisioning and device-command endpoints require:
|
||||
|
||||
```bash
|
||||
MESHPRESS_ALLOW_COMMANDS="1"
|
||||
```
|
||||
|
||||
Without that flag the bridge will read MeshCentral state but refuse provisioning actions.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
cd /storage/meshcentral-workspace/bridge/meshpress-bridge
|
||||
sudo ./install.sh
|
||||
sudo nano /etc/gracepress/meshpress-bridge.env
|
||||
pm2 restart gp-meshpress-bridge
|
||||
```
|
||||
|
||||
## Required Config
|
||||
|
||||
```bash
|
||||
MESHPRESS_BRIDGE_PORT="3099"
|
||||
MESHPRESS_BRIDGE_BIND="127.0.0.1"
|
||||
MESHPRESS_BRIDGE_TOKEN="generated-secret"
|
||||
MESHPRESS_ALLOWED_IPS=""
|
||||
MESHPRESS_AUTH_WINDOW_SECONDS="900"
|
||||
MESHPRESS_AUTH_MAX_FAILURES="30"
|
||||
MESHCTRL_URL="wss://127.0.0.1"
|
||||
PUBLIC_MESH_URL="https://mesh.yourdomain.com"
|
||||
MESHCTRL_USER="admin"
|
||||
MESHCTRL_PASS=""
|
||||
MESHCTRL_DOMAIN=""
|
||||
MESHCTRL_LOGIN_KEY_FILE="/etc/gracepress/meshcentral-login.key"
|
||||
MESHCTRL_PATH=""
|
||||
MESHCTRL_IGNORE_CERT="0"
|
||||
MESHPRESS_LINK_HIDE=""
|
||||
MESHPRESS_LINK_MODE="gotonode"
|
||||
MESHPRESS_ALLOW_COMMANDS="0"
|
||||
WP_DOMAIN="https://christp2p.com"
|
||||
WP_API_KEY="same-token-used-in-meshpress"
|
||||
MESHPRESS_PUSH_INTERVAL_SECONDS="3600"
|
||||
MESHPRESS_PUSH_EVENTS="1"
|
||||
```
|
||||
|
||||
If auto-detection cannot find `meshctrl`, set `MESHCTRL_PATH` to the full path of `meshctrl.js`.
|
||||
|
||||
When `WP_DOMAIN` and `WP_API_KEY` are set, the bridge pushes fleet snapshots to WordPress at startup and then every hour.
|
||||
When `MESHPRESS_PUSH_EVENTS` is enabled, selected bridge lifecycle events are posted to MeshPress so WordPress can record them through OmniLog.
|
||||
|
||||
## Public Exposure Hardening
|
||||
|
||||
Do not expose port `3099` to the public internet without firewall/VPN controls. Preferred options:
|
||||
|
||||
1. Bind to localhost and proxy privately:
|
||||
|
||||
```bash
|
||||
MESHPRESS_BRIDGE_BIND="127.0.0.1"
|
||||
```
|
||||
|
||||
2. Bind to a Tailscale address only:
|
||||
|
||||
```bash
|
||||
MESHPRESS_BRIDGE_BIND="100.x.y.z"
|
||||
```
|
||||
|
||||
3. If the bridge must listen on all interfaces temporarily, restrict source IPs at both the firewall and app layer:
|
||||
|
||||
```bash
|
||||
MESHPRESS_BRIDGE_BIND="0.0.0.0"
|
||||
MESHPRESS_ALLOWED_IPS="WORDPRESS_SERVER_IP,YOUR_ADMIN_IP"
|
||||
```
|
||||
|
||||
The app-layer allowlist only accepts exact IP addresses. It is a backstop, not a replacement for firewall rules.
|
||||
|
||||
## Diagnostics
|
||||
|
||||
Use MeshPress > Diagnostics & Manual Actions first. It calls these bridge endpoints:
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer TOKEN" http://127.0.0.1:3099/api/health
|
||||
curl -H "Authorization: Bearer TOKEN" http://127.0.0.1:3099/api/version
|
||||
curl -H "Authorization: Bearer TOKEN" http://127.0.0.1:3099/api/status
|
||||
curl -H "Authorization: Bearer TOKEN" http://127.0.0.1:3099/api/self-test
|
||||
curl -H "Authorization: Bearer TOKEN" http://127.0.0.1:3099/api/groups?refresh=1
|
||||
curl -H "Authorization: Bearer TOKEN" http://127.0.0.1:3099/api/devices?refresh=1
|
||||
```
|
||||
|
||||
`/api/self-test` verifies the bridge can find `meshctrl`, has an auth method, has a public MeshCentral URL, and can list device groups and devices.
|
||||
|
||||
For direct session links, test both URL styles:
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer TOKEN" "http://127.0.0.1:3099/api/session-links/NODEID"
|
||||
curl -H "Authorization: Bearer TOKEN" "http://127.0.0.1:3099/api/link/console/NODEID?link_mode=all"
|
||||
```
|
||||
|
||||
To trigger a catalog-managed bridge update from MeshPress admin or curl:
|
||||
|
||||
```bash
|
||||
curl -X POST -H "Authorization: Bearer TOKEN" http://127.0.0.1:3099/api/update-now
|
||||
```
|
||||
|
||||
To test the first provisioning path, enable commands and create a temporary group:
|
||||
|
||||
```bash
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"MeshPress Test Group","description":"Manual bridge validation"}' \
|
||||
http://127.0.0.1:3099/api/groups/create
|
||||
```
|
||||
|
||||
## MeshCentral Auth
|
||||
|
||||
The bridge supports either a MeshCentral login key file or a dedicated integration username/password.
|
||||
|
||||
For username/password auth, set:
|
||||
|
||||
```bash
|
||||
MESHCTRL_USER="your-generated-integration-user"
|
||||
MESHCTRL_PASS="your-generated-integration-password"
|
||||
```
|
||||
|
||||
If `MESHCTRL_LOGIN_KEY_FILE` exists, the bridge will prefer it. If the file does not exist and `MESHCTRL_PASS` is set, it will use username/password auth.
|
||||
|
||||
## MeshCentral Login Key Option
|
||||
|
||||
On the MeshCentral server:
|
||||
|
||||
```bash
|
||||
cd /opt/meshcentral
|
||||
sudo node node_modules/meshcentral --loginTokenKey > /etc/gracepress/meshcentral-login.key
|
||||
sudo chmod 600 /etc/gracepress/meshcentral-login.key
|
||||
```
|
||||
|
||||
MeshCentral must have login tokens enabled in `meshcentral-data/config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"settings": {
|
||||
"allowLoginToken": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Restart MeshCentral after changing config.
|
||||
Reference in New Issue
Block a user