Очень часто при администрировании веб-сервера Apache возникает необходимость настройки режимов обработки адресов URL. Например необходимо, чтобы запросы автоматически перенаправлялись с одного адреса на другой. Также, если нужно, чтобы веб-приложения работали на «чистых» ссылках, то для этого также необходима настройка модуля mod_rewrite. В данной статье на простых примерах будут рассмотрены базовые приёмы обработки перезаписи URL, реализуемой модулем mod_rewrite, на основе которых можно легко построить свои собственные правила и режимы обработки ссылок.
Включение модуля mod_rewrite и управление его работой
Обычно модуль mod_rewrite уже имеется в базовой поставке Apache и устанавливать его дополнительно не нужно. Остаётся его только включить. Например, для Ubuntu:
$ sudo a2enmod rewrite
Управление работой самого модуля mod_rewrite осуществляется при помощи файла .htaccess. Этот файл предназначен для активации и задействования директив веб-сервера Apache индивидуально для каждого из виртуальных хостов (или доменов).
Итак, для начала необходимо удостовериться, что Apache разрешает обработку файлов .htaccess. В конфигурационном файле Apache /etc/apache2/apache2.conf
директива AllowOverride должна иметь значение All в блоке:
Options Indexes FollowSymLinks AllowOverride All Require all granted
Следует заметить, что вместо «/var/www/html» может быть указан и другой каталог, в зависимости от того, как и где настроено расположение корневого каталога виртуальных хостов Apache. Также необходимо проверить, что в файле /etc/sites-enabled/000-default.conf
не содержится лишних директив (а лучше их убрать) AllowOverride, противоречащих тем, что установлены в файле apache2.conf. После сохранения всех изменений необходимо перезапустить веб-сервер:
$ sudo systemctl restart apache2
Далее, в начало файла .htaccess нужно добавить директиву:
RewriteEngine on
Она указывает, что Apache должен использовать модуль mod_rewrite для обработки условий и правил перезаписи URL.
Файл .htaccess может быть создан, как уже отмечалось, отдельно для каждого из виртуальных хостов. Обычно его помещают в корневой каталог, в котором находятся файлы требуемого виртуального хоста. В данном руководстве для расположения файла .htaccess будет использоваться каталог /var/www/html/
для глобальной обработки URL на веб-сервере.
Пример создания простой страницы и перезаписи URL для неё
Для демонстрации работы модуля mod_rewrite по перезаписи URL страницы, можно эту самую страницу создать (в самом простом варианте) и применить к ней (точнее, к её адресу) простой шаблон перезаписи.
Итак, нужно создать файл HTML-страницы hello.html, которая будет размещаться в каталоге /var/www/html/hello.html
со следующим содержимым:
<html> <head> <title>Hello, World</title> </head> <body> <h1>Hello, Worl</h1> </body> </html>
Эта страница будет доступна по адресу ip_server/hello.html
. Здесь «ip_server»– это IP-адрес сервера, на котором работает Apache. Вместо IP-адреса также можно использовать и доменное имя при должных настройках.
Особенность в том, что эта страница доступна только если вводить адрес, содержащий «hello.html». Любое другое написание, например «hello» приведёт к ошибке 404 — нет такого документа. Чтобы иметь возможность получать доступ к странице hello.html по «hello» нужно всего лишь настроить перезапись адреса. Редактирование файла .htaccess:
$ sudo nano /var/www/html/.htaccess
После ранее добавленной строки «RewriteEngine on» нужно добавить следующую:
RewriteRule ^hello$ hello.html [NC]
Только после этих изменений в веб-браузере по адресу ip_server/hello страница hello.html будет доступна.
Синтаксис добавленной записи следующий:
- ^hello$ — это шаблон подстановки, который должен совпадать с частью URL, вводимого в веб-браузере. Здесь символ (^) обозначает начало фразы шаблона, а символ ($) — его окончание;
- hello.html – это действительный путь к исходной странице hello.html;
- [NC] – флаг, отключающий зависимость написания URL символами разного регистра.
В результате, теперь страница hello.html будет доступна по следующим адресам: ip_server/hello, ip_server/Hello и ip_server/hello.html.
Таким образом и происходит перезапись URL модулем mod_rewrite по инструкциям из .htaccess.
Применение общих шаблонов перезаписи
Выражения в файле .htaccess, применённые в предыдущей главе — это ничто иное, как правила перезаписи. В общем виде они имеют следующий синтаксис:
RewriteRule pattern substitution [flags]
Здесь RewriteRule – это, собственно, сама директива, pattern – шаблон, задаваемый регулярным выражением. Он предназначен для поиска подстроки. Далее, substitution – это целевой действительный URL. А flags – флаги опций, которые задают определённое специфическое поведение правил.
Самым наглядным и общим примером является перезапись (точнее, упрощение) строки дополнительного запроса. Они используются веб-приложениями для передачи параметров скриптам, по которым нужно получить соответствующий результат. Строки запроса начинаются с символа «?» и заканчиваются символом «&». Например:
http://my-site.ru/results.php?item=shoes&season=summer
Если этот URL очистить с помощью правил перезаписи, то упрощённый вариант будет выглядеть примерно так:
http://my-site.ru/shoes/summer
Это куда как более удобно для восприятия. Подобные результаты очистки URL достигаются наиболее часто используемыми шаблонами перезаписи:
- простая замена;
- группирование и сопоставление;
- сопоставление наборов символов;
В первом случае нужно создать следующее правило:
RewriteRule ^shoes/summer$ results.php?item=shoes&season=summer
В результате подстрока URL «results.php?item=shoes&season=summer» будет переписываться строкой «shoes/summer».
Второй случай используется, когда нужно оптимизировать используемое правило так, чтобы оно являлось универсальным для разных строк запросов, т. е. с разными параметрами. Для данного примера пусть требуется, чтобы правило обрабатывало строку запросов для нескольких сезонов, а не только для «summer». Для этого нужно сначала определить набор самих параметров, которые должны разделяться символом вертикальной черты «|». После этого можно в регулярном выражении ссылаться на эту группу параметров, используя переменную $1, где «1» — это номер набора. Например:
RewriteRule ^shoes/(summer|winter|autmn|spring) results.php?item=shoes&season=$1
Сопоставление набора символов используется обычно, когда нужно, чтобы пользователи могли открывать чистые ссылки любых других разделов сайта, а не только «shoes», как в данном примере. Для этого нужно:
- составить регулярное выражение, определяющее все буквенные и цифровые символы, которые могут повторяться неограниченное число раз. Такое выражение заключается в квадратные скобки, объединяемыми знаком плюса «+»;
- это выражение нужно заключить в группу (в круглые скобки) и присвоить его переменной $2 – группа №2.
В результате получится следующее правило:
RewriteRule ^([A-Za-z0-9]+)/(summer|winter|autmn|spring) results.php?item=$1&season=$2
Полученное правило перепишет URL:
http://my-site.ru/results.php?item=hat&season=summer
в следующую чистую ссылку:
Задание условий RewriteCond для работы правил
Если задать определённое условие с помощью директивы RewriteCond, то если оно выполняется, Apache запустит выполнение правила, следующего сразу за этим условием. Синтаксис RewriteCond следующий:
RewriteCond tststr condition [flags]
Здесь tststr – строка, с которой сравнивается условие. А condition – шаблон, с которым сравнивается строка, заданная в tststr. Дополнительные параметры задаются с помощью флагов flags.
В качестве примера можно создать условие, при котором все запросы к несуществующим страница будут перенаправляться например, на домашнюю страницу:
RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^admin/(.*)$ /admin/home
Здесь выражение %{REQUEST_FILENAME} выполняет проверку строки запроса. Далее, оператор (!), означающий условие «не», предписывает, что отсутствие требуемого в запросе файла (-f) должно указывать Apache запускать в обработку следующее за этим условием правило перенаправления. Далее выполняется само правило переадресации, которое перенаправляет все запросы на страницу /admin/home
.
Пример блокировки всего трафика, кроме поступающего с определённого IP-адреса:
RewriteCond %{REMOTE_ADDR} !^(12\.38\.57\.123)$ RewriteRule (.*) - [F, L]
Здесь флаг «F» запрещает доступ, а флаг «L» – указывает, что данное правило должно выполниться последним.
Для обратного эффекта, т. е. для разрешения запросов с любых IP-адресов кроме 12.38.57.123 нужно перед регулярным выражением записи IP-адреса в определении условия убрать оператор «не» — символ восклицательного знака (!):
RewriteCond %{REMOTE_ADDR} ^(12\.38\.57\.123)$ RewriteRule (.*) - [F, L]
Заключение
в заключении стоит ещё раз отметить, что были рассмотрены только самые базовые приёмы управления модулем mod_rewrite для веб-сервера Apache. Для более подробного и глубокого освоения написания правили задания условий следует хорошо знать и составлять как регулярные выражения, так и назначение ключевых слов и дополнительных директив
Apache.