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

Как использовать Apache в качестве обратного прокси с mod_proxy в CentOS 7


Введение

Обратный прокси-сервер – это тип прокси-сервера, который принимает запросы HTTP(S) и прозрачно распределяет их на один или несколько внутренних серверов. Обратные прокси-серверы полезны, потому что многие современные веб-приложения обрабатывают входящие HTTP-запросы, используя внутренние серверы приложений, которые не предназначены для прямого доступа пользователей и часто поддерживают только рудиментарные функции HTTP.

Вы можете использовать обратный прокси-сервер, чтобы предотвратить прямой доступ к этим базовым серверам приложений. Их также можно использовать для распределения нагрузки от входящих запросов на несколько разных серверов приложений, повышая производительность при масштабировании и обеспечивая отказоустойчивость. Они могут заполнить пробелы с помощью функций, которые не предлагают серверы приложений, таких как кэширование, сжатие или шифрование SSL.

В этом руководстве вы настроите Apache в качестве базового обратного прокси-сервера, используя расширение mod_proxy для перенаправления входящих подключений на один или несколько внутренних серверов, работающих в одной сети. В этом руководстве используется простой бэкэнд, написанный с помощью веб-фреймворка with Flask, но вы можете использовать любой бэкенд-сервер, который вам больше нравится.

Предпосылки

Чтобы следовать этому руководству, вам понадобятся:

  • Один сервер CentOS 7, настроенный с помощью этого руководства по начальной настройке сервера, включая пользователя sudo без полномочий root.
  • Apache 2 установлен на вашем сервере, выполнив шаг 1 инструкции по установке стека Linux, Apache, MySQL, PHP (LAMP) в CentOS 7.
  • При необходимости текстовый редактор nano устанавливается с помощью yum install nano. CentOS поставляется с текстовым редактором vi по умолчанию, но nano может быть более удобным для пользователя.

Шаг 1 — Знакомство с необходимыми модулями Apache

Модули, необходимые для использования Apache в качестве обратного прокси-сервера, включают сам mod_proxy и несколько его дополнительных модулей, которые расширяют его функциональность для поддержки различных сетевых протоколов. В частности, мы будем использовать:

  • mod_proxy, основной прокси-модуль Apache для перенаправления соединений; это позволяет Apache выступать в качестве шлюза для базовых серверов приложений.
  • mod_proxy_http, добавляющий поддержку проксирования HTTP-соединений.
  • mod_proxy_balancer и mod_lbmethod_byrequests, которые добавляют функции балансировки нагрузки для нескольких внутренних серверов.

Все четыре модуля включены по умолчанию при новой установке CentOS 7. Вы можете убедиться, что они включены, запустив:

  1. httpd -M

В выводе команды будут перечислены все включенные модули Apache. Четыре строки, которые вы ищете, являются вышеупомянутыми именами модулей:

Output
. . . proxy_module (shared) . . . lbmethod_byrequests_module (shared) . . . proxy_balancer_module (shared) . . . proxy_http_module (shared) . . .

Если модули не включены, вы можете включить их, открыв /etc/httpd/conf.modules.d/00-proxy.conf с помощью nano:

  1. sudo nano /etc/httpd/conf.modules.d/00-proxy.conf

и раскомментировать строки с необходимыми модулями, удалив знак # в начале строк, чтобы файл выглядел следующим образом:

. . . 
LoadModule proxy_module modules/mod_proxy.so
. . . 
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
. . . 
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
. . . 
LoadModule proxy_http_module modules/mod_proxy_http.so
. . . 

Чтобы изменения вступили в силу, сохраните файл и перезапустите Apache.

  1. sudo systemctl restart httpd

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

Шаг 2 — Создание внутренних тестовых серверов

Запуск нескольких простых внутренних серверов — это простой способ проверить, правильно ли работает ваша конфигурация Apache. Здесь мы создадим два тестовых сервера, которые отвечают на HTTP-запросы выводом строки текста. Один сервер скажет Hello world! а другой скажет Привет мир!.

Примечание. В нетестовых установках внутренние серверы обычно возвращают контент одного типа. Однако, в частности, для этого теста два сервера возвращают разные сообщения, что упрощает проверку того, что механизм балансировки нагрузки использует оба.

Flask — это микрофреймворк Python для создания веб-приложений. Мы используем Flask для создания тестовых серверов, потому что базовое приложение требует всего несколько строк кода. Вам не нужно знать Python, чтобы настроить их, но если вы хотите научиться, вы можете просмотреть эти учебные пособия по Python.

