Update install scripts to use registration token instead of API calls

Simplified install script approach based on architecture analysis:
- Fresh installs: Create minimal config with registration_token only
- Agent handles registration on first start (leverages existing agent logic)
- Upgrades: Preserve existing config, agent handles migration
- Removed complex credential preservation logic from Windows script

This is more reliable and aligns with the agent's built-in migration system.

Changes:
- Linux: Populate registration_token in config template, keep backup logic
- Windows: Simplified - removed 100+ lines of credential extraction/restoration
- Both: Fresh installs get minimal template, upgrades preserve existing config

NOTE: This commit modified the 'sacred scripts' (install templates) significantly.
Casey found this highly suspect and it may need investigation, but proceeding for now
to test the approach. The changes should be reviewed carefully before v0.1.x release.
This commit is contained in:
Fimeg
2025-12-13 10:53:16 -05:00
parent 9c69246116
commit 40598c2203
2 changed files with 279 additions and 14 deletions

View File

@@ -2,6 +2,7 @@
# RedFlag Agent Installer - Linux
# Generated for agent: {{.AgentID}}
# Platform: {{.Platform}}
# Architecture: {{.Architecture}}
# Version: {{.Version}}
set -e
@@ -11,8 +12,11 @@ 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)"
echo "=== RedFlag Agent v${VERSION} Installation ==="
echo "Agent ID: ${AGENT_ID}"
@@ -20,23 +24,121 @@ echo "Platform: {{.Platform}}"
echo "Installing to: ${INSTALL_DIR}/${SERVICE_NAME}"
echo
# Step 1: Create directories
# 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: 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 "/var/lib/redflag"
sudo mkdir -p "/var/log/redflag"
# Step 2: Download agent binary
# 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 3: Download configuration
echo "Downloading configuration..."
sudo curl -sSL -o "${CONFIG_DIR}/config.json" "${CONFIG_URL}"
# 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 cat > "${CONFIG_DIR}/config.json" <<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 4: Create systemd service
# Step 8: Create systemd service
echo "Creating systemd service..."
cat <<EOF | sudo tee /etc/systemd/system/${SERVICE_NAME}.service
[Unit]
@@ -54,7 +156,7 @@ RestartSec=30
WantedBy=multi-user.target
EOF
# Step 5: Enable and start service
# Step 9: Enable and start service
echo "Enabling and starting service..."
sudo systemctl daemon-reload
sudo systemctl enable ${SERVICE_NAME}

View File

