#!/bin/bash

# Nginx编译安装与配置脚本
# 功能：编译安装 + 常用模块集成 + 基础配置 + 安全加固
# 支持系统：Rocky Linux 8 / Ubuntu 24

set -eo pipefail

# 配置区 ======================================================
NGINX_VERSION="1.25.4"                 # Nginx版本
INSTALL_DIR="/usr/local/nginx"         # 安装目录
WEB_ROOT="/var/www/html"               # 网站根目录
LOG_DIR="/var/log/nginx"               # 日志目录
NGINX_USER="www-data"                  # 运行用户
NGINX_GROUP="www-data"                 # 运行组
CPU_CORES=$(grep -c ^processor /proc/cpuinfo)
SSL_COUNTRY="CN"                       # SSL证书国家
SSL_STATE="Beijing"                    # 省份
SSL_LOCALITY="Beijing"                 # 城市
SSL_ORG="My Company"                   # 组织名称
SSL_OU="IT Dept"                       # 部门名称
SSL_CN="localhost"                     # 域名

# 第三方模块配置
THIRD_PARTY_MODULES=(
    "https://github.com/google/ngx_brotli.git"
    "https://github.com/openresty/headers-more-nginx-module.git"
)

# 函数定义 ====================================================
detect_os() {
    if grep -q "Rocky" /etc/redhat-release 2>/dev/null; then
        echo "rocky"
    elif grep -q "Ubuntu" /etc/lsb-release 2>/dev/null; then
        echo "ubuntu"
    else
        echo "Unsupported OS"
        exit 1
    fi
}

install_dependencies() {
    local os_type=$1
    echo "[+] 安装依赖 ($os_type)..."

    if [ "$os_type" = "rocky" ]; then
        dnf install -y \
            git gcc make pcre-devel zlib-devel openssl-devel \
            wget tar jq gd-devel perl-ExtUtils-Embed \
            GeoIP-devel libxslt-devel gperftools-devel
    elif [ "$os_type" = "ubuntu" ]; then
        apt-get update
        apt-get install -y \
            git build-essential libpcre3-dev zlib1g-dev libssl-dev \
            wget tar jq libgd-dev libperl-dev libgeoip-dev \
            libxslt-dev libgoogle-perftools-dev
    fi
}

prepare_env() {
    echo "[+] 准备环境..."
    # 创建系统用户
    if ! id "$NGINX_USER" &>/dev/null; then
        useradd -r -s /sbin/nologin "$NGINX_USER"
    fi

    # 创建目录结构
    mkdir -p \
        "$WEB_ROOT" \
        "$LOG_DIR" \
        "${INSTALL_DIR}/conf/"{sites-available,sites-enabled} \
        "${INSTALL_DIR}/ssl"
    
    chown -R "$NGINX_USER:$NGINX_GROUP" "$WEB_ROOT" "$LOG_DIR"
}

download_sources() {
    local temp_dir=$(mktemp -d)
    trap 'rm -rf "$temp_dir"' EXIT

    echo "[+] 下载Nginx源码..."
    wget -q "https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz" -P "$temp_dir"
    tar -xzf "$temp_dir/nginx-${NGINX_VERSION}.tar.gz" -C "$temp_dir"

    # 下载第三方模块
    for module in "${THIRD_PARTY_MODULES[@]}"; do
        echo "[+] 下载第三方模块: $(basename $module)"
        git clone --depth 1 "$module" "$temp_dir/$(basename "$module" .git)"
    done

    echo "$temp_dir"
}

compile_nginx() {
    local src_dir=$1
    cd "$src_dir/nginx-${NGINX_VERSION}"

    # 构建配置参数
    local configure_args=(
        "--prefix=${INSTALL_DIR}"
        "--user=${NGINX_USER}"
        "--group=${NGINX_GROUP}"
        "--with-http_ssl_module"
        "--with-http_v2_module"
        "--with-http_realip_module"
        "--with-http_gzip_static_module"
        "--with-http_stub_status_module"
        "--with-http_sub_module"
        "--with-http_geoip_module"
        "--with-http_image_filter_module"
        "--with-stream"
        "--with-threads"
        "--with-file-aio"
        "--with-http_addition_module"
        "--with-http_gunzip_module"
        "--with-http_random_index_module"
        "--with-http_secure_link_module"
    )

    # 添加第三方模块
    for module_path in "${THIRD_PARTY_MODULES[@]}"; do
        local module_name=$(basename "$module_path" .git)
        configure_args+=("--add-module=$src_dir/$module_name")
    done

    # 执行编译安装
    ./configure "${configure_args[@]}"
    make -j$CPU_CORES
    make install
}

