Files
homelab/services/openclaw/README.md
Jordan Ramos e08951de21 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>
2026-02-03 18:14:58 -07:00

368 lines
13 KiB
Markdown

# 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)