Давайте сначала установим файлы репозитория пакетов IUS. IUS (Inline with Upstream Stable) — это проект сообщества, который предоставляет обновленные версии избранного программного обеспечения для CentOS, включая Python 3.

  1. sudo yum -y install https://centos7.iuscommunity.org/ius-release.rpm

Затем установите Python 3 и Pip, рекомендуемый менеджер пакетов Python.

  1. sudo yum -y install python35u python35u-pip

Используйте Pip для установки Flask.

  1. sudo pip3.5 install flask

Теперь, когда все необходимые компоненты установлены, начните с создания нового файла, который будет содержать код для первого внутреннего сервера в домашнем каталоге текущего пользователя.

  1. nano ~/backend1.py

Скопируйте следующий код в файл, затем сохраните и закройте его.

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
    return 'Hello world!'

Первые две строки инициализируют среду Flask. Есть одна функция, home(), которая возвращает строку текста (Hello world!). Строка @app.route(/) над определением функции home() указывает Flask использовать возвращаемое значение home() в качестве ответа. на HTTP-запросы, направленные на корневой URL-адрес / приложения.

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

  1. cp ~/backend1.py ~/backend2.py

Откройте только что скопированный файл.

  1. nano ~/backend2.py

Измените сообщение, которое будет возвращено из Hello world! Привет, мир!, затем сохраните и закройте файл.

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
    return 'Howdy world!'

Используйте следующую команду, чтобы запустить первый фоновый сервер на порту 8080. Это также перенаправляет вывод Flask в /dev/null, потому что в дальнейшем это затуманит вывод консоли.

  1. FLASK_APP=~/backend1.py flask run --port=8080 >/dev/null 2>&1 &

Здесь мы предшествуем команде flask, устанавливая переменную среды FLASK_APP в той же строке. Переменные среды — это удобный способ передачи информации в процессы, порожденные оболочкой. Вы можете узнать больше о переменных среды в разделе Как читать и устанавливать переменные среды и оболочки на Linux VPS.

В этом случае использование переменной среды гарантирует, что параметр применяется только к выполняемой команде и не будет оставаться доступным впоследствии, так как мы будем передавать другое имя файла таким же образом, чтобы указать команде flask запустить команду второй сервер

Аналогичным образом используйте эту команду для запуска второго сервера на порту 8081. Обратите внимание на другое значение переменной среды FLASK_APP.

  1. FLASK_APP=~/backend2.py flask run --port=8081 >/dev/null 2>&1 &

Вы можете проверить, что два сервера работают, используя curl. Протестируйте первый сервер:

  1. curl http://127.0.0.1:8080/

Это выведет Hello world! в терминале. Протестируйте второй сервер:

  1. curl http://127.0.0.1:8081/

Это выведет Привет, мир! вместо.

Примечание. Чтобы закрыть оба тестовых сервера после того, как они вам больше не понадобятся, например, когда вы закончите работу с этим руководством, вы можете просто выполнить killall flask.

На следующем шаге мы изменим файл конфигурации Apache, чтобы разрешить его использование в качестве обратного прокси.

Шаг 3 — Изменение конфигурации по умолчанию для включения обратного прокси

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

Примечание. В этом руководстве мы применяем конфигурацию на уровне виртуального хоста. При установке Apache по умолчанию виртуальные хосты не настроены. Мы создадим один виртуальный хост по умолчанию, который будет перехватывать весь трафик. Однако вы можете использовать все эти фрагменты конфигурации и на других виртуальных хостах. Чтобы узнать больше о виртуальных хостах в Apache, вы можете прочитать это руководство Как настроить виртуальные хосты Apache в CentOS 7.

Если ваш сервер Apache действует как HTTP- и HTTPS-сервер, ваша конфигурация обратного прокси-сервера должна быть размещена на виртуальных хостах HTTP и HTTPS. Чтобы узнать больше о SSL с Apache, вы можете прочитать это руководство Как создать SSL-сертификат на Apache для CentOS 7.

Создайте новый виртуальный хост по умолчанию, создав новый пустой файл конфигурации Apache в каталоге /etc/httpd/conf.d с помощью nano или вашего любимого текстового редактора.

  1. sudo nano /etc/httpd/conf.d/default-site.conf

В первом примере ниже объясняется, как настроить виртуальный хост по умолчанию для обратного прокси-сервера для одного внутреннего сервера, а во втором — настроить обратный прокси-сервер с балансировкой нагрузки для нескольких внутренних серверов.

Пример 1 — Обратное проксирование одного внутреннего сервера

Вставьте следующее содержимое в файл default-site.conf, чтобы ваш файл конфигурации выглядел так:

