nginx
May 30

NGINX Proxy Manager

Раньше я знал все свои IP-адреса наизусть. Теперь я по FQDN, и только мама зовёт меня по имени.

Если вы только начинаете осваивать маршрутизацию трафика или хотите удобно управлять несколькими сайтами на одном IP — эта статья для вас. Сегодня поговорим о NGINX Proxy Manager, который делает управление Nginx простым и понятным даже без глубоких знаний.

Что такое NGINX Proxy Manager?

Это удобный веб-интерфейс для управления прокси через NGINX. Представьте, что это графическая панель, где вы кликаете мышкой вместо того, чтобы редактировать конфиги в терминале. Это идеальный инструмент для домашней лаборатории или небольшого проекта.

Работает как Docker-образ, то есть его легко запустить и настроить. Всё уже собрано — просто стартуем контейнер и заходим в интерфейс через браузер.

Зачем он нужен?

Допустим, у вас есть несколько сайтов/сервисов, которые крутятся в разных контейнерах/ВМ. У всех свои IP адреса и порты. Запомнить довольно сложно, когда вываливается такой список, как ниже.

Все они ведут на один внешний IP-адрес вашего сервера. И вот тут NGINX Proxy Manager берёт на себя задачу смотреть на заголовок запроса (Host) и отправлять пользователя куда нужно — на нужный сервер, контейнер или виртуальную машину внутри вашей сети.