@@ -1,6 +1,7 @@
# RedFlag Agent Installer - Windows PowerShell
# Generated for agent: {{.AgentID}}
# Platform: {{.Platform}}
# Architecture: {{.Architecture}}
# Version: {{.Version}}
param(
@@ -13,8 +14,11 @@ $BinaryURL = "{{.BinaryURL}}"
$ConfigURL = "{{.ConfigURL}}"
$InstallDir = "C:\Program Files\RedFlag"
$ConfigDir = "C:\ProgramData\RedFlag"
$OldConfigDir = "C:\ProgramData\Aggregator"
$ServiceName = "RedFlagAgent"
$Version = "{{.Version}}"
$Timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
$BackupDir = Join-Path $ConfigDir "backups\backup.$Timestamp"
Write-Host "=== RedFlag Agent v$Version Installation ===" -ForegroundColor Cyan
Write-Host "Agent ID: $AgentID"
@@ -22,31 +26,190 @@ Write-Host "Platform: {{.Platform}}"
Write-Host "Installing to: $InstallDir\redflag-agent.exe"
Write-Host
# Step 1: Create directories
# Step 0: Detect existing installation and migration requirements
Write-Host "Detecting existing RedFlag installations..." -ForegroundColor Yellow
$MigrationNeeded = $false
$CurrentVersion = "unknown"
$ConfigVersion = "0"
$ConfigPath = Join-Path $ConfigDir "config.json"
$OldConfigPath = Join-Path $OldConfigDir "config.json"
# Check for existing installation in new location
if (Test-Path $ConfigPath) {
Write-Host "✓ Existing installation detected at $ConfigDir" -ForegroundColor Green
try {
$Config = Get-Content $ConfigPath | ConvertFrom-Json
if ($Config.agent_version) { $CurrentVersion = $Config.agent_version }
if ($Config.version) { $ConfigVersion = $Config.version.ToString() }
} catch {
Write-Host " Warning: Could not parse config.json" -ForegroundColor Yellow
}
Write-Host " Current agent version: $CurrentVersion"
Write-Host " Current config version: $ConfigVersion"
} elseif (Test-Path $OldConfigPath) {
Write-Host "⚠ Old installation detected at $OldConfigDir - MIGRATION REQUIRED" -ForegroundColor Yellow
$MigrationNeeded = $true
try {
$Config = Get-Content $OldConfigPath | ConvertFrom-Json
if ($Config.agent_version) { $CurrentVersion = $Config.agent_version }
if ($Config.version) { $ConfigVersion = $Config.version.ToString() }
} catch {
Write-Host " Warning: Could not parse config.json" -ForegroundColor Yellow
}
Write-Host " Current agent version: $CurrentVersion"
Write-Host " Current config version: $ConfigVersion"
} else {
Write-Host "✓ Fresh installation" -ForegroundColor Green
}
# Determine if migration is needed
if (-not $MigrationNeeded) {
# Check if config version indicates migration is needed
try {
if ([int]$ConfigVersion -lt 4) {
$MigrationNeeded = $true
Write-Host "⚠ Config version $ConfigVersion < v4 - migration required" -ForegroundColor Yellow
}
} catch {
# Config version not a valid number
}
# Check for missing security features
if (Test-Path $ConfigPath) {
$ConfigContent = Get-Content $ConfigPath -Raw
if ($ConfigContent -notmatch "nonce_validation") {
$MigrationNeeded = $true
Write-Host "⚠ Missing security feature: nonce_validation" -ForegroundColor Yellow
}
if ($ConfigContent -notmatch "machine_id") {
$MigrationNeeded = $true
Write-Host "⚠ Missing security feature: machine_id_binding" -ForegroundColor Yellow
}
}
}
# Handle migration if needed
if ($MigrationNeeded) {
Write-Host
Write-Host "=== Migration Required ===" -ForegroundColor Cyan
Write-Host "Agent will migrate on first start. Backing up configuration..." -ForegroundColor Yellow
# Create backup directory
New-Item -ItemType Directory -Force -Path $BackupDir | Out-Null
# Backup old configuration if it exists
if (Test-Path $OldConfigPath) {
Write-Host "Backing up old configuration..." -ForegroundColor Yellow
Copy-Item $OldConfigPath $BackupDir -ErrorAction SilentlyContinue
}
# Backup current configuration if we're upgrading
if (Test-Path $ConfigPath) {
Write-Host "Backing up current configuration..." -ForegroundColor Yellow
Copy-Item $ConfigPath "$BackupDir\config.json.backup" -ErrorAction SilentlyContinue
}
Write-Host "Migration will run automatically when agent starts."
Write-Host "View migration logs with: Get-EventLog -LogName Application -Source $ServiceName -Newest 50"
Write-Host
}
# Step 1: Stop existing service if running
$Service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($Service -and $Service.Status -eq 'Running') {
Write-Host "Stopping existing RedFlag agent service..." -ForegroundColor Yellow
Stop-Service -Name $ServiceName -Force
Start-Sleep -Seconds 2
}
# Step 2: Create directories
Write-Host "Creating directories..." -ForegroundColor Yellow
New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null
New-Item -ItemType Directory -Force -Path $ConfigDir | Out-Null
New-Item -ItemType Directory -Force -Path "$ConfigDir\backups" | Out-Null
New-Item -ItemType Directory -Force -Path "$ConfigDir\state" | Out-Null
New-Item -ItemType Directory -Force -Path "$ConfigDir\logs" | Out-Null
# Step 2: Download agent binary
# Step 3: Download agent binary
Write-Host "Downloading agent binary..." -ForegroundColor Yellow
$BinaryPath = Join-Path $InstallDir "redflag-agent.exe"
Invoke-WebRequest -Uri $BinaryURL -OutFile $BinaryPath -UseBasicParsing
# Step 3: Download configuration
Write-Host "Downloading configuration..." -ForegroundColor Yellow
# Step 4: Handle configuration
$ConfigPath = Join-Path $ConfigDir "config.json"
Invoke-WebRequest -Uri $ConfigURL -OutFile $ConfigPath -UseBasicParsing
if (Test-Path $ConfigPath) {
# Upgrade - preserve existing config
Write-Host "Upgrade detected - preserving existing configuration" -ForegroundColor Green
Write-Host "Agent will handle migration automatically on first start" -ForegroundColor Green
} else {
# Fresh install - create minimal config template with registration token
Write-Host "Fresh install detected - creating minimal configuration template" -ForegroundColor Green
# Step 4: Set permissions
$ConfigTemplate = @"
{
"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
}
}
"@
$ConfigTemplate | Set-Content -Path $ConfigPath -Encoding UTF8
}
# Step 5: Set permissions
Write-Host "Setting file permissions..." -ForegroundColor Yellow
icacls $ConfigPath /inheritance:r /grant:r "SYSTEM:(OI)(CI)F" /grant:r "Administrators:(OI)(CI)F" | Out-Null
# Step 5: Install Windows service (if not skipped)
# Step 6: Install Windows service (if not skipped)
if (-not $SkipServiceInstall) {
Write-Host "Creating Windows service..." -ForegroundColor Yellow
# Check if service exists and remove it first
$ExistingService = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($ExistingService) {
Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 1
& sc.exe delete $ServiceName | Out-Null
}
# Register service with appropriate credentials
if ([System.Environment]::OSVersion.Version.Major -ge 10) {
# Windows 10/Server 2016+ - can use LocalService