К основному содержимому

.htaccess: редиректы, правила rewrite и защита сайта

Хостинг и cPanel · 15.07.2025 · 4 мин чтения
Иллюстрация к статье «.htaccess: редиректы, правила rewrite и защита сайта»

Файл .htaccess позволяет настраивать Apache прямо в папке сайта без доступа к конфигурации сервера. Он находится в public_html/.

⚠️ Ошибка в .htaccess вызывает ошибку 500 для всего сайта. Всегда делайте резервную копию перед редактированием.

301 редиректы

RewriteEngine On

# Со старой страницы на новую
Redirect 301 /old-page.html /new-page

# Редирект всей папки
RedirectMatch 301 ^/old-section/(.*)$ /new-section/$1

www ↔ без www

RewriteEngine On

# Перенаправить ВСЕ запросы на www
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]

# Или наоборот — убрать www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

HTTP → HTTPS редирект

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Защита папки паролем

# Создайте файл .htpasswd:
# htpasswd -c /home/user/.htpasswd adminuser

# В .htaccess папки:
AuthType Basic
AuthName "Protected Area"
AuthUserFile /home/user/.htpasswd
Require valid-user

Блокировка IP-адресов

# Заблокировать конкретный IP
Deny from 203.0.113.42

# Разрешить только свой IP
Order deny,allow
Deny from all
Allow from 203.0.113.10

Кэширование статических файлов

<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"
</IfModule>
✅ После изменений в .htaccess проверьте сайт в режиме инкогнито. Если ошибка 500 — верните предыдущую версию через cPanel → Файловый менеджер.

Порядок правил имеет значение

Если объединить редирект на HTTPS и добавление www в одном файле бездумно, легко получить двойной редирект или зацикливание — Apache применяет правила по порядку сверху вниз и останавливается только на первом сработавшем флаге L.

# Правильный порядок: сначала HTTPS, затем www,
# чтобы браузер не делал два отдельных редиректа подряд
RewriteEngine On

RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]

RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]

Оба условия ведут на один и тот же итоговый адрес с www и HTTPS одновременно — так браузер получает один редирект вместо двух последовательных.

Безопасное тестирование правил

Каждое серьёзное изменение проверяйте с сохранённой резервной копией рядом — правило можно откатить мгновенно, не дожидаясь восстановления из панели хостинга.

# Перед правкой сохранить рабочую копию
cp .htaccess .htaccess.bak

# Если сайт упал с 500 после правки — вернуть прежнюю версию одной командой
cp .htaccess.bak .htaccess

Типичные ошибки в .htaccess

СимптомПричина
500 Internal Server Error сразу после сохраненияСинтаксическая ошибка в директиве: пропущен пробел между RewriteCond и шаблоном, лишняя кавычка или неверный флаг вроде [R=301,L,X]
RewriteRule: bad flag delimitersФлаги в квадратных скобках записаны без запятой между ними или с лишним пробелом внутри скобок
ERR_TOO_MANY_REDIRECTS в браузереПравило www ↔ без www и HTTP → HTTPS конфликтуют по порядку, особенно если на Cloudflare уже включён Flexible SSL и повторное правило перенаправляет туда-обратно
Invalid command 'ExpiresActive'Директива используется без обёртки <IfModule mod_expires.c>, а модуль на аккаунте отключён — Apache не понимает команду и падает с 500
Basic Auth не спрашивает парольФайл .htpasswd указан неверным абсолютным путём или у него нет прав на чтение процессом Apache

Когда .htaccess не подходит

  • Сайт работает на Nginx — .htaccess читает только Apache, для Nginx правила переписываются в конфиг виртуального хоста на стороне провайдера
  • Правил становится много и они лежат в подпапках — при AllowOverride All Apache сканирует дерево директорий на каждый запрос, что заметно замедляет ответ
  • Нужно менять настройки, не разрешённые в AllowOverride (лимиты процесса, модули ядра) — .htaccess переопределяет только то, что явно открыто хостингом
  • Изменения нужно применить сразу к сотням доменов — держать идентичный файл в каждой папке неудобно, синхронизация легко расходится

Проверка результата

После правки всегда проверяйте реальный HTTP-ответ, а не только внешний вид страницы в браузере — код ответа виден не всегда, особенно если сработал кэш. Если правила редиректа связаны с миграцией на HTTPS, см. также статью про настройку HTTPS-редиректа; при ошибке 500 разбор причин — в статье про диагностику error_log.

# Проверить код ответа и адрес назначения редиректа
curl -I http://example.com/old-page.html

# Убедиться, что заголовки кэширования применились к статике
curl -I https://example.com/style.css | grep -i cache-control
Статья помогла?
← Назад в базу знаний Задать вопрос поддержке