Команды Диагностика VPS PEM→PFX

Хостинг Apache + Nginx

Apache обрабатывает PHP, Nginx отдаёт статику (css/js/img). Доступ к error.log и access.log. Можно менять версию PHP через панель. Нет sudo — только .htaccess

VPS / VDS Полный root

Полный доступ к серверу. systemd, Nginx/Apache конфиги, iptables, все логи. Полный контроль над всеми службами и настройками.

CMS WordPress / Joomla / Bitrix

Типичные проблемы каждой CMS с пошаговыми решениями. Кэш, плагины, конфигурация, совместимость с PHP и сервером.

403 Forbidden
500 Internal Error
502 Bad Gateway
503 Unavailable
504 Timeout
.htaccess Rules
Apache на хостинге

Хостинг 403 Forbidden

На вашем хостинге Nginx стоит перед Apache и отдаёт статику (css, js, изображения), а динамические запросы (.php) проксирует на Apache. 403 может возникнуть на обоих уровнях.

БраузерNginx (статика: .css .js .png) → Apache (PHP) → PHP
1
Проверить error.log — что именно блокирует
Цель: error.log покажет точную причину: это Nginx заблокировал или Apache. Если 403 на статике (css/js) — проблема в Nginx. Если на .php — проблема в Apache.
# Путь к error.log зависит от хостинга. # Типичные пути: ~/www/site/logs/error.log /var/www/username/data/logs/site.error.log ~/logs/site_error.log tail -f ~/www/site/logs/error.log
open() ... failed (13: Permission denied) — Apache не может прочитать файл. directory index of "..." is forbidden — нет index.php в директории.
2
Проверить права файлов через FTP/SSH
Цель: Файлы должны быть доступны для чтения пользователю Apache. Стандарт: файлы 644, папки 755.
# Через SSH (из корня сайта): find . -type f -not -perm 644 -exec chmod 644 {} \; find . -type d -not -perm 755 -exec chmod 755 {} \; # Через FTP: правый клик → File Permissions → 644/755
Не ставьте 777! На некоторых хостингах файлы принадлежат системному пользователю — тогда достаточно прав 644/755.
3
Проверить .htaccess
Цель: Ошибки в .htaccess — причина №1 для 403 на Apache. Переименуйте .htaccess → .htaccess.bak и проверьте.
mv .htaccess .htaccess.bak
Если заработал — проблема в .htaccess. Восстанавливайте правила по одному. Типичные ошибки: Deny from all, Require all denied, кривые RewriteRule.
4
Проверить Nginx для статики
Цель: Если 403 возникает на статических файлах (css, js, картинки) — проблема в конфигурации Nginx на стороне хостинга. Проверьте access.log: если запрос к .css/.js/.png возвращает 403 — Nginx не может прочитать файл.
# access.log — видим какие запросы возвращают 403: grep " 403 " ~/www/site/logs/access.log
Если в access.log 403 на статике — проблема на стороне конфигурации хостинга. Проверьте что файлы доступны для чтения и нет правил блокировки в .htaccess.
5
Проверить наличие index.php
Цель: В корневой директории сайта (обычно public_html или www) должен быть index.php. Без него — 403.
Обратите внимание на регистр: index.php != Index.php на Linux. Также убедитесь что сайт указывает на правильную директорию в настройках хостинга.

Хостинг 500 Internal Server Error

500 означает что Apache/PHP столкнулся с ошибкой. На хостинге с Apache + Nginx для статики 500 почти всегда вызван PHP или .htaccess.

1
error.log — главная точка диагностики
Цель: error.log содержит детальное описание ошибки PHP или Apache.
tail -f ~/www/site/logs/error.log # Фильтрация по типу ошибки: grep "PHP Fatal" ~/www/site/logs/error.log | tail -10 grep "Parse error" ~/www/site/logs/error.log | tail -10 grep "Allowed memory" ~/www/site/logs/error.log | tail -10
Ключевые фразы в error.log: PHP Fatal error (ошибка в коде), Parse error (синтаксис), Allowed memory size exhausted (нехватка памяти), .htaccess: Invalid command (ошибка в .htaccess).
2
Проверить .htaccess
Цель: Синтаксическая ошибка в .htaccess — причина 500. Переименуйте и проверьте.
mv .htaccess .htaccess.bak
Если сайт заработал — ошибка в .htaccess. Типичные проблемы: php_flag (не работает в PHP-FPM режиме), RewriteRule с ошибками, Options с запрещёнными директивами.
3
Включить отображение ошибок PHP
Цель: Создать тестовый файл для вывода ошибки прямо в браузере.
Удалите test.php сразу после диагностики!
4
Сменить версию PHP
Цель: Смена версии PHP перезапускает PHP-процессы. Также 500 может быть из-за несовместимости кода с текущей версией PHP.
В панели хостинга смените PHP на соседнюю версию (например 8.1 → 8.2). Если заработало — проблема в совместимости кода. Также смена версии перезапускает зависшие PHP-процессы.
5
Увеличить лимиты PHP через панель хостинга
Цель: Если error.log показывает «Allowed memory size exhausted» — увеличьте лимиты через панель хостинга.
# .htaccess (если Apache + mod_php): php_value memory_limit 256M php_value max_execution_time 120 php_value upload_max_filesize 64M php_value post_max_size 64M
На большинстве хостингов с PHP-FPM/CGI лимиты задаются через панель: «PHP Settings», «PHP Manager», «Select PHP Version». Если error.log показывает «Allowed memory» — увеличьте memory_limit минимум до 256M.
6
Проверить PHP расширения
Цель: Отсутствующее PHP-расширение = 500. Создайте info.php для проверки.
<?php phpinfo(); ?> // Сохранить как info.php, открыть в браузере // Удалить после проверки!
Типичные необходимые расширения: mbstring, curl, xml/dom, json, zip, gd/intl, pdo_mysql. Включите их в панели хостинга в разделе «Расширения PHP».

Хостинг 502 Bad Gateway

