OpenClaw is only as safe as the VPS it runs on. This article walks through a practical “secure-by-default” baseline for a Hetzner Cloud VM: deny-by-default inbound at the cloud perimeter, mirror that posture on the host with UFW, enforce SSH key-only access for an unprivileged sudo user, and add fail2ban to reduce noisy internet traffic. The aim is a minimal exposed surface (usually SSH only, restricted by source IP), while keeping the OpenClaw Gateway/dashboard private unless you explicitly choose a private-access method like Tailscale.
Secure OpenClaw on Hetzner (Basic Setup): Cloud Firewall + SSH Keys + fail2ban, with a Minimal Port Surface
Design goal (what we’re optimizing for)
For a single-tenant VPS running OpenClaw, the highest-leverage security posture is:
- Only one public entrypoint: SSH
- SSH is key-only (no passwords), ideally no root login
- Inbound is deny-by-default at both the Hetzner perimeter and the VM
- OpenClaw’s Gateway UI stays on loopback/private by default
- Remote usage happens via Telegram and/or private networking (e.g., Tailscale), not by exposing admin UIs to the open internet
This matches how SetupClaw’s Basic Setup (£249) is intended to run: secure defaults first, then optional expansions when you have a clear reason.
Step 1 — Put a deny-by-default perimeter around the VPS (Hetzner Cloud Firewall)
Hetzner Cloud Firewalls are your “edge” control: traffic is filtered before it reaches your VM. In practice, that means mistakes on the host are less likely to become an internet exposure.
Baseline rules (recommended for Basic Setup)
- Create a Cloud Firewall in Hetzner.
- Attach it to your OpenClaw server.
- Add one inbound allow rule:
- TCP 22 (SSH)
- Source: your fixed IP(s) (home, office). If you truly need it, add a temporary admin IP and remove it after.
Keep everything else blocked inbound.
Notes:
- The usual “minimal ports” stance is SSH only.
- Don’t open the OpenClaw Gateway/dashboard to the internet by default.
(Reference: Hetzner Cloud Firewall overview)
Step 2 — Mirror the perimeter on the VM (UFW defense-in-depth)
Why both a Hetzner firewall and UFW?
- Hetzner firewall = edge protection, safer by default.
- UFW = host-level safety net if cloud rules drift or are misapplied.
UFW baseline (Ubuntu)
On the VPS:
sudo apt update
sudo apt install -y ufw
# Deny inbound by default; allow outbound
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Allow SSH (you can also restrict to your IP here, but do that at the Hetzner layer first)
sudo ufw allow 22/tcp
# Enable
sudo ufw enable
sudo ufw status verbose
If you want to restrict SSH at the host layer too:
# Example: allow SSH only from one IP
sudo ufw delete allow 22/tcp
sudo ufw allow from <YOUR_PUBLIC_IP> to any port 22 proto tcp
sudo ufw status numbered
Step 3 — SSH keys only: remove password guessing from the equation
The biggest practical win for SSH is eliminating passwords.
3.1 Create an unprivileged sudo user
Avoid operating as root day-to-day.
sudo adduser claw
sudo usermod -aG sudo claw
3.2 Install your public key
From your local machine, copy your public key (example uses ~/.ssh/id_ed25519.pub).
ssh-copy-id -i ~/.ssh/id_ed25519.pub claw@<SERVER_IP>
Or manually:
sudo -u claw mkdir -p /home/claw/.ssh
sudo -u claw chmod 700 /home/claw/.ssh
# paste your public key into:
sudo -u claw nano /home/claw/.ssh/authorized_keys
sudo -u claw chmod 600 /home/claw/.ssh/authorized_keys
3.3 Test in a second session before locking things down
Open a new terminal and confirm you can log in with the key:
ssh claw@<SERVER_IP>
Only after this succeeds should you proceed.
3.4 Harden sshd_config
Edit /etc/ssh/sshd_config (exact options can vary by distro; check comments in-file):
Recommended baseline:
- Disable password auth
- Disable root login
- Optionally restrict allowed users/groups
Example settings:
PasswordAuthentication no
PermitRootLogin no
# Optional tightening
AllowUsers claw
Then reload:
sudo systemctl reload ssh
Reference for options: man sshd_config.
Step 4 — Add fail2ban to reduce noisy internet traffic
If SSH is key-only, why fail2ban?
- Key-only blocks password guessing, but fail2ban:
- reduces noise/log spam
- slows repeated authentication failures
- provides an extra response layer for misbehaving IPs
Install and enable:
sudo apt install -y fail2ban
sudo systemctl enable --now fail2ban
sudo fail2ban-client status
Create a minimal jail override (Ubuntu commonly uses /etc/fail2ban/jail.d/*.conf):
sudo nano /etc/fail2ban/jail.d/sshd.local
Example:
[sshd]
enabled = true
# Defaults are often fine for a baseline; tune if needed
# maxretry = 5
# findtime = 10m
# bantime = 1h
Then:
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
Important: fail2ban helps manage rate and noise; it does not replace strong authentication.
Step 5 — Patch hygiene: automatic security updates
Hardening only matters if the box stays patched. On Ubuntu, enable unattended security updates:
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
Document the operational reality: some updates (kernel, key libraries) may require reboots. For a Basic Setup baseline, it’s enough to:
- enable security updates
- agree on a reboot habit (manual when needed, or a maintenance window)
Step 6 — OpenClaw-specific posture (tie the hardening to the product)
Once the VPS is hard to break into, you can trust the layer above it:
- Keep the OpenClaw Gateway/dashboard private (loopback) by default.
- Prefer private remote access (e.g., Tailscale) if you need “admin from anywhere.”
- Treat your Telegram bot token as a secret stored server-side; combine with allowlisting/DM policy so only intended users can command the agent.
If someone asks “can we just expose the OpenClaw dashboard publicly?” — treat that as a deliberate design change that needs explicit protections (reverse proxy, TLS, authentication, IP allowlisting). It’s not the Basic Setup default.
Practical “done” checks
Run these after hardening:
# Firewall status
sudo ufw status verbose
# Confirm SSH is key-only (password auth disabled)
sudo sshd -T | egrep 'passwordauthentication|permitrootlogin'
# fail2ban status
sudo fail2ban-client status
sudo fail2ban-client status sshd
# Updates
sudo systemctl status unattended-upgrades --no-pager
And validate from the outside:
- SSH works from allowed IPs
- SSH fails from non-allowed IPs (Hetzner firewall should drop)
Deliverables SetupClaw leaves behind (Basic Setup baseline)
A good handoff is a short runbook, not a pile of screenshots. For this hardening slice, the deliverables should include:
- What inbound ports are intentionally exposed (usually only TCP 22) and why
- Where rules live:
- Hetzner Cloud Firewall name + rule summary
- UFW policy summary + any IP restrictions
- SSH access model:
- which user(s) can log in
- where to add/remove authorized keys
- confirmation that password auth is disabled
- fail2ban basics:
- how to check status and jails
- Break-glass note:
- Hetzner console access
- key rotation steps if a laptop is lost
Want this baseline implemented cleanly (and documented)?
Get OpenClaw setup on your own Hetzner VPS — see how we can help.
References
- Hetzner Cloud Firewalls: https://docs.hetzner.com/cloud/firewalls/overview/
- UFW (Ubuntu firewall): https://help.ubuntu.com/community/UFW
- Automatic security updates (Ubuntu): https://help.ubuntu.com/community/AutomaticSecurityUpdates
-
sshd_configmanual: https://man.openbsd.org/sshd_config - fail2ban docs: https://fail2ban.readthedocs.io/
- OpenClaw docs (incl. Tailscale): https://docs.openclaw.ai
Top comments (0)