#!/bin/bash
#
# server_audit_notify.sh - Server Audit Notification Script
#
# This script performs server security audits and sends notifications
# via Forward Email's SMTP service when issues are detected.
#
# Usage: ./server_audit_notify.sh [options]
#
# Options:
#   -e, --email EMAIL     Email address to send notifications to
#   -s, --smtp HOST       SMTP server hostname (default: smtp.forwardemail.net)
#   -p, --port PORT       SMTP port (default: 587)
#   -u, --user USERNAME   SMTP username
#   -w, --pass PASSWORD   SMTP password
#   -l, --level LEVEL     Audit level: basic, standard, thorough (default: standard)
#   -i, --interval HOURS  Run as daemon with specified interval in hours
#   -q, --quiet           Suppress console output
#   -h, --help            Display this help message
#
# Example:
#   ./server_audit_notify.sh --email admin@example.com --user user@yourdomain.com --pass yourpassword
#
# Dependencies:
#   - mailx or sendmail for email notifications
#   - lynis for security auditing (will be installed if not present)
#   - common system utilities (grep, awk, etc.)
#
# Author: Forward Email Team
# Website: https://forwardemail.net
# License: MIT

set -e

# Default values
EMAIL=""
SMTP_HOST="smtp.forwardemail.net"
SMTP_PORT="587"
SMTP_USER=""
SMTP_PASS=""
AUDIT_LEVEL="standard"
INTERVAL=0
QUIET=false
REPORT_DIR="/var/log/server_audit"
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
LOG_FILE="${REPORT_DIR}/audit_${TIMESTAMP}.log"
SUMMARY_FILE="${REPORT_DIR}/summary_${TIMESTAMP}.txt"

# Display help message
show_help() {
    grep "^#" "$0" | grep -v "!/bin/bash" | sed 's/^# \?//'
    exit 0
}

# Parse command line arguments
parse_args() {
    while [[ $# -gt 0 ]]; do
        case "$1" in
            -e|--email)
                EMAIL="$2"
                shift 2
                ;;
            -s|--smtp)
                SMTP_HOST="$2"
                shift 2
                ;;
            -p|--port)
                SMTP_PORT="$2"
                shift 2
                ;;
            -u|--user)
                SMTP_USER="$2"
                shift 2
                ;;
            -w|--pass)
                SMTP_PASS="$2"
                shift 2
                ;;
            -l|--level)
                AUDIT_LEVEL="$2"
                shift 2
                ;;
            -i|--interval)
                INTERVAL="$2"
                shift 2
                ;;
            -q|--quiet)
                QUIET=true
                shift
                ;;
            -h|--help)
                show_help
                ;;
            *)
                echo "Unknown option: $1"
                show_help
                ;;
        esac
    done

    # Validate required parameters
    if [[ -z "$EMAIL" ]]; then
        echo "Error: Email address is required"
        show_help
    fi

    if [[ -z "$SMTP_USER" || -z "$SMTP_PASS" ]]; then
        echo "Error: SMTP username and password are required"
        show_help
    fi
}

# Check for dependencies and install if necessary
check_dependencies() {
    # Create report directory
    mkdir -p "$REPORT_DIR"

    # Check for mailx
    if ! command -v mailx &> /dev/null; then
        log_message "Installing mailx..."
        if command -v apt-get &> /dev/null; then
            apt-get update && apt-get install -y mailutils
        elif command -v yum &> /dev/null; then
            yum install -y mailx
        else
            log_message "Error: Could not install mailx. Please install it manually."
            exit 1
        fi
    fi

    # Check for Lynis
    if ! command -v lynis &> /dev/null; then
        log_message "Installing Lynis..."
        if command -v apt-get &> /dev/null; then
            apt-get update && apt-get install -y lynis
        elif command -v yum &> /dev/null; then
            yum install -y lynis
        else
            log_message "Error: Could not install Lynis. Please install it manually."
            exit 1
        fi
    fi
}

# Log message to console and log file
log_message() {
    local message="$1"
    local timestamp=$(date +"%Y-%m-%d %H:%M:%S")

    if [[ "$QUIET" == false ]]; then
        echo "[${timestamp}] ${message}"
    fi

    echo "[${timestamp}] ${message}" >> "$LOG_FILE"
}

# Run security audit
run_audit() {
    log_message "Starting server security audit (level: $AUDIT_LEVEL)..."

    # Set Lynis audit parameters based on level
    local lynis_params=""
    case "$AUDIT_LEVEL" in
        basic)
            lynis_params="--quick"
            ;;
        standard)
            lynis_params=""
            ;;
        thorough)
            lynis_params="--pentest"
            ;;
        *)
            log_message "Unknown audit level: $AUDIT_LEVEL. Using standard."
            lynis_params=""
            ;;
    esac

    # Run Lynis audit
    log_message "Running Lynis security audit..."
    lynis audit system $lynis_params --no-colors --quiet > "${REPORT_DIR}/lynis_${TIMESTAMP}.log" 2>&1

    # Check for failed SSH login attempts
    log_message "Checking for failed SSH login attempts..."
    grep "Failed password" /var/log/auth.log | tail -n 50 > "${REPORT_DIR}/ssh_failures_${TIMESTAMP}.log"

    # Check for large files
    log_message "Checking for large files..."
    find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | sort -k5,5hr | head -n 20 > "${REPORT_DIR}/large_files_${TIMESTAMP}.log"

    # Check disk usage
    log_message "Checking disk usage..."
    df -h > "${REPORT_DIR}/disk_usage_${TIMESTAMP}.log"

    # Check for listening ports
    log_message "Checking for listening ports..."
    netstat -tuln > "${REPORT_DIR}/listening_ports_${TIMESTAMP}.log"

    # Check for recent package installations
    log_message "Checking for recent package installations..."
    if command -v apt &> /dev/null; then
        grep " install " /var/log/dpkg.log | tail -n 50 > "${REPORT_DIR}/recent_packages_${TIMESTAMP}.log"
    elif command -v yum &> /dev/null; then
        yum history | head -n 20 > "${REPORT_DIR}/recent_packages_${TIMESTAMP}.log"
    fi

    # Create summary
    create_summary

    log_message "Audit completed. Results saved to ${REPORT_DIR}"
}

