Как настроить mod_rewrite для Apache на CentOS 7
Введение
Apache — это модульный веб-сервер, который позволяет настраивать его возможности, включая и отключая модули. Это дает администраторам возможность адаптировать функциональность Apache к потребностям своего веб-приложения.
В этом руководстве мы установим Apache на сервер CentOS 7, подтвердим, что модуль mod_rewrite
включен, и изучим некоторые важные функции.
Предпосылка
Прежде чем следовать этому руководству, убедитесь, что у вас есть обычный пользователь без полномочий root с привилегиями sudo. Вы можете узнать больше о том, как настроить пользователя с этими привилегиями, из нашего руководства «Как создать пользователя Sudo в CentOS».
Шаг 1 — Установка Apache
Мы установим Apache с помощью yum
, утилиты управления пакетами по умолчанию для CentOS.
- sudo yum install httpd
При появлении сообщения Is this ok [y/d/N]:
введите Y
и нажмите клавишу ENTER
, чтобы авторизовать установку.
Затем запустите демон Apache, автономный процесс, который создает пул дочерних процессов или потоков для обработки запросов, с помощью утилиты systemctl
:
- sudo systemctl start httpd
Чтобы убедиться, что Apache успешно запущен, проверьте его состояние с помощью команды status
:
- sudo systemctl status httpd
Output. . .
systemd[1]: Starting The Apache HTTP Server...
systemd[1]: Started The Apache HTTP Server.
Когда Apache запущен и работает, давайте обратим внимание на его модули.
Шаг 2 – Проверка mod_rewrite
Начиная с CentOS версии 7 модуль Apache mod_rewrite
включен по умолчанию. Мы проверим это с помощью команды httpd
и флага -M
, который выводит список всех загруженных модулей:
- httpd -M
Output . . .
remoteip_module (shared)
reqtimeout_module (shared)
rewrite_module (shared)
setenvif_module (shared)
slotmem_plain_module (shared)
. . .
Если rewrite_module
не отображается в выходных данных, включите его, отредактировав файл 00-base.conf
в редакторе vi
:
- sudo vi /etc/httpd/conf.modules.d/00-base.conf
Когда текстовый файл откроется, введите i
, чтобы войти в режим вставки, а затем добавьте или раскомментируйте выделенную строку ниже:
#
# This file loads most of the modules included with the Apache HTTP
# Server itself.
#
. . .
LoadModule rewrite_module modules/mod_rewrite.so
. . .
Теперь нажмите ESC
, чтобы выйти из режима вставки. Затем введите :x
, затем нажмите клавишу ENTER
, чтобы сохранить и выйти из файла.
Затем примените изменение конфигурации, перезапустив Apache:
- sudo systemctl restart httpd
С установленным Apache и включенным модулем mod_rewrite
мы готовы настроить использование файла .htaccess
.
Шаг 3 – Настройка файла .htaccess
Файл .htaccess
позволяет определять директивы для Apache, включая RewriteRule
, для каждого домена без изменения файлов конфигурации сервера. В Linux файлы, которым предшествует точка (.
), считаются скрытыми.
Прежде чем использовать файл .htaccess
, нам нужно обновить параметр AllowOverride
, чтобы иметь возможность перезаписывать директивы Apache.
- sudo vi /etc/httpd/conf/httpd.conf
Найдите раздел
и измените директиву AllowOverride
с None
на All
:
. . .
<Directory /var/www/html>
. . .
#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
# Options FileInfo AuthConfig Limit
#
AllowOverride All
. . .
</Directory>
. . .
Сохраните и выйдите из файла, а затем перезапустите Apache, чтобы применить изменения:
- sudo systemctl restart httpd
Затем создайте файл .htaccess
в корне документа по умолчанию, /var/www/html
, для Apache.
- sudo vi /var/www/html/.htaccess
Добавьте следующую строку в начало файла, чтобы активировать RewriteEngine
, который указывает Apache обрабатывать все следующие правила:
RewriteEngine On
Сохраните и закройте файл.
Теперь у вас есть файл .htaccess
, который позволит вам определить правила для управления URL-адресами по мере необходимости. Прежде чем мы приступим к написанию реальных правил, давайте рассмотрим основной синтаксис mod_rewrite
.
Шаг 4 – Изучение синтаксиса RewriteRule
Директива RewriteRule
позволяет нам переназначить запрос на Apache на основе URL-адреса. Файл .htaccess
может содержать более одного правила перезаписи, но во время выполнения Apache применяет правила в установленном порядке. Правило перезаписи имеет следующую структуру:
Подстановка шаблона RewriteRule [флаги]
- RewriteRule: указывает директиву
RewriteRule
- Шаблон: PCRE (совместимое с Perl регулярное выражение), которое соответствует нужной строке. Подробнее о регулярных выражениях можно узнать здесь.
- Подстановка: куда следует отправлять совпадающие запросы
- [Флаги]: необязательные параметры для изменения правила. Дополнительные сведения о доступных флагах и их значениях см. в документации Apache по флагам перезаписи.
RewriteRule
— это рабочая лошадка директив mod_rewrite
, поэтому мы в основном сосредоточимся на нем в этом руководстве.
Шаг 5 — Изучение синтаксиса RewriteCond
Директива RewriteCond
позволяет нам добавлять условия к правилу перезаписи. Условие перезаписи имеет следующую структуру:
Условие RewriteCond TestString [флаги]
- RewriteCond: указывает директиву
RewriteCond
- TestString: строка для проверки
- Условие: шаблон для соответствия
- [Флаги]: необязательный параметр для изменения условия.
Директива RewriteCond
не позволяет Apache учитывать какие-либо правила перезаписи, которые следуют за ней, если конкретное условие не оценивается как истинное.
Шаг 6 – Настройка файлов
Мы установим базовое правило перезаписи, позволяющее пользователям посещать страницу about.html
без ввода расширения файла (.html
) в адресной строке веб-браузера. Начните с создания файла about.html
в корневом каталоге документа:
- sudo vi /var/www/html/about.html
Скопируйте в файл следующий HTML-код:
<!DOCTYPE html>
<html>
<head>
<title>About Us</title>
</head>
<body>
<h1>About Us</h1>
</body>
</html>
Сохраните и закройте файл.
В веб-браузере перейдите по следующему адресу:
http://server_domain_or_IP/about.html
Вы должны увидеть белую страницу с надписью «О нас». Если вы удалите .html из адресной строки и перезагрузите страницу, вы получите ошибку 404 Not Found. Apache может обращаться к компонентам только по их полному имени файла, но мы можем изменить это с помощью правила перезаписи.
Шаг 7 – Настройка RewriteRule
Мы хотели бы, чтобы посетители страницы «О нас» могли получить к ней доступ, не вводя .html
. Для этого мы создадим правило.
Откройте файл .htaccess
:
- sudo vi /var/www/html/.htaccess
После строки RewriteEngine On
добавьте следующее:
RewriteRule ^about$ about.html [NC]
Сохраните и закройте файл.
Теперь посетители могут получить доступ к странице «О нас» по URL-адресу http://server_domain_or_IP/about
.
Давайте рассмотрим правило перезаписи:
^about$
служит шаблоном, который сопоставляется с URL-адресом и тем, что пользователь вводит в свой браузер.
^
указывает начало URL-адреса после удаленияserver_domain_or_IP/
.&
означает конец URL.
about.html
показывает путь к файлу, который Apache обслуживает, когда обнаруживает соответствующий шаблон.
[NC]
— это флаг, указывающий правилу перезаписи быть нечувствительным к регистру, чтобы пользователь мог вводить строчные и прописные буквы в URL-адресе. Например, следующие URL-адреса указывают на файл about.html
:
- server_domain_or_IP/о
- домен_сервера_или_IP/О программе
- server_domain_or_IP/О КОМПАНИИ
С помощью простого правила перезаписи мы добавили динамический аспект того, как пользователи могут получить доступ к странице «О нас».
Общие шаблоны
Теперь, когда у нас есть общее представление о правилах перезаписи, мы рассмотрим два дополнительных примера в этом разделе.
Файлы примеров можно настроить, но это руководство не включает их создание; только сами правила перезаписи.
Пример 1. Упрощение строк запроса с помощью RewriteRule
Веб-приложения часто используют строки запроса, которые добавляются к URL-адресу с помощью символа вопросительного знака (?
) и разделяются символом амперсанда (&
). Apache игнорирует эти два символа при сопоставлении правил перезаписи. Однако иногда могут потребоваться строки запроса для передачи данных между страницами. Например, URL-адрес страницы результатов поиска, написанный на PHP, может выглядеть так:
http://example.com/results.php?item=shoes&type=women
Вместо этого мы хотели бы, чтобы наши посетители могли использовать следующий более чистый URL:
http://example.com/shoes/women
Мы можем добиться таких результатов одним из двух способов — путем простой замены или сопоставления вариантов.
Пример 1A: простая замена
Мы создадим правило перезаписи, которое выполняет простую замену, упрощая длинный URL-адрес запроса:
RewriteRule ^shoes/women$ results.php?item=shoes&type=women
Правило сопоставляет shoes/women
с results.php?item=shoes&type=women
.
Пример 1B: варианты сопоставления
В некоторых случаях нам может понадобиться обобщить строку запроса, включив в нее разные типы обуви. Мы можем добиться этого, выполнив следующие действия:
- Укажите ряд параметров, используя вертикальную черту
|
и логический оператор \ИЛИ - Сгруппируйте соответствие с помощью
()
, затем укажите ссылку на группу, используя переменную$1
, с1
для первой совпадающей группы.
Правило перезаписи теперь выглядит так:
RewriteRule ^shoes/(men|women|youth) results.php?item=shoes&type=$1
Правило, показанное выше, соответствует URL-адресу shoes/
, за которым следует указанный тип. Это изменит исходный URL, чтобы:
http://example.com/shoes/men
становится:
http://example.com/results.php?item=shoes&type=men
Эта опция сопоставления позволяет Apache оценивать несколько шаблонов без необходимости создавать отдельное правило перезаписи для каждого из них.
Пример 1C: Сопоставление наборов символов
Однако мы также хотели бы указать любой элемент, а не ограничиваться только /shoes
. Итак, мы будем делать следующее:
- Напишите регулярное выражение, соответствующее всем буквенно-цифровым символам. Выражение в скобках
[ ]
соответствует любому символу внутри него, а+
соответствует любому количеству символов, указанному в скобках - Сгруппируйте соответствие и укажите ссылку на него с помощью
$2
в качестве второй переменной в файле.
RewriteRule ^([A-Za-z0-9]+)/(men|women|youth) results.php?item=$1&type=$2
Приведенный выше пример преобразует:
http://example.com/pants/men
к:
http://example.com/results.php?item=pants&type=men
Мы успешно расширили возможность сопоставления, включив несколько аспектов URL.
Пример 1D: передача строк запроса
В этом разделе не вводятся какие-либо новые концепции, но рассматривается проблема, которая может возникнуть. Используя приведенный выше пример, скажем, мы хотели бы перенаправить http://example.com/pants/men
, но передаем дополнительную строку запроса ?page=2
. Мы хотели бы сопоставить следующий URL:
http://example.com/pants/men?page=2
к:
http://example.com/results.php?item=pants&type=men&page=2
Если бы вы попытались получить доступ к указанному выше URL-адресу с нашими текущими настройками, вы бы обнаружили, что строка запроса page=2
теряется. Это легко исправить с помощью дополнительного флага QSA
, который вызывает объединение строк запроса. Изменение правила перезаписи для соответствия следующему обеспечит желаемое поведение.
RewriteRule ^([A-Za-z0-9]+)/(men|women|youth) results.php?item=$1&type=$2 [QSA]
Пример 2: Добавление условий с помощью логики
Теперь мы рассмотрим использование директивы RewriteCond
. Если условие перезаписи оценивается как истинное, Apache рассматривает следующий за ним RewriteRule
.
Пример 2A: страница по умолчанию
Ранее мы видели, как Apache обрабатывал запрос недопустимого URL-адреса, предоставляя страницу 404 Not Found. Однако вместо страницы с ошибкой мы хотели бы, чтобы все некорректные URL-адреса перенаправлялись обратно на домашнюю страницу. Используя условие, мы можем проверить, существует ли запрошенный файл.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^admin/(.*)$ /admin/home
Это перенаправит что-то вроде /admin/random_text
на /admin/home
.
Разберем приведенное выше правило:
%{REQUEST_FILENAME}
проверяет запрошенную строку!-f
оператор!
или not указывает, что если запрошенное имя файла не существует, выполняется следующее правило перезаписи.RewriteRule
перенаправляет запросы обратно в/admin/home
Определение 404 ErrorDocument
будет соответствовать лучшим практикам. Для этого мы создадим правило ErrorDocument
, чтобы направлять ошибки 404 на страницу error.html
:
ErrorDocument 404 /error.html
Это перенаправляет любой запрос, который приводит к ответу HTTP 404, на страницу error.html
.
Пример 2B: Ограничение IP-адреса
RewriteCond
можно использовать для разрешения доступа к сайту с определенного IP-адреса.
Этот пример блокирует трафик отовсюду, кроме 198.51.100.24.
RewriteCond %{REMOTE_ADDR} !^(198\.51\.100\.24)$
RewriteRule (.*) - [F,L]
Все правило гласит, что если IP-адрес, запрашивающий ресурсы, не 198.51.100.24, то не разрешать доступ.
Суммируя:
%{REMOTE_ADDR}
— адресная строка!^(198\.51\.100\.24)$
инвертирует IP-адрес. Обратная косая черта\
исключает точку.
, потому что в противном случае они служат метасимволами, используемыми для соответствия любому символу.- Флаг
F
запрещает доступ, а флагL
указывает, что это правило выполняется последним, если оно выполняется.
Если вы предпочитаете заблокировать доступ с определенного адреса, используйте вместо этого следующее:
RewriteCond %{REMOTE_ADDR} ^(198\.51\.100\.24)$
RewriteRule (.*) - [F,L]
Хотя вы можете использовать другие методы для блокировки или разрешения трафика на ваш сайт, настройка ограничения в файле .htaccess
— это самый простой способ добиться этих результатов.
Заключение
В этом руководстве мы использовали файл .htaccess
для работы с директивами RewriteRule
и RewriteCond
. Существует много причин для использования правил перезаписи, и следующие ресурсы подробно описывают возможности модуля mod_rewrite
:
- Введение в Apache mod_rewrite
- Документация Apache для mod_rewrite
- памятка mod_rewrite
Модуль mod_rewrite
является важнейшим компонентом веб-сервера Apache, и с его помощью можно многое сделать. Однако не всегда все идет по плану, и когда это происходит, вы можете столкнуться с циклом перенаправления или двусмысленной ошибкой 500 запрещено
. Советы по отладке подобных ситуаций см. в этой публикации StackOverflow.