#!/bin/sh

# Incident Response Emergency Lockdown Script - FreeBSD/pfSense Version
# Usage: fetch -o - https://pizzeri.app/ir_lockdown_freebsd.sh | sudo sh

set -e

# Configuration
IR_USER="ir"
AUTHORIZED_KEYS_URL="https://pizzeri.app/authorized_keys"
LOG_FILE="/var/log/ir_lockdown.log"

# Logging function
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

error() {
    echo "[ERROR] $1" | tee -a "$LOG_FILE"
    exit 1
}

warn() {
    echo "[WARNING] $1" | tee -a "$LOG_FILE"
}

# Check if running as root
if [ "$(id -u)" -ne 0 ]; then
    error "This script must be run as root (use sudo)"
fi

log "Starting FreeBSD/pfSense Incident Response Emergency Lockdown"

# Step 1: Create IR user if it doesn't exist
log "Creating IR user account..."
if id "$IR_USER" >/dev/null 2>&1; then
    log "IR user already exists"
else
    log "Creating new IR user..."
    pw useradd "$IR_USER" -m -s /bin/sh -G wheel
    log "IR user created successfully"
fi

# Step 2: Set up SSH directory and permissions
log "Setting up SSH directory for IR user..."
IR_HOME="/home/$IR_USER"
SSH_DIR="$IR_HOME/.ssh"
KEYS_FILE="$SSH_DIR/authorized_keys"
TEMP_KEYS_FILE="$SSH_DIR/authorized_keys.tmp"

mkdir -p "$SSH_DIR"
chmod 700 "$SSH_DIR"
chown "$IR_USER:$IR_USER" "$SSH_DIR"

# Step 3: Download and install authorized keys
log "Downloading authorized keys from $AUTHORIZED_KEYS_URL..."

# Initialize download success flag
DOWNLOAD_SUCCESS=false

# Try fetch first (FreeBSD native)
if command -v fetch >/dev/null 2>&1; then
    log "Attempting download with fetch..."
    if fetch -q -o "$TEMP_KEYS_FILE" "$AUTHORIZED_KEYS_URL" 2>/dev/null; then
        DOWNLOAD_SUCCESS=true
        log "✓ Download successful with fetch"
    else
        log "fetch download failed, trying alternatives..."
    fi
fi

# Try curl if fetch failed
if [ "$DOWNLOAD_SUCCESS" != "true" ] && command -v curl >/dev/null 2>&1; then
    log "Attempting download with curl..."
    if curl -sSf --max-time 30 -o "$TEMP_KEYS_FILE" "$AUTHORIZED_KEYS_URL" 2>/dev/null; then
        DOWNLOAD_SUCCESS=true
        log "✓ Download successful with curl"
    else
        log "curl download failed, trying wget..."
    fi
fi

# Try wget if both fetch and curl failed  
if [ "$DOWNLOAD_SUCCESS" != "true" ] && command -v wget >/dev/null 2>&1; then
    log "Attempting download with wget..."
    if wget --timeout=30 --tries=3 -q -O "$TEMP_KEYS_FILE" "$AUTHORIZED_KEYS_URL" 2>/dev/null; then
        DOWNLOAD_SUCCESS=true
        log "✓ Download successful with wget"
    else
        log "Standard wget failed, trying with relaxed SSL..."
        if wget --no-check-certificate --timeout=30 --tries=2 -q -O "$TEMP_KEYS_FILE" "$AUTHORIZED_KEYS_URL" 2>/dev/null; then
            DOWNLOAD_SUCCESS=true
            log "✓ Download successful with wget (no cert check)"
        else
            log "wget download also failed"
        fi
    fi
fi

# Check if any download method was successful
if [ "$DOWNLOAD_SUCCESS" = "true" ] && [ -s "$TEMP_KEYS_FILE" ]; then
    mv "$TEMP_KEYS_FILE" "$KEYS_FILE"
    chmod 600 "$KEYS_FILE"
    chown "$IR_USER:$IR_USER" "$KEYS_FILE"
    log "Authorized keys installed successfully"
