📑 Table des matières

Securing Your OpenClaw Installation

04 - Sécuriser son installation OpenClaw

OpenClaw 🟡 Intermédiaire ⏱️ 12 min de lecture 📅 2026-02-09

Why Security is Critical

Your OpenClaw agent is not just a simple chatbot. It's a program that has access to your terminal, files, API keys, and potentially your messaging accounts. In other words: if someone compromises your server, they compromise everything your agent can do.

The attack surface is real:
- Arbitrary shell command execution
- File read/write on the entire system
- Network access to internal and external services
- Sending messages via Telegram, WhatsApp, Discord…

A poorly secured server is like leaving the keys to your house on the door. This guide walks you through step by step to lock down your installation.

💡 Tip: OpenClaw includes a built-in audit tool. Run it regularly:

openclaw security audit
openclaw security audit --deep

It automatically detects dangerous configurations (exposed ports, overly broad permissions, missing authentication).


Securing SSH

SSH is the entry point to your server. It's the first thing to lock down.

Changing the SSH Port

Port 22 is constantly scanned by bots. Changing the port doesn't protect you from a determined attacker, but it eliminates 99% of the noise.

sudo nano /etc/ssh/sshd_config

Find the line #Port 22 and replace it with:

Port [[ssh_port]]

⚠️ Warning: choose a port between 1024 and 65535. Make sure to note it down — if you lose access, you're locked out.

Restart SSH:

sudo systemctl restart sshd

Test in a new terminal (keep your current session open!):

ssh -p [[ssh_port]] [[username]]@[[ip]]

Disabling Password Authentication

SSH keys are infinitely more secure than passwords. If you don't have an SSH key yet, generate one on your local machine:

ssh-keygen -t ed25519 -C "[[email]]"
ssh-copy-id -p [[ssh_port]] [[username]]@[[ip]]

Once connected with your key, disable passwords:

sudo nano /etc/ssh/sshd_config

Modify these lines:

PasswordAuthentication no
PermitRootLogin prohibit-password
PubkeyAuthentication yes
sudo systemctl restart sshd

⚠️ Don't close your current session until you've verified that key-based connection works in another terminal.

Configuring SSH Timeouts

To automatically disconnect inactive sessions, add to /etc/ssh/sshd_config:

ClientAliveInterval 300
ClientAliveCountMax 2

This disconnects inactive sessions after 10 minutes (300s × 2). Useful for avoiding ghost sessions.

Disabling Dangerous Protocols

Add these lines to harden the SSH configuration:

X11Forwarding no
AllowAgentForwarding no
MaxAuthTries 3
LoginGraceTime 30
  • X11Forwarding no: disables graphical forwarding (unnecessary for a server)
  • MaxAuthTries 3: limits the number of attempts before disconnection
  • LoginGraceTime 30: only 30 seconds to authenticate

Installing Fail2ban

Fail2ban monitors login attempts and bans IPs after too many failures.

sudo apt update && sudo apt install -y fail2ban

Create a local configuration:

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

Modify the [sshd] section:

[sshd]
enabled = true
port = [[ssh_port]]
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600

Enable and start:

sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Check the status:

sudo fail2ban-client status sshd

Firewall with UFW

UFW (Uncomplicated Firewall) is Ubuntu's standard firewall. The idea is simple: block everything, then open only what's needed.

Installation and Configuration

sudo apt install -y ufw

Configure basic rules:

# Block all incoming traffic by default
sudo ufw default deny incoming

# Allow all outgoing traffic
sudo ufw default allow outgoing

# Open your custom SSH port
sudo ufw allow 2222/tcp comment 'SSH custom'

# Open HTTPS if you're using a reverse proxy
sudo ufw allow 443/tcp comment 'HTTPS'

⚠️ IMPORTANT: add the SSH rule before enabling UFW, otherwise you'll lose access!

Enable the firewall:

sudo ufw enable

Check the rules:

sudo ufw status verbose

💡 Tip: don't open the OpenClaw Gateway port (default 3578) directly. Use an SSH tunnel or Cloudflare Tunnel instead.

Useful Additional Rules

# Limit SSH connections (built-in brute-force protection)
sudo ufw limit 2222/tcp

# See firewall logs
sudo ufw logging on

HTTPS with Cloudflare Tunnel

Why a Tunnel?

With a Cloudflare tunnel, your server exposes no ports publicly. All traffic goes through Cloudflare's network, which:
- Hides your real IP address
- Provides free HTTPS
- Protects against DDoS attacks
- Eliminates the need to open port 443

This is the recommended method to expose a web interface related to OpenClaw.

Installing cloudflared

# Download and install cloudflared
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt update && sudo apt install -y cloudflared

Authentication and Tunnel Creation

# Log in to Cloudflare (opens a browser)
cloudflared tunnel login

# Create a tunnel
cloudflared tunnel create openclaw-tunnel

# List tunnels
cloudflared tunnel list

Tunnel Configuration

Create the configuration file:

mkdir -p ~/.cloudflared
nano ~/.cloudflared/config.yml
tunnel: <YOUR-TUNNEL-ID>
credentials-file: /root/.cloudflared/<YOUR-TUNNEL-ID>.json

