How to Secure and Harden OpenClaw on a VeerHost VPS

Estimated reading: 4 minutes

Running OpenClaw on a VPS gives you full control, but it also makes you responsible for server security. This guide shows you how to harden your VeerHost VPS so your OpenClaw deployment is harder to scan, exploit, or abuse.

Note: Some older guides may still refer to OpenClaw as Moltbot or Clawdbot. This document uses the current name: OpenClaw.

Security principles

Before changing anything, follow these rules:

  • Expose as few ports as possible
  • Run services with least privilege
  • Keep secrets out of public repos
  • Use HTTPS for public-facing endpoints
  • Keep the OS and packages updated
  • Monitor logs and restart failures quickly

1) Keep the system updated

Run updates regularly:

sudo apt update && sudo apt -y upgrade

Enable automatic security updates if appropriate for your workflow:

sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

2) Create a sudo user and avoid daily root login

If you are still working as root, create a dedicated admin user:

adduser openclawadmin
usermod -aG sudo openclawadmin

Test sudo access:

su - openclawadmin
sudo whoami

3) Use SSH keys

Generate a key on your local machine if you do not already have one:

ssh-keygen -t ed25519

Copy it to the server:

ssh-copy-id openclawadmin@YOUR_VPS_IP

Test login:

ssh openclawadmin@YOUR_VPS_IP

4) Harden SSH

Edit the SSH config:

sudo nano /etc/ssh/sshd_config

Recommended settings:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding no

Reload SSH:

sudo systemctl reload ssh

Important: make sure your SSH key works before disabling password login.

5) Configure the firewall

Allow only required traffic:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable
sudo ufw status verbose

If OpenClaw runs behind Nginx, do not expose its internal app port publicly.

6) Bind OpenClaw to localhost only

If OpenClaw listens on port 3000, bind it to 127.0.0.1 instead of 0.0.0.0.

Example Docker port binding:

ports:
  - "127.0.0.1:3000:3000"

This prevents direct public access while still allowing Nginx to proxy requests locally.

7) Put Nginx in front of OpenClaw

A reverse proxy helps with:

  • HTTPS termination
  • Cleaner domain routing
  • Optional basic auth
  • Rate limiting
  • Hiding internal ports

Basic example:

server {
    listen 80;
    server_name bot.yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        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 $scheme;
    }
}

8) Enable HTTPS

Install Certbot:

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d bot.yourdomain.com

This is especially important if OpenClaw uses webhooks, dashboards, or admin endpoints over the web.

9) Protect environment files and secrets

Your .env file should never be world-readable.

Check permissions:

ls -l .env

Set secure permissions:

chmod 600 .env

Best practices:

  • Never commit .env to Git
  • Rotate tokens after leaks
  • Use strong database passwords
  • Keep API keys out of screenshots, logs, and tutorials

10) Secure the database

If PostgreSQL or MySQL is used only by OpenClaw, keep it private.

Good practice:

  • Bind database services to localhost or Docker internal networking
  • Do not expose database ports publicly
  • Use a dedicated database user with limited privileges
  • Back up the database regularly

Check open listening ports:

sudo ss -tulpn

11) Add Fail2ban

Install Fail2ban to reduce brute-force attacks:

sudo apt install -y fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Check status:

sudo fail2ban-client status

12) Limit dashboard and webhook exposure

If OpenClaw includes an admin panel, dashboard, or webhook endpoint:

  • Protect it with HTTPS
  • Add authentication where possible
  • Restrict by IP if only you need access
  • Use strong random secrets
  • Disable unused endpoints

13) Watch logs

Check logs often for failed logins, repeated crashes, or suspicious requests.

Docker logs:

docker compose logs -f openclaw

System auth logs:

sudo journalctl -u ssh -n 100 --no-pager

Nginx logs:

sudo tail -f /var/log/nginx/access.log /var/log/nginx/error.log

14) Back up critical files

At minimum, back up:

  • .env
  • docker-compose.yml
  • Nginx config
  • Database dumps

Example PostgreSQL backup:

docker exec -t openclaw_postgres pg_dump -U openclaw_user openclaw > openclaw_backup.sql

15) Restart safely after changes

Whenever you change environment variables, proxy settings, or Docker config, restart the stack cleanly:

docker compose down
docker compose up -d

Then verify:

docker compose ps
docker compose logs --tail=50

Common mistakes to avoid

  • Leaving port 3000 open to the public internet
  • Keeping root SSH login enabled
  • Using weak passwords for the database or bot tokens
  • Storing secrets in GitHub repositories
  • Running outdated Docker images for months
  • Exposing database ports like 5432 or 3306 publicly

Quick hardening checklist

  • System updated
  • SSH keys enabled
  • Root SSH disabled
  • Firewall enabled
  • OpenClaw bound to localhost
  • Nginx reverse proxy configured
  • HTTPS enabled
  • .env locked down
  • Database not publicly exposed
  • Fail2ban installed
  • Backups tested
  • Logs monitored