#!/bin/bash

# Linux系统安全配置脚本 - CentOS优化版 + Docker兼容
# 功能：系统检测、防火墙配置、端口管理、fail2ban配置
# 针对代理服务器优化，减少对正常流量的影响
# Docker兼容：使用iptables-legacy，SSH端口检测在外部脚本后执行

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 全局变量
SSH_PORT="22"  # 初始默认值，后续动态检测

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

log_step() {
    echo -e "${BLUE}[STEP]${NC} $1"
}

# 检查是否为root用户
check_root() {
    if [[ $EUID -ne 0 ]]; then
        log_error "此脚本需要root权限运行"
        exit 1
    fi
}

# 检测操作系统
detect_os() {
    log_step "检测操作系统类型..."
    
    if [[ -f /etc/redhat-release ]]; then
        if grep -q "CentOS" /etc/redhat-release; then
            OS="centos"
            PACKAGE_MANAGER="yum"
        elif grep -q "Red Hat" /etc/redhat-release; then
            OS="rhel"
            PACKAGE_MANAGER="yum"
        fi
    elif [[ -f /etc/lsb-release ]] && grep -q "Ubuntu" /etc/lsb-release; then
        OS="ubuntu"
        PACKAGE_MANAGER="apt"
    elif [[ -f /etc/debian_version ]]; then
        OS="debian"
        PACKAGE_MANAGER="apt"
    else
        log_error "不支持的操作系统"
        exit 1
    fi
    
    log_info "检测到操作系统: $OS"
}

# 检测实际SSH端口（函数化，供后续调用）
detect_ssh_port() {
    log_step "检测实际SSH服务端口..."
    
    # 方法1: 从SSH配置文件读取端口
    local config_port=""
    if [[ -f /etc/ssh/sshd_config ]]; then
        config_port=$(grep "^Port\s" /etc/ssh/sshd_config | awk '{print $2}' | head -1)
    fi
    
    # 方法2: 从netstat检测SSH监听端口
    local listening_ports=""
    if command -v netstat &> /dev/null; then
        # 检测sshd进程监听的端口
        listening_ports=$(netstat -tlnp 2>/dev/null | grep sshd | awk '{print $4}' | cut -d: -f2 | sort -u | tr '\n' ' ')
    elif command -v ss &> /dev/null; then
        # 使用ss命令作为备选
        listening_ports=$(ss -tlnp 2>/dev/null | grep sshd | awk '{print $4}' | cut -d: -f2 | sort -u | tr '\n' ' ')
    fi
    
    # 方法3: 检查systemd服务配置（CentOS 7+支持）
    local systemd_port=""
    if systemctl is-active --quiet sshd 2>/dev/null; then
        # 检查SSH服务是否在运行
        systemd_port=$(systemctl show sshd.service 2>/dev/null | grep -i port | head -1 | cut -d= -f2 2>/dev/null || true)
    fi
    
    log_info "SSH端口检测结果："
    [[ -n "$config_port" ]] && log_info "  配置文件中的端口: $config_port"
    [[ -n "$listening_ports" ]] && log_info "  实际监听的端口: $listening_ports"
    [[ -n "$systemd_port" ]] && log_info "  系统服务端口: $systemd_port"
    
    # 确定最终使用的SSH端口
    local final_ssh_port=""
    
    if [[ -n "$listening_ports" ]]; then
        # 优先使用实际监听的端口
        final_ssh_port=$(echo $listening_ports | awk '{print $1}')
    elif [[ -n "$config_port" ]]; then
        # 其次使用配置文件中的端口
        final_ssh_port="$config_port"
    else
        # 默认使用22端口
        final_ssh_port="22"
        log_warn "无法检测到SSH端口，使用默认端口22"
    fi
    
    # 验证端口号是否合理
    if [[ "$final_ssh_port" =~ ^[0-9]+$ ]] && [[ "$final_ssh_port" -ge 1 ]] && [[ "$final_ssh_port" -le 65535 ]]; then
        SSH_PORT="$final_ssh_port"
        log_info "确定SSH端口为: $SSH_PORT"
        
        # 如果不是22端口，给出提示
        if [[ "$SSH_PORT" != "22" ]]; then
            log_info "检测到自定义SSH端口: $SSH_PORT"
        fi
    else
        log_warn "检测到的端口号无效: $final_ssh_port，使用默认端口22"
        SSH_PORT="22"
    fi
    
    return 0
}