ingress:
  - hostname: agent.yourdomain.com
    service: http://localhost:3578
  - service: http_status:404

Configuring DNS and Launching

# Create DNS entry
cloudflared tunnel route dns openclaw-tunnel agent.yourdomain.com

# Test the tunnel
cloudflared tunnel run openclaw-tunnel

To run it as a system service:

sudo cloudflared service install
sudo systemctl enable cloudflared
sudo systemctl start cloudflared

💡 Alternative: if you're using Tailscale, tailscale serve is an excellent option for private access without public exposure. OpenClaw documents this approach in its network guides.


Automatic Updates

An unupdated server is an easy target. Security updates should install automatically.

Installation

sudo apt install -y unattended-upgrades apt-listchanges

Configuration

sudo dpkg-reconfigure -plow unattended-upgrades

Select Yes to enable automatic updates.

To customize, edit:

sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

Important options:

Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}";
    "${distro_id}:${distro_codename}-security";
    "${distro_id}ESMApps:${distro_codename}-apps-security";
    "${distro_id}ESM:${distro_codename}-infra-security";
};

// Automatically reboot if necessary (at night)
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "04:00";

// Clean up old kernels
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";

Check that everything works:

sudo unattended-upgrades --dry-run --debug

Permissions and Isolation

Creating a Dedicated User

Never run OpenClaw as root in production. Create a dedicated user:

# Create the user
sudo adduser --disabled-password --gecos "" openclaw

# Give them Docker access if needed
sudo usermod -aG docker openclaw

# Log in as this user
sudo su - openclaw

Install OpenClaw under this user:

npm install -g openclaw

File Permissions

# Protect the configuration directory
chmod 700 ~/.openclaw

# Protect the configuration file
chmod 600 ~/.openclaw/openclaw.json

# Protect credentials
chmod 600 ~/.openclaw/credentials/*.json 2>/dev/null

💡 openclaw security audit --fix automatically applies these permissions.

Protecting API Keys

Never put your API keys directly in openclaw.json. Use environment variables:

# Create a .env file
nano ~/.openclaw/.env
ANTHROPIC_API_KEY=sk-ant-xxxxx
OPENAI_API_KEY=sk-xxxxx
TELEGRAM_BOT_TOKEN=123456:ABCdef
# Protect the file
chmod 600 ~/.openclaw/.env

In your systemd service, load the variables:

[Service]
EnvironmentFile=/home/openclaw/.openclaw/.env

⚠️ Never commit a .env file to Git. Add it to .gitignore.


Isolating with Docker (Optional)

For even stronger isolation, run OpenClaw in a Docker container:

# Example launch with Docker
docker run -d \
  --name openclaw \
  --restart unless-stopped \
  -v ~/.openclaw:/root/.openclaw \
  -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
  openclaw/openclaw:latest

The container isolates the process from the rest of the system, limiting the impact of a potential compromise.

Auditing Permissions Regularly

# Find files with overly broad permissions
find ~/.openclaw -type f -perm /o+r -ls

# Check that no sensitive files are readable by others
stat -c '%a %n' ~/.openclaw/openclaw.json ~/.openclaw/.env 2>/dev/null

OpenClaw's built-in audit does part of this work. Make it a habit to run it after every modification:

openclaw security audit --fix

The --fix option automatically applies safe corrections: file permissions, group policy, and log redaction.


Monitoring

Monitoring Connections

Essential commands to know:

# Who's currently connected?
who

# Recent connections
last -20

# Failed connections
sudo lastb -20

# Open ports and active connections
sudo ss -tulnp

# Network processes
sudo ss -tp

Logs to Check Regularly

# SSH attempts
sudo grep "Failed password" /var/log/auth.log | tail -20

# Successful connections
sudo grep "Accepted" /var/log/auth.log | tail -20

# System logs
sudo journalctl -u openclaw --since "1 hour ago" --no-pager

# Fail2ban logs
sudo fail2ban-client status sshd

Healthcheck Script

Create a simple script to check your installation's status:

nano ~/healthcheck.sh
#!/bin/bash
echo "=== OpenClaw Healthcheck ==="
echo ""

# Check that the Gateway is running
if openclaw gateway status | grep -q "running"; then
    echo "✅ Gateway: running"
else
    echo "❌ Gateway: stopped!"
fi

# Check UFW
if sudo ufw status | grep -q "active"; then
    echo "✅ Firewall: active"
else
    echo "❌ Firewall: inactive!"
fi

# Check Fail2ban
if systemctl is-active --quiet fail2ban; then
    echo "✅ Fail2ban: active"
else
    echo "❌ Fail2ban: inactive!"
fi

# Check disk space
DISK_USAGE=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$DISK_USAGE" -lt 80 ]; then
    echo "✅ Disk: ${DISK_USAGE}% used"
else
    echo "⚠️ Disk: ${DISK_USAGE}% used (attention!)"
fi

# Check security updates
UPDATES=$
#sécurité #ssh #firewall #ufw #cloudflare #fail2ban #openclaw #vps #https