feat(openclaw): deploy OpenClaw AI chatbot gateway on VM 120
- Add Docker Compose configs with security hardening (cap_drop ALL, non-root, read-only FS) - Add Prometheus node_exporter scrape target for 192.168.2.120:9100 - Update services/README.md, INDEX.md, and CLAUDE_STATUS.md with VM 120 - Image pinned to v2026.2.1 (patches CVE-2026-25253) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
367
services/openclaw/README.md
Normal file
367
services/openclaw/README.md
Normal file
@@ -0,0 +1,367 @@
|
||||
# OpenClaw - Multi-Platform AI Chatbot Gateway
|
||||
|
||||
## Overview
|
||||
|
||||
OpenClaw (formerly Moltbot/Clawdbot) is a multi-platform AI chatbot gateway deployed as a Docker service on VM 120. It bridges messaging platforms with LLM providers through a WebSocket gateway, allowing unified conversational AI access across multiple channels from a single deployment.
|
||||
|
||||
**Key Benefits**:
|
||||
- Multi-platform messaging support (Discord, Telegram, Slack, WhatsApp)
|
||||
- Multi-provider LLM backend (Anthropic, OpenAI, Ollama)
|
||||
- WebSocket gateway with integrated web UI
|
||||
- Secure pairing-based DM policy (prevents unauthorized direct messages)
|
||||
- OAuth integration for platform authentication
|
||||
|
||||
## Infrastructure Details
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| **VM** | 120 (QEMU/KVM on Vault ZFS) |
|
||||
| **IP Address** | 192.168.2.120 |
|
||||
| **Ports** | 18789 (Gateway WS+UI), 18790 (Bridge), 1455 (OAuth) |
|
||||
| **Domain** | openclaw.apophisnetworking.net |
|
||||
| **Docker Image** | ghcr.io/openclaw/openclaw:2026.2.1 |
|
||||
| **Template** | Cloned from 107 (ubuntu-docker) |
|
||||
| **Resources** | 4 vCPUs, 16 GB RAM, 50 GB disk |
|
||||
| **Deployment Date** | 2026-02-03 |
|
||||
|
||||
## Integration Architecture
|
||||
|
||||
```
|
||||
+-------------------------------------+
|
||||
| INTERNET |
|
||||
+------------------+------------------+
|
||||
|
|
||||
+----------------------+----------------------+
|
||||
| | |
|
||||
v v v
|
||||
+-----------+ +-----------+ +-----------+
|
||||
| Discord | | Telegram | | Slack / |
|
||||
| Gateway | | Bot API | | WhatsApp |
|
||||
+-----+-----+ +-----+-----+ +-----+-----+
|
||||
| | |
|
||||
+----------------------+----------------------+
|
||||
|
|
||||
| Tokens
|
||||
v
|
||||
+-------------------------------------------------------------------------------+
|
||||
| CT 102 - Nginx Proxy Manager (192.168.2.101) |
|
||||
| +-------------------------------------------------------------------------+ |
|
||||
| | SSL Termination, Reverse Proxy, WebSocket Upgrade, TinyAuth | |
|
||||
| +-------------------------------+-----------------------------------------+ |
|
||||
+----------------------------------+--------------------------------------------+
|
||||
|
|
||||
v
|
||||
+-------------------------------+
|
||||
| VM 120 - OpenClaw |
|
||||
| (192.168.2.120) |
|
||||
| |
|
||||
| :18789 Gateway (WS + UI) |
|
||||
| :18790 Bridge |
|
||||
| :1455 OAuth |
|
||||
| |
|
||||
| +-------------------------+ |
|
||||
| | LLM Providers | |
|
||||
| | - Anthropic API | |
|
||||
| | - OpenAI API | |
|
||||
| | - Ollama (local) | |
|
||||
| +-------------------------+ |
|
||||
+-------------------------------+
|
||||
```
|
||||
|
||||
### Request Flow
|
||||
|
||||
1. **User sends a message** on a connected platform (Discord, Telegram, Slack, WhatsApp)
|
||||
2. **Platform delivers** the message to OpenClaw via bot tokens and webhooks
|
||||
3. **DM policy check**: If `DM_POLICY=pairing`, the user must be paired before interaction is allowed
|
||||
4. **OpenClaw routes** the message to the configured LLM provider
|
||||
5. **LLM responds** and OpenClaw relays the response back to the originating platform
|
||||
6. **Web UI access**: Users can also interact directly via the gateway at `https://openclaw.apophisnetworking.net`
|
||||
|
||||
## Security Considerations
|
||||
|
||||
**CRITICAL**: CVE-2026-25253 (1-click RCE, CVSS 8.8) is patched in v2026.1.29. The deployed version MUST be >= 2026.2.1. Do not downgrade below this version under any circumstances.
|
||||
|
||||
### Hardening Measures
|
||||
|
||||
**Network**:
|
||||
- All ports bound to `127.0.0.1` (localhost only); reverse proxy required for external access
|
||||
- UFW firewall: default deny-all inbound, whitelist `192.168.2.0/24` and `192.168.1.91`
|
||||
- Twingate zero-trust access (no direct internet exposure to management interfaces)
|
||||
|
||||
**Docker**:
|
||||
- `cap_drop: ALL` -- no Linux capabilities granted
|
||||
- `security_opt: no-new-privileges:true` -- prevents privilege escalation
|
||||
- `read_only: true` -- read-only root filesystem (writable tmpfs at `/tmp`)
|
||||
- Non-root user (`1001:1001`)
|
||||
- No Docker socket mounted
|
||||
- Resource limits enforced (3.5 CPUs, 14 GB memory)
|
||||
|
||||
**Host**:
|
||||
- fail2ban on SSH (3 retries before ban)
|
||||
- `unattended-upgrades` enabled for automatic security patches
|
||||
- `.env` file permissions set to `chmod 600` (owner-only read/write)
|
||||
- Secrets never committed to git
|
||||
|
||||
**Application**:
|
||||
- `DM_POLICY=pairing` (secure default; users must be explicitly paired)
|
||||
- `NODE_ENV=production`
|
||||
- Log rotation via Docker json-file driver (50 MB x 5 files)
|
||||
|
||||
### Skills Policy
|
||||
|
||||
Only install vetted, read-only skills from the curated skills list. Use the `skill-vetter` tool to audit any new skill before installation. Avoid skills that require:
|
||||
- Computer-use or screen interaction
|
||||
- Shell/bash command execution
|
||||
- Deployment or infrastructure modification capabilities
|
||||
|
||||
## Configuration
|
||||
|
||||
### Docker Compose
|
||||
|
||||
The deployment uses two Compose files:
|
||||
|
||||
**File**: `/home/jramos/homelab/services/openclaw/docker-compose.yml`
|
||||
|
||||
Defines the core service including image, ports (all bound to `127.0.0.1`), volumes, environment variables, healthcheck, and logging configuration.
|
||||
|
||||
**File**: `/home/jramos/homelab/services/openclaw/docker-compose.override.yml`
|
||||
|
||||
Applies security hardening: drops all capabilities, enables `no-new-privileges`, enforces a read-only filesystem, sets the non-root user, and configures resource limits.
|
||||
|
||||
Docker Compose automatically merges the override file when running `docker compose up`.
|
||||
|
||||
### Environment Variables
|
||||
|
||||
**File**: `/home/jramos/homelab/services/openclaw/.env` (create from `.env.example`)
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
chmod 600 .env
|
||||
```
|
||||
|
||||
| Variable Group | Variables | Notes |
|
||||
|----------------|-----------|-------|
|
||||
| **Version** | `OPENCLAW_VERSION` | Must be >= `2026.2.1` (CVE-2026-25253) |
|
||||
| **Gateway Auth** | `GATEWAY_TOKEN` | Required. Generate with `openssl rand -hex 32` |
|
||||
| **LLM Providers** | `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `OLLAMA_BASE_URL` | Configure at least one provider |
|
||||
| **Messaging** | `DISCORD_TOKEN`, `TELEGRAM_TOKEN`, `SLACK_TOKEN`, `WHATSAPP_TOKEN` | Configure per platform as needed |
|
||||
| **App Settings** | `LOG_LEVEL`, `DM_POLICY` | Defaults: `info`, `pairing` |
|
||||
|
||||
**Critical Notes**:
|
||||
- `GATEWAY_TOKEN` is mandatory -- the service will not start without it
|
||||
- At least one LLM provider key must be configured for the bot to respond
|
||||
- `DM_POLICY=pairing` is the secure default; do not change to `open` in production
|
||||
- The `.env` file must never be committed to git (it is excluded via `.gitignore`)
|
||||
|
||||
### Nginx Proxy Manager Configuration
|
||||
|
||||
**Proxy Host**: `openclaw.apophisnetworking.net`
|
||||
- **Scheme**: http
|
||||
- **Forward Hostname/IP**: 192.168.2.120
|
||||
- **Forward Port**: 18789
|
||||
- **WebSocket Support**: Enabled (required for gateway functionality)
|
||||
- **Force SSL**: Enabled
|
||||
- **HTTP/2 Support**: Enabled
|
||||
- **SSL Certificate**: Let's Encrypt (auto-renewed)
|
||||
|
||||
**TinyAuth Protection**: Apply the same `auth_request` pattern used for other protected services. See `/home/jramos/homelab/services/tinyauth/README.md` for the Nginx advanced configuration template.
|
||||
|
||||
## Deployment
|
||||
|
||||
### Quick Start
|
||||
|
||||
1. **Create environment file**:
|
||||
```bash
|
||||
cd /home/jramos/homelab/services/openclaw
|
||||
cp .env.example .env
|
||||
chmod 600 .env
|
||||
```
|
||||
|
||||
2. **Generate gateway token**:
|
||||
```bash
|
||||
GATEWAY_TOKEN=$(openssl rand -hex 32)
|
||||
sed -i "s/^GATEWAY_TOKEN=$/GATEWAY_TOKEN=${GATEWAY_TOKEN}/" .env
|
||||
```
|
||||
|
||||
3. **Configure at least one LLM provider** by editing `.env` and adding an API key (e.g., `ANTHROPIC_API_KEY`).
|
||||
|
||||
4. **Create data directories** on VM 120:
|
||||
```bash
|
||||
sudo mkdir -p /opt/openclaw/{data,sessions,logs,config}
|
||||
sudo chown -R 1001:1001 /opt/openclaw
|
||||
```
|
||||
|
||||
5. **Start the service**:
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
6. **Verify health**:
|
||||
```bash
|
||||
curl -f http://127.0.0.1:18789/health
|
||||
# Expected: HTTP 200 with JSON status
|
||||
```
|
||||
|
||||
### Volume Mounts
|
||||
|
||||
| Host Path | Container Path | Purpose |
|
||||
|-----------|---------------|---------|
|
||||
| `/opt/openclaw/data` | `/app/data` | Persistent application data |
|
||||
| `/opt/openclaw/sessions` | `/app/sessions` | User session storage |
|
||||
| `/opt/openclaw/logs` | `/app/logs` | Application logs |
|
||||
|
||||
## Monitoring
|
||||
|
||||
- **Prometheus**: Scrapes `node_exporter` at `192.168.2.120:9100` for host-level metrics
|
||||
- **Grafana**: VM resource utilization dashboards available at `http://192.168.2.114:3000`
|
||||
- **Healthcheck**: Docker built-in healthcheck polls `http://localhost:18789/health` every 30 seconds
|
||||
- **Logs**: Structured JSON logs with rotation (50 MB x 5 files)
|
||||
|
||||
## Backup
|
||||
|
||||
### Proxmox Backup Server
|
||||
- **Schedule**: Daily at 02:00
|
||||
- **Mode**: Snapshot
|
||||
- **Compression**: zstd
|
||||
- **Storage**: PBS-Backups
|
||||
|
||||
### Application-Level Backup
|
||||
```bash
|
||||
# Weekly tar of application data (run on VM 120)
|
||||
tar czf /tmp/openclaw-backup-$(date +%Y%m%d).tar.gz \
|
||||
/opt/openclaw/data \
|
||||
/opt/openclaw/sessions \
|
||||
/opt/openclaw/config
|
||||
|
||||
# Backup .env file separately (contains secrets)
|
||||
cp /home/jramos/homelab/services/openclaw/.env \
|
||||
/home/jramos/homelab/services/openclaw/.env.backup-$(date +%Y%m%d)
|
||||
```
|
||||
|
||||
## Maintenance
|
||||
|
||||
### Logs
|
||||
```bash
|
||||
# Live container logs
|
||||
docker logs -f openclaw
|
||||
|
||||
# Last 100 lines
|
||||
docker logs --tail 100 openclaw
|
||||
|
||||
# Filter for errors
|
||||
docker logs openclaw 2>&1 | grep -i error
|
||||
|
||||
# Application logs on disk
|
||||
ls -la /opt/openclaw/logs/
|
||||
```
|
||||
|
||||
### Health Check
|
||||
```bash
|
||||
# Container status
|
||||
docker ps | grep openclaw
|
||||
|
||||
# Health endpoint
|
||||
curl -f http://127.0.0.1:18789/health
|
||||
|
||||
# Check resource usage
|
||||
docker stats openclaw --no-stream
|
||||
```
|
||||
|
||||
### Restart
|
||||
```bash
|
||||
cd /home/jramos/homelab/services/openclaw
|
||||
docker compose restart
|
||||
```
|
||||
|
||||
### Updates
|
||||
```bash
|
||||
cd /home/jramos/homelab/services/openclaw
|
||||
|
||||
# Update version in .env
|
||||
# Edit OPENCLAW_VERSION to the new version (must be >= 2026.2.1)
|
||||
|
||||
# Pull and recreate
|
||||
docker compose pull
|
||||
docker compose down
|
||||
docker compose up -d
|
||||
|
||||
# Verify health after update
|
||||
curl -f http://127.0.0.1:18789/health
|
||||
```
|
||||
|
||||
**Before updating**: Check the OpenClaw release notes for breaking changes. Always verify the new version is not affected by known CVEs.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Symptoms: Service fails to start
|
||||
|
||||
**Check**:
|
||||
1. `GATEWAY_TOKEN` is set in `.env`: `grep GATEWAY_TOKEN .env`
|
||||
2. Data directories exist and are owned by `1001:1001`: `ls -la /opt/openclaw/`
|
||||
3. Port conflicts: `ss -tlnp | grep -E '18789|18790|1455'`
|
||||
|
||||
**Commands**:
|
||||
```bash
|
||||
docker compose logs openclaw
|
||||
docker inspect openclaw | grep -A 5 "State"
|
||||
```
|
||||
|
||||
### Symptoms: Bot does not respond to messages
|
||||
|
||||
**Check**:
|
||||
1. At least one LLM provider key is configured in `.env`
|
||||
2. Platform tokens are valid and not expired
|
||||
3. Health endpoint returns 200: `curl -f http://127.0.0.1:18789/health`
|
||||
4. Container is healthy: `docker ps | grep openclaw`
|
||||
|
||||
**Commands**:
|
||||
```bash
|
||||
# Check which providers are configured
|
||||
docker exec openclaw env | grep -E 'ANTHROPIC|OPENAI|OLLAMA'
|
||||
|
||||
# Check platform connections
|
||||
docker logs openclaw 2>&1 | grep -iE 'connect|discord|telegram|slack|whatsapp'
|
||||
```
|
||||
|
||||
### Symptoms: WebSocket connection fails through reverse proxy
|
||||
|
||||
**Check**:
|
||||
1. NPM proxy host has WebSocket support enabled
|
||||
2. SSL certificate is valid for `openclaw.apophisnetworking.net`
|
||||
3. Gateway port is accessible from NPM: `curl -f http://192.168.2.120:18789/health` (from CT 102)
|
||||
|
||||
**Fix**: Ensure WebSocket upgrade headers are passed in NPM configuration.
|
||||
|
||||
### Symptoms: "Unauthorized" or "Pairing required" errors
|
||||
|
||||
**Check**:
|
||||
1. `DM_POLICY` setting in `.env` (default is `pairing`)
|
||||
2. User has been paired via the web UI or admin commands
|
||||
3. `GATEWAY_TOKEN` matches between client and server
|
||||
|
||||
### Symptoms: High memory or CPU usage
|
||||
|
||||
**Check**:
|
||||
1. Resource limits are applied: `docker inspect openclaw | grep -A 10 "Resources"`
|
||||
2. Log volume is not excessive: `du -sh /opt/openclaw/logs/`
|
||||
3. Number of active sessions: check `/opt/openclaw/sessions/`
|
||||
|
||||
**Commands**:
|
||||
```bash
|
||||
docker stats openclaw --no-stream
|
||||
docker compose logs --tail 50 openclaw
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- **OpenClaw GitHub**: https://github.com/openclaw/openclaw
|
||||
- **CVE-2026-25253 Advisory**: https://github.com/openclaw/openclaw/security/advisories/CVE-2026-25253
|
||||
- **TinyAuth Integration**: `/home/jramos/homelab/services/tinyauth/README.md`
|
||||
- **Nginx Proxy Manager**: https://nginxproxymanager.com/
|
||||
- **Docker Compose Security**: https://docs.docker.com/compose/compose-file/05-services/#security_opt
|
||||
|
||||
---
|
||||
|
||||
**Maintained by**: Homelab Infrastructure Team
|
||||
**Last Updated**: 2026-02-03
|
||||
**Status**: Operational - Deployed with CVE-2026-25253 patched (v2026.2.1)
|
||||
Reference in New Issue
Block a user