На хостинге с Nginx перед Apache: 502 означает что Nginx не получил ответ от Apache. Это значит Apache упал, перезапускается или перегружен. Вы не управляете Apache напрямую, но можете влиять через PHP и логи.

БраузерNginxApache DOWN502
1
Подождать 1-2 минуты
Цель: На хостинге Apache/PHP-FPM часто перезапускается автоматически. 502 может быть временным (Apache перезагружается или PHP-процесс крашится и восстанавливается).
Если 502 появляется периодически — это признак нестабильности: PHP-процессы падают и перезапускаются. Переходите к следующим шагам.
2
Проверить error.log — почему Apache не отвечает
Цель: error.log покажет что происходит с Apache/PHP.
tail -50 ~/www/site/logs/error.log grep -i "child\|crash\|segfault" ~/www/site/logs/error.log | tail -10
server reached MaxRequestWorkers — все процессы Apache заняты. segfault — PHP-расширение крашит процесс. Out of memory — нехватка RAM.
3
Сменить версию PHP — перезапуск
Цель: Смена версии PHP в панели хостинга перезапускает PHP-процессы и Apache worker'ы. Это «лечит» зависшие процессы.
В панели хостинга смените PHP на другую версию, подождите 30 секунд, затем верните обратно. Это принудительный перезапуск PHP-FPM/Apache.
4
Уменьшить нагрузку — отключить тяжёлые скрипты
Цель: Если Apache перегружен и не отвечает — нужно снизить нагрузку. Частые виновники: backup-плагины, импорт/экспорт, cron-задачи, брутфорс.
WordPress: переименуйте папку подозрительного плагина через FTP (plugins/plugin-nameplugin-name.disabled). Также проверьте wp-cron.php — он может запускаться при каждом визите.
5
Проверить PHP-FPM на утечки памяти
Цель: Периодические 502 часто вызваны утечками памяти PHP-процессов. Параметр pm.max_requests заставляет процессы перезапускаться.
# Размер одного PHP процесса: ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1 } END { printf ("%dMB\n", sum/NR/1024) }' # В панели хостинга установить: # pm.max_requests = 500 # pm.max_children = увеличить
pm.max_requests = 500 означает что процесс перезапускается после 500 запросов — это предотвращает накопление утечек памяти. Если размер одного процесса > 150MB — ищите проблемный скрипт.

Хостинг 503 Service Unavailable

503 на хостинге обычно означает что Apache/PHP перегружен: все worker-процессы заняты, превышен лимит одновременных соединений (Entry Processes), или сервер хостинга перегружен другими пользователями.

1
Проверить access.log — паттерн запросов
Цель: access.log покажет что вызывает перегрузку: боты, брутфорс, один тяжёлый запрос, или много одновременных.
# Топ IP по количеству запросов: awk '{print $1}' ~/www/site/logs/access.log | sort | uniq -c | sort -rn | head -10 # Топ запрашиваемых URL: awk '{print $7}' ~/www/site/logs/access.log | sort | uniq -c | sort -rn | head -10
Если один IP делает сотни запросов — это бот или брутфорс. Если все запросы к wp-login.php или xmlrpc.php — атака на WordPress.
2
Заблокировать ботов через .htaccess
Цель: Если access.log показывает аномальную активность — заблокируйте через .htaccess.
# В .htaccess — заблокировать IP: <RequireAll> Require all granted Require not ip 1.2.3.4 </RequireAll> # Заблокировать wp-login.php: <Files wp-login.php> Require all denied </Files> # Заблокировать xmlrpc.php: <Files xmlrpc.php> Require all denied </Files>
3
Отключить wp-cron (WordPress)
Цель: wp-cron.php запускается при каждом визите на сайт. При высокой посещаемости это может загрузить сервер.
# В wp-config.php (перед «That's all, stop editing»): define('DISABLE_WP_CRON', true);
После отключения wp-cron настройте cron через панель хостинга: wget -q -O - https://site.com/wp-cron.php?doing_wp_cron каждые 15 минут.
4
Включить кеширование статики через Nginx
Цель: Убедиться что Nginx отдаёт статику без обращения к Apache. Проверьте access.log: если css/js/img обрабатываются Apache (статус 200 в access.log Apache), а не Nginx — настройка хостинга не оптимальна.
Убедитесь что кеширование включено: WordPress — плагин кеширования (LiteSpeed Cache, WP Super Cache). Также проверьте что статические файлы имеют заголовки Cache-Control через .htaccess.

Хостинг 504 Gateway Timeout

504 означает что Nginx дождался ответа от Apache, но тот не уложился в таймаут. Apache + PHP обрабатывают запрос слишком долго.

1
access.log — найти медленный URL
Цель: access.log содержит время ответа. Найдите какие запросы самые медленные.
# Найти URL с 504: grep " 504 " ~/www/site/logs/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -10
2
Увеличить max_execution_time через панель
Цель: Увеличить время выполнения PHP через панель хостинга или .htaccess.
# .htaccess (если Apache + mod_php): php_value max_execution_time 300 php_value max_input_time 300 php_value memory_limit 512M
На хостингах с PHP-FPM/CGI: откройте панель → «PHP Settings» → увеличьте max_execution_time. Изменения вступают в силу через 1-2 минуты.
3
Оптимизировать CMS
Цель: Вместо увеличения таймаута лучше ускорить сам сайт.
WordPress: Query Monitor — покажет медленные запросы. Оптимизируйте БД через WP-Optimize. Удалите неиспользуемые плагины. Включите объектный кеш (Redis/Memcached если хостинг поддерживает). Joomla: очистите кеш через админку. Bitrix: включите композитный кеш и кеширование в настройках.
4
Проверить медленные SQL-запросы
Цель: 504 часто вызван медленным SQL-запросом. Найдите и оптимизируйте его.
# WordPress wp-config.php: define('SAVEQUERIES', true); # Плагин Query Monitor — покажет # все запросы и время выполнения # Joomla: Debug System: Yes # покажет SQL внизу страницы
SAVEQUERIES записывает каждый SQL-запрос. Отключите после диагностики — это замедляет сайт. Query Monitor показывает запросы прямо в админке.