Кроме этого:

  • Поддерживает HTTPS (можно автоматически получать сертификаты Let's Encrypt).
  • Позволяет настраивать доступ по спискам разрешённых/запрещённых IP.
  • Есть аудит действий пользователей и система ролей.

Устанавливаем NPM

Подготовка среды

Мы будем использовать Ubuntu 22.04 LTS (можно и другие ОС, но пример на Ubuntu).
Нам понадобятся:
- 2 ядра процессора
- 1 ГБ оперативной памяти
- 10 ГБ дискового пространства

Обновляем систему и устанавливаем Docker:

sudo apt update && sudo apt upgrade -y
sudo apt install -y docker.io docker-compose

Создаём файл docker-compose.yml

nano docker-compose.yaml

Копируем и сохраняем

version: "3"
services:
  nginx-proxy-manager:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '80:80' # HTTP port
      - '443:443' # HTTPS port
      - '81:81' # Admin web port
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt

Запускаем контейнер:

docker-compose up -d

Через пару минут можно открыть браузер и перейти по адресу:
http://IP_адрес_хоста:81

Логин по умолчанию:
Email - admin@example.com
Пароль - changeme

При первом входе сервис предложит создать нового администратора и поменять пароль — обязательно сделайте это.

Настраиваем

Добавляем сертификат.

В моём случае, был сгенерирован самоподписанный SSL сертификат, который добавлен в корневые сертификаты на доверенные устройства в сети.

Переходим в SSL Certificates -> Add SSL Certificate -> Custom.

Указываем Name, прикрепляем Certificate Key и Certificate -> Save.

Промежуточный не обязателен, а он и не создавался.

Сертификат появится в интерфейсе

Добавляем хост

Переходим в раздел Proxy HostsAdd Proxy Host.

Во вкладке Details указываем:

Domain Names - доменное имя хоста

Scheme- http/s

Forward Hostname / IP - адрес хоста.

То есть, даже если мы выбираем Scheme - http, NGINX заворачивает его в SSL терминацию и мы ходим по https, так как браузер обращается в системное хранилище сертификатов

Во вкладке SSL выбираем ранее добавленный SSL Certificate.

Включаем все тумблеры и читаем дальше почему.

Force SSL

Принудительно перенаправляет все HTTP-запросы на HTTPS. Если пользователь попытается открыть сайт по протоколу http, его автоматически перенаправит на https, обеспечивая защищённое соединение.


HTTP/2 Support

Включает поддержку протокола HTTP/2 для данного домена. HTTP/2 ускоряет загрузку сайтов за счёт мультиплексирования запросов, более эффективной компрессии заголовков и других улучшений, но работает только поверх HTTPS.


HSTS Enabled

Включает HTTP Strict Transport Security (HSTS) — механизм, который сообщает браузеру, что сайт всегда должен открываться только по HTTPS. Даже если пользователь наберёт http, браузер сам заменит протокол на https до отправки запроса. Это защищает от атак типа “downgrade” и перехвата трафика.


HSTS Subdomains

Расширяет действие политики HSTS на все поддомены выбранного домена. Например, если включено для home.local, то и для *.home.local браузер будет использовать только HTTPS.

Сохраняем — и сайт будет доступен по вашему домену.

Однако, важно:

DNS-запись вашего домена должна указывать на IP-адрес, где работает NGINX Proxy Manager. Для этого рекомендуется развернуть локальный DNS-сервер, например, AdGuard Home, который поддерживает функцию перезаписи DNS-запросов.

Просто развернуть только Nginx Proxy Manager для перенаправления запросов в локальной сети недостаточно, потому что по умолчанию ваш роутер не знает о существовании такого доменного имени. В результате браузер будет пытаться найти этот адрес во внешнем интернете, а не внутри вашей сети. Рекомендую посмотреть видеоролик “Процесс загрузки web страницы” или "Что делает браузер, чтобы загрузить Веб-страницу?" — это поможет лучше понять процесс.

Решение:
Разверните локальный DNS-сервер и укажите его в качестве дополнительного DNS-сервера в настройках вашего роутера. После этого все устройства в вашей локальной сети смогут обращаться к локальным доменным именам, и изменения вступят в силу автоматически.

Немного теории

Как работает SSL-терминация

Если вы выбираете использование SSL-сертификата (даже если Scheme выбран как http), NPM настраивает так называемую SSL-терминацию:

  • Внешний клиент (браузер) подключается к вашему серверу по HTTPS.
  • Nginx принимает зашифрованный трафик, расшифровывает его с помощью SSL-сертификата, и далее передаёт уже расшифрованный HTTP-трафик на внутренний сервер (по указанному IP и порту).
  • Таким образом, внутренний сервис может работать по обычному HTTP, а пользователи снаружи всегда используют защищённое HTTPS-соединение.

Это стандартная практика для обратных прокси и называется SSL-терминацией (SSL termination):

SSL-терминация является процессом на обратном прокси сервере, который обрабатывает шифрование и дешифровку SSL таким образом, чтобы трафик между прокси и внутренними серверами был в HTTP.

Что происходит в браузере

  • Браузер пользователя устанавливает HTTPS-соединение с Nginx Proxy Manager.
  • При этом браузер проверяет SSL-сертификат, который хранится в системном хранилище сертификатов (или добавлен вручную, если это self-signed или локальный CA).

Полезные фишки

Статистика и мониторинг

Если хочется видеть нагрузку, количество запросов, ошибки и прочее — можно добавить в `docker-compose` ещё один сервис для анализа логов:

npm-monitoring:
  image: xavierh/goaccess-for-nginxproxymanager:latest
  restart: always
  environment:
    - TZ=Asia/Yekaterinburg
    - LOG_TYPE=NPM
  ports:
    - '82:7880'
  volumes:
    - ./data/logs:/opt/log

Открываете http://IP_адрес_хоста:82 и видите красивую статистику по трафику.

Кастомная страница 404

Вместо скучного сообщения об ошибке можно сделать весёлый редирект. Например, на видео с котиками или... на Rickroll 😄

Добавляем в `docker-compose`:

error-page-404:
  image: 'kale5/rickroll:latest'
  restart: unless-stopped
  ports:
    - '83:80'

А в настройках NGINX Proxy Manager указываем редирект на `http://localhost:83`.

Финальный `docker-compose.yml`

version: "3"
services:
  nginx-proxy-manager:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '80:80'
      - '443:443'
      - '81:81'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
  npm-monitoring:
    image: xavierh/goaccess-for-nginxproxymanager:latest
    restart: always
    environment:
      - TZ=Asia/Yekaterinburg
      - LOG_TYPE=NPM
    ports:
      - '82:7880'
    volumes:
      - ./data/logs:/opt/log
  error-page-404:
    image: 'kale5/rickroll:latest'
    restart: unless-stopped
    ports:
      - '83:80'

NGINX Proxy Manager — это отличный выбор для тех, кто хочет быстро поднять reverse proxy без головной боли. Он простой, удобный, поддерживает HTTPS «из коробки» и позволяет настраивать всё через веб-интерфейс.

Мне помогли:

https://akmalov.com/blog/nginx-proxy-manager