Setting Up OpenClaw Safely
If you have been following the AI agent space, you have probably come across OpenClaw. It’s an open-source, self-hosted AI assistant that connects to your messaging platforms and runs as a persistent daemon on your machine. It can execute shell commands, manage files, and automate tasks. That’s both the appeal and the risk. You’re essentially giving an AI agent the keys to your system.
Apart from what many people may be doing, the sensible thing to do is to not run it on your daily machine. Instead, you can spin up an isolated virtual machine on Proxmox, lock it down with firewall rules so it cannot touch anything else on your network (unless that is what you want), and access it securely through Tailscale both inside and outside of your LAN. That’s what this guide will cover.
Note: This guide is meant for personal use in a self-hosted environment and not meant for corporate or professional use. You are responsible for your own setup and the author is not responsible for any issues that may arise from your setup.
Getting the Debian Cloud Image and Creating the VM
We’ll use a Debian cloud image as the base. Cloud images are minimal, pre-built disk images designed for automated provisioning via cloud-init. They’re small, boot fast, and don’t require you to sit through an installer.
SSH into your Proxmox host and download the latest Debian 13 (Trixie) generic cloud image:
mkdir ~/debian-iso
cd ~/debian-iso
wget https://cloud.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2
Now create a new VM. Pick an unused VM ID. In this example I’ll use 200.
qm create 200 --name openclaw-vm --memory 4096 --cores 2 --net0 virtio,bridge=vmbr0,firewall=1
Import the downloaded image as the VM’s disk:
qm importdisk 200 debian-13-generic-amd64.qcow2 local-lvm
Replace local-lvm with whatever storage backend you use. After the import completes, attach the disk and configure cloud-init:
qm set 200 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-200-disk-0
qm set 200 --ide2 local-lvm:cloudinit
qm set 200 --boot c --bootdisk scsi0
qm set 200 --serial0 socket --vga serial0
The default disk is only a few gigabytes, so resize it to something more reasonable:
qm resize 200 scsi0 +28G
Now configure the cloud-init settings. You can do this through the Proxmox web UI under the VM’s Cloud-Init tab. I suggest using a fixed IP but DHCP is possible if you use the Tailscale IP.
Set the user, password, and SSH key to whatever you prefer. Ensure that you have an SSH key as the image disables password authentication by default. Start the VM with qm start 200, give it a minute for cloud-init to finish its first boot setup, and then SSH in. You can find its IP from the Proxmox summary page or by checking your router’s DHCP leases.

