| title | description |
|---|---|
Security Architecture |
Firewall configuration, Docker isolation, and security hardening details |
This playbook implements a multi-layer defense strategy to secure Clawdbot installations.
# Default policies
Incoming: DENY
Outgoing: ALLOW
Routed: DENY
# Allowed
SSH (22/tcp): ALLOW
Tailscale (41641/udp): ALLOWAutomatic protection against SSH brute-force attacks:
# Configuration
Max retries: 5 attempts
Ban time: 1 hour (3600 seconds)
Find time: 10 minutes (600 seconds)
# Check status
sudo fail2ban-client status sshd
# Unban an IP
sudo fail2ban-client set sshd unbanip IP_ADDRESSCustom iptables chain that prevents Docker from bypassing UFW:
*filter
:DOCKER-USER - [0:0]
-A DOCKER-USER -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A DOCKER-USER -i lo -j ACCEPT
-A DOCKER-USER -i <default_interface> -j DROP
COMMIT
Result: Even docker run -p 80:80 nginx won't expose port 80 externally.
All container ports bind to 127.0.0.1:
ports:
- "127.0.0.1:3000:3000"Container processes run as unprivileged clawdbot user.
The clawdbot service runs with security restrictions:
NoNewPrivileges=true- Prevents privilege escalationPrivateTmp=true- Isolated /tmp directoryProtectSystem=strict- Read-only system directoriesProtectHome=read-only- Limited home directory accessReadWritePaths- Only ~/.clawdbot is writable
The clawdbot user has limited sudo permissions (not full root):
# Allowed commands only:
- systemctl start/stop/restart/status clawdbot
- systemctl daemon-reload
- tailscale commands
- journalctl for clawdbot logsUnattended-upgrades is configured for automatic security patches:
# Check status
sudo unattended-upgrade --dry-run
# View logs
sudo cat /var/log/unattended-upgrades/unattended-upgrades.logNote: Automatic reboots are disabled. Monitor for pending reboots:
cat /var/run/reboot-required 2>/dev/null || echo "No reboot required"# Check firewall
sudo ufw status verbose
# Check fail2ban
sudo fail2ban-client status
# Check Tailscale status
sudo tailscale status
# Check Docker isolation
sudo iptables -L DOCKER-USER -n -v
# Port scan from external machine (only SSH + Tailscale should be open)
nmap -p- YOUR_SERVER_IP
# Test container isolation
sudo docker run -d -p 80:80 --name test-nginx nginx
curl http://YOUR_SERVER_IP:80 # Should fail/timeout
curl http://localhost:80 # Should work
sudo docker rm -f test-nginx
# Check unattended-upgrades
sudo systemctl status unattended-upgradesClawdbot's web interface (port 3000) is bound to localhost. Access it via:
-
SSH tunnel:
ssh -L 3000:localhost:3000 user@server # Then browse to http://localhost:3000 -
Tailscale (recommended):
# On server: already done by playbook sudo tailscale up # From your machine: # Browse to http://TAILSCALE_IP:3000
Internet → UFW (SSH only) → fail2ban → DOCKER-USER Chain → DROP
Container → NAT → Internet (outbound allowed)
- macOS firewall configuration is basic (Application Firewall only)
- No fail2ban equivalent on macOS
- Consider using Little Snitch or similar for enhanced macOS security
- Docker IPv6 is disabled by default (
ip6tables: falsein daemon.json) - If your network uses IPv6, review and test firewall rules accordingly
- The
curl | bashinstallation pattern has inherent risks - For high-security environments, clone the repository and audit before running
- Consider using
--checkmode first:ansible-playbook playbook.yml --check
After installation, verify:
-
sudo ufw statusshows only SSH and Tailscale allowed -
sudo fail2ban-client status sshdshows jail active -
sudo iptables -L DOCKER-USER -nshows DROP rule -
nmap -p- YOUR_IPfrom external shows only port 22 -
docker run -p 80:80 nginx+curl YOUR_IP:80times out - Tailscale access works for web UI
If you discover a security vulnerability, please report it privately:
- Clawdbot: https://github.com/clawdbot/clawdbot/security
- This installer: https://github.com/openclaw/clawdbot-ansible/security