#!/bin/bash

# Linux系统安全配置脚本
# 功能：系统检测、防火墙配置、端口管理、fail2ban配置

set -e

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

# 日志函数
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"
}

# 更新系统包管理器
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外)
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
install_iptables() {
    log_step "安装并配置iptables..."
    
    case $PACKAGE_MANAGER in
        "yum")
            log_info "正在安装iptables和相关服务，可能需要确认..."
            yum install -y iptables iptables-services
            systemctl enable iptables
            systemctl start iptables
            ;;
        "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
            ;;
    esac
    
    log_info "iptables安装完成"
}

# 配置基础iptables规则
configure_basic_iptables() {
    log_step "配置基础iptables规则..."
    
    # 清空现有规则
    log_info "清空现有iptables规则..."
    iptables -F
    iptables -X
    iptables -t nat -F
    iptables -t nat -X
    iptables -t mangle -F
    iptables -t mangle -X
    
    # 设置默认策略
    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
    
    # 开放SSH端口(22)
    log_info "开放SSH端口(22)..."
    iptables -A INPUT -p tcp --dport 22 -j ACCEPT
    
    # 开放指定端口
    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
    
    # 永久关闭ICMP ping
    log_info "禁用ICMP ping..."
    iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
    
    log_info "基础iptables规则配置完成"
    log_info "已开放端口: 22(SSH), 12748, 80, 443"
    log_info "已永久禁用ICMP ping"
}

# 用户交互：添加自定义端口
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
                iptables -A INPUT -p tcp --dport "$port" -j ACCEPT
                log_info "已开放TCP端口: $port"
            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规则已保存"
}

# 安装和配置fail2ban
install_configure_fail2ban() {
    log_step "安装和配置fail2ban..."
    
    # 安装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
    
    # 配置fail2ban
    log_info "配置fail2ban规则..."
    cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
# 封禁时间(秒) - 12小时
bantime = 43200
# 查找时间窗口(秒) - 10分钟
findtime = 600
# 最大重试次数
maxretry = 5
# 忽略的IP地址
ignoreip = 127.0.0.1/8 ::1

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
bantime = 43200
findtime = 600
EOF

    # CentOS/RHEL的日志路径不同
    if [[ "$OS" == "centos" || "$OS" == "rhel" ]]; then
        sed -i 's|/var/log/auth.log|/var/log/secure|g' /etc/fail2ban/jail.local
    fi
    
    # 启动fail2ban服务
    log_info "启动fail2ban服务..."
    systemctl enable fail2ban
    systemctl restart fail2ban
    
    log_info "fail2ban安装和配置完成"
    log_info "SSH防护规则: 连续5次登录失败将封禁IP 12小时"
}

# 显示当前状态
show_status() {
    log_step "显示当前配置状态..."
    
    echo -e "\n${GREEN}=== 配置完成总结 ===${NC}"
    echo -e "${BLUE}操作系统:${NC} $OS"
    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}"
    iptables -L INPUT -n | grep "dpt:" | awk '{print $7}' | sort -u
    
    echo -e "\n${BLUE}fail2ban状态:${NC}"
    fail2ban-client status sshd 2>/dev/null || echo "fail2ban SSH监控已启用"
}

# 运行外部脚本
run_external_script() {
    log_step "准备运行外部脚本..."
    echo -e "${YELLOW}即将运行外部脚本，该脚本包含交互内容${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 "下载外部脚本失败"
    fi
}

# 主函数
main() {
    echo -e "${GREEN}========================================${NC}"
    echo -e "${GREEN}      Linux系统安全配置脚本${NC}"
    echo -e "${GREEN}========================================${NC}"
    
    check_root
    detect_os
    update_system
    disable_system_firewalls
    install_iptables
    configure_basic_iptables
    add_custom_ports
    save_iptables
    install_configure_fail2ban
    show_status
    run_external_script
    
    echo -e "\n${GREEN}========================================${NC}"
    echo -e "${GREEN}      所有配置已完成！${NC}"
    echo -e "${GREEN}========================================${NC}"
    
    log_info "系统安全配置完成，建议重启系统以确保所有配置生效"
}

# 执行主函数
main "$@"