Once you’re in, install the QEMU guest agent so Proxmox can report the IP and manage the VM properly:
sudo apt update
sudo apt install -y qemu-guest-agent
Setting Up Firewall Rules
The goal here is straightforward: the OpenClaw VM should be able to reach the internet (it needs to call AI provider APIs), but it should not be able to reach anything else on your LAN. If the agent gets compromised or behaves unexpectedly, it cannot pivot to your NAS, your other VMs, or anything else on your local network.
We’ll assume your LAN is 192.168.1.0/24, with the gateway at 192.168.1.1. Let’s say the Proxmox host is at 192.168.1.100 and the VM gets assigned 192.168.1.150 via DHCP. Adjust these to match your setup.
Proxmox has a built-in firewall that works at three levels: datacenter, host (node), and VM. The important thing to know is that datacenter-level rules apply to hosts, not to VMs. VM firewall rules must be set on the VM itself. Also, none of the rules take effect until you enable the firewall at the datacenter level.
Datacenter Level
Go to Datacenter, then Firewall, then Options, and ensure you set Firewall to Yes.
VM Level
This is where the isolation happens. The VM firewall configuration lives at /etc/pve/firewall/<VMID>.fw, so for our VM with ID 200, that is /etc/pve/firewall/200.fw. You can create these rules through the web GUI (select the VM, then Firewall, then Add), but again, editing the file directly is easier to get right.
Before editing the file, make sure the firewall is enabled on the VM’s network device. In the Proxmox web UI, go to the VM’s Hardware tab, double-click the network adapter, and check that the Firewall checkbox is ticked. Without this, the VM firewall rules are ignored entirely regardless of what is in the file.
Now create or edit the VM firewall file:
nano /etc/pve/firewall/200.fw
Add the following:
[OPTIONS]
enable: 1
policy_in: ACCEPT
policy_out: DROP
[RULES]
OUT ACCEPT -dest 192.168.1.1
OUT DROP -dest 192.168.1.0/24
OUT ACCEPT
The order of rules matters because Proxmox evaluates them top to bottom. The first rule allows outbound traffic to the gateway at 192.168.1.1, which is needed for DNS resolution and routing. The second rule blocks outbound traffic to every other IP in the LAN subnet. The third rule allows all remaining outbound traffic, which at this point can only be internet-bound since LAN has already been blocked by the rule above it.
We set policy_in to ACCEPT and policy_out to DROP. The ACCEPT policy on inbound means any device on the LAN (or anywhere) can reach the VM freely. You can SSH in, access the OpenClaw web interface, and generally treat it like any other machine on your network. The DROP policy on outbound means the VM cannot send traffic anywhere unless a rule explicitly permits it. The three outbound rules above are the only holes we poke: the router, and the internet. Everything else on the LAN is unreachable from the VM’s perspective.
This is the asymmetry we want. Your laptop can talk to the VM, but the VM cannot talk to your laptop, your NAS, your other VMs, or anything else on the local network. If something on the VM goes sideways, the blast radius is limited to the VM itself and whatever it can reach on the public internet.
After saving the file, the rules take effect immediately. You can verify the firewall status and check for configuration errors by running:
pve-firewall status
pve-firewall compile
The compile command parses all the firewall configuration files and reports any syntax errors without actually applying changes, which is useful for catching mistakes.
Testing the Firewall
SSH into the VM and run a few tests. First, confirm you can reach the internet:
ping -c 3 8.8.8.8
ping -c 3 google.com
Both should succeed. The first confirms basic outbound connectivity, and the second confirms DNS resolution works (which goes through your gateway).
Next, confirm the gateway is reachable:
ping -c 3 192.168.1.1
This should also succeed, since we explicitly allowed it.
Now test that you cannot reach other devices on the LAN. Pick any other IP on your network, for example your NAS or another VM:
ping -c 3 192.168.1.100
ping -c 3 192.168.1.50
These should time out. If they do, your firewall rules are working. The VM can talk to the internet and the gateway, but nothing else on your local network.

Installing OpenClaw
With the VM set up and locked down, we can install OpenClaw. The official method uses a one-liner install script that handles Node.js detection, installation, and the onboarding wizard:
curl -fsSL https://openclaw.ai/install.sh | bash
The script will install Node.js if it is not already present, install the OpenClaw packages, and launch an interactive onboarding wizard. The wizard will walk you through configuring your AI provider (you’ll need an Anthropic API key or equivalent), setting up the gateway, and optionally connecting messaging channels like Telegram or WhatsApp. My recommendations for an OpenClaw setup for personal use:
- Use OpenRouter with free models for LLM models
- Use Brave API for the web search skill
- Use Telegram as a channel (in addition to using the OpenClaw Dashboard Chat)
After installation, verify everything is working:
openclaw --version
openclaw doctor
openclaw gateway status
The doctor command checks for configuration issues, and gateway status confirms the gateway process is running.

One important security setting: by default, OpenClaw’s web interface binds to localhost. Which means no device on the network can reach it. We will need to setup a reverse proxy to pipe this out. Caddy is a convenient choice of a reverse proxy. We’ll set it up after we install Tailscale.
For now, ensure that TLS is supported by adding it to the gateway config in ~/.openclaw/openclaw.json. In addition, we allow multiple origins on the UI and disable device authentication. This allows OpenClaw to support the LAN connectivity, but the risks are mitigated because this is a Proxmox VM, and any internet ingress should be disabled so only your Tailscale network and LAN is able to reach this machine.