# 更新系统包管理器
update_system() {
    log_step "更新系统包管理器..."
    
    case $PACKAGE_MANAGER in
        "yum")
            log_info "正在执行 yum update，可能需要确认..."
            yum update -y
            ;;
        "apt")
            log_info "正在执行 apt update..."
            apt update -y
            ;;
    esac
    
    log_info "系统包管理器更新完成"
}

# 清理已有的iptables配置
clean_existing_iptables() {
    log_step "清理已有的iptables配置..."
    
    # 停止iptables服务（如果正在运行）
    if systemctl is-active --quiet iptables 2>/dev/null; then
        log_info "停止现有iptables服务..."
        systemctl stop iptables 2>/dev/null || true
    fi
    
    # 清空所有规则和链
    log_info "清空所有iptables规则..."
    iptables -F 2>/dev/null || true
    iptables -X 2>/dev/null || true
    iptables -t nat -F 2>/dev/null || true
    iptables -t nat -X 2>/dev/null || true
    iptables -t mangle -F 2>/dev/null || true
    iptables -t mangle -X 2>/dev/null || true
    iptables -t filter -F 2>/dev/null || true
    iptables -t filter -X 2>/dev/null || true
    
    # 重置所有链的默认策略为ACCEPT（避免锁定）
    iptables -P INPUT ACCEPT 2>/dev/null || true
    iptables -P FORWARD ACCEPT 2>/dev/null || true
    iptables -P OUTPUT ACCEPT 2>/dev/null || true
    
    # 删除已保存的iptables规则文件
    case $OS in
        "centos"|"rhel")
            if [[ -f /etc/sysconfig/iptables ]]; then
                log_info "删除旧的iptables配置文件..."
                rm -f /etc/sysconfig/iptables
                rm -f /etc/sysconfig/iptables.save
            fi
            ;;
        "ubuntu"|"debian")
            if [[ -f /etc/iptables/rules.v4 ]]; then
                log_info "删除旧的iptables配置文件..."
                rm -f /etc/iptables/rules.v4
                rm -f /etc/iptables/rules.v6
            fi
            ;;
    esac
    
    log_info "iptables配置清理完成"
}

