WIP: Save current state - security subsystems, migrations, logging

This commit is contained in:
Fimeg
2025-12-16 14:19:59 -05:00
parent f792ab23c7
commit f7c8d23c5d
89 changed files with 8884 additions and 1394 deletions

View File

@@ -7,6 +7,33 @@
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}}"
@@ -17,6 +44,9 @@ 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}"
@@ -44,23 +74,98 @@ if [ "${MIGRATION_NEEDED}" = true ]; then
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
# 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}
@@ -70,7 +175,7 @@ fi
echo "Creating directories..."
sudo mkdir -p "${CONFIG_DIR}"
sudo mkdir -p "${CONFIG_DIR}/backups"
sudo mkdir -p "/var/lib/redflag"
sudo mkdir -p "$AGENT_HOME"
sudo mkdir -p "/var/log/redflag"
# Step 5: Download agent binary
@@ -88,7 +193,7 @@ if [ -f "${CONFIG_DIR}/config.json" ]; then
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
sudo tee "${CONFIG_DIR}/config.json" > /dev/null <<EOF
{
"version": 5,
"agent_version": "${VERSION}",
@@ -138,24 +243,57 @@ fi
# Step 7: Set permissions on config file
sudo chmod 600 "${CONFIG_DIR}/config.json"
# Step 8: Create systemd service
echo "Creating systemd service..."
# 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=root
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
@@ -163,6 +301,22 @@ sudo systemctl enable ${SERVICE_NAME}
sudo systemctl start ${SERVICE_NAME}
echo
echo "✓ Installation complete!"
echo "Agent is running. Check status with: sudo systemctl status ${SERVICE_NAME}"
echo "View logs with: sudo journalctl -u ${SERVICE_NAME} -f"
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