...
"tls": {
"enabled": true
},
"controlUi": {
"allowedOrigins": [
"*"
],
"dangerouslyDisableDeviceAuth": true
},
...
Installing and Setting Up Tailscale and Caddy
Tailscale gives you secure access to the VM from anywhere, whether you’re on the same LAN or on the other side of the world. It uses WireGuard under the hood and handles NAT traversal automatically, so you don’t need to open any ports on your router.
Install Tailscale using their official install script:
curl -fsSL https://tailscale.com/install.sh | sh
Once installed, bring it up:
sudo tailscale up
This will print a URL. Open it in your browser, authenticate with your Tailscale account (Google, GitHub, Microsoft, or whatever provider you use), and authorize the machine. After authentication, the VM gets a Tailscale IP in the 100.x.x.x range.
Verify it’s connected:
tailscale status
tailscale ip
Since this VM is a server that you want running continuously, you should disable key expiry so you don’t have to re-authenticate periodically. You can do this from the Tailscale admin console at https://login.tailscale.com/admin/machines by clicking on the machine and disabling key expiry.
Now we install a reverse proxy so that we access the web service over standard ports instead of the :18789 default port.
# Install Caddy
sudo apt install -y caddy
# Configure it
sudo nano /etc/caddy/Caddyfile
We then set it up like the following (assuming your Tailscale IP is 100.12.123.123). tls_insecure_skip_verify is ok because the upstream is localhost with a self-signed certificate. I hope I don’t have to teach you how to trust a self-signed certificate.
{
local_certs
}
https://100.12.123.123 {
tls internal
reverse_proxy https://localhost:18789 {
transport http {
tls_insecure_skip_verify
}
}
}
http://100.12.123.123 {
reverse_proxy https://localhost:18789 {
transport http {
tls_insecure_skip_verify
}
}
}
https://192.168.1.150 {
tls internal
reverse_proxy https://localhost:18789 {
transport http {
tls_insecure_skip_verify
}
}
}
http://192.168.1.150 {
reverse_proxy https://localhost:18789 {
transport http {
tls_insecure_skip_verify
}
}
}
Now, from any other device on your Tailscale network, you can access the OpenClaw web interface using the Tailscale IP.
Testing Browser Access
From your laptop or phone (which should also have Tailscale installed and connected to the same tailnet), open a browser and navigate to https://100.12.123.123 or https://192.168.1.150.
You should see the OpenClaw dashboard. If you set up messaging channels during onboarding, you can also test sending a message through Telegram, WhatsApp, or whichever platform you configured.

Once you see this, you can use the same token generated into the ~/.openclaw/openclaw.json file to login.

Next Steps
At this point you have a working, isolated OpenClaw installation accessible over Tailscale. Here are some things worth looking into from here.
First, consider setting up automatic updates for both the VM and OpenClaw itself. You can configure unattended-upgrades on Debian for OS-level patches, and use openclaw update to keep OpenClaw current. These are agents with access to your system, so staying on top of security patches matters. Automating it is fine as this is a personal setup.
Second, take a look at OpenClaw’s consent mode. Setting the exec “ask” configuration forces the agent to ask for your approval before executing write or destructive commands. This is especially useful while you’re still getting comfortable with what the agent can and will do. You can read OpenClaw’s hardening documentation for more information.
Third, review the skills you install carefully. OpenClaw has a marketplace of community-contributed Skills (similar to plugins), and not all of them are thoroughly reviewed. If you haven’t read the source code, don’t install it. This applies to any software, but it’s especially relevant for an agent that can execute arbitrary commands.
Fourth, consider taking a snapshot of the VM in Proxmox now that everything is set up. If something breaks or the agent does something unexpected, you can roll back to a known good state in seconds. I setup a daily backup for all my VMs.
Finally, think about backup. Your OpenClaw configuration, conversation history, and workspace live in ~/.openclaw/ on the VM. A simple cron job that rsyncs that directory to a backup location (or even a Proxmox backup schedule for the entire VM) ensures you don’t lose your setup if something goes wrong.
The point of all this isolation is not paranoia. It’s pragmatism. These are powerful tools, and running them in a way that limits the blast radius of anything unexpected is just good practice. The VM can talk to the internet but not to your other devices, you access it through an encrypted tunnel everywhere you go, and if everything goes sideways, you can nuke the VM and start fresh from a snapshot. That’s a reasonable precaution for testing out OpenClaw.