Блог

301-редирект в Apache и .htaccess

Для выделенного исходного хоста достаточно mod_alias. Покажем два VirtualHost для HTTP и HTTPS, а затем вариант для shared-хостинга, где доступна только .htaccess.

Выберите уровень настройки

Пример маршрута
Исходный URLhttps://example.com/catalog/item?ref=mail
HTTP301
Назначениеhttps://www.example.com/catalog/item?ref=mail

Одна директива переносит остаток пути и исходную query, если новая query не задана.

Нужны Apache с mod_alias, управление исходным доменом и право менять его vhost или .htaccess. Для HTTPS дополнительно необходимы mod_ssl, слушатель 443 и уже выданный действительный сертификат источника. Его выпуск и продление должен обслуживать хостинг или настроенный ACME-клиент.

Если доступна конфигурация сервера, предпочтите её: правило видно вместе с привязкой домена. .htaccess полезен на shared-хостинге, но зависит от разрешений владельца сервера. Этот пример предназначен для хоста, который целиком отдаётся под перенаправление.

Все адреса example.com и example.org здесь демонстрационные. Замените их своими. Меняйте только исходный хост: рабочие DNS-записи назначения должны остаться на месте. Источник и назначение не должны перенаправлять друг на друга.

Для проверки нового правила можно сначала выбрать 302. После подтверждённого постоянного переезда переключите его на 301: браузер способен кешировать постоянный редирект, и откат серверной настройки не удаляет уже сохранённый ответ у посетителя.

1. Настройте отдельный VirtualHost

Найдите конфигурацию именно example.com и сохраните её копию. Не добавляйте второй конфликтующий vhost и не меняйте vhost назначения www. В сервере должны быть объявлены необходимые Listen; не дублируйте существующие listeners.

Apache · HTTP и HTTPS источника
<VirtualHost *:80>
    ServerName example.com
    Redirect 301 / https://www.example.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName example.com
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
    Redirect 301 / https://www.example.com/
</VirtualHost>

Redirect 301 / https://www.example.com/ сопоставляет начало пути и дописывает остаток. Завершающий слеш у назначения здесь нужен. Когда в новом адресе нет собственной query, mod_alias переносит исходные параметры.

Указанные пути сертификата — пример для существующего Certbot lineage, не команда его выпуска. Подставьте реальные файлы вашей установки. Не включайте HTTPS-vhost, пока сертификат не готов. .htaccess не заменяет этот TLS-этап.

2. Если есть только .htaccess

Откройте document root, принадлежащий только исходному хосту. В его .htaccess добавьте одну строку:

.htaccess · только в каталоге источника
Redirect 301 / https://www.example.com/

Не помещайте её в каталог, который одновременно обслуживает www: назначение начнёт перенаправлять само на себя. Если оба домена используют общую директорию, сначала разделите их обработку с хостингом.

Нужны загруженный mod_alias и разрешение AllowOverride FileInfo либо подходящий AllowOverrideList для Redirect. Эти разрешения задаются в серверной конфигурации, не внутри .htaccess. При отсутствии доступа их проверяет хостинг.

Файл .htaccess не открывает порт 443, не подключает mod_ssl и не выдаёт сертификат. В панели хостинга HTTPS должен быть включён именно для исходного имени; сертификат целевого сайта его не заменит.

3. Примените правило

Для изменения vhost
sudo apachectl configtest
sudo apachectl graceful

Выполняйте graceful только после успешного configtest. Название команды и управление службой могут отличаться в вашей установке. Ошибка .htaccess способна проявиться лишь при запросе к каталогу: успешная проверка основной конфигурации не отменяет проверку URL.

После выдачи нового сертификата обслуживающий ACME-клиент должен обеспечить его загрузку Apache. Согласуйте продление с текущим способом challenge: общий Redirect не должен перехватывать нужные проверочные запросы. Для HTTP-01 сохраните проверенное исключение средствами своего клиента/хостинга; одна строка выше не настраивает ACME.

4. Проверьте оба протокола

Проверка корня и вложенного URL · GET
curl -sS -o /dev/null -D - 'http://example.com/'
curl -sS -o /dev/null -D - 'http://example.com/docs/start?tag=a&tag=b&utm_source=mail'
curl -sS -o /dev/null -D - 'https://example.com/'
curl -sS -o /dev/null -D - 'https://example.com/docs/start?tag=a&tag=b&utm_source=mail'

Ожидайте код 301. Для корня заголовок Location должен быть https://www.example.com/, для вложенного адреса — https://www.example.com/docs/start?tag=a&tag=b&utm_source=mail. Версия HTTP и регистр имени заголовка в выводе могут отличаться. Если временно выбрали 302, ожидаемый код — 302.

Дополнительно: HEAD и закодированные символы
curl -sS -I 'https://example.com/docs/start?tag=a&tag=b'
curl --path-as-is -sS -o /dev/null -D - 'https://example.com/files/report%20one.pdf?tag=a&tag=b&q=a%2Fb'

Не добавляйте -L к первой проверке: важно увидеть ответ источника, а не скрыть его за переходом. Затем отдельно откройте адрес назначения и убедитесь, что там есть нужная страница. DNS не создаёт HTTP-ответ, а сертификат назначения не заменяет сертификат источника.

Для /catalog/item?ref=mail ожидается https://www.example.com/catalog/item?ref=mail. Не считайте mod_alias обещанием побайтового сохранения любого необычного URL: отдельно проверьте закодированные символы и настройки обработки слеша в вашей версии Apache. Фрагмент после # сервер не получает.

Ошибки и откат

Частые симптомы
СимптомГде искать причину
500 после добавления .htaccessПроверьте error log: директива может быть запрещена, модуль отсутствовать или синтаксис быть неверным. Удалите только новую строку и повторите запрос.
HTTP работает, HTTPS не соединяетсяПроверьте Listen 443, mod_ssl, нужный TLS-vhost и сертификат исходного имени.
Перенаправление зациклилосьИсточник и назначение используют один document root либо на www настроено обратное правило.
Правило не действуетУбедитесь, что запрос попадает в нужный vhost, а .htaccess читается и разрешён.

Для отката .htaccess восстановите его сохранённое содержимое и сразу проверьте запрос. Для vhost восстановите предыдущую конфигурацию, выполните configtest и graceful. Не удаляйте чужие RewriteRule или другие правила сайта заодно. Кешированный 301 у клиента может пережить откат.

Что остаётся на вашей стороне

На shared-хостинге сервер обслуживает провайдер, но вам нужны действующий тариф, доступ к исходному домену и подтверждённый порядок обновления сертификата. На своём Apache остаются также обновления ОС, сервера и ACME-клиента. Уже оплаченный хостинг может не требовать доплаты за правило.

Для постоянного переезда выбирайте код осознанно. Для рекламной ссылки с меняющимся назначением временный 302 часто удобнее; смена кода не решает ошибку DNS или сертификата.

Документация

Нужен редирект, а не ещё одна настройка?

Если Apache уже оплачен и обслуживается, строка Redirect может быть достаточным решением. Redirect301 пригодится, когда не хочется сохранять хостинг только ради перенаправления.

Redirect301 — 500 ₽ за домен в год. Мы берём на себя правила перенаправления, HTTPS и продление сертификата исходного домена. Подключение через DNS охватывает весь исходный хост; для отдельных страниц живого сайта нужна отдельная интеграция.

Что входит в 500 ₽

Redirect301

Узнать о запуске Redirect301

Оставьте email, чтобы получить уведомление об открытии доступа.