#!/bin/bash
################################################################################
# 安全合规检测模块
# 功能: 检测系统安全状态、认证失败、异常账户、防火墙规则等
# 作者: Claude Code
# 日期: 2026-07-20
################################################################################

# 获取脚本所在目录并加载依赖
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIB_DIR="${LIB_DIR:-/tmp/check_modules}"

# 加载配置文件和通用函数库
if [ -f "$LIB_DIR/lib/config.sh" ]; then
    source "$LIB_DIR/lib/config.sh"
else
    echo "ERROR: 配置文件不存在: $LIB_DIR/lib/config.sh"
    exit 1
fi

if [ -f "$LIB_DIR/lib/common.sh" ]; then
    source "$LIB_DIR/lib/common.sh"
else
    echo "ERROR: 通用函数库不存在: $LIB_DIR/lib/common.sh"
    exit 1
fi

# ==================== 检测函数 ====================

# 检测认证失败历史
check_auth_failures() {
    local auth_fail_count=0

    if [ -f "/var/log/secure" ]; then
        auth_fail_count=$(grep -c "Failed password" /var/log/secure 2>/dev/null || echo "0")
    elif [ -f "/var/log/auth.log" ]; then
        auth_fail_count=$(grep -c "Failed password" /var/log/auth.log 2>/dev/null || echo "0")
    fi

    output_result "AUTH_FAILURES_24H" "$auth_fail_count"

    if [ "$auth_fail_count" -gt 1000 ]; then
        output_result "AUTH_FAILURES_LEVEL" "严重"
    elif [ "$auth_fail_count" -gt 100 ]; then
        output_result "AUTH_FAILURES_LEVEL" "警告"
    else
        output_result "AUTH_FAILURES_LEVEL" "正常"
    fi
}

# 检测当前登录用户
check_current_users() {
    local current_users=""
    local user_count="0"

    if command -v who &>/dev/null; then
        current_users=$(who 2>/dev/null)
        if [ -n "$current_users" ]; then
            user_count=$(echo "$current_users" | wc -l)
        fi
    fi

    output_result "CURRENT_USERS_COUNT" "${user_count:-0}"

    if [ -n "$current_users" ] && [ "$user_count" -gt 0 ]; then
        local users_list
        users_list=$(echo "$current_users" | cut -d' ' -f1 | tr '\n' ',' | sed 's/,$//' 2>/dev/null)
        [ -n "$users_list" ] && output_result "CURRENT_USERS" "$users_list"
    fi
}

# 检测防火墙规则
check_firewall_rules() {
    if command -v firewall-cmd &>/dev/null; then
        if systemctl is-active --quiet firewalld 2>/dev/null; then
            output_result "FIREWALL_STATUS" "firewalld运行中"
        else
            output_result "FIREWALL_STATUS" "firewalld未运行"
        fi
    fi

    if command -v iptables &>/dev/null; then
        local iptables_rules
        iptables_rules=$(iptables -L -n 2>/dev/null)
        if [ -n "$iptables_rules" ]; then
            output_result "IPTABLES_STATUS" "iptables已配置"
            output_result "IPTABLES_RULES_COUNT" "$(echo "$iptables_rules" | grep -c "^Chain" || echo "0")"
        fi
    fi

    local open_ports
    open_ports=$(ss -tlnp 2>/dev/null | grep LISTEN | awk '{print $4}' | grep -oE '[0-9]+$' | sort -u | wc -l)
    output_result "OPEN_PORTS_COUNT" "$open_ports"
}

# 检测异常账户（UID=0的非root账户）
check_abnormal_accounts() {
    local abnormal_accounts=""

    if [ -r "/etc/passwd" ]; then
        while IFS=: read -r username x uid rest; do
            if [ "$uid" = "0" ] && [ "$username" != "root" ]; then
                if [ -z "$abnormal_accounts" ]; then
                    abnormal_accounts="$username"
                else
                    abnormal_accounts="$abnormal_accounts,$username"
                fi
            fi
        done < /etc/passwd 2>/dev/null || true
    fi

    if [ -n "$abnormal_accounts" ]; then
        output_result "ABNORMAL_ACCOUNTS" "$abnormal_accounts"
        output_result "ABNORMAL_ACCOUNTS_LEVEL" "严重"
    else
        output_result "ABNORMAL_ACCOUNTS" "无"
        output_result "ABNORMAL_ACCOUNTS_LEVEL" "正常"
    fi
}