Хостинг Практичные правила .htaccess

Готовые блоки .htaccess для shared-хостинга. Копируйте нужные секции. Не вставляйте всё сразу — добавляйте по одному блоку и проверяйте сайт.

1
Редиректы — HTTP на HTTPS, www, канонические URL
HTTP → HTTPS: Принудительный редирект всех запросов на защищённое соединение.
RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
www → без www (или наоборот):
# www → без www: RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC] RewriteRule ^(.*)$ https://%1/$1 [R=301,L] # без www → www: RewriteCond %{HTTP_HOST} !^www\. [NC] RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
Редирект старой страницы на новую:
Redirect 301 /old-page.html https://example.com/new-page Redirect 301 /old-category/ https://example.com/new-category/
Редирект со старого домена на новый:
RewriteEngine On RewriteCond %{HTTP_HOST} ^old-domain\.com$ [NC,OR] RewriteCond %{HTTP_HOST} ^www\.old-domain\.com$ [NC] RewriteRule ^(.*)$ https://new-domain.com/$1 [R=301,L]
Редирект старого домена ставится в .htaccess корня СТАРОГО сайта. SSL на старом домене должен быть активен, иначе браузер покажет предупреждение до редиректа.
2
Security Headers — HSTS, CSP, X-Frame, X-Content-Type
Базовый набор заголовков безопасности:
Header always set X-Content-Type-Options "nosniff" Header always set X-Frame-Options "SAMEORIGIN" Header always set X-XSS-Protection "1; mode=block" Header always set Referrer-Policy "strict-origin-when-cross-origin" Header always set Permissions-Policy "geolocation=(), camera=(), microphone=()"
HSTS — принудительный HTTPS (только если SSL работает стабильно):
Header always set Strict-Transport-Security \ "max-age=31536000; includeSubDomains" env=HTTPS
Content Security Policy — базовый:
Header always set Content-Security-Policy \ "default-src 'self'; script-src 'self' 'unsafe-inline'; \ style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; \ font-src 'self' data:"
CSP может сломать внешний скрипты (Google Analytics, YouTube embed, рекламные сети). Тестируйте в режиме report-only перед применением: замените Content-Security-Policy на Content-Security-Policy-Report-Only.
3
Блокировка доступа к敏感ным файлам и директориям
Запрет доступа к конфигурационным и системным файлам:
# Блокировка скрытых файлов и директорий: RewriteRule (^\.|/\.) - [F,L] # Блокировка чувствительных файлов: <FilesMatch "^(\.|wp-config\.php|php\.ini|\.env| package\.json|composer\.json|composer\.lock| \.git|\.htaccess|\.htpasswd)"> Require all denied </FilesMatch> # Блокировка логов и бэкапов: <FilesMatch "\.(log|bak|old|orig|save|swp|sql| tar|gz|zip|rar)$"> Require all denied </FilesMatch>
Запрет листинга директорий:
Options -Indexes
Отключение серверной сигнатуры:
ServerSignature Off Header unset Server
ServerSignature Off и Header unset Server могут не работать на shared-хостинге — это директивы уровня сервера. Но попробовать стоит.
4
Блокировка по User-Agent — боты, сканеры, парсеры
Блокировка известных плохих ботов:
RewriteEngine On RewriteCond %{HTTP_USER_AGENT} ^$ [NC,OR] RewriteCond %{HTTP_USER_AGENT} \ (AhrefsBot|SemrushBot|MJ12bot|DotBot|Rogerbot|\ exabot|ia_archiver|Sogou|Baiduspider) [NC] RewriteRule ^ - [F,L]
Блокировка сканеров уязвимостей:
RewriteCond %{HTTP_USER_AGENT} \ (nikto|sqlmap|nmap|masscan|ZmEu|w3af|\ acunetix|nessus|openvas) [NC] RewriteRule ^ - [F,L]
Блокировка PHP-скриптов в uploads:
# Положить этот .htaccess В ПАПКУ uploads: <FilesMatch "\.(php|phtml|php3|php4|php5| phps|pl|cgi|py|jsp|asp)$"> Require all denied </FilesMatch>
Отдельный .htaccess в папке uploads — важная линия защиты. Если хакер загрузит PHP-шелл через уязвимость, он не сможет его выполнить.
5
Блокировка по IP и по стране (GeoIP)
Блокировка отдельных IP:
<RequireAll> Require all granted Require not ip 1.2.3.4 Require not ip 5.6.7.0/24 </RequireAll>
Разрешить доступ только с определённых IP (для админки):
# Положить в .htaccess внутри wp-admin/: Require ip 1.2.3.4 Require ip 5.6.7.8
GeoIP — блокировка по стране (требует mod_geoip):
# Блокировка стран (требует mod_geoip): GeoIPEnable On SetEnvIf GEOIP_COUNTRY_CODE CN BlockCountry SetEnvIf GEOIP_COUNTRY_CODE RU BlockCountry Deny from env=BlockCountry # Разрешить ТОЛЬКО определённые страны: SetEnvIf GEOIP_COUNTRY_CODE US AllowCountry SetEnvIf GEOIP_COUNTRY_CODE GB AllowCountry Deny from all Allow from env=AllowCountry
mod_geoip редко доступен на shared-хостинге. Альтернатива: блокировка по стране через Cloudflare (Firewall Rules) или панель хостинга если поддерживает.
6
Защита от брутфорса — wp-login.php и xmlrpc.php
Ограничение доступа к wp-login.php по IP:
RewriteCond %{REQUEST_URI} ^(.*)?wp-login\.php(.*)$ [OR] RewriteCond %{REQUEST_URI} ^(.*)?wp-admin$ RewriteCond %{REMOTE_ADDR} !^1\.2\.3\.4$ RewriteRule ^(.*)$ - [R=403,L]
Полная блокировка xmlrpc.php:
RedirectMatch 404 /xmlrpc\.php
Rate limiting через RewriteMap (если поддерживается):
# Простой rate limit через .htaccess: # (требует mod_rewrite и mod_ratelimit) <IfModule mod_ratelimit.c> <Location /> SetOutputFilter RATE_LIMIT SetEnv rate-limit 400 </Location> </IfModule>
На shared-хостинге лучший способ защиты от брутфорса — Cloudflare (бот-менеджмент) или плагин вроде Wordfence. .htaccess не может считать запросы между разными процессами Apache.
7
Кеширование статики — Brotli/Gzip, Cache-Control, ETag
Сжатие Brotli (приоритет) + Gzip (фолбэк):
# Brotli сжатие (приоритет): <IfModule mod_brotli.c> AddOutputFilterByType BROTLI_COMPRESS \ text/html text/plain text/xml text/css \ application/javascript application/json \ image/svg+xml </IfModule> # Gzip сжатие (фолбэк): <IfModule mod_deflate.c> AddOutputFilterByType DEFLATE \ text/html text/plain text/xml text/css \ application/javascript application/json \ image/svg+xml </IfModule>
Cache-Control для статики:
<IfModule mod_expires.c> ExpiresActive On ExpiresByType image/jpeg "access plus 1 year" ExpiresByType image/png "access plus 1 year" ExpiresByType image/webp "access plus 1 year" ExpiresByType image/svg+xml "access plus 1 year" ExpiresByType text/css "access plus 1 month" ExpiresByType application/javascript "access plus 1 month" ExpiresByType font/woff2 "access plus 1 year" ExpiresByType font/ttf "access plus 1 year" </IfModule> <FilesMatch "\.(jpg|jpeg|png|webp|svg|ico|gif)$"> Header set Cache-Control "max-age=31536000, public, immutable" </FilesMatch> <FilesMatch "\.(css|js)$"> Header set Cache-Control "max-age=2592000, public" </FilesMatch>
Отключение ETag (чтобы не дублировал Cache-Control):
FileETag None Header unset ETag
8
ModSecurity — WAF правила для .htaccess
Включить/выключить ModSecurity для сайта:
# Отключить ModSecurity (если ложные срабатывания): <IfModule mod_security2.c> SecRuleEngine Off </IfModule> # Отключить конкретное правило: <IfModule mod_security2.c> SecRuleRemoveById 950001 </IfModule>
Защита от SQL-инъекций и XSS через RewriteRule:
RewriteEngine On # Блокировка SQL-инъекций: RewriteCond %{QUERY_STRING} \ (union.*select|insert.*into|update.*set|delete.*from) [NC,OR] RewriteCond %{QUERY_STRING} (--|;|\'|\%27) [OR] RewriteCond %{QUERY_STRING} (concat|char\(|load_file) [NC] RewriteRule ^ - [F,L] # Блокировка XSS: RewriteCond %{QUERY_STRING} (<script|%3Cscript) [NC,OR] RewriteCond %{QUERY_STRING} (javascript:|onerror=|onload=) [NC] RewriteRule ^ - [F,L]
Это не замена полноценному WAF. ModSecurity (OWASP CRS) или Cloudflare WAF дают гораздо лучшую защиту. Эти правила — базовый фильтр для shared-хостинга без WAF.
9
MIME-типы и обработка файлов
Корректные MIME-типы для современных форматов:
AddType image/webp .webp AddType image/avif .avif AddType font/woff2 .woff2 AddType application/font-woff .woff AddType application/json .json AddType video/mp4 .mp4 AddType video/webm .webm
Запрет выполнения PHP в определённых директориях:
# Положить в .htaccess внутри папки: RemoveHandler .php .phtml .php3 .php4 .php5 RemoveType .php .phtml .php3 .php4 .php5 AddType text/plain .php .phtml .php3 .php4 .php5
AddType text/plain означает что PHP-файлы в этой директории будут отдаваться как обычный текст, а не выполняться. Это дополнительная линия защиты если FilesMatch не сработал.
10
Полный готовый шаблон .htaccess
Универсальный шаблон для WordPress на shared-хостинге:
# === 1. Базовые настройки === Options -Indexes +FollowSymLinks ServerSignature Off # === 2. HTTP → HTTPS === RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L] # === 3. www → без www === RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC] RewriteRule ^(.*)$ https://%1/$1 [R=301,L] # === 4. Security Headers === Header always set X-Content-Type-Options "nosniff" Header always set X-Frame-Options "SAMEORIGIN" Header always set X-XSS-Protection "1; mode=block" Header always set Referrer-Policy "strict-origin-when-cross-origin" # === 5. Блокировка чувствительных файлов === <FilesMatch "^(\.|wp-config\.php|php\.ini|\.env|\.git)"> Require all denied </FilesMatch> # === 6. Сжатие === <IfModule mod_deflate.c> AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript application/json </IfModule> # === 7. Кеширование статики === <IfModule mod_expires.c> ExpiresActive On ExpiresByType image/jpeg "access plus 1 year" ExpiresByType image/png "access plus 1 year" ExpiresByType image/webp "access plus 1 year" ExpiresByType text/css "access plus 1 month" ExpiresByType application/javascript "access plus 1 month" ExpiresByType font/woff2 "access plus 1 year" </IfModule> # === 8. Блокировка xmlrpc === RedirectMatch 404 /xmlrpc\.php # === 9. WordPress Rewrite === <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>
Перед заменой .htaccess сделайте бэкап текущего файла. Добавляйте секции по одной и проверяйте сайт после каждой. Если после добавления секции сайт сломался — уберите её и проверьте error.log.

