5. Частые случаи и примеры использования mod_rewrite
В предыдущих частях мы изучили практически всю документацию по mod_rewrite. Остались директивы RewriteMap и RewriteOptions. RewriteMap также используется для перезаписи URL адресов, но применяется реже других; к ней мы вернёмся позже. Директива RewriteOptions также применяется нечасто. Особенностью RewriteMap является то, что её нельзя использовать в .htaccess. Её можно использовать только в контексте сервера, либо виртуальных хостов. По большому счёту, RewriteMap не добавляет новой функциональности – она только позволяет вынести большой массив данных, которые нецелесообразно или слишком сложно описывать при помощи регулярных выражений, в отдельные файлы. Получаются такие выделенные базы данных. Тем не менее, мы всё равно рассмотрим RewriteMap в одной из последующих частей.
Сейчас для закрепления изученной теории, мы перейдём к практическим примерам самых частых случаев использования mod_rewrite, включая подробное описание того, как они работаю. Если после знакомства с теорией и этими примерами у вас остались вопросы, то пишите их здесь в комментариях.
Обратите внимание, что во многих примерах используются конкретные файловые пути, значения запросов и прочее – эти примеры не будут работать у вас без изменений в вашей конфигурации сервера, поэтому важно, чтобы вы их понимали, а не просто копировали в вашу конфигурацию.
Проверка доступности mod_rewrite
Как включить RewriteEngine
О включении модуля mod_rewrite в конфигурационном файле Apache было рассказано в первой части. Если модуль включен, то его необходимо активировать в файле .htaccess директивой RewriteEngine:
Это достаточно сделать один раз, даже если вы используете несколько правил перезаписи.
Для работы модуля также необходима активация опции FollowSymLinks. Эта опция может быть активирована в конфигурационном файле Apache (об этом также уже было сказано в первой части). Если эта опция отключена на уровне веб-сервера (или виртуального хоста), то её можно включить в файле .htaccess. Её нужно указать до директивы RewriteEngine:
Как проверить, включён ли mod_rewrite
Как проверить в PHP включён mod_rewrite или нет
Самым простым способом является использование функции phpinfo(). Если модуль включён, то в таблице apache2handler в колонке Loaded Modules будет указано mod_rewrite (а также все другие модули, которые включены).

Этот способ является самым универсальным: вы можете использовать его в любой системе, в том числе на совместном (shared) хостинге.
Как проверить в Windows включён ли mod_rewrite
Откройте командную строку (Win+x, затем выберите Windows PowerShell). Перейдите в каталог, где размещены бинарные файлы Apache. Например, в моём случае это папка C:\Server\bin\Apache24\bin\:
И выполните там команду:
Будет выведен полный список модулей.

