Настройка обратного прокси Nginx в Ubuntu

Обратный прокси-сервер — это рекомендуемый метод вывода сервера приложений в сеть. При работе с приложением Node.js в режиме разработки или с минимальным встроенным веб-сервером Flask эти серверы приложений часто привязываются к localhost с портом TCP. Значит, по умолчанию приложение будет доступно только локально на той машине, на которой оно находится. Но можно указать другую точку привязки для доступа в сеть. 

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

Со стороны клиента взаимодействие с обратным прокси ничем не отличается от взаимодействия с сервером приложений напрямую. Функционально это одно и то же, и клиент не видит разницы. Клиент запрашивает ресурс, а затем получает его без дополнительной настройки.

В этом туториале мы разберем настройку обратного прокси-сервера с помощью Nginx – популярного веб-сервера и обратного прокси. Установим Nginx, настроим его как обратный прокси-сервер с помощью директивы proxy_pass и перенаправим заголовки из запроса клиента. Если у вас нет сервера приложений для тестирования, можно настроить тестовое приложение с помощью WSGI-сервера Gunicorn.

Требования

  • Сервер Ubuntu, настроенный по этому мануалу.
  • Адрес сервера приложений, который будет проксирован; в этом мануале он будет условно называться app_server_address. Это может быть IP с портом TCP (например, http://127.0.0.1:8000 по умолчанию в Gunicorn) или сокет домена unix (например, http://unix:/tmp/pgadmin4.sock для pgAdmin). Если у вас нет настроенного сервера приложений для тестирования, мы настроим приложение Gunicorn, которое будет привязано к http://127.0.0.1:8000.
  • Домен, указывающий на внешний IP сервера. Этот домен будет настроен с помощью Nginx для проксирования сервера приложений.

1: Установка Nginx

Nginx доступен для установки с помощью apt через репозитории по умолчанию. Обновите индекс репозитория, а затем установите Nginx:

sudo apt update
sudo apt install nginx

Чтобы подтвердить установку нажмите Y. Если будет предложено перезапустить службы, нажмите ENTER, чтобы принять настройки по умолчанию.

Нужно разрешить доступ к Nginx через брандмауэр. Для этого добавьте правило в ufw:

sudo ufw allow 'Nginx HTTP'

Теперь проверим, что Nginx работает:

systemctl status nginx

nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2022-08-29 06:52:46 UTC; 39min ago
       Docs: man:nginx(8)
   Main PID: 9919 (nginx)
      Tasks: 2 (limit: 2327)
     Memory: 2.9M
        CPU: 50ms
     CGroup: /system.slice/nginx.service
             ├─9919 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
             └─9920 "nginx: worker process

Далее давайте добавим server block с вашим доменом и данными прокси сервера приложений.

2: Настройка Server Block

Рекомендуем не редактировать конфигурацию по умолчанию, а создать пользовательский конфигурационный файл для новых блоков server. С помощью nano или другого текстового редактора создайте и откройте новый файл конфигурации Nginx:

sudo nano /etc/nginx/sites-available/your_domain

Если у вас нет сервера приложений для тестирования, по умолчанию используйте http://127.0.0.1:8000 (мы настроим сервер Gunicorn в разделе 3). Вставьте следующее в новый файл, не забудьте изменить your_domain и app_server_address: 

server {
    listen 80;
    listen [::]:80;

    server_name your_domain www.your_domain;
       
    location / {
        proxy_pass app_server_address;
        include proxy_params;
    }
}

Сохраните и закройте файл. В nano нажмите CTRL+O, затем CTRL+X.

Файл конфигурации начинается со стандартной настройки Nginx, где Nginx будет слушать порт 80 и отвечать на запросы к your_domain и www.your_domain. Обратный прокси включается с помощью директивы Nginx proxy_pass. При такой конфигурации переход к your_domain в локальном браузере будет таким же, как открытие app_server_address на удаленной машине. В этом мануале будет проксироваться только один сервер приложений, но Nginx может быть  прокси-сервером для нескольких серверов сразу. Для этого нужно добавить дополнительные блоки location, одно имя сервера может объединить несколько серверов приложений через прокси в одно веб-приложение.

У всех HTTP-запросов есть заголовки, которые содержат информацию об отправившем запрос клиенте. Сюда входят сведения: IP, настройки кеша, отслеживание cookie, статус авторизации и т.д. В Nginx есть рекомендуемые настройки пересылки заголовков, которые мы включили как proxy_params, детали можно найти в /etc/nginx/proxy_params:

proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

Цель использования обратных прокси  — передать соответствующую информацию о клиенте, а иногда и информацию о самом обратном прокси. Бывают случаи, когда прокси-сервер хочет знать, какой обратный прокси-сервер обработал запрос, но обычно важная информация содержится в исходном запросе клиента. Чтобы передать эти заголовки и сделать информацию доступной в местах, где она необходима, Nginx использует директиву proxy_set_header.

Когда Nginx работает как обратный прокси-сервер, по умолчанию он изменяет два заголовка, удаляет все пустые заголовки, а затем передает запрос. У нас есть два измененных заголовка — это Host и Connection. Можете ознакомиться с подробным списком заголовков HTTP для получения дополнительной информации об их функциях (некоторые заголовки для обратных прокси мы рассмотрим дальше в этом мануале).

Пересылаемые заголовки proxy_params и переменные, в которых он хранит данные:

  • Host: этот заголовок содержит исходный хост, запрошенный клиентом, который является доменом сайта и портом. Nginx хранит эти данные в переменной $http_host.
  • X-Forwarded-For: заголовок содержит IP клиента, который отправил исходный запрос. Также в нем может быть список IP, причем первым идет исходный IP, а затем список всех IP обратных прокси-серверов, через которые прошел запрос. Nginx хранит его в переменной $proxy_add_x_forwarded_for.
  • X-Real-IP: всегда содержит один IP удаленного клиента. Он отличается от аналогичного X-Forwarded-For, который может содержать список адресов. Если X-Forwarded-For отсутствует, это будет то же самое, что и X-Real-IP.
  • X-Forwarded-Proto: содержит протокол, который исходный клиент использует для подключения (HTTP или HTTPS). Nginx хранит его в переменной $scheme.

Включите этот конфигурационный файл (Nginx считывает его при запуске). Создайте ссылку из него на каталог sites-enabled:

sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/

Теперь можно проверить файл конфигурации на наличие синтаксических ошибок:

sudo nginx -t

Если проблем не обнаружено, перезапустите Nginx, чтобы применить изменения:

sudo systemctl restart nginx

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

В противном случае перейдите к настройке тестового приложения и сервера с помощью Gunicorn.

3: Тестирование обратного прокси с помощью Gunicorn (опционально)

Если перед началом туториала у вас был подготовлен и запущен сервер приложений, вы можете перейти к нему в браузере:

your_domain

Однако, если у вас нет сервера приложений для тестирования обратного прокси-сервера, можете выполнить следующие шаги, чтобы установить Gunicorn вместе с тестовым приложением. Gunicorn — это WSGI-сервер на языке Python, который часто используется в паре с обратным прокси Nginx.

Обновите индекс репозитория apt и установите gunicorn:

sudo apt update
sudo apt install gunicorn

Можно также установить Gunicorn через pip с PyPI для получения последней версии, которая может быть сопряжена с виртуальной средой Python, но apt используется здесь в качестве быстрого тестового варианта.

Далее мы напишем функцию Python для вывода HTTP-ответа “Hello World!”, который будет отображаться в браузере. Создайте test.py с помощью nano или другого текстового редактора:

nano test.py

Вставьте следующий код Python в файл:

def app(environ, start_response):
    start_response("200 OK", [])
    return iter([b"Hello, World!"])

Это минимальный код, который нужен Gunicorn для запуска ответа HTTP, который выводит строку текста в браузере. После просмотра кода сохраните и закройте файл.

Теперь запустите сервер Gunicorn, указав test модуль Python и функцию app внутри него. Запуск сервера откроет терминал:

gunicorn --workers=2 test:app

[2022-08-29 07:09:29 +0000] [10568] [INFO] Starting gunicorn 20.1.0
[2022-08-29 07:09:29 +0000] [10568] [INFO] Listening at: http://127.0.0.1:8000 (10568)
[2022-08-29 07:09:29 +0000] [10568] [INFO] Using worker: sync
[2022-08-29 07:09:29 +0000] [10569] [INFO] Booting worker with pid: 10569
[2022-08-29 07:09:29 +0000] [10570] [INFO] Booting worker with pid: 10570

Вывод подтверждает, что Gunicorn прослушивает адрес http://127.0.0.1:8000 по умолчанию. Это адрес, который мы ранее установили для проксирования в конфигурации Nginx. Если вывод не такой, вернитесь к файлу /etc/nginx/sites-available/your_domain и отредактируйте app_server_address, связанный с директивой proxy_pass.

Откройте браузер и перейдите к домену, который настроили с помощью Nginx:

your_domain

Обратный прокси-сервер Nginx теперь обслуживает сервер веб-приложений Gunicorn и выводит “Hello World!”.

Подводим итоги

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

Читайте также: Обслуживание приложений Flask с помощью Gunicorn и Nginx в Ubuntu 16.04

Tags: , , ,

Добавить комментарий