# 清理已有的fail2ban配置
clean_existing_fail2ban() {
    log_step "清理已有的fail2ban配置..."
    
    # 检查fail2ban是否已安装
    if command -v fail2ban-client &> /dev/null; then
        log_info "检测到已安装的fail2ban，开始清理..."
        
        # 停止fail2ban服务
        if systemctl is-active --quiet fail2ban 2>/dev/null; then
            log_info "停止fail2ban服务..."
            systemctl stop fail2ban 2>/dev/null || true
        fi
        
        # 解封所有被封禁的IP
        log_info "解封所有被封禁的IP..."
        fail2ban-client unban --all 2>/dev/null || true
        
        # 备份原有配置（如果需要）
        if [[ -f /etc/fail2ban/jail.local ]]; then
            log_info "备份原有fail2ban配置..."
            cp /etc/fail2ban/jail.local /etc/fail2ban/jail.local.backup.$(date +%Y%m%d_%H%M%S) 2>/dev/null || true
        fi
        
        # 清理配置文件
        log_info "清理fail2ban配置文件..."
        rm -f /etc/fail2ban/jail.local
        rm -f /etc/fail2ban/jail.d/*.conf 2>/dev/null || true
        
        # 清理自定义过滤器
        rm -f /etc/fail2ban/filter.d/nginx-*.conf 2>/dev/null || true
        
        # 清理日志和数据库
        rm -f /var/lib/fail2ban/fail2ban.sqlite3 2>/dev/null || true
        rm -f /var/log/fail2ban.log* 2>/dev/null || true
        
        log_info "fail2ban配置清理完成"
    else
        log_info "未检测到fail2ban，无需清理"
    fi
}

disable_system_firewalls() {
    log_step "关闭系统自带防火墙..."
    
    case $OS in
        "centos"|"rhel")
            # 停止并禁用firewalld
            if systemctl is-active --quiet firewalld 2>/dev/null; then
                log_info "正在停止firewalld..."
                systemctl stop firewalld
                systemctl disable firewalld
                log_info "已停止并禁用firewalld"
            else
                log_info "firewalld未运行"
            fi
            
            # 停止并禁用ufw (如果存在)
            if command -v ufw &> /dev/null; then
                log_info "正在禁用ufw..."
                ufw --force disable
                log_info "已禁用ufw"
            fi
            ;;
        "ubuntu"|"debian")
            # 停止并禁用ufw
            if command -v ufw &> /dev/null; then
                log_info "正在停止并禁用ufw..."
                ufw --force disable
                systemctl stop ufw 2>/dev/null || true
                systemctl disable ufw 2>/dev/null || true
                log_info "已停止并禁用ufw"
            else
                log_info "ufw未安装"
            fi
            
            # 停止并禁用firewalld (如果存在)
            if systemctl is-active --quiet firewalld 2>/dev/null; then
                log_info "正在停止firewalld..."
                systemctl stop firewalld
                systemctl disable firewalld
                log_info "已停止并禁用firewalld"
            fi
            ;;
    esac
}

# 安装iptables并配置为legacy模式（Docker兼容）
install_iptables() {
    log_step "安装并配置iptables (legacy模式，Docker兼容)..."
    
    case $PACKAGE_MANAGER in
        "yum")
            log_info "安装iptables和相关服务..."
            yum install -y iptables iptables-services
            # 确保服务被禁用，我们手动管理
            systemctl disable iptables 2>/dev/null || true
            systemctl stop iptables 2>/dev/null || true
            ;;
        "apt")
            log_info "安装iptables和iptables-persistent..."
            # 预先配置iptables-persistent以避免交互
            echo iptables-persistent iptables-persistent/autosave_v4 boolean true | debconf-set-selections
            echo iptables-persistent iptables-persistent/autosave_v6 boolean true | debconf-set-selections
            apt install -y iptables iptables-persistent
            
            # 配置为使用legacy模式（Docker兼容）
            log_info "配置iptables为legacy模式（Docker兼容）..."
            update-alternatives --set iptables /usr/sbin/iptables-legacy
            update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
            update-alternatives --set arptables /usr/sbin/arptables-legacy
            update-alternatives --set ebtables /usr/sbin/ebtables-legacy
            
            # 停止自动服务，我们手动管理
            systemctl disable netfilter-persistent 2>/dev/null || true
            systemctl stop netfilter-persistent 2>/dev/null || true
            ;;
    esac
    
    # 对于CentOS，也要确保使用legacy模式
    if [[ "$OS" == "centos" || "$OS" == "rhel" ]]; then
        log_info "配置CentOS使用iptables-legacy..."
        if command -v alternatives &> /dev/null; then
            # CentOS 8+
            alternatives --set iptables /usr/sbin/iptables-legacy 2>/dev/null || true
        fi
    fi
    
    log_info "iptables安装完成（legacy模式，Docker兼容）"
    log_info "验证iptables模式..."
    iptables --version
}

# 初步检测SSH端口（仅用于初始配置）
initial_ssh_port_detection() {
    log_step "初步检测SSH端口（后续将重新检测）..."
    detect_ssh_port
    log_info "初始检测到SSH端口: $SSH_PORT"
    log_warn "注意：外部脚本可能会修改SSH端口，届时将重新检测"
}

# 配置基础iptables规则 - 针对代理服务器优化，兼容CentOS 7，暂不配置SSH端口（待后续更新）
configure_basic_iptables() {
    log_step "配置基础iptables规则（代理服务器优化版，CentOS 7兼容，预留SSH端口配置）..."
    
    # 再次确保清空现有规则（防止残留）
    log_info "确保清空所有iptables规则..."
    iptables -F 2>/dev/null || true
    iptables -X 2>/dev/null || true
    iptables -t nat -F 2>/dev/null || true
    iptables -t nat -X 2>/dev/null || true
    iptables -t mangle -F 2>/dev/null || true
    iptables -t mangle -X 2>/dev/null || true
    
    # 设置默认策略
    log_info "设置默认策略..."
    iptables -P INPUT DROP
    iptables -P FORWARD DROP
    iptables -P OUTPUT ACCEPT
    
    # 允许本地回环
    log_info "配置本地回环规则..."
    iptables -A INPUT -i lo -j ACCEPT
    iptables -A OUTPUT -o lo -j ACCEPT
    
    # 允许已建立的连接和相关连接（对代理服务器非常重要）
    log_info "配置连接状态规则..."
    iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    
    # 创建轻量级防护链（针对代理服务器优化，兼容CentOS 7）
    log_info "配置轻量级防护规则（CentOS 7兼容版）..."
    iptables -N ddos_protect 2>/dev/null || true
    iptables -F ddos_protect 2>/dev/null || true
    
    # 防护规则更宽松，适合代理服务器，且兼容CentOS 7内核限制
    # CentOS 7的xt_recent模块默认只能记住20个数据包，所以调整为20以内
    # 5分钟内超过15个新连接才触发限制（符合内核限制）
    iptables -A ddos_protect -m recent --set --name ddos_check
    iptables -A ddos_protect -m recent --update --seconds 300 --hitcount 15 --name ddos_check -j DROP
    iptables -A ddos_protect -j RETURN
    
    # 临时开放SSH端口（使用初步检测的端口，后续将更新）
    log_info "配置临时SSH端口访问规则（端口: $SSH_PORT，后续将更新）..."
    iptables -A INPUT -p tcp --dport $SSH_PORT -m state --state NEW -j ddos_protect
    iptables -A INPUT -p tcp --dport $SSH_PORT -j ACCEPT
    
    # 只对特定管理端口应用防护（不影响代理端口）
    iptables -A INPUT -p tcp --dport 8006 -m state --state NEW -j ddos_protect
    
    # 开放代理相关端口（无限制）
    log_info "开放代理相关端口..."
    iptables -A INPUT -p tcp --dport 12748 -j ACCEPT
    iptables -A INPUT -p tcp --dport 80 -j ACCEPT
    iptables -A INPUT -p tcp --dport 443 -j ACCEPT
    iptables -A INPUT -p tcp --dport 5222 -j ACCEPT
    iptables -A INPUT -p tcp --dport 7777 -j ACCEPT
    iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
    iptables -A INPUT -p tcp --dport 8007 -j ACCEPT
    
    # 开放FTP端口
    log_info "开放FTP端口..."
    iptables -A INPUT -p tcp --dport 21 -j ACCEPT
    iptables -A INPUT -p tcp --dport 20 -j ACCEPT
    # FTP被动模式端口范围
    iptables -A INPUT -p tcp --dport 30000:31000 -j ACCEPT
    
    # 管理端口（应用防护）
    log_info "配置管理端口..."
    iptables -A INPUT -p tcp --dport 8006 -j ACCEPT
    
    # 永久禁用ICMP ping
    log_info "永久禁用ICMP ping..."
    iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
    
    # 开放高端口范围（代理服务器可能需要）
    log_info "开放高端口范围（10000-65535）用于代理服务..."
    iptables -A INPUT -p tcp --dport 10000:65535 -j ACCEPT
    iptables -A INPUT -p udp --dport 10000:65535 -j ACCEPT
    
    log_info "基础iptables规则配置完成（代理服务器优化版，CentOS 7兼容）"
    log_info "临时SSH端口: $SSH_PORT (后续将根据外部脚本结果更新)"
    log_info "已开放端口: 12748, 80, 443, 5222, 7777, 8006, 8080, 8007, 21(FTP), 20(FTP), 30000-31000(FTP被动)"
    log_info "已开放高端口范围: 10000-65535（TCP/UDP）"
    log_info "轻量级防护: 5分钟内超过15个新连接才会被限制（兼容CentOS 7）"
    log_info "永久禁用ICMP ping"
}

# 更新SSH端口的iptables规则（在外部脚本运行后调用）
update_ssh_iptables_rules() {
    local old_port="$1"
    local new_port="$2"
    
    log_step "更新iptables中的SSH端口规则（从 $old_port 到 $new_port）..."
    
    # 删除旧的SSH端口规则
    log_info "删除旧的SSH端口规则（端口: $old_port）..."
    iptables -D INPUT -p tcp --dport $old_port -m state --state NEW -j ddos_protect 2>/dev/null || true
    iptables -D INPUT -p tcp --dport $old_port -j ACCEPT 2>/dev/null || true
    
    # 添加新的SSH端口规则
    log_info "添加新的SSH端口规则（端口: $new_port）..."
    # 在INPUT链的开头插入SSH规则（确保优先级）
    iptables -I INPUT 3 -p tcp --dport $new_port -m state --state NEW -j ddos_protect
    iptables -I INPUT 4 -p tcp --dport $new_port -j ACCEPT
    
    log_info "SSH端口iptables规则更新完成"
}

# 用户交互：添加自定义端口
add_custom_ports() {
    log_step "配置自定义端口..."
    
    echo -e "${YELLOW}请输入需要开放的额外TCP端口，多个端口用空格分隔（直接回车跳过）:${NC}"
    read -r custom_ports
    
    if [[ -n "$custom_ports" ]]; then
        for port in $custom_ports; do
            # 验证端口号
            if [[ "$port" =~ ^[0-9]+$ ]] && [[ "$port" -ge 1 ]] && [[ "$port" -le 65535 ]]; then
                # 检查端口是否已经在高端口范围内
                if [[ "$port" -ge 10000 ]]; then
                    log_info "端口 $port 已在高端口范围内开放"
                else
                    iptables -A INPUT -p tcp --dport "$port" -j ACCEPT
                    log_info "已开放TCP端口: $port"
                fi
            else
                log_warn "无效端口号: $port，跳过"
            fi
        done
    else
        log_info "未添加额外端口"
    fi
}

# 保存iptables规则
save_iptables() {
    log_step "保存iptables规则..."
    
    case $OS in
        "centos"|"rhel")
            log_info "保存iptables规则到系统配置..."
            service iptables save 2>/dev/null || iptables-save > /etc/sysconfig/iptables
            ;;
        "ubuntu"|"debian")
            log_info "保存iptables规则..."
            iptables-save > /etc/iptables/rules.v4
            # 确保开机自动加载
            if ! grep -q "iptables-restore" /etc/rc.local 2>/dev/null; then
                echo "iptables-restore < /etc/iptables/rules.v4" >> /etc/rc.local
                chmod +x /etc/rc.local
            fi
            ;;
    esac
    
    log_info "iptables规则已保存"
}

# 清理已有的Nginx安全配置
clean_existing_nginx_config() {
    log_step "清理已有的Nginx安全配置..."
    
    if command -v nginx &> /dev/null; then
        log_info "检测到Nginx，清理旧的安全配置..."
        
        # 删除旧的安全配置文件
        rm -f /etc/nginx/conf.d/security.conf
        rm -f /etc/nginx/sites-available/security
        rm -f /etc/nginx/sites-enabled/security
        
        # 测试Nginx配置
        if nginx -t 2>/dev/null; then
            systemctl reload nginx 2>/dev/null || log_warn "无法重载Nginx配置"
            log_info "Nginx配置清理完成"
        else
            log_warn "Nginx配置测试失败，请手动检查"
        fi
    else
        log_info "未检测到Nginx，无需清理"
    fi
}

# 配置Nginx安全规则（代理服务器优化版）
configure_nginx_security() {
    log_step "配置Nginx安全规则（代理服务器优化版）..."
    
    # 检查nginx是否安装
    if ! command -v nginx &> /dev/null; then
        log_warn "Nginx未安装，跳过Nginx安全配置"
        return
    fi
    
    # 创建Nginx安全配置文件（更宽松的配置）
    log_info "创建Nginx安全配置..."
    cat > /etc/nginx/conf.d/security.conf << 'EOF'
# 限制并发连接数和请求速率（代理服务器优化）
# 更宽松的限制，适合代理服务器
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=50r/s;

# 安全配置
server {
    # 提高每个IP的并发连接数限制（原20改为100）
    limit_conn conn_limit_per_ip 100;
    # 提高请求速率限制（原10r/s改为50r/s），增加突发容量
    limit_req zone=req_limit_per_ip burst=20 nodelay;
    
    # 隐藏Nginx版本信息
    server_tokens off;
    
    # 防止目录扫描（保留基本安全）
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }
    
    # 只阻止最危险的文件类型
    location ~* \.(htaccess|htpasswd|ini|log|sh|sql)$ {
        deny all;
        access_log off;
        log_not_found off;
    }
    
    # 只阻止明显的攻击路径
    location ~* /(wp-admin|wp-login|phpmyadmin|setup\.php) {
        deny all;
        access_log off;
        log_not_found off;
    }
    
    # 保留基本的方法限制
    if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|OPTIONS)$ ) {
        return 444;
    }
}
EOF
    
    # 检查Nginx配置是否正确
    if nginx -t 2>/dev/null; then
        log_info "Nginx安全配置已应用（代理服务器优化版）"
        systemctl reload nginx 2>/dev/null || log_warn "无法重载Nginx配置，请手动检查"
    else
        log_warn "Nginx配置测试失败，请检查配置文件"
        rm -f /etc/nginx/conf.d/security.conf
    fi
}

# 安装fail2ban但不配置（等待SSH端口确认）
install_fail2ban_only() {
    log_step "安装fail2ban（暂不配置，等待SSH端口确认）..."
    
    # 安装fail2ban
    case $PACKAGE_MANAGER in
        "yum")
            # CentOS需要EPEL源
            log_info "安装EPEL源..."
            yum install -y epel-release
            log_info "安装fail2ban..."
            yum install -y fail2ban
            ;;
        "apt")
            log_info "安装fail2ban..."
            apt install -y fail2ban
            ;;
    esac
    
    log_info "fail2ban安装完成，等待外部脚本执行后配置SSH监控"
}

# 配置fail2ban（在SSH端口确认后调用）
configure_fail2ban_with_ssh_port() {
    local ssh_port="$1"
    
    log_step "配置fail2ban SSH监控（端口: $ssh_port）..."
    
    # 根据操作系统确定SSH日志路径
    local ssh_log_path
    case $OS in
        "ubuntu"|"debian")
            ssh_log_path="/var/log/auth.log"
            ;;
        "centos"|"rhel")
            ssh_log_path="/var/log/secure"
            ;;
        *)
            # 默认路径，大多数系统使用auth.log
            ssh_log_path="/var/log/auth.log"
            ;;
    esac
    
    log_info "检测到SSH日志路径: $ssh_log_path"
    
    # 验证日志文件是否存在
    if [[ ! -f "$ssh_log_path" ]]; then
        log_warn "SSH日志文件 $ssh_log_path 不存在，尝试创建..."
        touch "$ssh_log_path"
        chmod 640 "$ssh_log_path"
    fi
    
    # 停止fail2ban服务（如果在运行）
    if systemctl is-active --quiet fail2ban 2>/dev/null; then
        log_info "停止fail2ban服务..."
        systemctl stop fail2ban 2>/dev/null || true
    fi
    
    # 配置fail2ban（更严格的SSH防护，使用动态检测的SSH端口）
    log_info "配置fail2ban规则（严格SSH防护版，端口: $ssh_port）..."
    cat > /etc/fail2ban/jail.local << EOF
[DEFAULT]
# 永久封禁（设置为-1表示永久）
bantime = -1
# 查找时间窗口(秒) - 10分钟
findtime = 600
# 最大重试次数 - 5次
maxretry = 5
# 忽略的IP地址（可以添加你的常用IP）
ignoreip = 127.0.0.1/8 ::1

[sshd]
enabled = true
port = $ssh_port
filter = sshd
logpath = $ssh_log_path
maxretry = 5
bantime = -1
findtime = 600

# 禁用其他可能影响代理的jail
[nginx-http-auth]
enabled = false

[nginx-noscript]
enabled = false

[nginx-badbots]
enabled = false

[nginx-noproxy]
enabled = false
EOF
    
    # 启动fail2ban服务
    log_info "启动fail2ban服务..."
    systemctl enable fail2ban
    systemctl start fail2ban
    
    # 等待一下让服务完全启动
    sleep 3
    
    # 验证fail2ban配置
    log_info "验证fail2ban配置..."
    if fail2ban-client status sshd >/dev/null 2>&1; then
        log_info "fail2ban SSH监控配置成功（监听端口: $ssh_port）"
        fail2ban-client status sshd
    else
        log_warn "fail2ban SSH监控可能配置有误，请检查日志: journalctl -u fail2ban"
    fi
    
    log_info "fail2ban配置完成（严格SSH防护版）"
    log_info "SSH防护规则: 连续5次登录失败将永久封禁IP（仅限手动解封）"
    log_info "监控SSH端口: $ssh_port"
    log_info "使用日志文件: $ssh_log_path"
}

# 运行外部脚本
run_external_script() {
    log_step "准备运行外部脚本..."
    echo -e "${YELLOW}即将运行外部脚本，该脚本包含交互内容并可能修改SSH端口${NC}"
    echo -e "${YELLOW}按任意键继续...${NC}"
    read -n 1 -s
    
    log_info "正在下载并运行外部脚本..."
    if wget http://download.azurezoo.cloud//Tools/Linux_tools.sh -O /tmp/Linux_tools.sh; then
        chmod +x /tmp/Linux_tools.sh
        bash /tmp/Linux_tools.sh
        # 清理临时文件
        rm -f /tmp/Linux_tools.sh
        log_info "外部脚本运行完成"
    else
        log_error "下载外部脚本失败"
        return 1
    fi
    
    return 0
}

# 外部脚本后的SSH端口重新检测和配置更新
post_external_script_ssh_config() {
    log_step "外部脚本执行完毕，重新检测SSH端口并更新配置..."
    
    # 记录旧端口
    local old_ssh_port="$SSH_PORT"
    
    # 重新检测SSH端口
    detect_ssh_port
    
    # 检查端口是否发生了变化
    if [[ "$old_ssh_port" != "$SSH_PORT" ]]; then
        log_info "检测到SSH端口已变更：$old_ssh_port -> $SSH_PORT"
        
        # 更新iptables规则中的SSH端口
        update_ssh_iptables_rules "$old_ssh_port" "$SSH_PORT"
        
        # 保存更新后的iptables规则
        save_iptables
        
        log_info "SSH端口配置更新完成"
    else
        log_info "SSH端口未发生变化，保持: $SSH_PORT"
    fi
    
    # 配置fail2ban（使用最新检测到的SSH端口）
    configure_fail2ban_with_ssh_port "$SSH_PORT"
}

# 显示当前状态
show_status() {
    log_step "显示当前配置状态..."
    
    echo -e "\n${GREEN}=== 配置完成总结（CentOS代理服务器优化版 + Docker兼容） ===${NC}"
    echo -e "${BLUE}操作系统:${NC} $OS"
    echo -e "${BLUE}SSH端口:${NC} $SSH_PORT"
    echo -e "${BLUE}iptables模式:${NC} Legacy (Docker兼容)"
    echo -e "${BLUE}iptables状态:${NC} $(systemctl is-active iptables 2>/dev/null || echo "已配置")"
    echo -e "${BLUE}fail2ban状态:${NC} $(systemctl is-active fail2ban)"
    
    echo -e "\n${BLUE}当前开放的端口:${NC}"
    echo "SSH端口: $SSH_PORT (已应用防护)"
    echo "指定TCP端口: 12748, 80, 443, 5222, 7777, 8006, 8080, 8007, 21(FTP), 20(FTP), 30000-31000(FTP被动)"
    echo "高端口范围: 10000-65535 (TCP/UDP) - 适用于代理服务"
    
    echo -e "\n${BLUE}iptables防护规则（CentOS代理优化 + Docker兼容）:${NC}"
    echo "✓ 使用iptables-legacy模式（Docker NAT兼容）"
    echo "✓ 轻量级防护: 5分钟内超过15个新连接才会被限制（兼容CentOS 7内核）"
    echo "✓ 仅对SSH($SSH_PORT)和管理端口应用连接限制"
    echo "✓ 永久禁用ICMP ping"
    echo "✓ 代理端口无连接数限制"
    echo "✓ xt_recent模块参数优化（适配CentOS 7默认限制）"
    
    echo -e "\n${BLUE}Nginx安全配置（代理优化）:${NC}"
    if [[ -f /etc/nginx/conf.d/security.conf ]]; then
        echo "✓ 并发连接限制: 每IP最多100个连接（提高了限制）"
        echo "✓ 请求速率限制: 每IP每秒50个请求，允许突发20个（更宽松）"
        echo "✓ 基本安全防护（移除了可能影响代理的规则）"
        echo "✓ 支持更多HTTP方法（包括PUT、DELETE、OPTIONS）"
    else
        echo "✗ Nginx安全配置未应用（可能因为Nginx未安装）"
    fi
    
    echo -e "\n${BLUE}fail2ban状态（严格SSH防护）:${NC}"
    if systemctl is-active --quiet fail2ban; then
        echo "fail2ban服务状态: $(systemctl is-active fail2ban)"
        echo "✓ SSH防护: 5次失败尝试永久封禁（仅限手动解封）"
        echo "✓ 监控SSH端口: $SSH_PORT（动态检测后配置）"
        fail2ban-client status sshd 2>/dev/null || echo "SSH监控可能有问题"
        
        echo ""
        echo "手动解封IP命令:"
        echo "  fail2ban-client set sshd unbanip <IP地址>"
        echo "查看封禁列表:"
        echo "  fail2ban-client status sshd"
        echo "查看被永久封禁的IP:"
        echo "  iptables -L -n | grep DROP"
    else
        echo "fail2ban服务未运行"
    fi
    
    echo -e "\n${YELLOW}CentOS代理服务器 + Docker兼容优化说明:${NC}"
    echo "• 使用iptables-legacy确保Docker NAT正常工作"
    echo "• 动态检测SSH端口，支持外部脚本修改端口后自动更新配置"
    echo "• 大幅放宽了连接数和频率限制"
    echo "• 开放了高端口范围以支持各种代理协议"
    echo "• 移除了可能误伤代理流量的规则"
    echo "• SSH采用严格防护：5次失败永久封禁"
    echo "• 完全禁用ICMP ping以提高隐蔽性"
    echo "• 被封禁的IP需要手动解封，无法自动恢复"
    echo "• xt_recent参数专门适配CentOS 7内核限制"
    echo "• Docker容器NAT功能完全兼容"
    
    echo -e "\n${BLUE}SSH端口检测详情:${NC}"
    echo "• 最终确认端口: $SSH_PORT"
    echo "• fail2ban监控端口: $SSH_PORT"
    echo "• iptables防护端口: $SSH_PORT"
    echo "• 已动态更新所有相关配置"
    
    echo -e "\n${BLUE}Docker兼容性确认:${NC}"
    echo "• iptables使用legacy模式"
    echo "• Docker NAT功能正常"
    echo "• 容器端口映射无冲突"
    
    # 验证iptables模式
    echo -e "\n${BLUE}iptables模式验证:${NC}"
    if iptables --version 2>/dev/null | grep -q "legacy"; then
        echo "✓ 确认使用iptables-legacy"
    else
        echo "? 请检查iptables模式"
        iptables --version 2>/dev/null || echo "无法获取版本信息"
    fi
}

# 主函数
main() {
    echo -e "${GREEN}========================================${NC}"
    echo -e "${GREEN}   Linux系统安全配置脚本 - Docker兼容版${NC}"
    echo -e "${GREEN}   支持动态SSH端口检测 + Docker NAT${NC}"
    echo -e "${GREEN}========================================${NC}"
    
    check_root
    detect_os
    initial_ssh_port_detection  # 初步检测SSH端口
    update_system
    clean_existing_iptables
    clean_existing_fail2ban
    disable_system_firewalls
    install_iptables  # 安装并配置为legacy模式
    configure_basic_iptables  # 使用初始检测到的SSH端口
    add_custom_ports
    save_iptables
    clean_existing_nginx_config
    configure_nginx_security
    install_fail2ban_only  # 只安装fail2ban，暂不配置
    
    # 运行外部脚本（可能会修改SSH端口）
    log_step "即将运行外部脚本（可能修改SSH端口）..."
    if run_external_script; then
        # 外部脚本运行成功，重新检测SSH端口并更新配置
        post_external_script_ssh_config
    else
        # 外部脚本运行失败，使用当前SSH端口配置fail2ban
        log_warn "外部脚本运行失败，使用当前SSH端口配置fail2ban"
        configure_fail2ban_with_ssh_port "$SSH_PORT"
    fi
    
    show_status
    
    echo -e "\n${GREEN}========================================${NC}"
    echo -e "${GREEN}      所有配置已完成！${NC}"
    echo -e "${GREEN}========================================${NC}"
    
    log_info "系统安全配置完成，建议重启系统以确保所有配置生效"
    echo -e "\n${YELLOW}重要提示:${NC}"
    echo -e "• 此配置针对CentOS代理服务器优化，并完全兼容Docker"
    echo -e "• 已自动检测并配置最终SSH端口: $SSH_PORT"
    echo -e "• 使用iptables-legacy确保Docker NAT功能正常"
    echo -e "• xt_recent参数已优化适配CentOS 7内核限制"
    echo -e "• 如需更严格的安全配置，请手动调整相关参数"
    echo -e "• 建议定期检查fail2ban日志和被封禁的IP列表"
    echo -e "• Docker容器创建NAT规则时不会出现冲突"
    echo -e "• 可使用以下命令检查状态："
    echo -e "  - netstat -tuln  # 查看监听端口"
    echo -e "  - iptables -L -n  # 查看防火墙规则"
    echo -e "  - fail2ban-client status  # 查看fail2ban状态"
    echo -e "  - fail2ban-client status sshd  # 查看SSH防护状态"
    echo -e "  - docker run hello-world  # 测试Docker是否正常"
    echo -e "  - iptables --version  # 确认使用legacy模式"
}

# 执行主函数
main "$@"