<VirtualHost *:80>
    ProxyPreserveHost On

    ProxyPass / http://127.0.0.1:8080/
    ProxyPassReverse / http://127.0.0.1:8080/
</VirtualHost>

Если вы следовали примерам серверов на шаге 2, используйте 127.0.0.1:8080, как написано в блоке выше. Если у вас есть собственные серверы приложений, используйте их адреса.

Здесь три директивы:

  • ProxyPreserveHost заставляет Apache передавать исходный заголовок Host на внутренний сервер. Это полезно, поскольку позволяет внутреннему серверу узнать адрес, используемый для доступа к приложению.
  • ProxyPass — это основная директива конфигурации прокси. В этом случае он указывает, что все под корневым URL-адресом (/) должно быть сопоставлено с внутренним сервером по заданному адресу. Например, если Apache получает запрос на /example, он подключается к http://вашему_бэкенд-серверу/example и возвращает ответ на оригинальный клиент.
  • ProxyPassReverse должен иметь ту же конфигурацию, что и ProxyPass. Он говорит Apache изменить заголовки ответов от внутреннего сервера. Это гарантирует, что если внутренний сервер вернет заголовок перенаправления местоположения, браузер клиента будет перенаправлен на адрес прокси-сервера, а не на адрес внутреннего сервера, что не будет работать должным образом.

Чтобы эти изменения вступили в силу, перезапустите Apache.

  1. sudo systemctl restart httpd

Теперь, если вы войдете в http://your_server_ip в веб-браузере, вы увидите ответ внутреннего сервера вместо стандартной страницы приветствия Apache. Если вы выполнили шаг 2, это означает, что вы увидите Hellow world!.

Пример 2 — Балансировка нагрузки между несколькими внутренними серверами

Если у вас есть несколько внутренних серверов, хорошим способом распределения трафика между ними при проксировании является использование функций балансировки нагрузки mod_proxy.

Замените все содержимое блока VirtualHost следующим, чтобы ваш файл конфигурации выглядел так:

<VirtualHost *:80>
<Proxy balancer://mycluster>
    BalancerMember http://127.0.0.1:8080
    BalancerMember http://127.0.0.1:8081
</Proxy>

    ProxyPreserveHost On

    ProxyPass / balancer://mycluster/
    ProxyPassReverse / balancer://mycluster/
</VirtualHost>

Конфигурация аналогична предыдущей, но вместо прямого указания одного внутреннего сервера мы использовали дополнительный блок Proxy для определения нескольких серверов. Блок называется balancer://mycluster (имя можно свободно изменить) и состоит из одного или нескольких элементов BalancerMember, которые определяют адреса базового внутреннего сервера. Директивы ProxyPass и ProxyPassReverse используют пул балансировщика нагрузки с именем mycluster вместо конкретного сервера.

Если вы следовали примерам серверов на шаге 2, используйте 127.0.0.1:8080 и 127.0.0.1:8081 для директив BalancerMember, как написано в блоке выше. Если у вас есть собственные серверы приложений, используйте их адреса.

Чтобы эти изменения вступили в силу, перезапустите Apache.

  1. sudo systemctl restart httpd

Если вы зайдете на http://your_server_ip в веб-браузере, вы увидите ответы ваших внутренних серверов вместо стандартной страницы Apache. Если вы выполнили шаг 2, при многократном обновлении страницы должно появиться сообщение Hello world! и Привет, мир!, что означает, что обратный прокси-сервер работает и распределяет нагрузку между обоими серверами.

Теперь вы знаете, как настроить Apache в качестве обратного прокси-сервера для одного или нескольких базовых серверов приложений. mod_proxy можно эффективно использовать для настройки обратного прокси-сервера для серверов приложений, написанных на самых разных языках и технологиях, таких как Python и Django или Ruby и Ruby on Rails. Его также можно использовать для балансировки трафика между несколькими внутренними серверами для сайтов с большим трафиком или для обеспечения высокой доступности через несколько серверов или для обеспечения безопасной поддержки SSL для внутренних серверов, которые изначально не поддерживают SSL.

Хотя mod_proxy с mod_proxy_http является, пожалуй, наиболее часто используемой комбинацией модулей, существует несколько других, поддерживающих различные сетевые протоколы. Мы не использовали их здесь, но некоторые другие популярные модули включают в себя:

  • mod_proxy_ftp для FTP.
  • mod_proxy_connect для туннелирования SSL.
  • mod_proxy_ajp для AJP (протокол Apache JServ), например серверные части на основе Tomcat.
  • mod_proxy_wstunnel для веб-сокетов.

Чтобы узнать больше о mod_proxy, вы можете прочитать официальную документацию Apache mod_proxy.