Files
Redflag/aggregator-server/internal/services/templates/install/scripts/linux.sh.tmpl

323 lines
11 KiB
Bash

#!/bin/bash
# RedFlag Agent Installer - Linux
# Generated for agent: {{.AgentID}}
# Platform: {{.Platform}}
# Architecture: {{.Architecture}}
# Version: {{.Version}}
set -e
# Check if running as root (required for user creation and sudoers)
if [ "$EUID" -ne 0 ]; then
echo "ERROR: This script must be run as root for secure installation (use sudo)"
exit 1
fi
AGENT_USER="redflag-agent"
AGENT_HOME="/var/lib/redflag-agent"
SUDOERS_FILE="/etc/sudoers.d/redflag-agent"
# Function to detect package manager
detect_package_manager() {
if command -v apt-get &> /dev/null; then
echo "apt"
elif command -v dnf &> /dev/null; then
echo "dnf"
elif command -v yum &> /dev/null; then
echo "yum"
elif command -v pacman &> /dev/null; then
echo "pacman"
elif command -v zypper &> /dev/null; then
echo "zypper"
else
echo "unknown"
fi
}
AGENT_ID="{{.AgentID}}"
BINARY_URL="{{.BinaryURL}}"
CONFIG_URL="{{.ConfigURL}}"
INSTALL_DIR="/usr/local/bin"
CONFIG_DIR="/etc/redflag"
OLD_CONFIG_DIR="/etc/aggregator"
SERVICE_NAME="redflag-agent"
VERSION="{{.Version}}"
LOG_DIR="/var/log/redflag"
BACKUP_DIR="${CONFIG_DIR}/backups/backup.$(date +%s)"
AGENT_USER="redflag-agent"
AGENT_HOME="/var/lib/redflag-agent"
SUDOERS_FILE="/etc/sudoers.d/redflag-agent"
echo "=== RedFlag Agent v${VERSION} Installation ==="
echo "Agent ID: ${AGENT_ID}"
echo "Platform: {{.Platform}}"
echo "Installing to: ${INSTALL_DIR}/${SERVICE_NAME}"
echo
# Step 1: Detect existing installation
echo "Detecting existing RedFlag installations..."
MIGRATION_NEEDED=false
if [ -f "${CONFIG_DIR}/config.json" ]; then
echo "✓ Existing installation detected at ${CONFIG_DIR}"
MIGRATION_NEEDED=true
elif [ -f "${OLD_CONFIG_DIR}/config.json" ]; then
echo "⚠ Old installation detected at ${OLD_CONFIG_DIR} - MIGRATION REQUIRED"
MIGRATION_NEEDED=true
else
echo "✓ Fresh installation"
fi
# Step 2: Create backup if migration needed
if [ "${MIGRATION_NEEDED}" = true ]; then
echo
echo "=== Migration Required ==="
echo "Agent will migrate on first start. Backing up configuration..."
sudo mkdir -p "${BACKUP_DIR}"
if [ -f "${OLD_CONFIG_DIR}/config.json" ]; then
echo "Backing up old configuration..."
sudo cp -r "${OLD_CONFIG_DIR}"/* "${BACKUP_DIR}/" 2>/dev/null || true
fi
if [ -f "${CONFIG_DIR}/config.json" ]; then
echo "Backing up current configuration..."
sudo cp "${CONFIG_DIR}/config.json" "${BACKUP_DIR}/config.json.backup" 2>/dev/null || true
fi
echo "Migration will run automatically when agent starts."
echo "View migration logs with: sudo journalctl -u ${SERVICE_NAME} -f"
echo
fi
# Step 3: Create system user and home directory
echo "Creating system user for agent..."
if id "$AGENT_USER" &>/dev/null; then
echo "✓ User $AGENT_USER already exists"
else
sudo useradd -r -s /bin/false -d "$AGENT_HOME" "$AGENT_USER"
echo "✓ User $AGENT_USER created"
fi
# Create home directory
if [ ! -d "$AGENT_HOME" ]; then
sudo mkdir -p "$AGENT_HOME"
sudo chown "$AGENT_USER:$AGENT_USER" "$AGENT_HOME"
sudo chmod 750 "$AGENT_HOME"
echo "✓ Home directory created at $AGENT_HOME"
fi
# Step 4: Install sudoers configuration with OS-specific commands
PM=$(detect_package_manager)
echo "Detected package manager: $PM"
echo "Installing sudoers configuration..."
case "$PM" in
apt)
cat <<'EOF' | sudo tee "$SUDOERS_FILE" > /dev/null
# RedFlag Agent minimal sudo permissions - APT
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/apt-get update
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/apt-get install -y *
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/apt-get upgrade -y
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/apt-get install --dry-run --yes *
EOF
;;
dnf|yum)
cat <<'EOF' | sudo tee "$SUDOERS_FILE" > /dev/null
# RedFlag Agent minimal sudo permissions - DNF/YUM
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/dnf makecache
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/dnf install -y *
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/dnf upgrade -y
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/yum makecache
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/yum install -y *
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/yum update -y
EOF
;;
pacman)
cat <<'EOF' | sudo tee "$SUDOERS_FILE" > /dev/null
# RedFlag Agent minimal sudo permissions - Pacman
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/pacman -Sy
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/pacman -S --noconfirm *
EOF
;;
*)
cat <<'EOF' | sudo tee "$SUDOERS_FILE" > /dev/null
# RedFlag Agent minimal sudo permissions - Generic (APT and DNF)
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/apt-get update
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/apt-get install -y *
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/dnf makecache
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/dnf install -y *
EOF
;;
esac
# Add Docker commands
cat <<'DOCKER_EOF' | sudo tee -a "$SUDOERS_FILE" > /dev/null
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/docker pull *
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/docker image inspect *
{{.AgentUser}} ALL=(root) NOPASSWD: /usr/bin/docker manifest inspect *
DOCKER_EOF
sudo chmod 440 "$SUDOERS_FILE"
if visudo -c -f "$SUDOERS_FILE" &>/dev/null; then
echo "✓ Sudoers configuration installed and validated"
else
echo "⚠ Sudoers configuration validation failed - using generic version"
fi
# Step 5: Stop existing service
if systemctl is-active --quiet ${SERVICE_NAME} 2>/dev/null; then
echo "Stopping existing RedFlag agent service..."
sudo systemctl stop ${SERVICE_NAME}
fi
# Step 4: Create directories
echo "Creating directories..."
sudo mkdir -p "${CONFIG_DIR}"
sudo mkdir -p "${CONFIG_DIR}/backups"
sudo mkdir -p "$AGENT_HOME"
sudo mkdir -p "/var/log/redflag"
# Step 5: Download agent binary
echo "Downloading agent binary..."
sudo curl -sSL -o "${INSTALL_DIR}/${SERVICE_NAME}" "${BINARY_URL}"
sudo chmod +x "${INSTALL_DIR}/${SERVICE_NAME}"
# Step 6: Handle configuration
# IMPORTANT: The agent handles its own migration on first start.
# We either preserve existing config OR create a minimal template.
if [ -f "${CONFIG_DIR}/config.json" ]; then
echo "[CONFIG] Upgrade detected - preserving existing configuration"
echo "[CONFIG] Agent will handle migration automatically on first start"
echo "[CONFIG] Backup created at: ${BACKUP_DIR}"
else
echo "[CONFIG] Fresh install - generating minimal configuration with registration token"
# Create minimal config template - agent will populate missing fields on first start
sudo tee "${CONFIG_DIR}/config.json" > /dev/null <<EOF
{
"version": 5,
"agent_version": "${VERSION}",
"agent_id": "",
"token": "",
"refresh_token": "",
"registration_token": "{{.RegistrationToken}}",
"machine_id": "",
"check_in_interval": 300,
"server_url": "{{.ServerURL}}",
"network": {
"timeout": 30000000000,
"retry_count": 3,
"retry_delay": 5000000000,
"max_idle_conn": 10
},
"proxy": {
"enabled": false
},
"tls": {
"enabled": false,
"insecure_skip_verify": false
},
"logging": {
"level": "info",
"max_size": 100,
"max_backups": 3,
"max_age": 28
},
"subsystems": {
"system": {"enabled": true, "timeout": 10000000000, "circuit_breaker": {"enabled": true, "failure_threshold": 3, "failure_window": 600000000000, "open_duration": 1800000000000, "half_open_attempts": 2}},
"filesystem": {"enabled": true, "timeout": 10000000000, "circuit_breaker": {"enabled": true, "failure_threshold": 3, "failure_window": 600000000000, "open_duration": 1800000000000, "half_open_attempts": 2}},
"network": {"enabled": true, "timeout": 30000000000, "circuit_breaker": {"enabled": true, "failure_threshold": 3, "failure_window": 600000000000, "open_duration": 1800000000000, "half_open_attempts": 2}},
"processes": {"enabled": true, "timeout": 30000000000, "circuit_breaker": {"enabled": true, "failure_threshold": 3, "failure_window": 600000000000, "open_duration": 1800000000000, "half_open_attempts": 2}},
"updates": {"enabled": true, "timeout": 30000000000, "circuit_breaker": {"enabled": false, "failure_threshold": 0, "failure_window": 0, "open_duration": 0, "half_open_attempts": 0}},
"storage": {"enabled": true, "timeout": 10000000000, "circuit_breaker": {"enabled": true, "failure_threshold": 3, "failure_window": 600000000000, "open_duration": 1800000000000, "half_open_attempts": 2}}
},
"security": {
"ed25519_verification": true,
"nonce_validation": true,
"machine_id_binding": true
}
}
EOF
fi
# Step 7: Set permissions on config file
sudo chmod 600 "${CONFIG_DIR}/config.json"
# Step 8: Create systemd service with security hardening
echo "Creating systemd service with security configuration..."
cat <<EOF | sudo tee /etc/systemd/system/${SERVICE_NAME}.service
[Unit]
Description=RedFlag Security Agent
After=network.target
StartLimitBurst=5
StartLimitIntervalSec=60
[Service]
Type=simple
User={{.AgentUser}}
Group={{.AgentUser}}
WorkingDirectory={{.AgentHome}}
ExecStart=${INSTALL_DIR}/${SERVICE_NAME}
Restart=always
RestartSec=30
RestartPreventExitStatus=255
# Security hardening
# Note: NoNewPrivileges disabled to allow sudo for package management
ProtectSystem=strict
ProtectHome=true
ReadWritePaths={{.AgentHome}} {{.ConfigDir}} {{.LogDir}}
PrivateTmp=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictRealtime=true
RestrictSUIDSGID=true
RemoveIPC=true
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=${SERVICE_NAME}
[Install]
WantedBy=multi-user.target
EOF
# Set proper permissions on directories
echo "Setting directory permissions..."
sudo chown -R {{.AgentUser}}:{{.AgentUser}} "{{.ConfigDir}}"
sudo chown {{.AgentUser}}:{{.AgentUser}} "{{.ConfigDir}}/config.json"
sudo chmod 600 "{{.ConfigDir}}/config.json"
sudo chown -R {{.AgentUser}}:{{.AgentUser}} "{{.AgentHome}}"
sudo chmod 750 "{{.AgentHome}}"
sudo chown -R {{.AgentUser}}:{{.AgentUser}} "{{.LogDir}}"
sudo chmod 750 "{{.LogDir}}"
# Step 9: Enable and start service
echo "Enabling and starting service..."
sudo systemctl daemon-reload
sudo systemctl enable ${SERVICE_NAME}
sudo systemctl start ${SERVICE_NAME}
echo
if systemctl is-active --quiet ${SERVICE_NAME}; then
echo "✓ Installation complete!"
echo ""
echo "=== Security Information ==="
echo "Agent is running with security hardening:"
echo " ✓ Dedicated system user: {{.AgentUser}}"
echo " ✓ Limited sudo access for package management only"
echo " ✓ Systemd service with security restrictions"
echo " ✓ Protected configuration directory"
echo ""
echo "Check status: sudo systemctl status ${SERVICE_NAME}"
echo "View logs: sudo journalctl -u ${SERVICE_NAME} -f"
else
echo "⚠ Installation complete but service not started"
echo " This may be normal for fresh installs awaiting registration"
echo ""
echo "To start after registration:"
echo " sudo systemctl start ${SERVICE_NAME}"
fi