#!/bin/bash # Скрипт для диагностики и исправления ошибки 502 Bad Gateway # Проблема: Apache не может связаться с PHP-FPM RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' log_info() { echo -e "${BLUE}[Инфо]${NC} $1"; } log_success() { echo -e "${GREEN}[Успех]${NC} $1"; } log_error() { echo -e "${RED}[Ошибка]${NC} $1"; } log_warning() { echo -e "${YELLOW}[Предупреждение]${NC} $1"; } log_step() { echo -e "${CYAN}[Шаг]${NC} $1"; } echo "==============================================================" echo "Диагностика и исправление ошибки 502 Bad Gateway" echo "==============================================================" # Функция проверки статуса сервиса check_service() { local service=$1 if systemctl is-active --quiet "$service"; then log_success "$service: работает" return 0 else log_error "$service: не работает" return 1 fi } # Шаг 1: Проверка статуса сервисов log_step "Проверка статуса сервисов" check_service "httpd" check_service "php83-php-fpm" || check_service "php-fpm" # Определяем PHP-FPM сервис if systemctl is-active --quiet php83-php-fpm; then PHP_FPM_SERVICE="php83-php-fpm" PHP_FPM_CONF="/etc/opt/remi/php83/php-fpm.d/www.conf" SOCKET_PATH="/var/opt/remi/php83/run/php-fpm/www.sock" log_info "Используется: php83-php-fpm" elif systemctl is-active --quiet php-fpm; then PHP_FPM_SERVICE="php-fpm" PHP_FPM_CONF="/etc/php-fpm.d/www.conf" SOCKET_PATH="/run/php-fpm/www.sock" log_info "Используется: php-fpm" else log_error "PHP-FPM не запущен!" exit 1 fi # Шаг 2: Проверка сокета PHP-FPM log_step "Проверка сокета PHP-FPM" if [ -S "$SOCKET_PATH" ]; then log_success "Сокет существует: $SOCKET_PATH" ls -la "$SOCKET_PATH" # Проверка прав доступа if [ "$(stat -c %U:%G "$SOCKET_PATH")" = "apache:apache" ]; then log_success "Права доступа к сокету корректны" else log_warning "Неправильные права доступа к сокету" chown apache:apache "$SOCKET_PATH" chmod 660 "$SOCKET_PATH" log_info "Права доступа исправлены" fi else log_error "Сокет не существует: $SOCKET_PATH" # Проверяем конфигурацию PHP-FPM log_info "Проверка конфигурации PHP-FPM..." if [ -f "$PHP_FPM_CONF" ]; then grep "^listen" "$PHP_FPM_CONF" fi log_info "Перезапуск PHP-FPM..." systemctl restart "$PHP_FPM_SERVICE" sleep 3 if [ -S "$SOCKET_PATH" ]; then log_success "Сокет создан после перезапуска" else log_error "Сокет не создался, переходим к исправлению конфигурации" fi fi # Шаг 3: Проверка и исправление конфигурации PHP-FPM log_step "Проверка конфигурации PHP-FPM" if [ -f "$PHP_FPM_CONF" ]; then log_info "Конфигурационный файл: $PHP_FPM_CONF" # Создаем резервную копию cp "$PHP_FPM_CONF" "${PHP_FPM_CONF}.backup.$(date +%Y%m%d_%H%M%S)" # Исправляем конфигурацию log_info "Исправление конфигурации PHP-FPM..." # Убеждаемся что используется правильный сокет sed -i "s|^listen = .*|listen = $SOCKET_PATH|" "$PHP_FPM_CONF" sed -i "s|^;listen = .*|listen = $SOCKET_PATH|" "$PHP_FPM_CONF" # Настраиваем права доступа sed -i 's|^;*listen.owner = .*|listen.owner = apache|' "$PHP_FPM_CONF" sed -i 's|^;*listen.group = .*|listen.group = apache|' "$PHP_FPM_CONF" sed -i 's|^;*listen.mode = .*|listen.mode = 0660|' "$PHP_FPM_CONF" # Настраиваем пользователя процесса sed -i 's|^;*user = .*|user = apache|' "$PHP_FPM_CONF" sed -i 's|^;*group = .*|group = apache|' "$PHP_FPM_CONF" # Убираем возможные конфликты с TCP sed -i 's|^listen = 127.0.0.1:9000|; listen = 127.0.0.1:9000|' "$PHP_FPM_CONF" log_success "Конфигурация PHP-FPM обновлена" # Показываем ключевые настройки echo "--- Ключевые настройки PHP-FPM ---" grep -E "^(listen|user|group)" "$PHP_FPM_CONF" | grep -v "^#" else log_error "Конфигурационный файл не найден: $PHP_FPM_CONF" exit 1 fi # Шаг 4: Проверка и исправление конфигурации Apache log_step "Проверка конфигурации Apache" # Проверяем загрузку необходимых модулей log_info "Проверка модулей Apache..." if httpd -M 2>/dev/null | grep -q "proxy_module"; then log_success "Модуль proxy загружен" else log_warning "Модуль proxy не загружен" fi if httpd -M 2>/dev/null | grep -q "proxy_fcgi_module"; then log_success "Модуль proxy_fcgi загружен" else log_warning "Модуль proxy_fcgi не загружен" fi # Создаем правильную конфигурацию Apache для PHP-FPM log_info "Создание конфигурации Apache для PHP-FPM..." cat > /etc/httpd/conf.d/php-fpm.conf << EOF # PHP-FPM configuration for Apache # Загрузка необходимых модулей LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so # Обработка PHP файлов через PHP-FPM SetHandler "proxy:unix:$SOCKET_PATH|fcgi://localhost" # Альтернативный способ для всех .php файлов ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:$SOCKET_PATH|fcgi://localhost/var/www/html/ # Настройки таймаутов ProxyTimeout 300 ProxyPreserveHost On # Индексные файлы DirectoryIndex index.php index.html # Логирование ошибок прокси LogLevel proxy:trace1 EOF # Также обновляем основную конфигурацию виртуального хоста log_info "Обновление конфигурации виртуального хоста..." # Проверяем есть ли файл конфигурации altcor if [ -f /etc/httpd/conf.d/altcor.conf ]; then VHOST_CONF="/etc/httpd/conf.d/altcor.conf" else VHOST_CONF="/etc/httpd/conf.d/000-default.conf" fi # Добавляем или обновляем секцию обработки PHP if [ -f "$VHOST_CONF" ]; then cp "$VHOST_CONF" "${VHOST_CONF}.backup.$(date +%Y%m%d_%H%M%S)" # Убираем старые настройки PHP sed -i '/SetHandler application\/x-httpd-php/d' "$VHOST_CONF" sed -i '/AddHandler php[0-9]*-script/d' "$VHOST_CONF" log_success "Основная конфигурация виртуального хоста обновлена" fi # Шаг 5: Создание директории для сокета log_step "Проверка директории сокета" socket_dir=$(dirname "$SOCKET_PATH") if [ ! -d "$socket_dir" ]; then log_info "Создание директории: $socket_dir" mkdir -p "$socket_dir" fi chown apache:apache "$socket_dir" chmod 755 "$socket_dir" log_success "Директория сокета настроена: $socket_dir" # Шаг 6: Проверка SELinux (если активен) if command -v getenforce >/dev/null 2>&1 && [ "$(getenforce)" = "Enforcing" ]; then log_step "Настройка SELinux" log_info "SELinux включен, настраиваем политики..." # Разрешаем Apache подключаться к сокету PHP-FPM setsebool -P httpd_can_network_connect 1 2>/dev/null || true setsebool -P httpd_execmem 1 2>/dev/null || true # Устанавливаем правильный контекст для сокета semanage fcontext -a -t httpd_var_run_t "$SOCKET_PATH" 2>/dev/null || true restorecon -R "$(dirname "$SOCKET_PATH")" 2>/dev/null || true log_success "SELinux политики обновлены" fi # Шаг 7: Тестирование конфигурации log_step "Тестирование конфигурации Apache" if httpd -t; then log_success "Конфигурация Apache корректна" else log_error "Ошибки в конфигурации Apache:" httpd -t exit 1 fi # Шаг 8: Перезапуск сервисов в правильном порядке log_step "Перезапуск сервисов" log_info "Перезапуск PHP-FPM..." systemctl restart "$PHP_FPM_SERVICE" sleep 3 if systemctl is-active --quiet "$PHP_FPM_SERVICE"; then log_success "PHP-FPM перезапущен" else log_error "PHP-FPM не запустился" systemctl status "$PHP_FPM_SERVICE" --no-pager exit 1 fi log_info "Перезапуск Apache..." systemctl restart httpd sleep 2 if systemctl is-active --quiet httpd; then log_success "Apache перезапущен" else log_error "Apache не запустился" systemctl status httpd --no-pager exit 1 fi # Шаг 9: Финальная диагностика log_step "Финальная проверка" echo "--- Статус сервисов ---" systemctl status httpd --no-pager -l | head -10 systemctl status "$PHP_FPM_SERVICE" --no-pager -l | head -10 echo "--- Проверка сокета ---" if [ -S "$SOCKET_PATH" ]; then log_success "Сокет активен: $SOCKET_PATH" ls -la "$SOCKET_PATH" else log_error "Сокет не активен: $SOCKET_PATH" fi echo "--- Тест PHP ---" cat > /var/www/html/phpinfo.php << 'EOF' EOF log_info "Создан тестовый файл /var/www/html/phpinfo.php" echo "" log_success "Исправление завершено!" echo "" echo "Проверьте работу:" echo "• http://62.109.14.183/phpinfo.php" echo "• http://62.109.14.183/" echo "" echo "Логи для отладки:" echo "• Apache: /var/log/httpd/error_log" echo "• PHP-FPM: /var/opt/remi/php83/log/php-fpm/error.log" echo "" echo "Если проблема сохраняется, проверьте логи:" echo "tail -f /var/log/httpd/error_log"