Как проверить в Linux включён ли mod_rewrite
Чтобы вывести список всех загруженных веб-сервером Apache модулей, используется опция -M. Исполнимый файл веб-сервера может называться apache2ctl или httpd в зависимости от используемого дистрибутива.
Для Debian, Ubuntu, Kali Linux, Linux Mint и их производных команда для вывода списка модулей следующая:
Для Arch Linux, BlackArch и некоторых других дистрибутивов команда такая:
Проверка включён ли mod_rewrite с помощью .htaccess
В файле .htaccess запишите директиву:
И попробуйте открыть адрес папки, где вы сохранили .htaccess, если возникнет ошибка «500 Internal server error», значит модуль mod_rewrite не включён в конфигурационном файле Apache.
Как сделать так, чтобы правила перезаписи использовались только если mod_rewrite включен
Конструкция <IfModule> проверяет, включён ли модуль. Если модуль включён, то выполняются директивы, которые находятся в секции <IfModule>…</IfModule>. Если модуль отключён, то эти директивы игнорируются. В результате, если модуль выключен, то неизвестные директивы не вызовут ошибку веб-сервера.
Синтаксис использования:
Вместо многоточий запишите желаемые директивы mod_rewrite, пример:
Перед именем модуля можно поставить ! (восклицательных знак) и тогда то, что внутри IfModule будет выполнено только если проверяемый модуль НЕ включён.
Секции <IfModule> можно использовать внутри другой секции <IfModule> и выполнять простые тестирования нескольких модулей в зависимости от условия предыдущих тестов модулей.
Эту секцию следуют использовать только если вам нужен один конфигурационный файл, которые работает независимо от того, доступен ли определённый модуль. При обычной работе директивы не должны размещаться в секциях <IfModule>.
Использование mod_rewrite для перенаправления (редиректа) и переназначения URL
Страница поменяла адрес, как показать новую страницу по старому адресу без редиректа
Описание:
Предположим, мы недавно переименовали страницу foo.html в bar.html и теперь хотим, чтобы старый URL также работал для обратной совместимости. Однако мы хотим, чтобы пользователи старого URL-адреса даже не узнали, что страницы были переименованы, то есть мы не хотим, чтобы адрес изменялся в их браузере.
Решение:
Мы с помощью RewriteRule делаем преобразования запроса, содержащего старый адрес, на новый, задав следующее правило:
В этом примере ^/foo\.html$ является регулярным выражением. Символы ^ и $ обозначают начало и конец строки соответственно. Перед точкой стоит слеш, чтобы символ трактовался буквально (как точка), а не как подстановочный символ (в качестве подстановочного символа точка означает любой один символ).
Страница поменяла адрес, как перенаправить на новую страницу при запросе старой (редирект)
Описание:
Предположим еще раз, что мы недавно переименовали страницу foo.html в bar.html и вновь хотим, чтобы старый URL работал для обратной совместимости. Но на этот раз мы хотим, чтобы пользователи старого URL-адреса получили намек на новый, т. е. поле адресной строки их веб-браузера должно измениться.
Решение:
Мы принудительно перенаправляем HTTP на новый URL-адрес, что приводит к изменению адреса страницы в браузере и, следовательно, того, что показано пользователю:
Кстати, для простых случаев редиректа можно использовать директиву Redirect. Эта директива не смогла бы заменить первый пример, когда мы показываем содержимое другой страницы без смены адреса (без редиректа). С Redirect второй пример выглядел бы так:
Переадресация при смене домена
Описание:
Если сайт сменил домен, но сохранил прежнюю структуру страниц. Вы хотите, чтобы старые URL адреса продолжали работать пока пользователи не обновят их закладки.
Решение:
Вы можете использовать mod_rewrite для перенаправления этих URL на новый домен, но также рассмотрите вариант с использованием директив Redirect или RedirectMatch.
В этом примере будет производиться переадресация на новый домен с сохранением запроса, замените НОВЫЙ-САЙТ.ru на адрес сайта, куда должен выполняться редирект
Ещё один вариант, который также делает переадресацию на новый домен с сохранением структуры сайта, замените НОВЫЙ-САЙТ.ru на адрес сайта, куда должен выполняться редирект, а СТАРЫЙ-САЙТ.ru на имя старого домена:
В последующих примерах замените example.com на адрес сайта, куда должен выполняться редирект.
Правило означает найти запросы, которые содержат строку, которая начинается с /docs/ (символ ^ означает начало строки, а /docs/ - это буквальная последовательность символов), за которой затем следует что угодно (точка означает любой символ, а знак плюс означает один или более раз). Скобки образуют обратную ссылку. Т.е. то, что совпадает с выражением в скобках, можно использовать в дальнейшем, сославшись на это с помощью $1.
В строке перезаписи http://new.example.com/docs/ является буквальной частью, а $1 – это то, что совпало с частью выражения в скобках, т.е. обратная ссылка на (.+).
Таким образом, если был сделан запрос http://another.com/docs/best, то будет сделана переадресация на адрес http://new.example.com/docs/best.
Директивы Redirect и RedirectMatch должы быть «легче» для сервера, но не всегда сложные случаи можно описать без использования mod_rewrite.
Простой редирект на новый сайт
Если сайт сменил домен и не сохранил структуру страниц, т.е. если вам нужно перенаправить все запросы на новый сайт (например, на его главную страницу), то это делается так:
В результате независимо от запрошенной страницы, все запросы будут переданы на главную страницу другого домена. Замените https://newsite.ru на тот сайт, куда вы перенаправляете запросы.
Как переправить все запросы из одной директории, в другую
Псевдоним для единичной директории:
Все обращения к содержимому директории source-directory будут переадресованы к содержимому директории target-directory.
Использовать URL адресов без расширения файлов .php
Этот снипет позволяет вам использовать URL без расширения PHP, например, example.com/users вместо example.com/users.php.
Универсальный документ ошибки (Error Document) для не найденных ресурсов (ошибка 404 Not Found)
Следующее правило выводит указанный вами файл в случае возникновения ошибки 404 Not Found. Обратите внимание, что вам самим нужно указать правильный код ответа HTTP 404 в заголовках ответа (в PHP коде, например).
Если это правило перезаписи вызовет ошибку сервера, то замените флаг [END] на [L]. Флаг [END] подходит лучше, но поддерживается Apache 2.4 и не поддерживается версией Apache 2.2.
Вместо /dir/error.php нужно указать путь до файла, который вы хотите показывать в случае возникновения ошибки 404 (файл не найден).
Со статики на динамику
Описание:
Как мы можем трансформировать статичную страницу foo.html в динамичный вариант foo.cgi бесшовным образом, т.е. без уведомления браузера/пользователя.
Решение:
Мы просто переписываем URL на CGI-скрипт и принуждаем обработчик быть cgi-скриптом так, что он выполняется как CGI программа. Таким образом, запрос /~quux/foo.html внутренне приводить к вызову /~quux/foo.cgi.
Обратная совместимость для изменений расширения файла
Описание:
Как мы можем сделать обратную совместимость URL (виртуально ещё существующих) после миграции document.YYYY в document.XXXX, например, после перехода ряда.html файлов на .php?
Решение:
Мы переписываем имя в его базовое имя и проверяем наличие файла с новым расширением. Если он существует, мы берем его, иначе URL используется в исходном состоянии.
Обсуждение
В этом примере используется часто забываемая возможность mod_rewrite, вытекающая из порядка выполнения набора правил. В частности, mod_rewrite оценивает левую сторону RewriteRule (Шаблон поиска), прежде чем оценивать директивы RewriteCond. Следовательно, $1 уже определён к тому времени, когда оцениваются директивы RewriteCond. Это позволяет нам проверять наличие исходного (document.html) и целевого (document.php) файла с использованием того же базового имени файла.
Этот набор правил предназначен для использования в контексте директорий (в блоке <Directory> или в файле .htaccess), так что проверки -f смотрят в каталог по правильному пути. Возможно, вам потребуется установить директиву RewriteBase, чтобы указать базу каталогов, в которой вы работаете.
Замена на WebP изображения
Если поддерживаются WebP изображения, и изображение с файловым расширением .webp найдено в том же месте, где на сервере находится картинка jpg/png, то вместо неё будет отправлено изображение WebP.
Канонические имена хостов и URL. HTTPS
К одной и той же странице можно обратиться по-разному. Например, главную страницу сайта можно открыть любым из следующих методов:
Вариантов может быть даже больше, если сайт доступен и на HTTP, и на HTTPS. Также варианты могут возникнуть из-за различных ошибок составления ссылок, при которых страница продолжает открываться. Например:
Хотя большинству людей понятно, что все эти URL являются одним и тем же, с технической точки зрения это не так. Для веб-сервера это различные URL. И если они открыты, поисковые системы их могут проиндексировать.
Поисковые системы стали значительно более продвинутыми, но не нужно рассчитывать только на них в вопросе борьбы с диблирующими страницами. К тому же, это может внести путаницу в аналитику (когда для каждого из перечисленного примера доход или посещаемостью считаются отдельно, хотя это одна и та же страница).
Поэтому веб-мастеру следует позаботиться о каноническом URL. На самом деле, нет никакой разницы, какую именно форму URL вы выберите в качестве канонической. Главное, выбрать что-то одно и придерживаться этого.
Как сделать редирект с HTTP на HTTPS
Помните, что для использования HTTPS протокола недостаточно просто сделать переадресацию, также должен быть настроен веб-сервер. То есть вы должны получить сертификаты и указать их в настройках хоста. Также веб-сервер должен быть настроен на прослушивание 443 порта. Если это всё готово, то для перенаправления на HTTPS, в файл .htaccess добавьте строки:
В этом примере переменная %{HTTPS} содержит on, если сайт использует HTTPS и содержит off, если используется HTTP. Таким образом, адрес страницы переписывается только если к ней обращаются по HTTP.
В RewriteRule в качестве шаблона поиска используется ^ - символ начала строки. Т.е. под это условие подпадают все строки. Цель переадресации указывается с помощью буквальной строки https:// и двух переменных окружения %{HTTP_HOST} и %{REQUEST_URI}.
Ещё один вариант записи, возможно, кому-то будет более простым для восприятия:
В этом примере !on (не включено) заменено на off (выключено) и вместо ^ (начало строки) используется (.*) (означает «что угодно»). По сути эти две записи делают одно и то же.
Также на вашем HTTPS веб-сайте рекомендуется включить HTTP Strict Transport Security (HSTS) для помощи в предотвращении атак человек-посередине. Для этого достаточно добавить строки:
Подробности: https://developer.mozilla.org/en-US/docs/Web/Security/HTTP_strict_transport_security
ВНИМАНИЕ: HSTS после включения трудно выключить. Поэтому HSTS включайте только осмысленно, когда вы точно уверены, что у вас не возникнет необходимости вновь откатываться с HTTPS до HTTP и вы уверены, что на сайте не должно быть страниц на HTTP. Либо вы понимаете, как отключить HSTS.
Как сделать редирект на с HTTP на HTTPS всех страниц кроме некоторых
Предположим, что нам нужно перевести на HTTPS все страницы кроме тех, которые находятся в папке /.well-known/, тогда используется следующая конструкция:
Замените /.well-known/ на желаемую папку или адрес страницы.
Если нужно исключить несколько страниц или каталогов, то составьте регулярное выражение с альтернативным выбором, т.е. с использованием трубы (|). Например, нужно включить переадресацию на HTTPS для всех страниц кроме находящихся в папке /.well-known/, в папке /test/, а также файла /stay-away.php:
Важно: если установлен заголовок Strict-Transport-Security:
То правила с выборочным использованием или не использованием HTTPS для определённых страниц работать НЕ БУДУТ! Веб-браузер, получая этот заголовок, для всего сайта — для всех страниц и даже для всех субдоменов, включает HSTS (HTTP Strict Transport Security). С практической точки зрения это означает, что веб-браузер будет работать только с HTTPS страницами — открывать их сразу по HTTPS протоколу даже если ссылка или редирект указывают на использование HTTP протокол. Аналогичное правило распространяется на субдомены; если сертификат не поддерживает какой-либо субдомен сайта, то такой адрес будет невозможно открыть. Сайт с включённым HSTS невозможно добавить в исключения веб-браузера, чтобы он игнорировал ошибки неправильных SSL сертификатов.
Как сделать редирект на с HTTP на HTTPS только некоторых страниц
Если вам нужно перенаправить с HTTP на HTTPS только отдельные страницы, то подойдут показанные ранее примеры. Единственное необходимое в них изменение – убрать восклицательный знак (!), который служит для отрицания совпадения.
Для настройки редиректа на HTTPS только для папки /.well-known/
Для настройки редиректа на HTTPS только для папки /.well-known/, папки /test/, а также файла /stay-away.php:
Принудительное использование HTTPS за прокси
Полезно, если у вас есть прокси-сервер перед вашим сервером, отключающий TLS.
Всегда использовать WWW перед именем домена
Если вы хотите, чтобы в строке браузера перед названием домена всегда шло www, то используйте следующие правила:
Обратите внимание, что example.com нужно заменить на домен вашего сайта, вместо протокола http:// может быть указано https://, а в строке ^example\.com слеш перед точкой не случаен – эта строка является регулярным выражением, чтобы точка рассматривалась не как подстановочный символ, а как буквальная точка, используется слеш.
Всегда использовать WWW перед именем домена – универсальный вариант
Этот вариант подойдёт без изменений для любых сайтов: не нужно указывать имя хоста (доменное имя), а также не нужно указывать, используется ли протокол HTTP или HTTPS. Т.е. это более универсальный вариант.
Первое условие проверяет, не является ли значение Host пустым (в случае HTTP/1.0). Второе проверяет, не начинается ли Host на www..
Обратите внимание на RewriteCond %{HTTPS}s ^on(s)|. Здесь используется довольно хитрый приём. Как было сказано чуть выше, переменная окружения %{HTTPS} содержит on, если сайт использует протокол HTTPS, и содержит off, если используется HTTP. К переменной окружения добавлена буквальная буква s, в результате происходит проверка строки %{HTTPS}s, которая, в зависимости от того, включен ли HTTPS или нет, может сводиться к ons или offs. Эта строка сравнивается с регулярным выражением ^on(s)|, где ^ - это символ начала строки. Символ трубы (|) говорит о том, что подойдёт любая альтернатива – стоящая перед этим символом или после. Перед этим символом стоит строка on(s), а после – ничего. Пустая строка соответствует любой сравниваемой строке. Исходя из этого, результат RewriteCond всегда будет сводиться к истине. Но в зависимости от того, какая часть регулярного выражения совпала: on(s) или пустая строка, обратная ссылка будет иметь значение «s» или будет пустой строкой. Обратная ссылка задаётся скобками, в которых находится буква s.
В результате http%1 при RewriteRule будет сводиться к https или к http.
Таким образом, это правило подойдёт для любого сайта, в нём не нужно прописывать свой домен как это нужно делать в предыдущем. Также не нужно заботиться о протоколе сайта.
Никогда не использовать WWW перед именем домена
Если вам не нужно, чтобы перед доменом в строке браузера были буквы www, то используйте следующее правило:
В нём замените http://example.com на имя вашего домена. Также обратите внимание на протокол. Во второй строке слеши используются для того, чтобы точки в регулярном выражении трактовались как буквальные символы (а не подстановочные).
Никогда не использовать WWW перед именем домена – универсальный вариант
Если вам нужно избавиться от www в адресной строке браузера, то следующее правило это сделает, переадресую запрос на аналогичный адрес, но без www:
В этом наборе условий и правила не нужно указывать свой домен – конструкция является универсальной для любого сайта, также подходит для сайтов на HTTP и HTTPS.
Принудительное использование канонического имени с HTTPS и www
Если ваш сайт работает через протокол HTTPS и в качестве канонического имени вы выбрали использовать www перед именем домена, то вам поможет любое из следующих правил. У них нет принципиальной разницы, если какоео-то из них не подошло для ваших условий, просто попробуйте другое.
Первый способ:
В этом примере имеются два правила перезаписи. Первое перенаправляет на HTTPS. Второе правило перезаписывает любой запрос с неверным доменом на использование www. Флаг [NC] означает совпадение независимо от регистра.
Второй способ:
Третий способ:
Четвёртый способ (замените domain.ru на свой домен):
Канонический вид с HTTPS и без www
Если ваш сайт работает на HTTPS, но вы не хотите видеть www в адресной строке браузера перед именем домена, то используйте:
Принудительное SSL и www для главного домена, принудительное SSL без www для всех поддоменов (кроме локальных)
Замените domain.ru на имя вашего домена.
Принудительное добавление конечного слеша к адресу сайта
Если вам нужно добавить к URL конечный слеш (в том случае, если он отсутствует), то воспользуйтесь этим правилом перезаписи:
Удаление конечного слеша
Этот сниппет перенаправит пути, заканчивающиеся на слеши, на аналогичные, но без конечного слеша (кроме действительных директорий), к примеру http://www.example.com/blog/ на http://www.example.com/blog. Это важно для SEO, поскольку рекомендуется иметь канонический URL для каждой страницы.
Если вам нужно убрать из URL конечный слеш, то для этого используйте:
Удаление конечных слешей из произвольных путей
Удаление конечных слешей из URL для веб-сайтов, размещённых в директории (как example.org/blog/):
Удаление лишних слешей в адресе URL
Например, страница /catalog///stranica.html доступна и открывается. Чтобы избежать такой ситуации и не плодить бесконечное число дублей следует записать следующий редирект:
Это правило удаляет лишние слеши из начала и конца URL.
В этом правиле используется переменная %{THE_REQUEST}, она содержит полный запрос, примерно следующего вида:
Для разделения частей запроса в выражениях условий, используется \s, которая означает белые пробелы.
В предыдущем правиле удаляются лишние слеши только в начале или конце запроса. Чтобы заменить два и более слеша в середине URL на одинарный слеш используйте следующее правило:
Контроль доступа и блокировка хотлинка
Ограничение доступа по IP
Модуль mod_rewrite умеет переадресовывать, показывать различные страницы или блокировать доступ в зависимости от IP пользователя. Но если вам нужно просто заблокировать доступ для определённых IP, либо разрешить доступ определённым IP, но намного более удобным и лучшим вариантом будет использовать другой модуль, отвечающий за Контроль доступа к сайту (по ссылке подробная инструкция и множество примеров ограничения доступа к папка и отдельным файлам).
Запрет доступа к скрытым файлам и директориям
Скрытые файлы и директории (это те, чьи имена начинаются на точку .), должно в основном, если не всегда, быть защищены от просмотра веб-клиентами. Примеры таких файлов и папок: .htaccess, .htpasswd, .git, .hg…
В качестве альтернативы, чтобы запутать атакующего, при попытке открыть такие файлы можно вызвать ошибку «Not Found».
Запрет хотлинка изображений
Хотлинк (англ. hotlink) – включение в веб-страницу файлов-изображений или других ресурсов с чужого сервера.
При использовании следующих правил вам нужно отредактировать домен example.com на имя вашего сайта.
Также при тестировании помните о кэшировании (если оно включено, то изображении некоторое время всё равно будет отдаваться из кэша).
Приведённый выше вариант разрешит отправку изображений при пустом реферере («Blank Referrers»).
Что такое пустой реферер? Некоторые посетители имеют персональные файерволы или антивирусные программы, которые удаляют информацию о реферере (referrer) страницы, которую отправляет ваш веб-браузер. Защита от хотлинка основывается на этой информации. Поэтому если вы выберите запрет отправки изображений пользователям с пустым реферером, то вы заблокируете этих пользователей. Также это не позволит пользователям напрямую получать доступ к изображению, если они набрали его URL в браузере.
Допустим, вы не хотите разрешать «пустой реферер», тогда используйте следующий вариант:
Допустим вы хотите показать изображение в духе «STOP HOTLINKING», тогда используйте следующий метод:
Не забудьте поменять адрес изображения (http://example.com/blocked.png) на свой. Также убедитесь, что это изображение НЕ защищено от хотлинка, в противном случае ваш сервер попадёт в бесконечную петлю.
Запрет хотлинкинга только для определённых доменов
Иногда нужно отключить хотлинкинг изображений только для некоторых плохих парней. Для запрета хотлинка только от определённых доменов, таких как blockurl1.com, blockurl2.com и blockurl3.com, но разрешения любым другим сайтам вставлять ваши изображения:
Вы можете добавить столько различных доменов, сколько вам нужно. Каждая строка RewriteCond должна заканчиваться флагами [NC,OR]. NC означает игнорировать регистр. OR означает логическое ИЛИ, т.е. правило сработает, если совпал этот домен или любой другой. Последний домен в списке идёт без флага OR, поскольку строки RewriteCond заканчиваются.
Последняя строка содержит URL "http://example.com/blocked.gif", который содержит изображение, которое будет показываться когда совпадут перечисленные условия – т.е. сработает запрет хотлинка.
Строка RewriteCond %{REQUEST_URI} !blocked\.gif$ [NC] ОТКЛЮЧАЕТ запрет хотлинка для изображения, которое показывается в случае срабатывания правил – это позволяет избежать бесконечного цикла.
Вы можете показывать сообщение об ошибке 403 Forbidden вместо изображения. Для этого замените последнюю строку в предыдущем примере на:
Разрешение хотлинка для определённых сайтов
Чтобы разрешить хотлинк для определённых сайтов, укажите в следующих правилах свой сайт и сайты, которым вы хотите предоставить разрешение на вставку ваших картинок:
Блокировка пользователя по рефереру (Referrer)
Блокировка пользователей на основе ссылающегося домена. Это запрещает доступ для всех пользователей, кто пришёл (отправлен с) определённого домена:
Замените somedomain.com и anotherdomain.com на действительные значения доменов (сайтов), которые вы не любите.
Бывают ситуации, когда негативный трафик идёт с определённых сайтов, например, с буксов или просто с сайтов, которые вам не нравятся. В некоторых случаях с такими переходами можно бороться, но не всегда.
Довольно часто на буксах бывают задания вроде «зайти в поисковую систему, ввести такой-то запрос, перейти на такой-то сайт» - с таким вряд ли получится бороться, поскольку этот запрос трудно отличить от обычного трафика.
Но если переход делается непосредственно с сайта букса, либо показывается в iframe, то с таким можно бороться.
Также если ваш сайт добавили в агрегатор или разместили ссылку на сайте, который вам не нравится, то этот метод также сработает.
К примеру плохим сайтом является https://site.click/. Чтобы заблокировать переходы с этого сайта, можно использовать следующее:

В этом случае всем, кто пришёл с сайта https://site.click/ будет показываться сообщение «404 страница не найдена». При желании, можно поставить любой другой код ответа вместо 404, например, 403 (доступ запрещён), 500 (внутренняя ошибка сервера) или любой другой.
При желании заблокировать доступ с нескольких сайтов, используйте флаг [OR], например:
Обратите внимание, в последней строке не нужно указывать флаг [OR].
Вместо вывода ошибки, можно сделать редирект на любую страницу своего сайта, например, в следующем случае все пришедшие с сайта https://site.click/ пользователи будут отправлены на страницу error.html вашего сайта:
А в следующие правила устанавливают всех пришедших с сайта https://site.click/ отправлять на https://natribu.org/ru/:
Блокировка плохих ботов, клонеров сайтов, офлайн браузеров
Для отключения доступа ботам и другим программам:
Обратите внимание, что список неполный и (возможно), неактуальный. Дополняйте/редактируйте список на основе анализа логов ваших веб-сайтов.
Если вместо блокировки доступа, вы хотите отправлять их на какие-нибудь адские веб-сайты по вашему выбору, то замените последнюю строку на:
Или отправьте их на виртуальную чёрную дыру фальшивых email адресов:
Запрет доступа к файлу или директории в определённые периоды времени
Закрытие доступа в полночь:
Закрытие доступа с 12 до 15 часов:
Следующий набор директив запрещает доступ с 18 часов до 7 часов утра. При попытке посетить сайт в этот промежуток времени, будет выдан ответ 403 Forbidden (флаг [F]):
Запрет доступа с пустым реферером (Referer)
Следующее правило запретит доступ всем запросом, в котором не установлен HTTP заголовок Referer (в данном случае в логах Apache вместо строки Referer записывается "-"):
Блокировка доступа по части пользовательского агента (User Agent)
Уже рассмотрены примеры блокировки ботов по User Agent, когда имя пользовательского агента короткое и представляет собой одну строку без пробела.
Необязательно указывать полное имя — можно указать только часть строки User Agent для совпадения. Специальные символы и пробелы должны быть экранированы.
Например, следующее правило заблокирует доступ для всех пользователей, в чьей строке User Agent встречается «Android 10»:
Примеры заблокированных этим правилом User Agent:
Как заблокировать доступ по точному совпадению User Agent
Если вам нужно заблокировать доступ к сайту определённым User Agent с точным совпадением имени, то используйте конструкцию с If:
If доступна начиная с Apache 2.4.
Запрет доступа к определённым страницам
Переменная %{REQUEST_URI} включает в себя всё, что идёт в запросе после имени хоста (но не включает то, что идёт после знака вопроса в URL), используя её можно фильтровать запросы по URL, строке запроса, именам файла или их частям. Например:
Не смотря на то, что в логах веб-сервера Apache некоторые символы, в том числе кириллица, отображается в URL кодировке, в данных правилах можно указывать кириллицу. Например, следующее правило заблокирует доступ к статье с URL https://zawindows.ru/как-узнать-какой-процесс-блокирует-фа/:
При желании, можно указать сразу несколько URL (или их частей). Каждая строка для поиска должна быть помещена в круглые скобки, между собой строки в скобках должны быть разделены символом | (конвейер, труба), например:
Поскольку %{REQUEST_URI} не включает то, что идёт после знака вопроса в URL, то для фильтрации по строке запроса, идущей после знака вопроса, используйте %{QUERY_STRING}. Об этом смотрите раздел «Как фильтровать по строке запроса, идущей после знака вопроса».
Запрет доступа IP и диапазонам
С помощью mod_rewrite можно блокировать отдельные IP от доступа к сайту:
Можно указать несколько IP адресов для блокировки:
Также можно использовать и диапазоны, но нужно помнить, что в данном случае строки расцениваются как регулярные выражения, но тесть нотация CIDR (например, 94.25.168.0/21) не поддерживается.
Диапазоны должны быть указаны как регулярные выражения — это можно сделать с использованием наборов символов. Например, для блокировки следующих диапазонов
будет работать правило:
Обратите внимание, что диапазон 94.25.168.0 — 94.25.175.255 нельзя записать как 94.25.1[68-75], это будет истолковано как строка «94.25.1», и набор символов, включающий в себя символ 6, диапазон 8-7 и символ 5. Из-за диапазона 8-7 данная запись вызовет ошибку на сервере.
Поэтому для записи 94.25.168.0 — 94.25.175.255 используется «94\.25\.1[6-7]».
Также обратите внимание, что последний октет 0-255 можно пропускать, поскольку для совпадения с регулярным выражением достаточно того, что совпадёт часть IP адреса.
Комбинирование правил контроля доступа
Задание: заблокировать пользователей, удовлетворяющих сразу ВСЕМ последующим критериями:
1. Пустой реферер
2. Пользовательский агент содержит строку «Android 10»
3. Доступ был сделан к странице, URL которой содержит любую из строк
4. Пользователь имеет IP адрес, принадлежащий любому из диапазонов:
Следующий набор правил будет соответствовать указанной задаче:
Обратите внимание, что правила, которые связаны логическим ИЛИ, должны быть собраны в одно большое правило. То есть ни с одним из правил нельзя использовать флаг [OR], иначе это сломает логику всего набора правил.
Пример правила блокировки всех пользователей с пустым Referer, кроме одного IP адреса (127.0.0.1):
Как фильтровать по строке запроса, идущей после знака вопроса
Переменная %{QUERY_STRING} содержит строку запроса, которая следует после символа ? (знак вопроса) текущего запроса к серверу.
Обратите внимание, что фильтруемое значение должно быть в URL кодировке. К примеру, следующее правило:
Заблокирует доступ к странице https://suay.ru/?p=5373&заблокировать, но не запретит доступ к странице https://suay.ru/?p=5373.
Обработка строки параметров URI в mod_rewrite
Источник: Обработка строки параметров URI в mod_rewrite (цитируется с разрешения)
Запросы: request и query
Чтобы не возникло путаницы, начнём с терминов. В английском языке используются два слова request и query. Проблема в том, что они переводятся одинаково как «запрос». При этом они могут использоваться в одном контексте — в английском языке это не вызывает путаницы, а в русском получается «запрос» и «запрос», которые означают разные вещи.
Слово request относится к HTTP запросу. Протокол HTTP передаёт запрос на сервер, в этом запросе содержаться заголовки (например, информация об интересующем хосте (сайте), User-Agent пользователя, имеющиеся для этого сайта кукиз и прочее). Также говорят об URI запроса, методе запроса и так далее. Среди передаваемой информации также имеется query — строка запроса.
К примеру, если я в веб-браузере открою страницу suay.ru/wp-admin/post.php?post=1673&action=edit, то в ней строкой запроса (query) будет post=1673&action=edit, то есть всё то, что следует после ? (знака вопроса).
Как в mod_rewrite искать по параметрам после знака вопроса
Нужно понимать эту разницу, так как по умолчанию mod_rewrite работает с REQUEST_URI, то есть частью запроса, которая НЕ включает в себя строку query. Причём RewriteRule просто игнорирует query.
Очень часто mod_rewrite используется для ЧПУ («красивых» адресов), когда нужно сделать преобразования вида: из
в
В этом случае, как мы видим, исходная строка не содержит строки запроса (query), поэтому при написании правила проблема игнорирования query не возникает:
А что если нам нужно сделать преобразование другого рода:
Из:
В:
То есть мы убираем из строки запроса (query) параметр idc вместе с его значением.
В этом случае мы уже не можем использовать RewriteRule, поскольку его правила полностью игнорируют строку query. Правда, используя некоторые флаги можно сделать так, чтобы исходная строка запроса query добавлялась к новому URI — но нам в рассматриваемой ситуации нужно не это.
Проблема решается с использованием директивы RewriteCond, которая умеет работать с переменной QUERY_STRING, содержащей строку query с запросом.
Что нам нужно знать про RewriteCond? Директива RewriteCond оказывает воздействие на RewriteRule, которое следует после строки (или блока строк) RewriteCond. В RewriteCond также можно использовать обратные ссылки, но для разграничения от обратных ссылок RewriteRule, вместо $ (знака доллара) используется % (знак процента), то есть вместо $1, первая обратная ссылка обозначается как %1.
Итак, составляем RewriteCond для нашего случая:
Рассмотрим эту строку подробно.
%{QUERY_STRING} означает, что анализируется строка запроса, следующая в URI после знака вопроса.
Строка idc=([0-9]+)&marea=([0-9]+)$ представляет собой шаблон поиска. То есть ищется строка, которая начинается на idc=, затем следуют цифры (одна или более) — причём, поскольку это регулярное выражение в скобках, то найденные цифры помещаются в первую обратную ссылку, затем идёт строка &marea=, затем опять цифры (одна или более), причём найденные цифры помещаются во вторую обратную ссылку. В данном случае символ $ означает конец анализируемой строки.
Чего мы этим добились? Мы сделали так, что значение idc будет помещено в первую обратную ссылку, а значение marea будет помещено во вторую обратную ссылку.
Переходим непосредственно к правилу перезаписи RewriteRule:
Рассмотрим это содержимое подробно:
Регулярное выражение (.*) означает «что угодно». Но мы помним, что это «что угодно» игнорирует строку запроса query. То есть это URI без строки query. Причём, поскольку это регулярное выражение в скобках, то оно помещается в первую обратную ссылку.
Далее строка /$1?marea=%2. Она начинается с указания на корневую папку сайта (/), затем идёт первая обратной ссылка $1, в неё помещается весь URI кроме строки запроса, затем добавляется строка ?marea=, к которой добавляется то, что содержится во второй обратной ссылке (%2) от RewriteCond.
Флаги [L,R] означают завершить проверку по другим правилам и сделать редирект на новый адрес (то есть адрес страницы измениться в адресной строке веб-браузера пользователя).
В результате получится, что адрес:
Превратится в:
Соберём условие перезаписи и правило перезаписи вместе:
Как с mod_rewrite удалить параметр из URI
Эта конструкция приводит к тому, что будет «вырезано» значение определённого параметра из получаемой строки запроса. Если говорить более точно, строка запроса будет заново пересобрана, но уже без одного из своих параметров. Используя эту технику можно убирать один или несколько параметров из запроса, либо присваивать их значения другим параметрам.
Построчно:
Если вы хотите, чтобы перенаправление было временным (302), вы можете просто удалить часть =permanent. Moved Temporarily (временно перемещено) это значение по умолчанию для флага R.
Перемещено Временно - значение по умолчанию для флага R.
mod_rewrite: отрицание в строке запроса %{QUERY_STRING}
Рассмотрим отрицание в строках запроса, то есть когда правило RewriteRule применяется только к запросам, в которых у query отсутствует определённая строка. Для этого перед Шаблоном укажите ! (восклицательный знак) или конструкцию !=. Также Шаблон не нужно помещать в кавычки, иначе условие перестаёт работать. В результате RewriteRule будет применено только к запросам без указанной строки в query (в данном случае без fromsubdomain=true).
Как в mod_rewrite переписать строку запроса
Далее идёт перевод официальной документации.
Описание:
Вы хотите захватить определенное значение из строки запроса и либо заменить его, либо включить его в другой компонент URL-адреса.
Решения:
Многие из решений в этом разделе будут использовать одно и то же условие, которое оставляет совпадающее значение в обратной ссылке %2 . %1 – это начало строки запроса (вплоть до интересующего ключа), а %3 – это остаток. Чтобы быть гибким и избегать двойных «&&» в подстановках условие получилось немного сложным.
Это решение удаляет соответствующий ключ и значение:
В приведённом выше решении в RewriteCond создаются три обратные ссылки: первая (%1) содержит то, что до mykey, вторая – содержит значение mykey, третья (%3) содержи значение других переменных, которые после mykey.
В результате перезаписи адрес до строки запроса остаётся не изменным (это обратная ссылка $1, которая указывает на то, что нашёл RewriteRule), затем через знак вопроса '?' дописываются обратные ссылки %1 и %3 – которые составляют исходную строку запроса, но уже без mykey.
Следующее решение использует захваченное значение mykey при создании нового URL, отбрасывая остальную часть исходной строки запроса; на конце добавляется '?':
Это решение проверяет захваченное значение в последующем условии:
Это решение показывает обратную сторону предыдущих, копируя компоненты пути (возможно, PATH_INFO) из URL-адреса в строку запроса.
Это решение преобразовывает путь до страницы в строку запроса:
Перенаправление портов
Как перенаправить запросы на 80-й порт
Если ваш сервер принимает запросы не только на стандартные порты, то вы можете сделать перенаправление.
Чтобы переправить все запросы, которые пришли не на 80-й порт:
Как перенаправить запросы на 443-й порт
Чтобы переправить все запросы, которые пришли не на 443-й порт:
Как перенаправить запросы на 80-й порт кроме некоторых страниц
Чтобы переправить все запросы, которые пришли не на 80-й порт, но сделать исключение для одной страницы (act=proxy-checker):
В результате все запросы, пришедшие не на 80-й порт будут перенаправлены на него, но запрос страницы сайт.ru/act=proxy-checker будет обработан на любом прослушиваемом порту.
Как в mod_rewrite читать параметры POST
mod_rewrite не может работать с данными, передаваемыми методом POST. То есть с помощью mod_rewrite не получится модифицировать запросы POST, либо заблокировать или выполнить другие действия на основе запросов, передаваемых методом POST.
В качестве альтернативы используйте обработку данных POST в скриптах вашего сайта (с помощью PHP) — это простой способ, либо с помощью модуля Apache mod_security — это очень сложный способ.
Продолжение: «6. Продвинутые техники применения mod_rewrite».