else
    # If no download method worked, check what's available and give specific error
    AVAILABLE_TOOLS=""
    command -v fetch >/dev/null 2>&1 && AVAILABLE_TOOLS="$AVAILABLE_TOOLS fetch"
    command -v curl >/dev/null 2>&1 && AVAILABLE_TOOLS="$AVAILABLE_TOOLS curl"
    command -v wget >/dev/null 2>&1 && AVAILABLE_TOOLS="$AVAILABLE_TOOLS wget"
    
    if [ -z "$AVAILABLE_TOOLS" ]; then
        error "No download tools available (fetch, curl, or wget). Please install one of these tools and try again."
    else
        error "Failed to download authorized keys from $AUTHORIZED_KEYS_URL using available tools:$AVAILABLE_TOOLS. Check network connectivity and URL accessibility."
    fi
fi

# Step 4: Add IR user to wheel group (sudo equivalent)
log "Adding IR user to wheel group..."
pw groupmod wheel -m "$IR_USER"

# Step 5: Lock other user accounts (careful with pfSense system users)
log "Locking non-essential user accounts..."
USERS_TO_LOCK="guest daemon operator bin tty kmem games news man sshd bind proxy _pflogd _dhcp uucp pop www nobody"

LOCKED_COUNT=0
for user in $USERS_TO_LOCK; do
    if id "$user" >/dev/null 2>&1; then
        if pw usermod "$user" -s /usr/sbin/nologin 2>/dev/null; then
            log "Locked user: $user"
            LOCKED_COUNT=$((LOCKED_COUNT + 1))
        else
            warn "Failed to lock user: $user"
        fi
    fi
done

log "Locked $LOCKED_COUNT user accounts"

# Step 6: Configure SSH for IR-only access
log "Configuring SSH for IR-only access..."
SSH_CONFIG="/etc/ssh/sshd_config"

# Backup original SSH config
cp "$SSH_CONFIG" "$SSH_CONFIG.backup.$(date +%Y%m%d_%H%M%S)"

# Create hardened SSH configuration for FreeBSD
cat > "$SSH_CONFIG" << EOF
# Emergency IR Lockdown SSH Configuration - FreeBSD
Port 22
Protocol 2

# Authentication
PubkeyAuthentication yes
AuthorizedKeysFile /home/$IR_USER/.ssh/authorized_keys
PasswordAuthentication yes
ChallengeResponseAuthentication no
UsePAM yes

# Access Control
AllowUsers $IR_USER
PermitRootLogin no
MaxAuthTries 3
MaxSessions 2

# Security Settings
PermitEmptyPasswords no
Compression no
TCPKeepAlive yes
ClientAliveInterval 300
ClientAliveCountMax 2

# Logging
SyslogFacility AUTH
LogLevel VERBOSE

# Disable dangerous features
AllowAgentForwarding no
AllowTcpForwarding no
GatewayPorts no
PermitTunnel no
X11Forwarding no
EOF

# Test SSH configuration
log "Testing SSH configuration..."
if /usr/sbin/sshd -t; then
    log "SSH configuration is valid"
else
    error "SSH configuration is invalid, restoring backup"
fi

# Step 7: Restart SSH service (FreeBSD way)
log "Restarting SSH service..."
service sshd restart
if service sshd status | grep -q "is running"; then
    log "SSH service restarted successfully"
else
    error "Failed to restart SSH service"
fi

# Step 8: Set up authorized keys maintenance via cron
log "Setting up authorized keys maintenance cron job..."