Хостинг Apache на shared-хостинге

На большинстве shared-хостингов Apache работает за Nginx-прокси. Nginx отдаёт статику, Apache обрабатывает PHP. У вас нет доступа к httpd.conf, но есть .htaccess, логи и панель хостинга.

1
Как работает Nginx + Apache на хостинге
Типичная архитектура shared-хостинга:
БраузерNginx:80/443 (статика) → Apache:8080 (PHP) → PHP-FPM/CGI
# Определить архитектуру хостинга: curl -sI https://site.com | grep -i server # Кто отдаёт статику: curl -sI https://site.com/style.css | grep -i server # Кто обрабатывает PHP: curl -sI https://site.com/index.php | grep -i "X-Powered-By"
Если curl показывает "Server: nginx" для статики и "Server: Apache" для PHP — классическая связка Nginx + Apache. Если везде "Server: nginx" — Nginx работает как reverse proxy и может отдавать PHP через fastcgi (без Apache).
2
Apache MPM — какой режим работает
Три режима MPM (Multi-Processing Module):
# Определить MPM (если есть SSH): apachectl -V | grep -i mpm # Возможные результаты: # mpm_prefork — один процесс = один запрос # mpm_worker — потоки + процессы # mpm_event — современный, лучший для PHP-FPM
Что это значит для вас:
# Prefork + mod_php: # - Каждый запрос = процесс Apache # - Высокое потребление RAM # - php_value/php_flag в .htaccess работают # Event/Worker + PHP-FPM: # - PHP — отдельный процесс # - Меньше RAM, выше скорость # - php_value/php_flag в .htaccess НЕ работают # - Настройки через панель хостинга
Большинство современных хостингов используют Event + PHP-FPM. Если php_value в .htaccess вызывает 500 Internal Error — у вас PHP-FPM. Используйте панель хостинга для настройки PHP.
3
Логи Apache — где найти и как читать
Типичные пути к логам на shared-хостинге:
# ISPmanager: ~/www/site/logs/error.log # cPanel: ~/public_html/error_log # Plesk: ~/httpdocs/logs/error_log # Панель от хостинга: ~/logs/error.log
Формат error.log Apache:
# Формат строки error.log: [Thu May 01 10:15:30 2026] [core:error] [pid 12345] \ [client 1.2.3.4:56789] AH00124: описание ошибки # Компоненты: # [дата] — когда # [модуль:уровень] — core:error, php:error, rewrite:trace3 # [pid] — ID процесса # [client] — IP посетителя # Текст — что случилось
Полезные команды для анализа логов:
# Последние 20 ошибок: tail -20 error.log # Топ IP по ошибкам: grep -oP '\[client \K[0-9.]+' error.log | \ sort | uniq -c | sort -rn | head -10 # Топ типов ошибок (по AH коду): grep -oP 'AH\d+' error.log | \ sort | uniq -c | sort -rn | head -10 # Только PHP ошибки: grep -i "PHP.*error\|PHP.*fatal" error.log
4
Apache коды ошибок (AH codes)
Частые AH-коды в error.log и что они означают:
AH00124 — слишком большой POST запрос AH00126 — невалидный URL в запросе AH01630 — доступ запрещён (deny/Require denied) AH01071 — PHP ошибка (после этого — текст ошибки) AH01215 — PHP скрипт упал (crash) AH01797 — заблокировано .htaccess правилом AH00052 — Segmentation fault (crash Apache процесса) AH00485 — Scoreboard full (нехватка процессов) AH00161 — MaxRequestWorkers (все процессы заняты) AH00558 — FQDN warning (можно игнорировать)
5
PHP-обработчики — mod_php, CGI, FPM, LiteSpeed
Как определить какой PHP-обработчик используется:
# Создать info.php: <?php phpinfo(); ?> # Открыть https://site.com/info.php # Найти "Server API": # - Apache 2.0 Handler = mod_php # - FPM/FastCGI = PHP-FPM # - LiteSpeed = LiteSpeed SAPI # - CGI/FastCGI = CGI # УДАЛИТЬ info.php сразу!
Сравнение обработчиков:
mod_php: + php_value в .htaccess работают - Один процесс на запрос (много RAM) - Только prefork MPM PHP-FPM: + Отдельный пул для каждого сайта + Меньше RAM, выше скорость - php_value в .htaccess НЕ работают - Настройки через панель хостинга LiteSpeed: + Самый быстрый (LSAPI) + Совместим с .htaccess + Встроенное кеширование (LSCache) CGI: - Самый медленный, процесс на запрос
Если на хостинге есть выбор в панели — выбирайте PHP-FPM или LiteSpeed. mod_php устарел и не подходит для высоконагруженных сайтов.
6
Apache + Nginx proxy — как обойти проблемы прокси
Проблема: Apache получает реальный IP посетителя
# Проблема: в логах все IP = 127.0.0.1 # Причина: Nginx проксирует запросы # Проверить X-Forwarded-For: curl -sI https://site.com | grep -i x-forwarded # На shared-хостинге: включить в панели # "Log real IP" или "X-Forwarded-For в логах"
Проблема: Nginx кеш отдаёт старую версию страницы
# Отключить кеш для динамических страниц: Header set Cache-Control "no-cache, no-store" Header set Pragma "no-cache" Header set Expires "0" # Для конкретного URL: <LocationMatch "/wp-admin|/administrator"> Header set Cache-Control "no-cache" </LocationMatch>
Проблема: Nginx timeout (504 Gateway Timeout)
# Nginx timeout = 60 секунд (обычно) # Apache не успевает ответить # Что делать: # 1. Найти медленный запрос (access.log) # 2. Оптимизировать PHP/SQL # 3. Увеличить max_execution_time # 4. Включить OPcache # 5. Долгие операции (импорт) — через CLI
7
Оптимизация Apache без доступа к httpd.conf
Что можно оптимизировать без root-доступа:
# Оптимизация без root-доступа: # 1. .htaccess — кеширование, сжатие, редиректы # 2. PHP-FPM через панель: # pm.max_children = (RAM / размер_процесса) # pm.max_requests = 500 # 3. OPcache через панель: # opcache.enable = 1 # opcache.memory_consumption = 128 # opcache.max_accelerated_files = 10000 # opcache.revalidate_freq = 60 # 4. WordPress: отключить wp-cron # define('DISABLE_WP_CRON', true) # 5. PHP сессии в Redis (если доступен)
Формула pm.max_children:
# pm.max_children = (RAM - MySQL) / PHP процесс # Пример: # RAM: 2048MB, MySQL: 512MB, PHP процесс: 50MB # (2048 - 512) / 50 = 30 # pm.max_children = 30 # Размер PHP процесса (SSH): ps -eo pid,rss,cmd | grep php-fpm | grep -v grep # RSS в KB. Разделить на 1024 = MB
На shared-хостинге pm.max_children обычно управляется автоматически. Если в панели есть поле — используйте формулу. Слишком большое значение = Out of Memory. Слишком маленькое = 503 Service Unavailable.
8
Когда shared-хостинг больше не подходит
Признаки что пора переходить на VPS:
# Когда переходить на VPS: # 1. 503 Entry Processes limit exceeded регулярно # 2. CPU limit 100%+ постоянно # 3. Бэкап занимает больше 30 минут # 4. Нужен cron с интервалом < 15 минут # 5. Нужен Node.js, Python, Redis, Elasticsearch # 6. Трафик > 10 000 посетителей/день # 7. Нужна специфичная версия PHP
Типичный VPS от 400 руб/мес даёт 2 CPU, 2GB RAM, 40GB SSD. Этого хватит для 3-5 WordPress сайтов с трафиком до 30 000 посетителей/день. Но потребуется настройка сервера (или используйте панель типа HestiaCP, CyberPanel, aaPanel).