generate_ssl() {
    echo "[+] 生成自签名SSL证书..."
    openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
        -keyout "${INSTALL_DIR}/ssl/selfsigned.key" \
        -out "${INSTALL_DIR}/ssl/selfsigned.crt" \
        -subj "/C=$SSL_COUNTRY/ST=$SSL_STATE/L=$SSL_LOCALITY/O=$SSL_ORG/OU=$SSL_OU/CN=$SSL_CN"
}

configure_nginx() {
    echo "[+] 生成配置文件..."

    # 生成nginx.conf
    cat > "${INSTALL_DIR}/conf/nginx.conf" << EOF
user $NGINX_USER $NGINX_GROUP;
worker_processes auto;
error_log $LOG_DIR/error.log warn;
pid ${INSTALL_DIR}/logs/nginx.pid;

events {
    worker_connections 1024;
    multi_accept on;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    
    # 日志格式
    log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" '
                    '\$status \$body_bytes_sent "\$http_referer" '
                    '"\$http_user_agent" "\$http_x_forwarded_for"';
    
    access_log  $LOG_DIR/access.log main;
    
    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;
    server_tokens   off;
    
    keepalive_timeout  65;
    client_max_body_size 100M;
    
    # Gzip配置
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css application/json application/javascript text/xml;
    
    # 站点配置
    include ${INSTALL_DIR}/conf/sites-enabled/*.conf;
}
EOF

    # 生成默认站点配置
    cat > "${INSTALL_DIR}/conf/sites-available/default.conf" << EOF
server {
    listen 80;
    listen [::]:80;
    
    server_name _;
    root $WEB_ROOT;
    
    access_log $LOG_DIR/access.log main;
    error_log $LOG_DIR/error.log;
    
    location / {
        try_files \$uri \$uri/ =404;
    }
    
    location /status {
        stub_status;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    
    ssl_certificate ${INSTALL_DIR}/ssl/selfsigned.crt;
    ssl_certificate_key ${INSTALL_DIR}/ssl/selfsigned.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    
    # 其他配置同80端口...
}
EOF

    # 启用默认站点
    ln -sf "../sites-available/default.conf" "${INSTALL_DIR}/conf/sites-enabled/"
}

setup_service() {
    echo "[+] 配置Systemd服务..."
    cat > /lib/systemd/system/nginx.service << EOF
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=network.target

[Service]
Type=forking
PIDFile=${INSTALL_DIR}/logs/nginx.pid
ExecStartPre=${INSTALL_DIR}/sbin/nginx -t
ExecStart=${INSTALL_DIR}/sbin/nginx
ExecReload=${INSTALL_DIR}/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT \$MAINPID
PrivateTmp=true
User=${NGINX_USER}
Group=${NGINX_GROUP}

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload
}

configure_firewall() {
    local os_type=$1
    echo "[+] 配置防火墙 ($os_type)..."

    if [ "$os_type" = "rocky" ]; then
        if systemctl is-active --quiet firewalld; then
            firewall-cmd --permanent --add-service=http
            firewall-cmd --permanent --add-service=https
            firewall-cmd --reload
        fi
    elif [ "$os_type" = "ubuntu" ]; then
        if command -v ufw &> /dev/null; then
            ufw allow 'Nginx Full'
            ufw reload
        fi
    fi
}

setup_logrotate() {
    echo "[+] 配置日志轮转..."
    cat > /etc/logrotate.d/nginx << EOF
$LOG_DIR/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 0640 $NGINX_USER $NGINX_GROUP
    sharedscripts
    postrotate
        [ -f ${INSTALL_DIR}/logs/nginx.pid ] && kill -USR1 \$(cat ${INSTALL_DIR}/logs/nginx.pid)
    endscript
}
EOF
}

main() {
    # 权限检查
    [[ $EUID -ne 0 ]] && echo "必须使用root权限运行" && exit 1

    local os_type=$(detect_os)
    echo "检测到系统类型: $os_type"

    install_dependencies "$os_type"
    prepare_env
    local src_dir=$(download_sources)
    compile_nginx "$src_dir"
    generate_ssl
    configure_nginx
    setup_service
    configure_firewall "$os_type"
    setup_logrotate

    # 设置权限
    chown -R "$NGINX_USER:$NGINX_GROUP" "$INSTALL_DIR"
    find "$INSTALL_DIR" -type d -exec chmod 755 {} \;
    find "$INSTALL_DIR" -type f -exec chmod 644 {} \;

    # 启动服务
    systemctl enable --now nginx

    echo -e "\n[+] 安装完成!"
    echo "访问地址: http://$(curl -s icanhazip.com)"
    echo "状态检查: systemctl status nginx"
}

main "$@"