Self-Host OpenClaw on Proxmox — VM Isolation for AI Agents That Have Shell Access

OpenClaw is an open-source AI agent with shell access on your server, access to your file system, and persistent memory between sessions. You can connect it with chat apps like Telegram, voice agents, or web interfaces.

Hundreds of OpenClaw instances have already been found exposed on the internet without authentication. This guide covers a secure setup on Proxmox.

Note: In the video I use clawdbot commands, but the package has since been renamed to openclaw. All commands in this guide reflect the current naming.

Why VM, Not LXC?

LXC containers share the host kernel. If OpenClaw gets compromised in an LXC container, an attacker might escape to your Proxmox host.

VMs have hypervisor isolation. Worst case: an attacker owns the VM, you delete it and restore from snapshot. Your Proxmox host stays safe.

For AI agents with shell access, use a VM.

1. Create the Proxmox VM

Create a new VM with these settings:

  • Name: openclaw

  • ISO: Ubuntu 24.04 LTS Server

  • Machine: q35

  • CPU: 2 cores, type host

  • RAM: 4096 MB

  • Disk: 32 GB

After creation, adjust these options:

  • Memory Ballooning: Disable (Options → Memory → Ballooning Device: No)

  • QEMU Guest Agent: Enable (Options → QEMU Guest Agent: Yes)

Start the VM and complete the Ubuntu installation. Enable OpenSSH server when prompted.

2. Base OS Setup

SSH into your new VM:

ssh your-user@<VM_IP>

Update the system:

sudo apt update && sudo apt upgrade -y

Install dependencies:

sudo apt install -y curl git build-essential ca-certificates gnupg qemu-guest-agent

3. Create a Dedicated User

We definitely don't want to run OpenClaw as root or our main user. Create a dedicated user instead, so that if something goes wrong, the attacker is stuck in that sandbox.

sudo adduser --disabled-password --gecos "" openclaw
sudo usermod -aG sudo openclaw
echo "openclaw ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/openclaw

Switch to the openclaw user:

sudo su - openclaw
export XDG_RUNTIME_DIR=/run/user/$(id -u)

There's one gotcha here: su doesn't create a full login session with the systemd user bus, so we need to export this manually.

Why passwordless sudo? OpenClaw runs system commands that need sudo. That's kind of the whole point. Without NOPASSWD, those commands hang waiting for input. The user has no password anyway, and VM isolation is your real security layer, not sudo restrictions.

4. Add Swap

Ubuntu Server with LVM doesn't create swap by default. OpenClaw pulls in node dependencies and compiles them, so let's give the compiler a bit more breathing room:

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Verify:

free -h

5. Install Node.js 24

curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt install -y nodejs

Verify:

node --version  # Should be v24.x.x
npm --version   # Should be v10.x.x or higher

6. Install OpenClaw

sudo npm install -g openclaw@latest
openclaw --version

7. Create a Telegram Bot

We'll be using Telegram to interact with OpenClaw. Before running the configuration, we need to set up a bot:

  1. Open Telegram and search for @BotFather

  2. Send /newbot

  3. Choose a display name and username (must end in bot)

  4. Save the token, you'll need it during configuration

  5. Send /setprivacy → Select your bot → Disable (bot needs to read all messages)

  6. Message @userinfobot to get your Telegram user ID

8. Configure OpenClaw

Thankfully OpenClaw comes with a nice onboarding wizard:

openclaw onboard

Use these settings:

  • Gateway mode: Local

  • Authentication: Your preferred AI providers API key

  • Gateway bind: Loopback (127.0.0.1)

  • Channels: Telegram → paste your bot token

  • Runtime: Node (not Bun)

  • Skip hooks and skills for now

Why Loopback?

Binding to loopback means the gateway is only accessible from inside the VM. No port is open to your network or the internet.

But how do chat clients connect? OpenClaw doesn't wait for incoming connections. It polls Telegram's API every few seconds: "Any new messages for me?" All communication is outgoing.

9. Enable the Service

The onboarding wizard might report that system user services are unavailable. We can set that up ourselves.

Enable lingering so the service runs after logout:

sudo loginctl enable-linger openclaw

Install and start the systemd service:

openclaw daemon install
systemctl --user daemon-reload
systemctl --user enable --now openclaw-gateway

Verify:

systemctl --user status openclaw-gateway

10. Security Audit

OpenClaw comes with a built-in security audit, which is pretty cool:

openclaw security audit --deep
openclaw security audit --fix

The --fix flag will automatically correct file permissions if needed.

11. Pair Your Telegram Account

One more layer of security is the pairing mechanism. By default, anyone who knows your bot's username can message it, but OpenClaw won't respond to them. Instead, they'll get a pairing code that needs to be approved on the server.

Send any message to your bot in Telegram. You'll receive a pairing code.

On your server, approve the pairing:

openclaw pairing list telegram
openclaw pairing approve telegram <CODE>

Now send another message. OpenClaw should respond.

Quick Reference

Service commands:

systemctl --user status openclaw-gateway
systemctl --user restart openclaw-gateway
journalctl --user -u openclaw-gateway -f

OpenClaw commands:

openclaw status
openclaw doctor
openclaw security audit --deep
openclaw pairing list telegram
openclaw logs --follow

Config location: ~/.openclaw/openclaw.json

Troubleshooting

Problem

Solution

Service won't start

openclaw doctor --fix

OOM during install

Add more swap

Bot not responding

Check openclaw pairing list telegram

"No API key" error

openclaw configure --section model

Port 18789 in use

lsof -nP -iTCP:18789 -sTCP:LISTEN

Keep Reading