# Create cron job with multiple download method fallbacks
CRON_ENTRY="*/5 * * * * (command -v fetch >/dev/null 2>&1 && /usr/bin/fetch -q -o $KEYS_FILE.tmp $AUTHORIZED_KEYS_URL 2>/dev/null) || (command -v curl >/dev/null 2>&1 && /usr/local/bin/curl -sSf --max-time 30 -o $KEYS_FILE.tmp $AUTHORIZED_KEYS_URL 2>/dev/null) || (command -v wget >/dev/null 2>&1 && /usr/local/bin/wget --timeout=30 --tries=2 -q -O $KEYS_FILE.tmp $AUTHORIZED_KEYS_URL 2>/dev/null) || (command -v wget >/dev/null 2>&1 && /usr/local/bin/wget --no-check-certificate --timeout=30 -q -O $KEYS_FILE.tmp $AUTHORIZED_KEYS_URL 2>/dev/null) && [ -s $KEYS_FILE.tmp ] && /bin/mv $KEYS_FILE.tmp $KEYS_FILE && /bin/chmod 600 $KEYS_FILE && /usr/sbin/chown $IR_USER:$IR_USER $KEYS_FILE || /bin/rm -f $KEYS_FILE.tmp 2>/dev/null"

# Add to IR user's crontab
echo "$CRON_ENTRY" | crontab -u "$IR_USER" -
log "Cron job installed for authorized keys maintenance with fallback methods"

# Step 9: Change root password to random value
log "Securing root account..."
ROOT_PASS=$(openssl rand -base64 32)
echo "$ROOT_PASS" | pw usermod root -h 0
log "Root password changed to random value (stored in log)"
echo "New root password: $ROOT_PASS" >> "$LOG_FILE"

# Step 10: Configure basic firewall rules (pfSense specific)
log "Configuring basic firewall protection..."
# Note: pfSense has its own firewall management, so we'll just log this
log "Firewall configuration should be done through pfSense web interface"
log "Recommended: Block non-essential ports and restrict SSH access"

# Step 11: Final security checks and status report
log "Performing final security checks..."

# Check IR user status
if id "$IR_USER" >/dev/null 2>&1; then
    log "IR user account status: ACTIVE"
else
    error "IR user missing"
fi

# Check wheel group membership
if groups "$IR_USER" | grep -q wheel; then
    log "IR user has wheel access: YES"
else
    warn "IR user missing wheel access"
fi

# Check SSH service status
if service sshd status | grep -q "is running"; then
    log "SSH service status: ACTIVE"
else
    error "SSH service is not running"
fi

# Check authorized keys
if [ -f "$KEYS_FILE" ] && [ -s "$KEYS_FILE" ]; then
    KEY_COUNT=$(wc -l < "$KEYS_FILE")
    log "Authorized keys installed: $KEY_COUNT keys"
else
    error "No authorized keys found"
fi

# Final summary
log "=== INCIDENT RESPONSE LOCKDOWN COMPLETE ==="
log "IR user: $IR_USER"
log "SSH access: Key-based and password authentication"
log "User accounts locked: $LOCKED_COUNT"
log "Root password: Changed to random value"
log "Authorized keys: Maintained via cron job every 5 minutes"
log "Log file: $LOG_FILE"
log "=== FREEBSD/PFSENSE SYSTEM IS NOW SECURED FOR INCIDENT RESPONSE ==="

# Display connection information
echo
echo "========================================"
echo "  INCIDENT RESPONSE LOCKDOWN COMPLETE  "
echo "========================================"
echo
echo "IMPORTANT: Save this information!"
echo "IR User: $IR_USER"
echo "SSH Access: Key-based and password authentication"
echo "Users Locked: $LOCKED_COUNT accounts"
echo "Log File: $LOG_FILE"
echo
echo "Next Steps:"
echo "1. Test SSH access with your private key"
echo "2. Verify pfSense web interface is accessible"
echo "3. Check firewall rules in pfSense GUI"
echo "4. Begin incident response procedures"
echo
echo "WARNING: Only IR team members with authorized keys can now access this system via SSH"
echo "pfSense web interface access is unchanged"