LIVE TAPE
OpenClaw 88,412 stars·CVE-2026-25898 disclosed (HIGH, Hermes)·Hermes Agent v2026.4.7 published·Hermes Agent +182 stars (last hour)·OpenClaw v2026.4.6 — credential vault hardening·CVE-2026-26133 patched (NanoClaw)·Pi 5 16GB rumoured for Q3 — recheck guidance·Nanobot +47 stars (last hour)·ZeroClaw v0.4.2 — Apple container fixes·Mac Mini M4 wins quarterly hardware survey·OpenClaw 88,412 stars·CVE-2026-25898 disclosed (HIGH, Hermes)·Hermes Agent v2026.4.7 published·Hermes Agent +182 stars (last hour)·OpenClaw v2026.4.6 — credential vault hardening·CVE-2026-26133 patched (NanoClaw)·Pi 5 16GB rumoured for Q3 — recheck guidance·Nanobot +47 stars (last hour)·ZeroClaw v0.4.2 — Apple container fixes·Mac Mini M4 wins quarterly hardware survey·
PocketClawvol. 1 · 2026

Nginx reverse proxy in front of a self-hosted AI agent

TLS termination, rate limiting, and basic abuse protection in front of OpenClaw or Hermes Agent using Nginx and Let's Encrypt. €0/year, 30 minutes.

Prerequisites

  • A VPS with a public IP and a domain pointing to it
  • An agent (OpenClaw, Hermes, etc.) running on localhost on a fixed port
  • Root or sudo access on the VPS

Steps

  1. Install Nginx and certbot

    Both are in the Ubuntu/Debian repos. Use the snap version of certbot for automatic renewal handling on long-lived hosts.

    sudo apt update
    sudo apt install -y nginx
    sudo snap install --classic certbot
    sudo ln -s /snap/bin/certbot /usr/local/bin/certbot
  2. Write a basic vhost

    Replace 'agent.example.com' with your subdomain. The configuration below assumes the agent listens on 127.0.0.1:8765. Saves to /etc/nginx/sites-available/agent.

    sudo tee /etc/nginx/sites-available/agent <<'EOF'
    upstream agent_backend {
        server 127.0.0.1:8765;
        keepalive 16;
    }
    
    # Rate-limit zone — 10 r/s per IP, burst 20.
    limit_req_zone $binary_remote_addr zone=agent:10m rate=10r/s;
    
    server {
        listen 80;
        server_name agent.example.com;
        return 301 https://$host$request_uri;
    }
    
    server {
        listen 443 ssl http2;
        server_name agent.example.com;
    
        # Let's Encrypt will fill these in.
        ssl_certificate /etc/letsencrypt/live/agent.example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/agent.example.com/privkey.pem;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!MD5;
    
        # Security headers.
        add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-Frame-Options "DENY" always;
        add_header Referrer-Policy "no-referrer" always;
    
        # Body size — agents send small JSON, no need for 10 MB defaults.
        client_max_body_size 1m;
    
        location / {
            limit_req zone=agent burst=20 nodelay;
    
            proxy_pass http://agent_backend;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;
    
            # WebSocket support (if your agent exposes one).
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
    
            proxy_read_timeout 300s;
            proxy_send_timeout 300s;
        }
    }
    EOF
    
    sudo ln -s /etc/nginx/sites-available/agent /etc/nginx/sites-enabled/
  3. Provision the certificate

    Certbot will edit the vhost in place to insert the SSL paths. Use the nginx plugin so the running Nginx is reloaded automatically.

    sudo certbot --nginx -d agent.example.com
    sudo nginx -t && sudo systemctl reload nginx
  4. Verify

    Hit the public URL. You should see the agent's response. Run a small flood to confirm rate limiting kicks in (you should get HTTP 503 after the burst).

    for i in $(seq 1 30); do curl -s -o /dev/null -w "%{http_code}\n" https://agent.example.com/; done

Troubleshooting

Certbot can't get a certificate (DNS validation fails)
Confirm the A/AAAA record points at the VPS public IP. Wait up to 5 minutes for DNS propagation. Re-run certbot.
WebSocket connection from the agent dashboard fails
Verify the Upgrade and Connection headers are in the Nginx config above. Some browser extensions also strip these headers — try Incognito.
Rate limit triggers on legitimate dashboard usage
Increase the rate (10r/s → 30r/s) or use a separate location block for the dashboard URL with no rate limit.

Where to go from here

Pair Nginx rate limiting with fail2ban for IPs that consistently hit 503. Consider Cloudflare in front of Nginx if you face automated scanning.

Other tutorials
intermediate
Hermes Agent on a Raspberry Pi 5
End-to-end install of Hermes Agent on a fresh Raspberry Pi 5 (8 GB), accessed via Tailscale, with Cl…
beginner
Tailscale for self-hosted AI dashboards
Set up Tailscale to access your agent dashboard from anywhere without exposing it on the public inte…
intermediate
Ollama + Phi-3 mini on a Raspberry Pi 5
Install Ollama and the smallest credible local LLM (Phi-3 mini 3.8B Q4) on a Raspberry Pi 5. Useful …
beginner
Caddy reverse proxy with HTTPS for a self-hosted AI dashboard
Front your agent dashboard with Caddy on port 443 with automatic HTTPS via Let's Encrypt — no certbo…