VPS 403 Forbidden

На VPS полный контроль. Основные причины: права файловой системы, deny в Nginx/Apache, SELinux, отсутствие index-файла.

1
Проверить права и владение файлов
Цель: Каждая директория в пути должна иметь r+x для www-data.
namei -l /var/www/site/index.php chown -R www-data:www-data /var/www/site find /var/www/site -type d -exec chmod 755 {} \; find /var/www/site -type f -exec chmod 644 {} \;
2
Проверить deny в Nginx / Apache
Цель: Найти правила блокировки.
grep -rn "deny" /etc/nginx/ grep -rn "Require all denied" /etc/apache2/
3
SELinux (CentOS/RHEL)
Цель: SELinux может блокировать доступ к файлам.
getenforce restorecon -Rv /var/www/
4
Логи и Fail2ban
Цель: Логи точно скажут причину 403.
tail -20 /var/log/nginx/error.log fail2ban-client set nginx-http-auth unbanip YOUR_IP

VPS 500 Internal Server Error

Полный доступ к логам. Диагностика: error.log → PHP-FPM логи → права → модули PHP.

1
Логи real-time
Цель: Открыть лог и воспроизвести ошибку.
tail -f /var/log/apache2/error.log tail -f /var/log/php8.2-fpm.log
2
PHP модули и права
Цель: Убедиться что все модули установлены и права верные.
php -m | grep -E "mbstring|xml|curl|json|pdo" apt install php8.2-mbstring php8.2-xml php8.2-curl chown -R www-data:www-data /var/www/site find /var/www/site -type d -exec chmod 755 {} \; find /var/www/site -type f -exec chmod 644 {} \;

