How to Secure Your OpenClaw AI Agent Installation
I exposed my OpenClaw instance to the internet on port 8080. Within hours, I found suspicious requests in my logs. Someone was probing my AI agent, trying to access files and run commands.
That’s when I realized: an AI agent with file system access and command execution capabilities is basically a remote code execution vulnerability waiting to happen.
Here’s how I locked it down.
The Problem with Default Installations
OpenClaw runs as a daemon with access to your file system, terminal, and various APIs. By default:
- It listens on a predictable port (8080)
- It may bind to all network interfaces (0.0.0.0)
- It runs with your user permissions
- It accepts connections from any IP
- Skills can execute arbitrary commands
This is convenient for development but dangerous for production. One misconfigured skill or leaked endpoint could give attackers full access to your system.
Step 1: Change the Default Port
The default port 8080 is a common target for automated scanners. I changed it to a non-standard port:
server: port: 38472 # Use a random high port host: 127.0.0.1 # Bind to localhost onlyAt first, I used port 3000. Bad idea—that’s another common port that scanners check. Then I tried 8081, still too predictable.
I ended up using a random port in the 30000-50000 range. The key is unpredictability. Automated scanners focus on common ports; a random high port reduces your attack surface.
After changing the port, restart OpenClaw:
sudo systemctl restart openclawTest it works:
curl http://localhost:38472/healthStep 2: Use a VPN (Tailscale)
Even with localhost binding, I wanted remote access. I initially tried SSH tunneling, but it was clunky. Then I discovered Tailscale.
Tailscale creates a private network between your devices. No port forwarding, no exposed services, no public IPs.
Here’s how I set it up:
# Install Tailscalecurl -fsSL https://tailscale.com/install.sh | sh
# Authenticatesudo tailscale upNow my server has a private IP like 100.x.y.z. I can access OpenClaw from anywhere:
curl http://100.x.y.z:38472/healthThe beauty is that port 38472 is never exposed to the internet. It’s only accessible within my Tailscale network.
┌─────────────┐ ┌──────────────┐│ Laptop │ │ Server ││ │ │ ││ Tailscale │◄───────►│ Tailscale ││ 100.x.y.z │ VPN │ 100.x.y.z │└─────────────┘ │ │ │ OpenClaw │ │ :38472 │ └──────────────┘ ▲ │ Internet (blocked)Step 3: Configure Firewall Rules
Defense in depth means multiple layers. Even though Tailscale hides my service, I still configured a firewall.
On Ubuntu, I used ufw:
# Default deny incomingsudo ufw default deny incomingsudo ufw default allow outgoing
# Allow SSH (don't lock yourself out!)sudo ufw allow ssh
# Allow Tailscale trafficsudo ufw allow in on tailscale0
# Enable firewallsudo ufw enableI made the mistake of not allowing SSH first. Don’t do that. Always allow SSH before enabling the firewall, or you’ll lock yourself out.
Check your rules:
sudo ufw status verboseOutput should show:
Status: activeLogging: on (low)Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From-- ------ ----22/tcp ALLOW IN AnywhereAnywhere on tailscale0 ALLOW IN AnywhereNow even if someone discovers my IP, they can’t reach OpenClaw.
Step 4: Use Isolated User Accounts
I initially ran OpenClaw with my regular user account. Big mistake. If compromised, an attacker would have access to all my files.
I created a dedicated user:
# Create openclaw user with no shellsudo useradd -r -s /usr/sbin/nologin openclaw
# Create directoriessudo mkdir -p /opt/openclaw/{config,logs,skills}sudo chown -R openclaw:openclaw /opt/openclawThen I configured OpenClaw to run as this user:
# /etc/systemd/system/openclaw.service[Unit]Description=OpenClaw AI AgentAfter=network.target
[Service]Type=simpleUser=openclawGroup=openclawWorkingDirectory=/opt/openclawExecStart=/usr/local/bin/openclaw --config /opt/openclaw/config/config.yamlRestart=on-failure
# Security hardeningNoNewPrivileges=truePrivateTmp=trueProtectSystem=strictProtectHome=trueReadWritePaths=/opt/openclaw
[Install]WantedBy=multi-user.targetThe systemd hardening options restrict what the process can do:
NoNewPrivileges=true: Prevents privilege escalationPrivateTmp=true: Isolates temporary filesProtectSystem=strict: Makes system directories read-onlyProtectHome=true: Blocks access to home directoriesReadWritePaths: Only allows writing to specified directories
Reload and restart:
sudo systemctl daemon-reloadsudo systemctl restart openclawsudo systemctl status openclawNow OpenClaw runs in a sandbox with minimal privileges.
Step 5: Scan and Audit Skills
Skills are OpenClaw’s power and danger. A malicious skill could exfiltrate data or run destructive commands.
I created an audit script to check skills before installation:
#!/bin/bash# Check for suspicious patterns in skill files
SKILL_DIR="$1"
if [ -z "$SKILL_DIR" ]; then echo "Usage: $0 <skill-directory>" exit 1fi
echo "Scanning $SKILL_DIR for security issues..."
# Check for suspicious patternsPATTERNS=( "curl.*|.*bash" "wget.*|.*sh" "eval\s" "exec\s*(" "__import__" "subprocess\.call" "os\.system" "rm\s+-rf")
for pattern in "${PATTERNS[@]}"; do MATCHES=$(grep -rE "$pattern" "$SKILL_DIR" 2>/dev/null) if [ -n "$MATCHES" ]; then echo "⚠️ WARNING: Found pattern '$pattern':" echo "$MATCHES" echo "" fidone
# Check for external network callsecho "Checking for external network calls..."grep -r "http://" "$SKILL_DIR" 2>/dev/null | head -20grep -r "https://" "$SKILL_DIR" 2>/dev/null | head -20
# Check file permissionsecho ""echo "File permissions:"find "$SKILL_DIR" -type f -exec ls -la {} \;Run this before installing any skill:
chmod +x audit-skills.sh./audit-skills.sh ~/.openclaw/skills/new-skillI also maintain a whitelist of approved skills in my configuration:
skills: allowed: auto_update: false # Manual review requiredThis prevents automatic installation of unverified skills.
Verification: Testing Your Setup
After implementing all five steps, I verified each layer:
Port check:
# From another machine on the same networknmap -p 38472 your-server-ip# Should show "filtered" or "closed"VPN access:
# From your Tailscale-connected laptopcurl http://100.x.y.z:38472/health# Should return 200 OKFirewall:
sudo ufw status# Should show only SSH and Tailscale allowedUser isolation:
ps aux | grep openclaw# Should show process running as 'openclaw' userSkill audit:
./audit-skills.sh /opt/openclaw/skills# Should show no warningsCommon Mistakes I Made
Mistake 1: Using default port 8080 I thought “no one will find my server.” Wrong. Automated scanners found it within hours.
Mistake 2: Running as root Convenient? Yes. Secure? Absolutely not. One vulnerability and attackers have root access.
Mistake 3: Skipping skill audits I installed a skill that made external API calls without checking. It wasn’t malicious, but it could have been.
Mistake 4: Not testing firewall rules I blocked myself out twice before adding an exception for SSH. Always test from another terminal before closing your session.
Summary
Securing OpenClaw requires defense in depth:
- Obscurity: Random port reduces automated scanning
- Network isolation: VPN hides your service from the internet
- Firewall: Explicit deny-by-default policy
- Least privilege: Dedicated user with minimal permissions
- Code audit: Scan skills before installation
No single step is sufficient. Together, they create multiple barriers that make exploitation significantly harder.
The most important insight: treat your AI agent like a remote code execution endpoint. Because that’s essentially what it is. Every security measure you add is another layer of protection between your data and the internet.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments