openboatmobile-ai/templates/userdata-openclaw.tpl
CeeLo Greenheart a593af9b27 Initial commit - Clean public release
Sanitized for public release:
- Removed all API keys, tokens, and secrets
- Removed personal Discord IDs from hermes-openclaw.json
- Updated git URLs to be generic placeholders
- All sensitive data uses environment variable interpolation
2026-04-22 19:13:28 +00:00

372 lines
No EOL
9.9 KiB
Smarty

#cloud-config
# OpenClaw Gateway Bootstrap
# Update packages
package_update: true
package_upgrade: true
# Install required packages
packages:
- curl
- git
- fail2ban
- ufw
- jq
- gnupg
- ca-certificates
- software-properties-common
# Create admin user (if different from root)
users:
- name: ${admin_user}
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_authorized_keys: ${jsonencode(admin_ssh_keys)}
groups: [sudo, systemd-journal]
# Write system configuration files
write_files:
# SSH hardening configuration
- path: /etc/ssh/sshd_config.d/99-hardening.conf
content: |
# SSH Security Hardening
Port ${ssh_port}
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding no
PrintMotd no
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
permissions: '0644'
# Fail2ban SSH configuration
%{if enable_fail2ban}
- path: /etc/fail2ban/jail.d/sshd.local
content: |
[sshd]
enabled = true
port = ${ssh_port}
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
permissions: '0644'
%{endif}
# OpenClaw environment file
- path: /etc/openclaw.env
content: |
# Secrets injected during provisioning - DO NOT commit to version control
# Inference API keys
%{if venice_api_key != ""}
VENICE_API_KEY=${venice_api_key}
%{endif}
%{if brave_search_api_key != ""}
BRAVE_SEARCH_API_KEY=${brave_search_api_key}
%{endif}
# Discord configuration
%{if discord_bot_token != ""}
DISCORD_BOT_TOKEN=${discord_bot_token}
%{endif}
%{if discord_server_id != ""}
DISCORD_SERVER_ID=${discord_server_id}
%{endif}
%{if length(discord_user_id) > 0}
DISCORD_USER_ID=${jsonencode(discord_user_id)}
%{endif}
# Tailscale auth key (if enabled)
%{if enable_tailscale && tailscale_auth_key != ""}
TAILSCALE_AUTH_KEY=${tailscale_auth_key}
%{endif}
permissions: '0600'
# OpenClaw configuration file (uses env var references for secrets)
- path: /home/${admin_user}/.openclaw/openclaw.json
content: |
{
"auth": {
"profiles": {
"venice:default": {
"provider": "venice",
"mode": "api_key"
}
}
},
"models": {
"mode": "merge",
"providers": ${models_config}
},
"agents": {
"defaults": {
"model": {
"primary": "${primary_model}",
"fallbacks": ${fallback_models}
},
"workspace": "/home/${admin_user}/.openclaw/workspace"
},
"list": [
{
"id": "${agent_name}",
"default": true,
"workspace": "/home/${admin_user}/.openclaw/workspace"
}
]
},
"tools": {
"web": {
"search": {
"enabled": true,
"provider": "brave",
"apiKey": "$${BRAVE_SEARCH_API_KEY}"
},
"fetch": { "enabled": true }
},
"exec": {
"security": "allowlist",
"ask": "on-miss"
}
},
"messages": {
"queue": { "mode": "collect" },
"ackReactionScope": "all"
},
"channels": {
"discord": {
"enabled": true,
"token": "$${DISCORD_BOT_TOKEN}",
"groupPolicy": "allowlist",
"guilds": {
"${discord_server_id}": {
"requireMention": false,
"users": ${jsonencode(discord_user_id)},
"channels": { "*": { "allow": true } }
}
}
}
},
"gateway": {
"port": 18789,
"mode": "local",
"bind": "loopback"
}
}
permissions: '0644'
# Systemd service for OpenClaw Gateway
- path: /etc/systemd/system/openclaw-gateway.service
content: |
[Unit]
Description=OpenClaw Gateway Service
After=network.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/openclaw gateway run
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=openclaw-gateway
EnvironmentFile=/etc/openclaw.env
WorkingDirectory=/home/${admin_user}/.openclaw
[Install]
WantedBy=multi-user.target
permissions: '0644'
# Health check script
- path: /usr/local/bin/openclaw-health-check.sh
content: |
#!/bin/bash
# OpenClaw Gateway Health Check
set -e
echo "=== OpenClaw Health Check ==="
echo ""
# Check if OpenClaw is installed
if command -v openclaw &> /dev/null; then
echo "✓ OpenClaw installed: $(openclaw --version)"
else
echo "✗ OpenClaw not found"
exit 1
fi
# Check if gateway is running
if systemctl is-active --quiet openclaw-gateway; then
echo "✓ Gateway service running"
else
echo "✗ Gateway service not running"
fi
# Check if gateway is listening
if lsof -i :18789 > /dev/null 2>&1; then
echo "✓ Gateway listening on port 18789"
else
echo "✗ Gateway not listening on port 18789"
fi
# Check firewall
if ufw status | grep -q "Status: active"; then
echo "✓ Firewall active"
else
echo "⚠ Firewall not active"
fi
# Check fail2ban
%{if enable_fail2ban}
if systemctl is-active --quiet fail2ban; then
echo "✓ fail2ban running"
else
echo "⚠ fail2ban not running"
fi
%{endif}
echo ""
echo "=== End Health Check ==="
permissions: '0755'
%{if enable_swap}
# Swap creation script
- path: /usr/local/bin/create-swap.sh
content: |
#!/bin/bash
set -e
if [ ! -f /swapfile ]; then
fallocate -l ${swap_size}G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
echo "Created ${swap_size}GB swap"
else
echo "Swap already exists"
fi
permissions: '0755'
%{endif}
%{if enable_tailscale}
# Tailscale setup script
- path: /usr/local/bin/setup-tailscale.sh
content: |
#!/bin/bash
set -e
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up --authkey=${tailscale_auth_key} --ssh
# Wait for Tailscale to connect
sleep 5
# Enable Tailscale Serve for gateway access
# This exposes the gateway on the tailnet via HTTPS
tailscale serve --bg 18789 || echo "Note: Tailscale serve may require 'Serve' to be enabled in admin console"
echo "Tailscale configured and serving on port 18789"
permissions: '0755'
%{endif}
# Run commands
runcmd:
# Create admin user home directory
- mkdir -p /home/${admin_user}
- chown ${admin_user}:${admin_user} /home/${admin_user}
%{if enable_swap}
# Create swapfile
- /usr/local/bin/create-swap.sh
%{endif}
# Install Node.js ${node_version}
- curl -fsSL https://deb.nodesource.com/setup_${node_version}.x | bash -
- apt-get install -y nodejs
- node --version
- npm --version
# Install OpenClaw
%{if openclaw_version == "latest"}
- curl -fsSL https://openclaw.ai/install.sh | bash
%{else}
%{if openclaw_version == "lts"}
- curl -fsSL https://openclaw.ai/install.sh | bash -s -- --version lts
%{else}
- curl -fsSL https://openclaw.ai/install.sh | bash -s -- --version ${openclaw_version}
%{endif}
%{endif}
- openclaw --version || echo "OpenClaw installed, needs configuration"
# Create OpenClaw config directory
- mkdir -p /home/${admin_user}/.openclaw/workspace
- chown -R ${admin_user}:${admin_user} /home/${admin_user}/.openclaw
# Configure firewall (SSH only)
- ufw default deny incoming
- ufw default allow outgoing
- ufw allow ${ssh_port}/tcp
- ufw --force enable
%{if enable_fail2ban}
# Enable fail2ban
- systemctl enable fail2ban
- systemctl start fail2ban
%{endif}
%{if enable_unattended_upgrades}
# Enable automatic security updates
- apt-get install -y unattended-upgrades
- dpkg-reconfigure --priority=low unattended-upgrades
%{endif}
# Set up SSH hardening
- systemctl restart sshd
%{if enable_tailscale}
# Install and configure Tailscale
- /usr/local/bin/setup-tailscale.sh
%{endif}
# Set permissions on environment file
- chown root:root /etc/openclaw.env
- chmod 600 /etc/openclaw.env
# Enable and start OpenClaw gateway service
# Config is pre-seeded, so gateway can start immediately
- systemctl daemon-reload
- systemctl enable openclaw-gateway.service
- systemctl start openclaw-gateway.service
# Print completion message
- |
echo ""
echo "======================================="
echo " OpenClaw Gateway Bootstrap Complete!"
echo "======================================="
echo ""
echo "Server is ready."
echo ""
%{if enable_tailscale}
echo "Access via Tailscale:"
echo " https://${server_name}.TAILNET.ts.net/"
echo ""
echo "If Tailscale Serve didn't start, run:"
echo " sudo tailscale serve --bg 18789"
echo ""
%{else}
echo "SSH into this server:"
echo " ${ssh_port != 22 ? "ssh -p ${ssh_port}" : "ssh"} ${admin_user}@$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address)"
echo ""
%{endif}
echo "Check gateway status:"
echo " systemctl status openclaw-gateway"
echo ""
echo "View logs:"
echo " journalctl -u openclaw-gateway -f"
echo ""