VPS 502 Bad Gateway

Nginx не получил ответ от Apache или PHP-FPM. Полный контроль: перезапуск, логи, настройка.

1
Проверить и перезапустить Apache/PHP-FPM
Цель: Проверить статус и перезапустить.
systemctl status apache2 systemctl restart apache2 systemctl status php8.2-fpm systemctl restart php8.2-fpm
2
Проверить сокеты и порты
Цель: Убедиться что Nginx правильно проксирует на Apache/PHP-FPM.
grep "proxy_pass\|fastcgi_pass" /etc/nginx/sites-enabled/* ss -tlnp | grep -E "80|443|8080|9000" ls -la /run/php/
3
OOM Killer и логи
Цель: Проверить не был ли процесс убит из-за нехватки памяти.
dmesg | grep -i "oom\|kill" dmesg | grep -i apache free -h

VPS 503 Service Unavailable

Сервер перегружен, Apache MaxRequestWorkers достигнут, или служба остановлена.

1
Проверить нагрузку
Цель: Узнать что грузит сервер.
uptime top -bn1 | head -15 free -h
2
Настроить Apache MaxRequestWorkers
Цель: Увеличить максимальное число процессов Apache.
# /etc/apache2/mods-enabled/mpm_prefork.conf: MaxRequestWorkers 150 MaxConnectionsPerChild 300 systemctl restart apache2
Формула: RAM_в_MB / размер_процесса_Apache ≈ MaxRequestWorkers. Для 2GB RAM с PHP: ~50-80 процессов.
3
Swap и оптимизация MySQL
Цель: Добавить swap если нет, уменьшить потребление RAM MySQL.
fallocate -l 2G /swapfile chmod 600 /swapfile mkswap /swapfile swapon /swapfile echo '/swapfile none swap sw 0 0' >> /etc/fstab

VPS 504 Gateway Timeout

Apache/PHP не уложился в таймаут Nginx. Контролируете все таймауты: Nginx, Apache, PHP, MySQL.

1
Логи и таймауты Nginx
Цель: Найти таймаут и увеличить лимиты Nginx.
grep "timed out" /var/log/nginx/error.log | tail -10 # В Nginx config: proxy_read_timeout 300s; fastcgi_read_timeout 300s; nginx -t && systemctl reload nginx
2
Медленные SQL-запросы
Цель: Найти и оптимизировать медленные запросы.
mysql -u root -p -e "SHOW FULL PROCESSLIST;" # Включить slow query log: SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 2;
3
Лимиты PHP и I/O диска
Цель: Увеличить PHP лимиты и проверить диск.
# php.ini: max_execution_time = 300 request_terminate_timeout = 300 # Проверить диск: iostat -x 1 5 systemctl restart php8.2-fpm

WordPress Типичные проблемы и решения

Самые частые проблемы WordPress на хостинге и VPS с их решениями.

1
Белый экран (White Screen of Death)
Симптом: Сайт полностью белый, без ошибок. Причина: PHP Fatal error, но display_errors выключен.
# В wp-config.php (перед «That's all, stop editing»): define('WP_DEBUG', true); define('WP_DEBUG_LOG', true); define('WP_DEBUG_DISPLAY', false); # Лог: wp-content/debug.log # Также проверяйте error.log хостинга
Шаг 1: Переименуйте папку plugins → plugins.disabled (через FTP). Если заработало — проблема в плагине. Шаг 2: Смените тему на default (переименуйте текущую тему). Шаг 3: Увеличьте memory_limit через панель хостинга (PHP Settings) или wp-config.php: define('WP_MEMORY_LIMIT', '256M');
2
Ошибка «Error establishing a database connection»
Симптом: WordPress не может подключиться к БД. Причина: неверные креды, БД упала, превышены подключения.
# Проверить wp-config.php: # DB_NAME, DB_USER, DB_PASSWORD, DB_HOST # Тест подключения через SSH: mysql -u db_user -p db_name -h db_host # В панели хостинга проверить: # 1. Существует ли БД # 2. Правильный ли пароль # 3. Лимит подключений к MySQL
На хостинге часто DB_HOST = localhost. Если БД на отдельном сервере — укажите правильный хост. Также проверьте что пользователь БД имеет права на базу.
3
Медленная админка и сайт
Симптом: Сайт и wp-admin тормозят. Причина: нет кеширования, тяжёлые плагины, медленная БД.
# wp-config.php: define('DISABLE_WP_CRON', true); define('WP_MEMORY_LIMIT', '256M'); # .htaccess — кеширование статики: <IfModule mod_expires.c> ExpiresActive On ExpiresByType text/css "access plus 1 month" ExpiresByType image/jpeg "access plus 1 year" ExpiresByType image/png "access plus 1 year" </IfModule>
Также: установите плагин кеширования (LiteSpeed Cache / WP Super Cache), оптимизируйте БД (WP-Optimize), обновите PHP до 8.1+ (WordPress работает быстрее на новых версиях PHP), используйте плагин Query Monitor для поиска медленных запросов.
4
404 на всех страницах кроме главной
Симптом: Главная работает, остальные страницы — 404. Причина: проблема с RewriteRule в .htaccess или mod_rewrite не включён.
# Стандартный .htaccess WordPress: RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L]
Также: зайдите в wp-admin → Настройки → Постоянные ссылки → просто нажмите «Сохранить» (это пересоздаст .htaccess). На VPS: убедитесь что a2enmod rewrite включён.
5
Ошибка при загрузке медиафайлов
Симптом: «HTTP error» при загрузке изображений. Причина: права на wp-content/uploads, лимиты PHP, нехватка памяти для обработки изображений.
# Права на uploads: chmod -R 755 wp-content/uploads # .htaccess (если Apache + mod_php): php_value upload_max_filesize 64M php_value post_max_size 64M php_value memory_limit 256M
Если ошибка «HTTP error» — также попробуйте в functions.php: add_filter( 'wp_image_editors', function() { return array( 'WP_Image_Editor_GD' ); } ); (переключить с Imagick на GD).

Joomla Типичные проблемы и решения

Частые проблемы Joomla на хостинге с Apache + Nginx.

1
500 ошибка после установки/обновления
Симптом: После установки или обновления Joomla — белый экран или 500. Причина: несовместимость с версией PHP, проблемы с правами, missing расширения.
# configuration.php — включить ошибки: public $error_reporting = 'maximum'; public $debug = '1'; # Права на директории Joomla: chmod -R 755 images/ chmod -R 755 tmp/ chmod -R 755 logs/ chmod -R 755 cache/
Joomla 4/5 требует PHP 8.1+. Joomla 3.x — PHP 7.4. Проверьте совместимость версии Joomla с текущей версией PHP. error.log покажет конкретную ошибку.
2
404 на всех страницах (SEF URL)
Симптом: SEF-URL (ЧПУ) возвращают 404. Причина: не переименован htaccess.txt, проблема с mod_rewrite.
# Переименовать htaccess.txt → .htaccess: mv htaccess.txt .htaccess # В Global Configuration Joomla: # SEO Settings → Search Engine Friendly URLs: Yes # Use URL Rewriting: Yes
Если Joomla установлена в поддиректорию (например /joomla), измените RewriteBase: RewriteBase /joomla/
3
Медленная работа Joomla
Симптом: Joomla работает медленно. Причина: кеширование выключено, тяжёлые расширения, нет OPCache.
# Joomla админка → Global Configuration: # System → Cache → Cache Handler: File # Cache Time: 15 минут # OPCache в настройках PHP хостинга: opcache.enable=1 opcache.memory_consumption=128 opcache.max_accelerated_files=10000
Также: включите сжатие Gzip в Joomla (Server → Gzip Page Compression), удалите неиспользуемые расширения, обновите Joomla до последней версии.
4
Ошибка «Unable to write entry» в кеш/сессии
Симптом: Joomla не может записать в cache или tmp. Причина: права на папки или переполненный tmp.
chmod -R 755 cache/ chmod -R 755 tmp/ rm -rf cache/* rm -rf tmp/*
Проверьте в Global Configuration → System → Path to Log Folder и Path to Temp Folder — пути должны быть правильными и существовать.

Bitrix Типичные проблемы и решения

1С-Битрикс — ресурсоёмкая CMS. Часто требует больше ресурсов чем WordPress/Joomla. Специфичные проблемы с ядром D7, прологами и композитным кешем.

1
Битрикс: белый экран / 500 ошибка
Симптом: Белый экран без ошибок. Причина: PHP error, нехватка памяти, проблема с .settings.php.
# bitrix/php_interface/dbconn.php: define('BX_DEBUG', true); # Или в bitrix/.settings.php: 'exception_handling' => [ 'value' => [ 'debug' => true, 'handled_errors_types' => E_ALL, 'exception_errors_types' => E_ALL, ], 'readonly' => false, ],
Увеличьте memory_limit минимум до 256M (рекомендуется 512M для Битрикс). PHP 7.4 или 8.1+. error.log хостинга покажет конкретную ошибку.
2
Битрикс: медленная работа сайта
Симптом: Сайт работает медленно, страницы грузятся 5+ секунд. Причина: кеширование отключено, нет OPCache, тяжёлые компоненты.
# .htaccess (если Apache + mod_php): php_value memory_limit 512M php_value max_execution_time 300 # OPCache (через панель хостинга): opcache.enable = 1 opcache.memory_consumption = 256
Админка Битрикс → Настройки → Настройки продукта → Автокеширование: включите автокеширование. Настройки → Производительность → HTML-кеширование: включите композитный кеш. Проверьте через Панель производительности (bitrix/admin/perfmon.php).
3
Битрикс: ошибка подключения к БД
Симптом: «Prolog.php: Error connection to database». Причина: неверные параметры подключения в .settings.php, БД перегружена.
# bitrix/.settings.php — проверить параметры: 'connections' => [ 'value' => [ 'default' => [ 'className' => 'Bitrix\Main\DB\MysqliConnection', 'config' => [ 'host' => 'localhost', 'database' => 'db_name', 'login' => 'db_user', 'password' => 'db_pass', ], ], ], ],
4
Битрикс: очистка кеша и переполнение
Симптом: Диск заполнен, сайт не работает. Причина: кеш Битрикс разросся (bitrix/cache, bitrix/managed_cache, bitrix/stack_cache).
# Очистить кеш Битрикс через SSH: rm -rf bitrix/cache/* rm -rf bitrix/managed_cache/* rm -rf bitrix/stack_cache/* rm -rf bitrix/html_cache/* # Или через админку: # Настройки → Автокеширование → Очистка файлов кеша
После очистки кеша первые запросы будут медленными — кеш перестраивается. Не паникуйте если сайт «тормозит» первые 5-10 минут.
5
Битрикс: оптимальные требования к хостингу
Рекомендуемые минимальные параметры для стабильной работы Битрикс:
PHP: 8.1 или 8.2 memory_limit: 512M минимум max_execution_time: 300 OPCache: включён, 256MB MySQL: innodb_buffer_pool_size >= 256M Диск: SSD обязательен
Битрикс очень требователен к PHP и БД. Если хостинг не даёт memory_limit >= 256M — сайт будет работать нестабильно. Для интернет-магазина на Битрикс рекомендуется VPS, не shared-хостинг.
6
Битрикс: ошибка «Prolog.php: Error connection to database»
Симптом: «Prolog.php: Error connection to database». Причина: неверные параметры подключения в .settings.php, БД перегружена.
# bitrix/.settings.php — проверить: # 'connections' → 'default' → 'config' # host, database, login, password # На хостинге проверить в панели БД: # 1. БД существует # 2. Пользователь имеет права
Битрикс D7 использует .settings.php для подключения. Старое ядро — bitrix/php_interface/dbconn.php. Проверьте оба файла.

Все CMS Общие проблемы и решения

Проблемы которые встречаются на любой CMS: WordPress, Joomla, Bitrix, самописные сайты.

1
Письма не отправляются / попадают в спам
Симптом: Контактные формы не работают, уведомления не доходят. Причина: функция mail() на хостинге ограничена, нет SPF/DKIM.
# WordPress: плагин WP Mail SMTP # Joomla: Global Configuration → Server → SMTP # Битрикс: Настройки → Почта → SMTP # Проверить SPF: dig example.com TXT
Функция mail() на shared-хостинге ненадёжна. Всегда используйте SMTP. На хостинге: SMTP-сервер указан в панели. Внешние сервисы: SendGrid, Mailgun, Amazon SES.
2
Mixed content — HTTPS показывает «не защищён»
Симптом: Сайт на HTTPS, но браузер показывает «не защищён». Причина: ресурсы (css, js, картинки) загружаются по HTTP.
# WordPress .htaccess: Header always set Content-Security-Policy "upgrade-insecure-requests;" # WordPress wp-config.php: define('FORCE_SSL_ADMIN', true); # Joomla configuration.php: public $force_ssl = 2;
Проверьте DevTools (F12) → Console — покажет все mixed content ошибки. Также проверьте внешние ресурсы: Google Fonts, CDN, рекламные скрипты, счётчики аналитики.
3
CDN/Cloudflare — диагностика проблем
Симптом: Сайт не обновляется после изменений, ошибки SSL, 522 ошибка. Причина: кеш CDN не сброшен, проксирование блокирует валидацию.
# Проверить Cloudflare: curl -sI https://example.com | grep -i "cf-ray" # Панель Cloudflare → Purge Cache # Development Mode → On (временно) # SSL/TLS → Full (strict) # Для SSL валидации: DNS only (без прокси)
Ошибка 522 (Connection timed out): Cloudflare не может достучаться до вашего сервера. Проверьте что порт 80/443 открыт и сервер работает. Ошибка 525 (SSL handshake failed): SSL/TLS mode в Cloudflare не соответствует вашему сертификату. Используйте Full (strict) если у вас валидный сертификат.
5
Сайт заражён — признаки и действия
Признаки заражения: редиректы на сторонние сайты, спам в выдаче Google, подозрительные файлы, антивирус блокирует сайт, незнакомые пользователи в админке.
# Подозрительный код: grep -rn "eval(base64_decode" /var/www/site/ --include="*.php" # Скрытые файлы: find /var/www/site/ -name ".*.php" -type f # Недавно изменённые: find /var/www/site/ -name "*.php" -mtime -7
План действий: 1) Сменить ВСЕ пароли (FTP, БД, админка, хостинг). 2) Удалить заражённые файлы. 3) Восстановить из чистого бэкапа. 4) Обновить CMS, плагины, темы. 5) Установить security-плагин. 6) Настроить ежедневные бэкапы.