Поиск по сайту:

Как настроить mod_rewrite для Apache на CentOS 7


Введение

Apache — это модульный веб-сервер, который позволяет настраивать его возможности, включая и отключая модули. Это дает администраторам возможность адаптировать функциональность Apache к потребностям своего веб-приложения.

В этом руководстве мы установим Apache на сервер CentOS 7, подтвердим, что модуль mod_rewrite включен, и изучим некоторые важные функции.

Предпосылка

Прежде чем следовать этому руководству, убедитесь, что у вас есть обычный пользователь без полномочий root с привилегиями sudo. Вы можете узнать больше о том, как настроить пользователя с этими привилегиями, из нашего руководства «Как создать пользователя Sudo в CentOS».

Шаг 1 — Установка Apache

Мы установим Apache с помощью yum, утилиты управления пакетами по умолчанию для CentOS.

  1. sudo yum install httpd

При появлении сообщения Is this ok [y/d/N]: введите Y и нажмите клавишу ENTER, чтобы авторизовать установку.

Затем запустите демон Apache, автономный процесс, который создает пул дочерних процессов или потоков для обработки запросов, с помощью утилиты systemctl:

  1. sudo systemctl start httpd

Чтобы убедиться, что Apache успешно запущен, проверьте его состояние с помощью команды status:

  1. 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, который выводит список всех загруженных модулей:

  1. 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:

  1. 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:

  1. sudo systemctl restart httpd

С установленным Apache и включенным модулем mod_rewrite мы готовы настроить использование файла .htaccess.

Шаг 3 – Настройка файла .htaccess

Файл .htaccess позволяет определять директивы для Apache, включая RewriteRule, для каждого домена без изменения файлов конфигурации сервера. В Linux файлы, которым предшествует точка (.), считаются скрытыми.

Прежде чем использовать файл .htaccess, нам нужно обновить параметр AllowOverride, чтобы иметь возможность перезаписывать директивы Apache.

  1. 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, чтобы применить изменения:

  1. sudo systemctl restart httpd

Затем создайте файл .htaccess в корне документа по умолчанию, /var/www/html, для Apache.

  1. 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 в корневом каталоге документа:

  1. 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:

  1. 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.