# 检测SSH配置安全检查
check_ssh_security() {
    local ssh_config="/etc/ssh/sshd_config"

    if [ -f "$ssh_config" ]; then
        local permit_root
        permit_root=$(grep -E "^PermitRootLogin" "$ssh_config" 2>/dev/null | grep -v "^#" | awk '{print $2}')
        output_result "SSH_PERMIT_ROOT" "${permit_root:-未设置}"

        local password_auth
        password_auth=$(grep -E "^PasswordAuthentication" "$ssh_config" 2>/dev/null | grep -v "^#" | awk '{print $2}')
        output_result "SSH_PASSWORD_AUTH" "${password_auth:-未设置}"

        local ssh_port
        ssh_port=$(grep -E "^Port" "$ssh_config" 2>/dev/null | grep -v "^#" | awk '{print $2}')
        output_result "SSH_PORT" "${ssh_port:-22}"

        if [ "$permit_root" = "yes" ]; then
            output_result "SSH_ROOT_LOGIN_LEVEL" "严重"
        else
            output_result "SSH_ROOT_LOGIN_LEVEL" "正常"
        fi
    fi
}

# 检测开放端口详情
check_open_ports_detail() {
    local tcp_ports
    tcp_ports=$(ss -tlnp 2>/dev/null | grep LISTEN | awk '{print $4}' | grep -oE '[0-9]+$' | sort -nu | tr '\n' ',' | sed 's/,$//')
    output_result "OPEN_TCP_PORTS" "$tcp_ports"

    # 高风险端口
    local high_risk_ports="23,135,139,445,1433,3389,5900,5901"
    local found_risk_ports=""
    for port in ${high_risk_ports//,/ }; do
        if ss -tlnp 2>/dev/null | grep -q ":$port "; then
            [ -z "$found_risk_ports" ] && found_risk_ports="$port" || found_risk_ports="$found_risk_ports,$port"
        fi
    done

    if [ -n "$found_risk_ports" ]; then
        output_result "HIGH_RISK_PORTS" "$found_risk_ports"
        output_result "HIGH_RISK_PORTS_LEVEL" "警告"
    else
        output_result "HIGH_RISK_PORTS" "无"
        output_result "HIGH_RISK_PORTS_LEVEL" "正常"
    fi
}

# 检测暴力破解IP
check_brute_force_ips() {
    local brute_force_ips=""

    if [ -f "/var/log/secure" ]; then
        brute_force_ips=$(grep "Failed password" /var/log/secure 2>/dev/null | grep -oE 'from [0-9.]+' | cut -d' ' -f2 | sort | uniq -c | sort -rn | head -5)
    elif [ -f "/var/log/auth.log" ]; then
        brute_force_ips=$(grep "Failed password" /var/log/auth.log 2>/dev/null | grep -oE 'from [0-9.]+' | cut -d' ' -f2 | sort | uniq -c | sort -rn | head -5)
    fi

    if [ -n "$brute_force_ips" ]; then
        local max_attempts
        max_attempts=$(echo "$brute_force_ips" | head -1 | awk '{print $1}')
        output_result "MAX_LOGIN_FAILURES" "$max_attempts"
        output_result "BRUTE_FORCE_IPS" "$(echo "$brute_force_ips" | sed 's/ /:/g' | tr '\n' ',' | sed 's/,$//')"

        if [ "$max_attempts" -gt 100 ]; then
            output_result "BRUTE_FORCE_LEVEL" "严重"
        elif [ "$max_attempts" -gt 20 ]; then
            output_result "BRUTE_FORCE_LEVEL" "警告"
        else
            output_result "BRUTE_FORCE_LEVEL" "正常"
        fi
    else
        output_result "MAX_LOGIN_FAILURES" "0"
        output_result "BRUTE_FORCE_LEVEL" "正常"
    fi
}

# ==================== 主检测流程 ====================
main() {
    log_info "开始安全合规检测..."

    set +e

    check_auth_failures 2>/dev/null || true
    check_current_users 2>/dev/null || true
    check_firewall_rules 2>/dev/null || true
    check_abnormal_accounts 2>/dev/null || true
    check_ssh_security 2>/dev/null || true
    check_open_ports_detail 2>/dev/null || true
    check_brute_force_ips 2>/dev/null || true

    log_info "安全合规检测完成"
}

main