fix: Update .gitignore and remove dev files from repository
Remove development and investigation files that shouldn't be in repo: - Kate editor swap files (*.swp, *.kate-swp) - Discord development folder (contains credentials) - Development investigation scripts (db_investigation.sh, etc.) - Configuration files (docker-compose.dev.yml) Note: Files removed from git but kept locally (rm --cached) Files are still present in working directory but won't be tracked
This commit is contained in:
Binary file not shown.
24
.gitignore
vendored
24
.gitignore
vendored
@@ -445,4 +445,26 @@ TEST-CLONE.md
|
|||||||
!docs/API.md
|
!docs/API.md
|
||||||
!docs/CONFIGURATION.md
|
!docs/CONFIGURATION.md
|
||||||
!docs/ARCHITECTURE.md
|
!docs/ARCHITECTURE.md
|
||||||
!docs/DEVELOPMENT.md
|
!docs/DEVELOPMENT.md
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Development and investigation files (should not be in repo)
|
||||||
|
# =============================================================================
|
||||||
|
db_investigation.sh
|
||||||
|
fix_agent_permissions.sh
|
||||||
|
install.sh
|
||||||
|
docker-compose.dev.yml
|
||||||
|
.migration_temp/
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Kate editor swap files
|
||||||
|
# =============================================================================
|
||||||
|
*.swp
|
||||||
|
*.kate-swp
|
||||||
|
.MIGRATION_STRATEGY.md.kate-swp
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Discord bot development (private, contains credentials)
|
||||||
|
# =============================================================================
|
||||||
|
discord/
|
||||||
|
discord/.env.example
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "=== RedFlag Database Investigation ==="
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Check if containers are running
|
|
||||||
echo "1. Checking container status..."
|
|
||||||
docker ps | grep -E "redflag|postgres"
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "2. Testing database connection with different credentials..."
|
|
||||||
|
|
||||||
# Try with postgres credentials
|
|
||||||
echo "Trying with postgres user:"
|
|
||||||
docker exec redflag-postgres psql -U postgres -c "SELECT current_database(), current_user;" 2>/dev/null
|
|
||||||
|
|
||||||
# Try with redflag credentials
|
|
||||||
echo "Trying with redflag user:"
|
|
||||||
docker exec redflag-postgres psql -U redflag -d redflag -c "SELECT current_database(), current_user;" 2>/dev/null
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "3. Listing databases:"
|
|
||||||
docker exec redflag-postgres psql -U postgres -c "\l" 2>/dev/null
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "4. Checking tables in redflag database:"
|
|
||||||
docker exec redflag-postgres psql -U postgres -d redflag -c "\dt" 2>/dev/null || echo "Failed to list tables"
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "5. Checking migration status:"
|
|
||||||
docker exec redflag-postgres psql -U postgres -d redflag -c "SELECT version, applied_at FROM schema_migrations ORDER BY version;" 2>/dev/null || echo "No schema_migrations table found"
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "6. Checking users table:"
|
|
||||||
docker exec redflag-postgres psql -U postgres -d redflag -c "SELECT id, username, email, created_at FROM users LIMIT 5;" 2>/dev/null || echo "Users table not found"
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "7. Checking for security_* tables:"
|
|
||||||
docker exec redflag-postgres psql -U postgres -d redflag -c "\dt security_*" 2>/dev/null || echo "No security_* tables found"
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "8. Checking agent_commands table for signature column:"
|
|
||||||
docker exec redflag-postgres psql -U postgres -d redflag -c "\d agent_commands" 2>/dev/null | grep signature || echo "Signature column not found"
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "9. Checking recent logs from server:"
|
|
||||||
docker logs redflag-server 2>&1 | tail -20
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "10. Password configuration check:"
|
|
||||||
echo "From docker-compose.yml POSTGRES_PASSWORD:"
|
|
||||||
grep "POSTGRES_PASSWORD:" docker-compose.yml
|
|
||||||
echo "From config/.env POSTGRES_PASSWORD:"
|
|
||||||
grep "POSTGRES_PASSWORD:" config/.env
|
|
||||||
echo "From config/.env REDFLAG_DB_PASSWORD:"
|
|
||||||
grep "REDFLAG_DB_PASSWORD:" config/.env
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
# Discord Configuration Template
|
|
||||||
# Copy this file to .env and fill in your actual values
|
|
||||||
|
|
||||||
# Discord Bot Configuration
|
|
||||||
DISCORD_BOT_TOKEN=your_bot_token_here
|
|
||||||
DISCORD_SERVER_ID=your_server_id_here
|
|
||||||
DISCORD_APPLICATION_ID=your_app_id_here
|
|
||||||
DISCORD_PUBLIC_KEY=your_public_key_here
|
|
||||||
|
|
||||||
# Server Management
|
|
||||||
SERVER_NAME=RedFlag Security
|
|
||||||
ADMIN_ROLE_ID=your_admin_role_id_here
|
|
||||||
|
|
||||||
# Channel IDs (to be filled after creation)
|
|
||||||
GENERAL_CHANNEL_ID=
|
|
||||||
ANNOUNCEMENTS_CHANNEL_ID=
|
|
||||||
SECURITY_ALERTS_CHANNEL_ID=
|
|
||||||
DEV_CHAT_CHANNEL_ID=
|
|
||||||
BUG_REPORTS_CHANNEL_ID=
|
|
||||||
|
|
||||||
# Category IDs (to be filled after creation)
|
|
||||||
COMMUNITY_CATEGORY_ID=
|
|
||||||
DEVELOPMENT_CATEGORY_ID=
|
|
||||||
SECURITY_CATEGORY_ID=
|
|
||||||
31
discord/.gitignore
vendored
31
discord/.gitignore
vendored
@@ -1,31 +0,0 @@
|
|||||||
# Environment files
|
|
||||||
.env
|
|
||||||
.env.local
|
|
||||||
.env.*.local
|
|
||||||
|
|
||||||
# Python
|
|
||||||
__pycache__/
|
|
||||||
*.pyc
|
|
||||||
*.pyo
|
|
||||||
*.pyd
|
|
||||||
.env
|
|
||||||
venv/
|
|
||||||
.venv/
|
|
||||||
env/
|
|
||||||
venv.bak/
|
|
||||||
venv/
|
|
||||||
|
|
||||||
# IDE
|
|
||||||
.vscode/
|
|
||||||
.idea/
|
|
||||||
*.swp
|
|
||||||
*.swo
|
|
||||||
*~
|
|
||||||
|
|
||||||
# Logs
|
|
||||||
*.log
|
|
||||||
logs/
|
|
||||||
|
|
||||||
# OS
|
|
||||||
.DS_Store
|
|
||||||
Thumbs.db
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,153 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Secure Discord Environment Manager
|
|
||||||
Handles loading Discord configuration from .env without exposing secrets
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import logging
|
|
||||||
from typing import Optional, Dict, Any
|
|
||||||
from dotenv import load_dotenv
|
|
||||||
|
|
||||||
# Configure logging
|
|
||||||
logging.basicConfig(
|
|
||||||
level=logging.INFO,
|
|
||||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
||||||
)
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
class DiscordEnvManager:
|
|
||||||
"""Secure environment manager for Discord configuration"""
|
|
||||||
|
|
||||||
def __init__(self, env_file: str = ".env"):
|
|
||||||
self.env_file = env_file
|
|
||||||
self._config = {}
|
|
||||||
self._load_config()
|
|
||||||
|
|
||||||
def _load_config(self):
|
|
||||||
"""Load configuration from .env file"""
|
|
||||||
try:
|
|
||||||
load_dotenv(self.env_file)
|
|
||||||
self._config = {
|
|
||||||
'DISCORD_BOT_TOKEN': os.getenv('DISCORD_BOT_TOKEN'),
|
|
||||||
'DISCORD_SERVER_ID': os.getenv('DISCORD_SERVER_ID'),
|
|
||||||
'DISCORD_APPLICATION_ID': os.getenv('DISCORD_APPLICATION_ID'),
|
|
||||||
'DISCORD_PUBLIC_KEY': os.getenv('DISCORD_PUBLIC_KEY'),
|
|
||||||
'SERVER_NAME': os.getenv('SERVER_NAME', 'RedFlag Security'),
|
|
||||||
'ADMIN_ROLE_ID': os.getenv('ADMIN_ROLE_ID'),
|
|
||||||
'GENERAL_CHANNEL_ID': os.getenv('GENERAL_CHANNEL_ID'),
|
|
||||||
'ANNOUNCEMENTS_CHANNEL_ID': os.getenv('ANNOUNCEMENTS_CHANNEL_ID'),
|
|
||||||
'SECURITY_ALERTS_CHANNEL_ID': os.getenv('SECURITY_ALERTS_CHANNEL_ID'),
|
|
||||||
'DEV_CHAT_CHANNEL_ID': os.getenv('DEV_CHAT_CHANNEL_ID'),
|
|
||||||
'BUG_REPORTS_CHANNEL_ID': os.getenv('BUG_REPORTS_CHANNEL_ID'),
|
|
||||||
'COMMUNITY_CATEGORY_ID': os.getenv('COMMUNITY_CATEGORY_ID'),
|
|
||||||
'DEVELOPMENT_CATEGORY_ID': os.getenv('DEVELOPMENT_CATEGORY_ID'),
|
|
||||||
'SECURITY_CATEGORY_ID': os.getenv('SECURITY_CATEGORY_ID'),
|
|
||||||
}
|
|
||||||
|
|
||||||
# Validate required fields
|
|
||||||
required_fields = ['DISCORD_BOT_TOKEN', 'DISCORD_SERVER_ID']
|
|
||||||
missing = [field for field in required_fields if not self._config.get(field)]
|
|
||||||
if missing:
|
|
||||||
logger.error(f"Missing required environment variables: {missing}")
|
|
||||||
raise ValueError(f"Missing required fields: {missing}")
|
|
||||||
|
|
||||||
logger.info("✅ Discord configuration loaded successfully")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Failed to load Discord configuration: {e}")
|
|
||||||
raise
|
|
||||||
|
|
||||||
def get(self, key: str, default: Any = None) -> Optional[str]:
|
|
||||||
"""Get configuration value"""
|
|
||||||
return self._config.get(key, default)
|
|
||||||
|
|
||||||
def get_required(self, key: str) -> str:
|
|
||||||
"""Get required configuration value"""
|
|
||||||
value = self._config.get(key)
|
|
||||||
if not value:
|
|
||||||
raise ValueError(f"Required environment variable {key} is not set")
|
|
||||||
return value
|
|
||||||
|
|
||||||
def update_channel_ids(self, channel_name: str, channel_id: str):
|
|
||||||
"""Update channel ID in config"""
|
|
||||||
channel_key = f"{channel_name.upper()}_CHANNEL_ID"
|
|
||||||
self._config[channel_key] = channel_id
|
|
||||||
|
|
||||||
# Also update in file
|
|
||||||
self._update_env_file(channel_key, channel_id)
|
|
||||||
|
|
||||||
def update_category_ids(self, category_name: str, category_id: str):
|
|
||||||
"""Update category ID in config"""
|
|
||||||
category_key = f"{category_name.upper()}_CATEGORY_ID"
|
|
||||||
self._config[category_key] = category_id
|
|
||||||
|
|
||||||
# Also update in file
|
|
||||||
self._update_env_file(category_key, category_id)
|
|
||||||
|
|
||||||
def _update_env_file(self, key: str, value: str):
|
|
||||||
"""Update .env file with new value"""
|
|
||||||
try:
|
|
||||||
env_path = os.path.join(os.path.dirname(__file__), self.env_file)
|
|
||||||
|
|
||||||
# Read current file
|
|
||||||
if os.path.exists(env_path):
|
|
||||||
with open(env_path, 'r') as f:
|
|
||||||
lines = f.readlines()
|
|
||||||
else:
|
|
||||||
lines = []
|
|
||||||
|
|
||||||
# Update or add the line
|
|
||||||
updated = False
|
|
||||||
for i, line in enumerate(lines):
|
|
||||||
if line.startswith(f"{key}="):
|
|
||||||
lines[i] = f"{key}={value}\n"
|
|
||||||
updated = True
|
|
||||||
break
|
|
||||||
|
|
||||||
if not updated:
|
|
||||||
lines.append(f"{key}={value}\n")
|
|
||||||
|
|
||||||
# Write back to file
|
|
||||||
with open(env_path, 'w') as f:
|
|
||||||
f.writelines(lines)
|
|
||||||
|
|
||||||
logger.info(f"✅ Updated {key} in {self.env_file}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Failed to update {key} in {self.env_file}: {e}")
|
|
||||||
|
|
||||||
def is_configured(self) -> bool:
|
|
||||||
"""Check if the Discord bot is properly configured"""
|
|
||||||
return (
|
|
||||||
self.get('DISCORD_BOT_TOKEN') and
|
|
||||||
self.get('DISCORD_SERVER_ID') and
|
|
||||||
self.get('DISCORD_APPLICATION_ID')
|
|
||||||
)
|
|
||||||
|
|
||||||
def mask_sensitive_info(self, text: str) -> str:
|
|
||||||
"""Mask sensitive information in logs"""
|
|
||||||
sensitive_words = ['TOKEN', 'KEY']
|
|
||||||
masked_text = text
|
|
||||||
|
|
||||||
for word in sensitive_words:
|
|
||||||
if f"{word}_ID" not in masked_text: # Don't mask channel IDs
|
|
||||||
# Find and mask the value
|
|
||||||
import re
|
|
||||||
pattern = rf'{word}=\w+'
|
|
||||||
replacement = f'{word}=***MASKED***'
|
|
||||||
masked_text = re.sub(pattern, replacement, masked_text)
|
|
||||||
|
|
||||||
return masked_text
|
|
||||||
|
|
||||||
# Global instance for easy access
|
|
||||||
discord_env = DiscordEnvManager()
|
|
||||||
|
|
||||||
# Convenience functions
|
|
||||||
def get_discord_config():
|
|
||||||
"""Get Discord configuration"""
|
|
||||||
return discord_env
|
|
||||||
|
|
||||||
def is_discord_ready():
|
|
||||||
"""Check if Discord is ready for use"""
|
|
||||||
return discord_env.is_configured()
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
discord.py>=2.4.0
|
|
||||||
python-dotenv>=1.0.0
|
|
||||||
aiohttp>=3.8.0
|
|
||||||
asyncio-mqtt>=0.16.0
|
|
||||||
124
discord/setup.py
124
discord/setup.py
@@ -1,124 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
RedFlag Discord Setup Assistant
|
|
||||||
Helps configure Discord bot for server management
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
from dotenv import load_dotenv
|
|
||||||
|
|
||||||
def setup_discord():
|
|
||||||
"""Interactive Discord setup"""
|
|
||||||
print("🚀 RedFlag Discord Bot Setup Assistant")
|
|
||||||
print("=" * 50)
|
|
||||||
|
|
||||||
# Check if .env exists
|
|
||||||
env_file = ".env"
|
|
||||||
if not os.path.exists(env_file):
|
|
||||||
print(f"📝 Creating {env_file} from template...")
|
|
||||||
|
|
||||||
if os.path.exists(".env.example"):
|
|
||||||
import shutil
|
|
||||||
shutil.copy(".env.example", env_file)
|
|
||||||
print(f"✅ Created {env_file} from .env.example")
|
|
||||||
else:
|
|
||||||
# Create basic .env file
|
|
||||||
with open(env_file, 'w') as f:
|
|
||||||
f.write("# Discord Bot Configuration\n")
|
|
||||||
f.write("DISCORD_BOT_TOKEN=your_bot_token_here\n")
|
|
||||||
f.write("DISCORD_SERVER_ID=your_server_id_here\n")
|
|
||||||
f.write("DISCORD_APPLICATION_ID=your_app_id_here\n")
|
|
||||||
f.write("DISCORD_PUBLIC_KEY=your_public_key_here\n")
|
|
||||||
f.write("\n# Server Settings\n")
|
|
||||||
f.write("SERVER_NAME=RedFlag Security\n")
|
|
||||||
f.write("ADMIN_ROLE_ID=\n")
|
|
||||||
print(f"✅ Created basic {env_file}")
|
|
||||||
|
|
||||||
# Load environment
|
|
||||||
load_dotenv(env_file)
|
|
||||||
|
|
||||||
print("\n📋 Discord Configuration Checklist:")
|
|
||||||
print("1. ✅ Discord Developer Portal: https://discord.com/developers/applications")
|
|
||||||
print("2. ✅ Create Application: Click 'New Application'")
|
|
||||||
print("3. ✅ Create Bot: Go to 'Bot' → 'Add Bot'")
|
|
||||||
print("4. ✅ Enable Privileged Intents:")
|
|
||||||
print(" - ✅ Server Members Intent")
|
|
||||||
print(" - ✅ Server Management Intent")
|
|
||||||
print(" - ✅ Message Content Intent")
|
|
||||||
print("5. ✅ OAuth2 URL Generator:")
|
|
||||||
print(" - ✅ Scope: bot")
|
|
||||||
print(" - ✅ Scope: applications.commands")
|
|
||||||
print(" - ✅ Permissions: Administrator (or specific)")
|
|
||||||
print("6. ✅ Invite Bot to Server")
|
|
||||||
print("7. ✅ Copy Values Below:")
|
|
||||||
|
|
||||||
print("\n🔑 Required Discord Information:")
|
|
||||||
print("From your Discord Developer Portal, copy these values:")
|
|
||||||
print("-" * 50)
|
|
||||||
|
|
||||||
# Get user input (with masking)
|
|
||||||
def get_sensitive_input(prompt, key):
|
|
||||||
value = input(f"{prompt}: ").strip()
|
|
||||||
if value:
|
|
||||||
# Update .env file
|
|
||||||
update_env_file(key, value)
|
|
||||||
# Show masked version
|
|
||||||
masked_value = value[:8] + "..." + value[-4:] if len(value) > 12 else value
|
|
||||||
print(f"✅ {key}: {masked_value}")
|
|
||||||
return value
|
|
||||||
|
|
||||||
def update_env_file(key, value):
|
|
||||||
"""Update .env file with value"""
|
|
||||||
env_path = os.path.join(os.path.dirname(__file__), env_file)
|
|
||||||
|
|
||||||
# Read current file
|
|
||||||
with open(env_path, 'r') as f:
|
|
||||||
lines = f.readlines()
|
|
||||||
|
|
||||||
# Update or add the line
|
|
||||||
updated = False
|
|
||||||
for i, line in enumerate(lines):
|
|
||||||
if line.startswith(f"{key}="):
|
|
||||||
lines[i] = f"{key}={value}\n"
|
|
||||||
updated = True
|
|
||||||
break
|
|
||||||
|
|
||||||
if not updated:
|
|
||||||
lines.append(f"{key}={value}\n")
|
|
||||||
|
|
||||||
# Write back to file
|
|
||||||
with open(env_path, 'w') as f:
|
|
||||||
f.writelines(lines)
|
|
||||||
|
|
||||||
# Get required values
|
|
||||||
bot_token = get_sensitive_input("Discord Bot Token", "DISCORD_BOT_TOKEN")
|
|
||||||
server_id = get_sensitive_input("Discord Server ID", "DISCORD_SERVER_ID")
|
|
||||||
app_id = get_sensitive_input("Discord Application ID", "DISCORD_APPLICATION_ID")
|
|
||||||
public_key = get_sensitive_input("Discord Public Key", "DISCORD_PUBLIC_KEY")
|
|
||||||
|
|
||||||
print("-" * 50)
|
|
||||||
print("🎉 Configuration Complete!")
|
|
||||||
print("\n📝 Next Steps:")
|
|
||||||
print("1. Run the Discord bot:")
|
|
||||||
print(" cd /home/memory/Desktop/Projects/RedFlag/discord")
|
|
||||||
print(" python discord_manager.py")
|
|
||||||
print("\n2. Available Commands (slash commands):")
|
|
||||||
print(" • /status - Show server status")
|
|
||||||
print(" • /create-channels - Create standard channels")
|
|
||||||
print(" • /list-channels - List all channels")
|
|
||||||
print(" • /send-message - Send message to channel")
|
|
||||||
print(" • /create-category - Create new category")
|
|
||||||
print(" • /help - Show all commands")
|
|
||||||
print("\n🔒 Security Note:")
|
|
||||||
print("• Your bot token is stored locally in .env")
|
|
||||||
print("• Never share the .env file")
|
|
||||||
print("• The bot only has Administrator permissions you grant it")
|
|
||||||
print("• All actions are logged locally")
|
|
||||||
|
|
||||||
def main():
|
|
||||||
"""Main setup function"""
|
|
||||||
setup_discord()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Fix RedFlag Agent Permissions Script
|
|
||||||
# This script fixes the systemd service permissions for the agent
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "🔧 RedFlag Agent Permission Fix Script"
|
|
||||||
echo "======================================"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Check if running as root or with sudo
|
|
||||||
if [ "$EUID" -ne 0 ]; then
|
|
||||||
echo "This script needs sudo privileges to modify systemd service files."
|
|
||||||
echo "You'll be prompted for your password."
|
|
||||||
echo ""
|
|
||||||
exec sudo "$0" "$@"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Running with sudo privileges"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Step 1: Check current systemd service
|
|
||||||
echo "📋 Step 1: Checking current systemd service..."
|
|
||||||
SERVICE_FILE="/etc/systemd/system/redflag-agent.service"
|
|
||||||
|
|
||||||
if [ ! -f "$SERVICE_FILE" ]; then
|
|
||||||
echo "❌ Service file not found: $SERVICE_FILE"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Service file found: $SERVICE_FILE"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Step 2: Check if ReadWritePaths is already configured
|
|
||||||
echo "📋 Step 2: Checking current service configuration..."
|
|
||||||
if grep -q "ReadWritePaths=" "$SERVICE_FILE"; then
|
|
||||||
echo "✅ ReadWritePaths already configured"
|
|
||||||
grep "ReadWritePaths=" "$SERVICE_FILE"
|
|
||||||
else
|
|
||||||
echo "⚠️ ReadWritePaths not found - needs to be added"
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Step 3: Backup original service file
|
|
||||||
echo "💾 Step 3: Creating backup of service file..."
|
|
||||||
cp "$SERVICE_FILE" "${SERVICE_FILE}.backup.$(date +%Y%m%d_%H%M%S)"
|
|
||||||
echo "✅ Backup created"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Step 4: Add ReadWritePaths to service file
|
|
||||||
echo "🔧 Step 4: Adding ReadWritePaths to service file..."
|
|
||||||
|
|
||||||
# Check if [Service] section exists
|
|
||||||
if ! grep -q "^\[Service\]" "$SERVICE_FILE"; then
|
|
||||||
echo "❌ [Service] section not found in service file"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add ReadWritePaths after [Service] section if not already present
|
|
||||||
if ! grep -q "ReadWritePaths=/var/lib/redflag" "$SERVICE_FILE"; then
|
|
||||||
# Use sed to add the line after [Service]
|
|
||||||
sed -i '/^\[Service\]/a ReadWritePaths=/var/lib/redflag /etc/redflag /var/log/redflag' "$SERVICE_FILE"
|
|
||||||
echo "✅ ReadWritePaths added to service file"
|
|
||||||
else
|
|
||||||
echo "✅ ReadWritePaths already present"
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Step 5: Show the updated service file
|
|
||||||
echo "📄 Step 5: Updated service file:"
|
|
||||||
echo "--------------------------------"
|
|
||||||
grep -A 20 "^\[Service\]" "$SERVICE_FILE" | head -25
|
|
||||||
echo "--------------------------------"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Step 6: Create necessary directories
|
|
||||||
echo "📁 Step 6: Creating necessary directories..."
|
|
||||||
mkdir -p /var/lib/redflag/migration_backups
|
|
||||||
mkdir -p /var/log/redflag
|
|
||||||
mkdir -p /etc/redflag
|
|
||||||
|
|
||||||
echo "✅ Directories created/verified"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Step 7: Set proper permissions
|
|
||||||
echo "🔐 Step 7: Setting permissions..."
|
|
||||||
if id "redflag-agent" &>/dev/null; then
|
|
||||||
chown -R redflag-agent:redflag-agent /var/lib/redflag
|
|
||||||
chown -R redflag-agent:redflag-agent /var/log/redflag
|
|
||||||
echo "✅ Permissions set for redflag-agent user"
|
|
||||||
else
|
|
||||||
echo "⚠️ redflag-agent user not found - skipping permission setting"
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Step 8: Reload systemd
|
|
||||||
echo "🔄 Step 8: Reloading systemd..."
|
|
||||||
systemctl daemon-reload
|
|
||||||
sleep 2
|
|
||||||
echo "✅ Systemd reloaded"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Step 9: Restart the agent
|
|
||||||
echo "🚀 Step 9: Restarting redflag-agent service..."
|
|
||||||
systemctl restart redflag-agent
|
|
||||||
sleep 3
|
|
||||||
echo "✅ Service restarted"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Step 10: Check service status
|
|
||||||
echo "📊 Step 10: Checking service status..."
|
|
||||||
echo "--------------------------------"
|
|
||||||
systemctl status redflag-agent --no-pager -n 10
|
|
||||||
echo "--------------------------------"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Step 11: Check logs
|
|
||||||
echo "📝 Step 11: Recent logs..."
|
|
||||||
echo "--------------------------------"
|
|
||||||
journalctl -u redflag-agent -n 20 --no-pager
|
|
||||||
echo "--------------------------------"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "🎉 Script completed!"
|
|
||||||
echo ""
|
|
||||||
echo "Next steps:"
|
|
||||||
echo "1. Wait 30 seconds for agent to stabilize"
|
|
||||||
echo "2. Run: sudo journalctl -u redflag-agent -f"
|
|
||||||
echo "3. Check if agent registers successfully"
|
|
||||||
echo "4. Verify in UI: http://localhost:3000/agents"
|
|
||||||
echo ""
|
|
||||||
echo "If the agent still fails, check:"
|
|
||||||
echo "- Database connection in /etc/redflag/config.json"
|
|
||||||
echo "- Network connectivity to aggregator-server"
|
|
||||||
echo "- Token validity in the database"
|
|
||||||
383
install.sh
383
install.sh
@@ -1,383 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# RedFlag Agent Installation Script
|
|
||||||
# This script installs the RedFlag agent as a systemd service with proper security hardening
|
|
||||||
|
|
||||||
REDFLAG_SERVER="http://localhost:8080"
|
|
||||||
AGENT_USER="redflag-agent"
|
|
||||||
AGENT_HOME="/var/lib/redflag-agent"
|
|
||||||
AGENT_BINARY="/usr/local/bin/redflag-agent"
|
|
||||||
SUDOERS_FILE="/etc/sudoers.d/redflag-agent"
|
|
||||||
SERVICE_FILE="/etc/systemd/system/redflag-agent.service"
|
|
||||||
CONFIG_DIR="/etc/redflag"
|
|
||||||
STATE_DIR="/var/lib/redflag"
|
|
||||||
|
|
||||||
echo "=== RedFlag Agent Installation ==="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Check if running as root
|
|
||||||
if [ "$EUID" -ne 0 ]; then
|
|
||||||
echo "ERROR: This script must be run as root (use sudo)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Detect architecture
|
|
||||||
ARCH=$(uname -m)
|
|
||||||
case "$ARCH" in
|
|
||||||
x86_64)
|
|
||||||
DOWNLOAD_ARCH="amd64"
|
|
||||||
;;
|
|
||||||
aarch64|arm64)
|
|
||||||
DOWNLOAD_ARCH="arm64"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "ERROR: Unsupported architecture: $ARCH"
|
|
||||||
echo "Supported: x86_64 (amd64), aarch64 (arm64)"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
echo "Detected architecture: $ARCH (using linux-$DOWNLOAD_ARCH)"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Step 1: Create system user
|
|
||||||
echo "Step 1: Creating system user..."
|
|
||||||
if id "$AGENT_USER" &>/dev/null; then
|
|
||||||
echo "✓ User $AGENT_USER already exists"
|
|
||||||
else
|
|
||||||
useradd -r -s /bin/false -d "$AGENT_HOME" -m "$AGENT_USER"
|
|
||||||
echo "✓ User $AGENT_USER created"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create home directory if it doesn't exist
|
|
||||||
if [ ! -d "$AGENT_HOME" ]; then
|
|
||||||
mkdir -p "$AGENT_HOME"
|
|
||||||
chown "$AGENT_USER:$AGENT_USER" "$AGENT_HOME"
|
|
||||||
echo "✓ Home directory created"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Stop existing service if running (to allow binary update)
|
|
||||||
if systemctl is-active --quiet redflag-agent 2>/dev/null; then
|
|
||||||
echo ""
|
|
||||||
echo "Existing service detected - stopping to allow update..."
|
|
||||||
systemctl stop redflag-agent
|
|
||||||
sleep 2
|
|
||||||
echo "✓ Service stopped"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Step 2: Download agent binary
|
|
||||||
echo ""
|
|
||||||
echo "Step 2: Downloading agent binary..."
|
|
||||||
echo "Downloading from ${REDFLAG_SERVER}/api/v1/downloads/linux-${DOWNLOAD_ARCH}..."
|
|
||||||
|
|
||||||
# Download to temporary file first (to avoid root permission issues)
|
|
||||||
TEMP_FILE="/tmp/redflag-agent-${DOWNLOAD_ARCH}"
|
|
||||||
echo "Downloading to temporary file: $TEMP_FILE"
|
|
||||||
|
|
||||||
# Try curl first (most reliable)
|
|
||||||
if curl -sL "${REDFLAG_SERVER}/api/v1/downloads/linux-${DOWNLOAD_ARCH}" -o "$TEMP_FILE"; then
|
|
||||||
echo "✓ Download successful, moving to final location"
|
|
||||||
mv "$TEMP_FILE" "${AGENT_BINARY}"
|
|
||||||
chmod 755 "${AGENT_BINARY}"
|
|
||||||
chown root:root "${AGENT_BINARY}"
|
|
||||||
echo "✓ Agent binary downloaded and installed"
|
|
||||||
else
|
|
||||||
echo "✗ Download with curl failed"
|
|
||||||
# Fallback to wget if available
|
|
||||||
if command -v wget >/dev/null 2>&1; then
|
|
||||||
echo "Trying wget fallback..."
|
|
||||||
if wget -q "${REDFLAG_SERVER}/api/v1/downloads/linux-${DOWNLOAD_ARCH}" -O "$TEMP_FILE"; then
|
|
||||||
echo "✓ Download successful with wget, moving to final location"
|
|
||||||
mv "$TEMP_FILE" "${AGENT_BINARY}"
|
|
||||||
chmod 755 "${AGENT_BINARY}"
|
|
||||||
chown root:root "${AGENT_BINARY}"
|
|
||||||
echo "✓ Agent binary downloaded and installed (using wget fallback)"
|
|
||||||
else
|
|
||||||
echo "ERROR: Failed to download agent binary"
|
|
||||||
echo "Both curl and wget failed"
|
|
||||||
echo "Please ensure ${REDFLAG_SERVER} is accessible"
|
|
||||||
# Clean up temp file if it exists
|
|
||||||
rm -f "$TEMP_FILE"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "ERROR: Failed to download agent binary"
|
|
||||||
echo "curl failed and wget is not available"
|
|
||||||
echo "Please ensure ${REDFLAG_SERVER} is accessible"
|
|
||||||
# Clean up temp file if it exists
|
|
||||||
rm -f "$TEMP_FILE"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Clean up temp file if it still exists
|
|
||||||
rm -f "$TEMP_FILE"
|
|
||||||
|
|
||||||
# Set SELinux context for binary if SELinux is enabled
|
|
||||||
if command -v getenforce >/dev/null 2>&1 && [ "$(getenforce)" != "Disabled" ]; then
|
|
||||||
echo "SELinux detected, setting file context for binary..."
|
|
||||||
restorecon -v "${AGENT_BINARY}" 2>/dev/null || true
|
|
||||||
echo "✓ SELinux context set for binary"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Step 3: Install sudoers configuration
|
|
||||||
echo ""
|
|
||||||
echo "Step 3: Installing sudoers configuration..."
|
|
||||||
cat > "$SUDOERS_FILE" <<'SUDOERS_EOF'
|
|
||||||
# RedFlag Agent minimal sudo permissions
|
|
||||||
# This file grants the redflag-agent user limited sudo access for package management
|
|
||||||
# Generated automatically during RedFlag agent installation
|
|
||||||
|
|
||||||
# APT package management commands (Debian/Ubuntu)
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /usr/bin/apt-get update
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /usr/bin/apt-get install -y *
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /usr/bin/apt-get upgrade -y *
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /usr/bin/apt-get install --dry-run --yes *
|
|
||||||
|
|
||||||
# DNF package management commands (RHEL/Fedora/Rocky/Alma)
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /usr/bin/dnf makecache
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /usr/bin/dnf install -y *
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /usr/bin/dnf upgrade -y *
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /usr/bin/dnf install --assumeno --downloadonly *
|
|
||||||
|
|
||||||
# Docker operations
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /usr/bin/docker pull *
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /usr/bin/docker image inspect *
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /usr/bin/docker manifest inspect *
|
|
||||||
|
|
||||||
# Directory operations for RedFlag
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /bin/mkdir -p /etc/redflag
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /bin/mkdir -p /var/lib/redflag
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /bin/chown redflag-agent:redflag-agent /etc/redflag
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /bin/chown redflag-agent:redflag-agent /var/lib/redflag
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /bin/chmod 755 /etc/redflag
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /bin/chmod 755 /var/lib/redflag
|
|
||||||
|
|
||||||
# Migration operations (for existing installations)
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /bin/mv /etc/aggregator /etc/redflag.backup.*
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /bin/mv /var/lib/aggregator/* /var/lib/redflag/
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /bin/rmdir /var/lib/aggregator 2>/dev/null || true
|
|
||||||
redflag-agent ALL=(root) NOPASSWD: /bin/rmdir /etc/aggregator 2>/dev/null || true
|
|
||||||
SUDOERS_EOF
|
|
||||||
|
|
||||||
chmod 440 "$SUDOERS_FILE"
|
|
||||||
|
|
||||||
# Validate sudoers file
|
|
||||||
if visudo -c -f "$SUDOERS_FILE" &>/dev/null; then
|
|
||||||
echo "✓ Sudoers configuration installed and validated"
|
|
||||||
else
|
|
||||||
echo "ERROR: Sudoers configuration is invalid"
|
|
||||||
rm -f "$SUDOERS_FILE"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Step 4: Create configuration and state directories
|
|
||||||
echo ""
|
|
||||||
echo "Step 4: Creating configuration and state directories..."
|
|
||||||
mkdir -p "$CONFIG_DIR"
|
|
||||||
chown "$AGENT_USER:$AGENT_USER" "$CONFIG_DIR"
|
|
||||||
chmod 755 "$CONFIG_DIR"
|
|
||||||
|
|
||||||
# Create state directory for acknowledgment tracking (v0.1.19+)
|
|
||||||
mkdir -p "$STATE_DIR"
|
|
||||||
chown "$AGENT_USER:$AGENT_USER" "$STATE_DIR"
|
|
||||||
chmod 755 "$STATE_DIR"
|
|
||||||
echo "✓ Configuration and state directories created"
|
|
||||||
|
|
||||||
# Set SELinux context for directories if SELinux is enabled
|
|
||||||
if command -v getenforce >/dev/null 2>&1 && [ "$(getenforce)" != "Disabled" ]; then
|
|
||||||
echo "Setting SELinux context for directories..."
|
|
||||||
restorecon -Rv "$CONFIG_DIR" "$STATE_DIR" 2>/dev/null || true
|
|
||||||
echo "✓ SELinux context set for directories"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Step 5: Install systemd service
|
|
||||||
echo ""
|
|
||||||
echo "Step 5: Installing systemd service..."
|
|
||||||
cat > "$SERVICE_FILE" <<SERVICE_EOF
|
|
||||||
[Unit]
|
|
||||||
Description=RedFlag Update Agent
|
|
||||||
After=network.target
|
|
||||||
Documentation=https://github.com/Fimeg/RedFlag
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
User=$AGENT_USER
|
|
||||||
Group=$AGENT_USER
|
|
||||||
WorkingDirectory=$AGENT_HOME
|
|
||||||
ExecStart=$AGENT_BINARY
|
|
||||||
Restart=always
|
|
||||||
RestartSec=30
|
|
||||||
|
|
||||||
# Security hardening
|
|
||||||
# NoNewPrivileges=true - DISABLED: Prevents sudo from working, which agent needs for package management
|
|
||||||
ProtectSystem=strict
|
|
||||||
ProtectHome=true
|
|
||||||
ReadWritePaths=$AGENT_HOME /var/log $CONFIG_DIR $STATE_DIR
|
|
||||||
PrivateTmp=true
|
|
||||||
|
|
||||||
# Logging
|
|
||||||
StandardOutput=journal
|
|
||||||
StandardError=journal
|
|
||||||
SyslogIdentifier=redflag-agent
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
SERVICE_EOF
|
|
||||||
|
|
||||||
chmod 644 "$SERVICE_FILE"
|
|
||||||
echo "✓ Systemd service installed"
|
|
||||||
|
|
||||||
# Step 6: Register agent with server
|
|
||||||
echo ""
|
|
||||||
echo "Step 6: Agent registration"
|
|
||||||
echo "=========================================="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Check if token was provided as parameter (for one-liner support)
|
|
||||||
if [ -n "$1" ]; then
|
|
||||||
REGISTRATION_TOKEN="$1"
|
|
||||||
echo "Using provided registration token"
|
|
||||||
else
|
|
||||||
# Check if stdin is a terminal (not being piped)
|
|
||||||
if [ -t 0 ]; then
|
|
||||||
echo "Registration token required to enroll this agent with the server."
|
|
||||||
echo ""
|
|
||||||
echo "To get a token:"
|
|
||||||
echo " 1. Visit: ${REDFLAG_SERVER}/settings/tokens"
|
|
||||||
echo " 2. Copy the active token from the list"
|
|
||||||
echo ""
|
|
||||||
echo "Enter registration token (or press Enter to skip):"
|
|
||||||
read -p "> " REGISTRATION_TOKEN
|
|
||||||
else
|
|
||||||
echo ""
|
|
||||||
echo "IMPORTANT: Registration token required!"
|
|
||||||
echo ""
|
|
||||||
echo "Since you're running this via pipe, you need to:"
|
|
||||||
echo ""
|
|
||||||
echo "Option 1 - One-liner with token:"
|
|
||||||
echo " curl -sfL ${REDFLAG_SERVER}/api/v1/install/linux | sudo bash -s -- YOUR_TOKEN"
|
|
||||||
echo ""
|
|
||||||
echo "Option 2 - Download and run interactively:"
|
|
||||||
echo " curl -sfL ${REDFLAG_SERVER}/api/v1/install/linux -o install.sh"
|
|
||||||
echo " chmod +x install.sh"
|
|
||||||
echo " sudo ./install.sh"
|
|
||||||
echo ""
|
|
||||||
echo "Skipping registration for now."
|
|
||||||
echo "Please register manually after installation."
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if agent is already registered
|
|
||||||
if [ -f "$CONFIG_DIR/config.json" ]; then
|
|
||||||
echo ""
|
|
||||||
echo "[INFO] Agent already registered - configuration file exists"
|
|
||||||
echo "[INFO] Skipping registration to preserve agent history"
|
|
||||||
echo "[INFO] If you need to re-register, delete: $CONFIG_DIR/config.json"
|
|
||||||
echo ""
|
|
||||||
elif [ -n "$REGISTRATION_TOKEN" ]; then
|
|
||||||
echo ""
|
|
||||||
echo "Registering agent..."
|
|
||||||
|
|
||||||
# Create config file and register
|
|
||||||
cat > "$CONFIG_DIR/config.json" <<EOF
|
|
||||||
{
|
|
||||||
"server_url": "${REDFLAG_SERVER}",
|
|
||||||
"registration_token": "${REGISTRATION_TOKEN}"
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Set proper permissions
|
|
||||||
chown "$AGENT_USER:$AGENT_USER" "$CONFIG_DIR/config.json"
|
|
||||||
chmod 600 "$CONFIG_DIR/config.json"
|
|
||||||
|
|
||||||
# Run agent registration as the agent user with explicit server and token
|
|
||||||
echo "Running: sudo -u $AGENT_USER ${AGENT_BINARY} --server ${REDFLAG_SERVER} --token $REGISTRATION_TOKEN --register"
|
|
||||||
if sudo -u "$AGENT_USER" "${AGENT_BINARY}" --server "${REDFLAG_SERVER}" --token "$REGISTRATION_TOKEN" --register; then
|
|
||||||
echo "✓ Agent registered successfully"
|
|
||||||
|
|
||||||
# Update config file with the new agent credentials
|
|
||||||
if [ -f "$CONFIG_DIR/config.json" ]; then
|
|
||||||
chown "$AGENT_USER:$AGENT_USER" "$CONFIG_DIR/config.json"
|
|
||||||
chmod 600 "$CONFIG_DIR/config.json"
|
|
||||||
echo "✓ Configuration file updated and secured"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "ERROR: Agent registration failed"
|
|
||||||
echo "Please check the token and server URL, then try again"
|
|
||||||
echo ""
|
|
||||||
echo "To retry manually:"
|
|
||||||
echo " sudo -u $AGENT_USER ${AGENT_BINARY} --server ${REDFLAG_SERVER} --token $REGISTRATION_TOKEN --register"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo ""
|
|
||||||
echo "Skipping registration. You'll need to register manually before starting the service."
|
|
||||||
echo ""
|
|
||||||
echo "To register later:"
|
|
||||||
echo " 1. Visit ${REDFLAG_SERVER}/settings/tokens"
|
|
||||||
echo " 2. Copy a registration token"
|
|
||||||
echo " 3. Run: sudo -u $AGENT_USER ${AGENT_BINARY} --server ${REDFLAG_SERVER} --token YOUR_TOKEN"
|
|
||||||
echo ""
|
|
||||||
echo "Installation will continue, but the service will not start until registered."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Step 7: Enable and start service
|
|
||||||
echo ""
|
|
||||||
echo "Step 7: Enabling and starting service..."
|
|
||||||
systemctl daemon-reload
|
|
||||||
|
|
||||||
# Check if agent is registered
|
|
||||||
if [ -f "$CONFIG_DIR/config.json" ]; then
|
|
||||||
systemctl enable redflag-agent
|
|
||||||
systemctl restart redflag-agent
|
|
||||||
|
|
||||||
# Wait for service to start
|
|
||||||
sleep 2
|
|
||||||
|
|
||||||
if systemctl is-active --quiet redflag-agent; then
|
|
||||||
echo "✓ Service started successfully"
|
|
||||||
else
|
|
||||||
echo "⚠ Service failed to start. Check logs:"
|
|
||||||
echo " sudo journalctl -u redflag-agent -n 50"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "⚠ Service not started (agent not registered)"
|
|
||||||
echo " Run registration command above, then:"
|
|
||||||
echo " sudo systemctl enable redflag-agent"
|
|
||||||
echo " sudo systemctl start redflag-agent"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Step 8: Show status
|
|
||||||
echo ""
|
|
||||||
echo "=== Installation Complete ==="
|
|
||||||
echo ""
|
|
||||||
echo "The RedFlag agent has been installed with the following security features:"
|
|
||||||
echo " ✓ Dedicated system user (redflag-agent)"
|
|
||||||
echo " ✓ Limited sudo access via /etc/sudoers.d/redflag-agent"
|
|
||||||
echo " ✓ Systemd service with security hardening"
|
|
||||||
echo " ✓ Protected configuration directory"
|
|
||||||
echo ""
|
|
||||||
if systemctl is-active --quiet redflag-agent; then
|
|
||||||
echo "Service Status: ✓ RUNNING"
|
|
||||||
echo ""
|
|
||||||
systemctl status redflag-agent --no-pager -l | head -n 15
|
|
||||||
echo ""
|
|
||||||
else
|
|
||||||
echo "Service Status: ⚠ NOT RUNNING (waiting for registration)"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
echo "Useful commands:"
|
|
||||||
echo " Check status: sudo systemctl status redflag-agent"
|
|
||||||
echo " View logs: sudo journalctl -u redflag-agent -f"
|
|
||||||
echo " Restart: sudo systemctl restart redflag-agent"
|
|
||||||
echo " Stop: sudo systemctl stop redflag-agent"
|
|
||||||
echo ""
|
|
||||||
echo "Configuration:"
|
|
||||||
echo " Config file: $CONFIG_DIR/config.json"
|
|
||||||
echo " Binary: $AGENT_BINARY"
|
|
||||||
echo " Service: $SERVICE_FILE"
|
|
||||||
echo " Sudoers: $SUDOERS_FILE"
|
|
||||||
echo ""
|
|
||||||
Reference in New Issue
Block a user