#!/usr/bin/env bash # optimize_apache.sh # Kịch bản tự động tối ưu hóa Apache Web Server để chống nghẽn hàng đợi và Slowloris # Hỗ trợ aaPanel/cPanel và các bản phân phối Linux tiêu chuẩn (CentOS, RHEL, Ubuntu) # Usage: sudo ./optimize_apache.sh set -euo pipefail # Màu sắc hiển thị RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color echo -e "${BLUE}==================================================================${NC}" echo -e "${GREEN} TIẾN TRÌNH TỰ ĐỘNG TỐI ƯU HÓA APACHE WEB SERVER (HIGH PERFORMANCE)${NC}" echo -e "${BLUE}==================================================================${NC}" # 1. KIỂM TRA QUYỀN ROOT if [ "$(id -u)" -ne 0 ]; then echo -e "${RED}LỖI: Vui lòng chạy script này dưới quyền root (sudo).${NC}" exit 1 fi # 2. XÁC ĐỊNH ĐƯỜNG DẪN CẤU HÌNH APACHE APA_DIR="" HTTPD_CONF="" MPM_CONF="" DEFAULT_CONF="" SERVICE_CMD="" if [ -d "/www/server/apache" ]; then # aaPanel / BT.cn APA_DIR="/www/server/apache" HTTPD_CONF="$APA_DIR/conf/httpd.conf" MPM_CONF="$APA_DIR/conf/extra/httpd-mpm.conf" DEFAULT_CONF="$APA_DIR/conf/extra/httpd-default.conf" SERVICE_CMD="/etc/init.d/httpd" echo -e "${GREEN}--> Phát hiện môi trường: aaPanel / Baota Control Panel${NC}" elif [ -f "/etc/httpd/conf/httpd.conf" ]; then # CentOS / RHEL tiêu chuẩn APA_DIR="/etc/httpd" HTTPD_CONF="$APA_DIR/conf/httpd.conf" MPM_CONF="$APA_DIR/conf.modules.d/00-mpm.conf" SERVICE_CMD="systemctl restart httpd" echo -e "${GREEN}--> Phát hiện môi trường: CentOS / RHEL (Standard)${NC}" elif [ -d "/etc/apache2" ]; then # Ubuntu / Debian tiêu chuẩn APA_DIR="/etc/apache2" HTTPD_CONF="$APA_DIR/apache2.conf" SERVICE_CMD="systemctl restart apache2" echo -e "${GREEN}--> Phát hiện môi trường: Ubuntu / Debian (Standard)${NC}" else echo -e "${RED}LỖI: Không tìm thấy thư mục cài đặt Apache tiêu chuẩn.${NC}" exit 2 fi echo -e "--> Thư mục Apache: ${YELLOW}$APA_DIR${NC}" echo -e "--> File cấu hình chính: ${YELLOW}$HTTPD_CONF${NC}" # Tạo thư mục sao lưu cấu hình BACKUP_DIR="$APA_DIR/backup_optimize_$(date +%s)" mkdir -p "$BACKUP_DIR" echo -e "--> Đã tạo thư mục sao lưu tại: ${YELLOW}$BACKUP_DIR${NC}" # Sao lưu file cấu hình hiện tại [ -f "$HTTPD_CONF" ] && cp -a "$HTTPD_CONF" "$BACKUP_DIR/" [ -n "$MPM_CONF" ] && [ -f "$MPM_CONF" ] && cp -a "$MPM_CONF" "$BACKUP_DIR/" [ -n "$DEFAULT_CONF" ] && [ -f "$DEFAULT_CONF" ] && cp -a "$DEFAULT_CONF" "$BACKUP_DIR/" # 3. TÍNH TOÁN CẤU HÌNH THEO TÀI NGUYÊN HỆ THỐNG TOTAL_RAM_KB=$(grep MemTotal /proc/meminfo | awk '{print $2}') TOTAL_RAM_GB=$((TOTAL_RAM_KB / 1024 / 1024)) echo -e "--> Tổng dung lượng RAM hệ thống: ${YELLOW}${TOTAL_RAM_GB} GB${NC}" # Tính toán MaxRequestWorkers dựa trên RAM # Trung bình 1 Thread của Event MPM chiếm ~5MB-10MB. 1 Worker Process chiếm ~30MB-50MB. # Chúng ta sẽ cấu hình an toàn nhưng vẫn đủ lớn để tải luồng video tĩnh. if [ "$TOTAL_RAM_GB" -le 1 ]; then MAX_WORKERS=150 THREADS_PER_CHILD=25 elif [ "$TOTAL_RAM_GB" -le 2 ]; then MAX_WORKERS=250 THREADS_PER_CHILD=25 elif [ "$TOTAL_RAM_GB" -le 4 ]; then MAX_WORKERS=384 THREADS_PER_CHILD=32 else MAX_WORKERS=800 THREADS_PER_CHILD=40 fi echo -e "--> Cấu hình tự động đề xuất MaxRequestWorkers: ${GREEN}$MAX_WORKERS${NC} (ThreadsPerChild: ${GREEN}$THREADS_PER_CHILD${NC})" # 4. CHUYỂN ĐỔI MPM SANG EVENT MPM (NẾU ĐANG CHẠY PREFORK) echo -e "${BLUE}--> [Bước 1] Kiểm tra và cấu hình Event MPM...${NC}" if [ -f "$MPM_CONF" ] && [ -d "/www/server/apache" ]; then # Đối với aaPanel: Cấu hình Event MPM trong extra/httpd-mpm.conf # Đảm bảo bật Include conf/extra/httpd-mpm.conf trong httpd.conf sed -i 's/#Include conf\/extra\/httpd-mpm.conf/Include conf\/extra\/httpd-mpm.conf/g' "$HTTPD_CONF" # Cập nhật thông số Event MPM trong httpd-mpm.conf # Tạo đoạn cấu hình mới NEW_MPM=" StartServers 3 MinSpareThreads 25 MaxSpareThreads 75 ThreadLimit $THREADS_PER_CHILD ThreadsPerChild $THREADS_PER_CHILD MaxRequestWorkers $MAX_WORKERS MaxConnectionsPerChild 10000 " # Thay thế block mpm_event_module trong httpd-mpm.conf bằng thông số tối ưu # Tìm vị trí và thay thế bằng cách truyền biến qua môi trường để tránh lỗi ký tự đặc biệt NEW_MPM="$NEW_MPM" perl -i -0777 -pe 's/.*?<\/IfModule>/$ENV{NEW_MPM}/s' "$MPM_CONF" echo -e "${GREEN} [OK] Đã cập nhật cấu hình Event MPM trong $MPM_CONF${NC}" elif [ -f "/etc/httpd/conf.modules.d/00-mpm.conf" ]; then # CentOS standard: kích hoạt event, tắt prefork/worker sed -i 's/^LoadModule mpm_prefork_module/#LoadModule mpm_prefork_module/g' "$MPM_CONF" sed -i 's/^LoadModule mpm_worker_module/#LoadModule mpm_worker_module/g' "$MPM_CONF" sed -i 's/^#LoadModule mpm_event_module/LoadModule mpm_event_module/g' "$MPM_CONF" # Thêm thông số Event MPM vào cuối file cat >> "$MPM_CONF" < StartServers 3 MinSpareThreads 25 MaxSpareThreads 75 ThreadLimit $THREADS_PER_CHILD ThreadsPerChild $THREADS_PER_CHILD MaxRequestWorkers $MAX_WORKERS MaxConnectionsPerChild 10000 EOF echo -e "${GREEN} [OK] Đã kích hoạt và tối ưu Event MPM trong $MPM_CONF${NC}" elif [ -d "/etc/apache2" ]; then # Ubuntu standard a2dismod mpm_prefork || true a2dismod mpm_worker || true a2enmod mpm_event || true # Tối ưu cấu hình trong /etc/apache2/mods-available/mpm_event.conf MPM_EVENT_DEB="/etc/apache2/mods-available/mpm_event.conf" if [ -f "$MPM_EVENT_DEB" ]; then cp -a "$MPM_EVENT_DEB" "$BACKUP_DIR/" cat > "$MPM_EVENT_DEB" < StartServers 3 MinSpareThreads 25 MaxSpareThreads 75 ThreadLimit $THREADS_PER_CHILD ThreadsPerChild $THREADS_PER_CHILD MaxRequestWorkers $MAX_WORKERS MaxConnectionsPerChild 10000 EOF fi echo -e "${GREEN} [OK] Đã kích hoạt và tối ưu mpm_event trên Ubuntu${NC}" fi # 5. TỐI ƯU HÓA KEEPALIVE VÀ TIMEOUTS ĐỂ TRÁNH NGHẼN KẾT NỐI echo -e "${BLUE}--> [Bước 2] Tối ưu hóa Timeout và Keep-Alive...${NC}" # Thiết lập các giá trị tối ưu hóa trực tiếp vào httpd.conf # Giảm Timeout từ 300s -> 60s # Đảm bảo KeepAlive On, KeepAliveTimeout = 2s hoặc 3s (Tránh giữ kết nối rảnh quá lâu) # MaxKeepAliveRequests lớn (500) để phục vụ nhiều file tĩnh nhanh trên cùng 1 kết nối # Cập nhật trong httpd.conf hoặc các file default if [ -f "$DEFAULT_CONF" ] && [ -d "/www/server/apache" ]; then # aaPanel sử dụng conf/extra/httpd-default.conf sed -i 's/#Include conf\/extra\/httpd-default.conf/Include conf\/extra\/httpd-default.conf/g' "$HTTPD_CONF" # Sửa trong httpd-default.conf sed -i 's/^Timeout .*/Timeout 60/g' "$DEFAULT_CONF" sed -i 's/^KeepAlive .*/KeepAlive On/g' "$DEFAULT_CONF" sed -i 's/^MaxKeepAliveRequests .*/MaxKeepAliveRequests 500/g' "$DEFAULT_CONF" sed -i 's/^KeepAliveTimeout .*/KeepAliveTimeout 2/g' "$DEFAULT_CONF" echo -e "${GREEN} [OK] Đã cập nhật Timeout & Keep-Alive trong $DEFAULT_CONF${NC}" else # Bản phân phối tiêu chuẩn hoặc không có file default tách biệt # Xóa các dòng cũ nếu có trong httpd.conf sed -i '/^Timeout /d' "$HTTPD_CONF" sed -i '/^KeepAlive /d' "$HTTPD_CONF" sed -i '/^MaxKeepAliveRequests /d' "$HTTPD_CONF" sed -i '/^KeepAliveTimeout /d' "$HTTPD_CONF" # Thêm cấu hình tối ưu vào cuối file httpd.conf cat >> "$HTTPD_CONF" < [Bước 3] Kích hoạt và cấu hình mod_reqtimeout (Chống Slow Connection)...${NC}" # Đảm bảo module mod_reqtimeout được nạp if [ -d "/www/server/apache" ]; then # Kích hoạt module trong httpd.conf của aaPanel sed -i 's/#LoadModule reqtimeout_module/LoadModule reqtimeout_module/g' "$HTTPD_CONF" fi # Thêm block cấu hình bảo vệ vào httpd.conf nếu chưa có if ! grep -q "mod_reqtimeout_module" "$HTTPD_CONF"; then cat >> "$HTTPD_CONF" < # Header: Cho phép tối đa 20s nhận Header, nếu tốc độ tối thiểu 500 bytes/s cho phép kéo dài đến tối đa 40s. # Body: Cho phép tối đa 20s nhận Body, nếu tốc độ tối thiểu 500 bytes/s cho phép kéo dài thêm. RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500 EOF echo -e "${GREEN} [OK] Đã thêm cấu hình bảo vệ RequestReadTimeout vào $HTTPD_CONF${NC}" else echo -e "${YELLOW} [!] Cấu hình mod_reqtimeout đã tồn tại trước đó, giữ nguyên.${NC}" fi # 7. KIỂM TRA VÀ KHỞI ĐỘNG LẠI APACHE echo -e "${BLUE}--> [Bước 4] Kiểm tra cú pháp cấu hình Apache...${NC}" TEST_CMD="" if [ -d "/www/server/apache" ]; then TEST_CMD="/www/server/apache/bin/apachectl configtest" elif command -v apache2ctl >/dev/null 2>&1; then TEST_CMD="apache2ctl configtest" else TEST_CMD="apachectl configtest" fi if $TEST_CMD; then echo -e "${GREEN}--> Cú pháp cấu hình hợp lệ! Đang khởi động lại dịch vụ Apache...${NC}" if [ -x "$SERVICE_CMD" ]; then $SERVICE_CMD restart || $SERVICE_CMD start else $SERVICE_CMD fi echo -e "${GREEN}=== TỐI ƯU HÓA APACHE THÀNH CÔNG ===${NC}" echo -e "Hệ thống Apache hiện tại đã được cấu hình chạy ${YELLOW}Event MPM${NC} với các tham số kết nối ngắn để triệt tiêu tình trạng treo cổ chai." else echo -e "${RED}LỖI: Cú pháp cấu hình Apache không hợp lệ. Tiến hành khôi phục cấu hình ban đầu...${NC}" cp -a "$BACKUP_DIR"/* "$APA_DIR/" || true if [ -f "$BACKUP_DIR/httpd-mpm.conf" ] && [ -d "$APA_DIR/conf/extra" ]; then cp -a "$BACKUP_DIR/httpd-mpm.conf" "$APA_DIR/conf/extra/" || true fi if [ -f "$BACKUP_DIR/httpd-default.conf" ] && [ -d "$APA_DIR/conf/extra" ]; then cp -a "$BACKUP_DIR/httpd-default.conf" "$APA_DIR/conf/extra/" || true fi echo -e "${GREEN}--> Đã khôi phục trạng thái cũ. Vui lòng kiểm tra lại log lỗi Apache.${NC}" $TEST_CMD || true exit 3 fi