# Create summary of audit findings
create_summary() {
    log_message "Creating audit summary..."

    {
        echo "SERVER AUDIT SUMMARY"
        echo "===================="
        echo "Date: $(date)"
        echo "Hostname: $(hostname)"
        echo "IP Address: $(hostname -I | awk '{print $1}')"
        echo "Audit Level: $AUDIT_LEVEL"
        echo ""

        echo "SYSTEM INFORMATION"
        echo "------------------"
        echo "OS: $(cat /etc/os-release | grep PRETTY_NAME | cut -d= -f2 | tr -d '"')"
        echo "Kernel: $(uname -r)"
        echo "Uptime: $(uptime -p)"
        echo ""

        echo "SECURITY WARNINGS"
        echo "-----------------"
        grep "Warning" "${REPORT_DIR}/lynis_${TIMESTAMP}.log" | tail -n 20
        echo ""

        echo "FAILED SSH ATTEMPTS"
        echo "------------------"
        wc -l "${REPORT_DIR}/ssh_failures_${TIMESTAMP}.log" | awk '{print $1 " failed SSH login attempts found"}'
        if [[ -s "${REPORT_DIR}/ssh_failures_${TIMESTAMP}.log" ]]; then
            echo "Top IP addresses:"
            grep "Failed password" "${REPORT_DIR}/ssh_failures_${TIMESTAMP}.log" | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head -n 5
        fi
        echo ""

        echo "DISK USAGE"
        echo "----------"
        grep -v "tmpfs" "${REPORT_DIR}/disk_usage_${TIMESTAMP}.log" | grep -v "udev"
        echo ""

        echo "LISTENING PORTS"
        echo "--------------"
        grep "LISTEN" "${REPORT_DIR}/listening_ports_${TIMESTAMP}.log" | wc -l | awk '{print $1 " open ports found"}'
        echo "Notable ports:"
        grep -E ":(22|80|443|25|3306|5432) " "${REPORT_DIR}/listening_ports_${TIMESTAMP}.log"
        echo ""

        echo "RECOMMENDATIONS"
        echo "--------------"
        echo "1. Review all security warnings"
        echo "2. Investigate any suspicious failed login attempts"
        echo "3. Check for unauthorized listening ports"
        if grep -q "Warning" "${REPORT_DIR}/lynis_${TIMESTAMP}.log"; then
            echo "4. Address Lynis security warnings"
        fi
        if grep -q "9[0-9]%" "${REPORT_DIR}/disk_usage_${TIMESTAMP}.log"; then
            echo "5. Free up disk space on partitions with >90% usage"
        fi
        echo ""

        echo "For detailed information, see the full audit logs in ${REPORT_DIR}"
        echo ""
        echo "Generated by server_audit_notify.sh"
        echo "Powered by Forward Email - https://forwardemail.net"
    } > "$SUMMARY_FILE"
}

# Send email notification
send_notification() {
    log_message "Sending email notification to $EMAIL..."

    # Create email content
    local email_subject="Server Audit Report: $(hostname) - $(date +"%Y-%m-%d")"
    local email_body_file="${REPORT_DIR}/email_${TIMESTAMP}.txt"

    {
        echo "Server Audit Notification"
        echo "========================="
        echo ""
        cat "$SUMMARY_FILE"
    } > "$email_body_file"

    # Configure mailx
    echo "set smtp=$SMTP_HOST:$SMTP_PORT" > ~/.mailrc
    echo "set smtp-use-starttls" >> ~/.mailrc
    echo "set smtp-auth=login" >> ~/.mailrc
    echo "set smtp-auth-user=$SMTP_USER" >> ~/.mailrc
    echo "set smtp-auth-password=$SMTP_PASS" >> ~/.mailrc
    echo "set ssl-verify=ignore" >> ~/.mailrc

    # Send email
    if cat "$email_body_file" | mailx -s "$email_subject" "$EMAIL"; then
        log_message "Email notification sent successfully"
    else
        log_message "Failed to send email notification"
    fi
}

# Main function
main() {
    log_message "Server Audit Notification Script started"

    check_dependencies

    if [[ $INTERVAL -gt 0 ]]; then
        log_message "Running in daemon mode with interval of $INTERVAL hours"
        while true; do
            run_audit
            send_notification
            log_message "Sleeping for $INTERVAL hours..."
            sleep $(($INTERVAL * 3600))
        done
    else
        run_audit
        send_notification
    fi

    log_message "Script completed successfully"
}

# Parse command line arguments
parse_args "$@"

# Run main function
main