Обратный прокси-сервер – это сервер, который принимает HTTP (S) запросы и равномерно распределяет между серверами бэкэнда. Обратные прокси-серверы очень полезны, поскольку многие современные веб-приложения обрабатывают входящие HTTP- запросы с помощью серверов приложений, которые не должны быть доступны пользователям напрямую и часто поддерживают только элементарные функции HTTP.
Обратный прокси-сервер позволяет заблокировать доступ к бэкэнду и серверам приложений. Также его можно использовать для распределения нагрузки (входящих запросов) между несколькими серверами приложений, что увеличит производительность и обеспечит отказоустойчивость сервера. Обратный прокси-сервер предоставляет функции, которых нет у обычного сервера приложений: кэширование, сжатие, шифрование SSL и т.д.
Данное руководство поможет выполнить базовую настройку Apache как обратного прокси-сервера с помощью модуля mod_proxy. В руководстве используется простой бэкэнд, написанный в фреймворке Flask, но вы можете использовать любой другой бэкэнд.
Требования
- Сервер Ubuntu 16.04.
- Доступ к sudo (подробнее – здесь).
- Предварительно установленный веб-сервер Apache 2 (инструкции можно найти в этом руководстве).
1: Включение модулей Apache
В комплекте с Apache поставляется множество модулей, но не все они включены по умолчанию. Сначала нужно включить модули, которые понадобятся нам в работе: это mod_proxy и ещё несколько дополнительных модулей, которые расширяют функции Apache.
Для работы нужны модули:
- mod_proxy: основной модуль проксирования Apache, который управляет соединениями и перенаправляет их.
- mod_proxy_http: включает поддержку проксирования HTTP.
- mod_proxy_balancer и mod_lbmethod_byrequests: добавляют балансировку нагрузки.
Чтобы включить их, выполните следующие команды:
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests
Чтобы обновить настройки, перезапустите Apache.
sudo systemctl restart apache2
Теперь Apache готов к настройке проксирования запросов HTTP. Следующий (опциональный) раздел поможет создать два простых сервера бэкэнда, с помощью которых можно проверить работу обратного прокси-сервера. Если у вас есть сервер на бэкэнде, можете перейти к разделу 3.
2: Создание серверов на бэкэнде
Серверы бэкэнда позволяют быстро протестировать настройку Apache. Создайте два сервера тестирования, которые будут принимать HTTP-запросы и выводить строку текста; пусть первый сервер отвечает «Hello world!», а второй – «Howdy world!».
Примечание: В производстве серверы бэкэнда обычно отвечают одинаково, возвращая один и тот же контент. Но в среде тестирования лучше получить от серверов разные ответы, чтобы убедиться, что балансировка нагрузки работает правильно.
Flask – это микрофреймворк Python, который позволяет быстро собирать веб-приложения. С помощью Flask можно создать серверы для тестирования, поскольку базовое приложение – это всего несколько строк кода. Для этого вам не обязательно хорошо владеть Python.
Читайте также: Другие руководства для Python
Обновите индекс пакетов:
sudo apt-get update
Установите pip, пакетный менеджер Python.
sudo apt-get -y install python3-pip
С помощью pip установите Flask:
sudo pip3 install flask
Теперь все необходимые компоненты установлены. Создайте в домашнем каталоге текущего пользователя новый файл, в котором будет храниться код первого сервера тестирования.
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 будет использовать вывод этой функции в качестве ответа на HTTP-запрос, отправленный на корневой URL-адрес приложения (/).
Код второго сервера тестирования почти такой же, отличается только фраза ответа.
Скопируйте файл первого сервера:
cp ~/backend1.py ~/backend2.py
Откройте полученный файл:
nano ~/backend2.py
И отредактируйте сообщение, заменив Hello world! на Howdy world!.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'Howdy world!'
Сохраните и закройте файл.
С помощью следующей команды запустите первый сервер (порт 8080). Также эта команда перенаправит вывод Flask в /dev/null, чтобы не засорять выход консоли.
FLASK_APP=~/backend1.py flask run --port=8080 >/dev/null 2>&1 &
Перед командой flask указана переменная окружения FLASK_APP. Переменные окружения позволяют передавать информацию процессам оболочки.
Читайте также: Чтение и установка переменных среды и оболочки на сервере Linux
В данном случае переменная передаётся вместе с командой, поскольку её значение применимо только в этом случае, команда flask не должна использовать этот файл постоянно. Чтобы запустить второй сервер, нужно указать его файл в переменной.
Запустите второй сервер (порт 8081):
FLASK_APP=~/backend2.py flask run --port=8081 >/dev/null 2>&1 &
Убедитесь, что первый сервер запущен:
curl http://127.0.0.1:8080/
На экране появится:
Hello world!
Теперь проверьте второй сервер:
curl http://127.0.0.1:8081/
В терминале появится:
Howdy world!
Примечание: Чтобы остановить серверы тестирования (в конце руководства), используйте команду:
killall flask
3: Настройка Apache
Теперь нужно настроить виртуальный хост веб-сервера Apache для поддержки проксирования. Обратный прокси-сервер может обслуживать один сервер бэкэнда или массив серверов с балансировкой нагрузки.
Примечание: В данном руководстве настройка проксирования происходит на уровне виртуального хоста. По умолчанию Apache обслуживает один стандартный виртуальный хост. Вы можете использовать предложенные здесь параметры и в файлах других виртуальных хостов.
Если сервер Apache поддерживает трафик HTTP и HTTPS, параметры обратного прокси-сервера нужно поместить в оба виртуальных хоста.
Читайте также:
- Настройка виртуальных хостов Apache в Ubuntu 16.04
- Создание SSL-сертификата на Apache в Ubuntu 16.04
Откройте файл виртуального хоста Apache по умолчанию:
sudo nano /etc/apache2/sites-available/000-default.conf
Найдите блок <VirtualHost *:80>.
Ниже вы найдёте инструкции для настройки обратного прокси-сервера для обслуживания одного сервера бэкэнда. Чтобы настроить прокси-сервер для поддержки массива серверов и распределения нагрузки, переходите к следующему подразделу.
Обратный прокси-сервер для одного сервера бэкэнда
Замените все параметры блока VirtualHost следующими настройками:
<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: передаёт исходный заголовок Host серверу бэкэнда (так он узнает адрес, используемый для доступа к приложению).
- ProxyPass: основная директива настройки проксирования. В данном случае всё, что идет после / (корневого URL), будет передаваться на указанный адрес сервера бэкэнда. К примеру, если веб-сервер Apache получает запрос к /example, он подключится к http://your_backend_server/example и вернёт клиенту ответ.
- ProxyPassReverse: эта директива должна иметь такие же настройки, что и ProxyPass. Она изменяет заголовки ответов сервера бэкэнда. Таким образом, если внутренний сервер возвращает заголовок редиректа, браузер клиента будет перенаправлен на адрес прокси-сервера, а адрес сервера, бэкэнда будет заблокирован.
Перезапустите Apache.
sudo systemctl restart apache2
Если вы откроете ссылку http://your_server_ip, вместо стандартной приветственной страницы веб-сервера вы увидите ответ сервера бэкэнда:
Hello world!
Обратный прокси-сервер и балансировка нагрузки
Если у вас есть массив серверов бэкэнда, вы можете распределить трафик между ними с помощью обратного прокси-сервера Apache и модуля 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, укажите в директиве BalancerMember адреса 127.0.0.1:8080 и 127.0.0.1:8081. Если вы используете собственные серверы, укажите их адреса.
Чтобы обновить настройки, перезапустите Apache.
sudo systemctl restart apache2
Если вы откроете в браузере ссылку:
http://your_server_ip
вместо стандартной приветственной страницы веб-сервера вы увидите ответ сервера бэкэнда:
Hello world!
Обновите страницу, и на экране появится ответ второго сервера:
Howdy world!
Если это так, обратный прокси-сервер работает правильно.
Заключение
Теперь вы умеете настраивать Apache как обратный прокси-сервер для одного или нескольких серверов бэкэнда. Модуль mod_proxy позволяет настроить обратный прокси-сервер для серверов приложений, написанных на разных языках программирования (Python и Django, Ruby и Ruby on Rails и т.д.). Также с его помощью можно настроить балансировку нагрузки между серверами и обеспечить SSL-шифрование для тех серверов, которые не поддерживают его по умолчанию.
Модули mod_proxy и mod_proxy_http часто используются в связке, но существует ещё несколько полезных модулей, которые поддерживают разные сетевые протоколы и которые можно добавить:
- mod_proxy_ftp для FTP.
- mod_proxy_connect для SSL-туннелирования.
- mod_proxy_ajp для поддержки AJP (Apache JServ Protocol, используется в приложениях на основе Tomcat).
- mod_proxy_wstunnel для поддержки веб-сокетов.
Читайте также: Официальная документация mod_proxy