Привет, мой друг! Сегодня поднимаем Nginx Proxy Manager reverse-proxy с графическим интерфейсом внутри Docker контейнера. Прокачаем свой скилл, потренируемся, и настроим рабочий reverse-proxy в пару кликов!

Содержание

Минимальные требования

Для достижения результата нам потребуется:

  • Сервер с root-доступом (я использую этот хостинг).
  • Установленный Docker и Docker Compose для управления контейнерами.
  • 20-30 минут свободного времени для развертывания и настройки.
  • Запастись терпением и энтузиазмом для освоения нового!

Что такое Nginx Proxy Manager

Nginx Proxy Manager — это удобный инструмент для управления обратным проксированием, основанный на Nginx. Он обладает интуитивно понятным веб-интерфейсом, который значительно упрощает процесс настройки.

Основная задача NPM — проксирование ваших приложений на нужный домен или поддомен, фактически связывая контейнер с доменом. Это позволяет легко управлять доступом и маршрутизацией.

Существуют два основных способа привязки (проксирования) доменов:

  1. По порту — самый простой метод, но он имеет недостаток: порт будет открыт наружу.
  2. По хостнейму — более безопасный и продвинутый способ, при котором наружу открываются только три порта: 80, 443 и порт управления панелью NPM. Порты остальных проксируемых контейнеров будут защищены.

В этом посте рассмотрим оба подхода к проксированию.

Кроме того, Nginx Proxy Manager поддерживает работу с TLS (SSL) сертификатами. Мы также обсудим способ получения бесплатных SSL-сертификатов:

  • Бесплатный самообновляющийся сертификат от Let’s Encrypt.

NPM автоматически продлевает самообновляющиеся сертификаты каждые три месяца, снимая эту задачу с ваших плеч.

Также в NPM предусмотрены специальные правила доступа (ACL) для ограничения или предоставления доступа к вашим приложениям на основе IP-адреса, пароля или их комбинации.

Помимо этого, NPM поддерживает работу с редиректами и стримами, но в рамках этой статьи мы эти функции рассматривать не будем.

Подготовка рабочего пространства

Для поддержания порядка и удобства управления контейнерами будем следовать правилу — размещать все Docker-контейнеры в единой структуре каталогов. Давайте создадим отдельную директорию для Nginx Proxy Manager:

sudo mkdir -p /app/NPM

Чтобы избежать проблем с правами доступа и следовать best practices безопасности, назначим владельцем директории текущего пользователя (не root):

sudo chown -R $USER:$USER /app/NPM

Сделаем нашего пользователя (не root !) владельцем этой директории.

Хотя технически вы можете работать под пользователем root, это не является хорошей практикой с точки зрения безопасности. Работа под root повышает риск случайного повреждения системы и делает её более уязвимой для потенциальных атак. Поэтому назначим владельцем директории обычного sudo пользователя.

Конфигурация и запуск

Перейдём в директорию, которую мы создавали выше:

cd /app/NPM

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

nano docker-compose.yml

Вставим следующую конфигурацию:

services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'   container_name: nginx-proxy-manager-app

    restart: unless-stopped
    ports:
      # Порты указываются в формате <порт-хоста>:<порт-контейнера>
      - '80:80'   # Публичный HTTP порт
      - '443:443' # Публичный HTTPS порт
      - '43013:81'   # Порт веб-интерфейса администратора
      # Вы можете добавить другие порты, которые хотите открыть
      # - '21:21' # FTP

    # Раскомментируйте следующую строку, если раскомментируете что-либо в этой секции
    # environment:
      # Раскомментируйте это, если хотите изменить расположение
      # файла SQLite БД внутри контейнера
      # DB_SQLITE_FILE: "/data/database.sqlite"
      # Раскомментируйте это, если IPv6 не включен на вашем хосте
      # DISABLE_IPV6: 'true'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt

Вы можете использовать MySQL/MariaDB для своих контейнеров, но в этой статье не будет рассматриваться такая конфигурация. Подробнее про добавление баз данных можете почитать в официальной документации.

Запускаем контейнер в фоновом режиме:

sudo docker-compose up -d

Настройка Nginx Proxy Manager

Для доступа к панели управления NPM откройте в браузере адрес вашего сервера с указанием порта. По умолчанию это порт 81, но в целях безопасности рекомендую использовать нестандартный порт (например, 43013). Это усложнит потенциальным злоумышленникам поиск панели управления.

http://ip.адрес.вашего.сервера:порт

Для первого входа используйте следующие учетные данные:

После успешной авторизации система предложит настроить вашу учетную запись. Вам нужно будет указать:

  • Имя пользователя
  • Актуальный email (он будет использоваться как логин)
  • Новый пароль

Важно: Настоятельно рекомендуется использовать реальный email-адрес. Он может понадобиться для восстановления доступа и получения важных уведомлений о безопасности.

В появившемся окне смены пароля введите текущий пароль (changeme) и установите новый надежный пароль. При выборе пароля старайтесь использовать комбинацию букв разного регистра, цифр и специальных символов.

Обновляем записи DNS

Для проксирования приложений нам потребуется настроить DNS-записи домена. Если у вас еще нет своего домена, вы можете получить его бесплатно на Freenom или приобрести на популярных регистраторах домена Reg.ru, Nic.ru и так далее.

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

Важно: После создания DNS-записи требуется время на её распространение. Обычно это занимает 5-10 минут, но в некоторых случаях может занимать до 72 часов. Это время называется «временем DNS propagation» для DNS-записей.

Начнем с проксирования панели управления NPM на поддомен npm.example.com. Для этого выполним следующие шаги:

  1. Заходим в панель управления Reg ru
  2. Переходим в раздел Домены
  3. Выбираем нужный домен
  4. Нажимаем на DNS-серверы и управление зоной
  5. Создаем новую A-запись со следующими параметрами:
    • В поле Subdomain указываем: npm
    • В поле IP Address вписываем: IP-адрес вашего сервера
  6. Нажимаем кнопку Save

Совет: Пока ждете обновления DNS, можете проверить статус распространения записей с помощью онлайн-инструментов DNS-проверки или командой dig в терминале

Вариант №1: Проксируем приложение через NPM по порту

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

  1. Откройте веб-панель NPM
  2. Перейдите в раздел Proxy Hosts
  3. Нажмите Add Proxy Host

Заполните форму следующими данными:

  • Domain Names: npm.example.com
  • Scheme: http
  • Forward Hostname / IP: указываем IP-адрес вашего сервера
  • Forward Port: 81 (рекомендуется сменить на нестандартный, например 43013)

Важно: При использовании международных доменов (IDN) необходимо указывать их в формате Punycode. Например, для домена домен.com нужно использовать xn--d1acufc.com (не указывая оригинальное имя).

После сохранения хост появится в списке. Проверьте его работу, перейдя по адресу http://npm.example.com

Добавляем SSL-сертификат:

  1. Нажмите на три точки справа от хоста
  2. Выберите Edit
  3. Перейдите на вкладку SSL
  4. Нажмите кнопку Request a new SSL Certificate
  5. Заполните необходимую информацию и нажмите Save

После успешной установки сертификата:

  • Сайт автоматически будет доступен по HTTPS
  • В адресной строке появится значок замка
  • При попытке доступа по HTTP произойдет автоматический редирект на HTTPS

Совет: По мере добавления новых хостов они будут отображаться в общем списке Proxy Hosts, что упрощает управление и мониторинг.

Теперь ваше приложение защищено SSL-сертификатом и доступно по настроенному домену. В следующей части мы рассмотрим более безопасный способ проксирования — через hostname.

Вариант 2: Проксируем приложение через hostname

Со временем приходит понимание, что открытые порты на сервере ни к чему, лучше их минимизировать. Давайте расскажу, как от них избавится. Настроим проксирование через внутреннюю сеть Docker, оставив открытыми только порты 80 и 443.

Создаем сеть Docker

sudo docker network create -d bridge venom

Примечание: Существующие контейнеры можно добавить в сеть командой:

sudo docker network connect venom container_name

Обновляем конфигурацию docker-compose.yml

services:
app:
image: 'jc21/nginx-proxy-manager:latest'
container_name: nginx-proxy-manager-app
restart: unless-stopped
ports:
- '80:80'
# - '43013:81' # Комментируем, так как больше не нужен
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
- default

networks:
default:
external: true
name: venom

Ключевые изменения:

  • Через container_name мы будем использовать прямое обращения к контейнеру
  • Настроили сеть venom
  • Закомментирован лишний порт

Перезапускаем контейнер с новой конфигурацией:

sudo docker-compose up -d --force-recreate

Настройка прокси в панели NPM:

  • Откройте Proxy Hosts
  • Добавьте или отредактируйте хост npm
  • В поле Forward Hostname / IP укажите: nginx-proxy-manager-app
  • В поле Forward Port укажите: 81
  • Нажмите Save

Важно: Используем порт 81, а не 43013, потому что обращаемся к контейнеру по внутренней сети. В Docker внутренний порт указывается справа от двоеточия в конфигурации (например, в 43013:81 внутренний порт — 81).

После этих настроек:

  • Открыты только необходимые порты (80 и 443)
  • Все приложения проксируются через внутреннюю сеть Docker
  • Повышена безопасность за счет отсутствия лишних открытых портов

Совет: При добавлении новых сервисов не забудьте включить их в сеть venom внутри docker-compose.yml или используя команды docker

Защищаем хосты через ACL

Nginx Proxy Manager предоставляет мощный инструмент Access Control List (ACL), позволяющий настроить многоуровневую защиту. С его помощью мы можем контролировать, кто и откуда имеет доступ к нашим приложениям.

Примечание: Перед настройкой ACL убедитесь, в правильности всех IP-адресов, которым потребуется доступ, не забывайте что домашние провайдеры по умолчанию выдают DHCP сети и ваш ip может сменится. Это поможет избежать случайной блокировки.

Создание правил доступа

  1. В панели управления NPM перейдите в раздел Access Lists
  2. Нажмите кнопку Add Access List
  3. В появившейся форме вы увидите два основных метода аутентификации:
    • Аутентификация по учетным данным (Login + Password)
    • Аутентификация по IP-адресу

Примечание: Рекомендуется использовать оба метода аутентификации — так надежнее.

Настройка режима проверки

Важным элементом является переключатель Satisfy Any:

  • Отключено: пользователь должен пройти все проверки (например, логин/пароль и проверка IP).
  • Включен: достаточно пройти любую из настроенных проверок

Функция Pass Auth to Host позволяет передавать данные аутентификации на ваш бэкэнд-сервер. Это полезно для приложений, которым нужно знать, кто именно авторизован.

Примечание: Если вы настроили проверку IP и логина/пароля, с включённым Satisfy Any пользователь получит доступ, выполнив хотя бы одно условие. Режим «Satisfy Any» может быть полезен, но в продакшене рекомендуется держать его выключенным.

Настройка учетных данных

Во вкладке Authorization:

  1. Добавьте пары логин/пароль для авторизованных пользователей
  2. Для добавления нескольких пользователей используйте кнопку Add
  3. Рекомендуется использовать сложные пароли и уникальные логины для каждого пользователя

Примечание: Храните учетные данные в безопасном месте.

Настройка IP-фильтрации

Во вкладке Access:

  1. Укажите разрешенные IP-адреса в одном из форматов:
    • Одиночный IP: xxx.xxx.xxx.xxx
    • Подсеть: xxx.xxx.xxx.xxx/24
  2. Можно добавить несколько адресов или подсетей
  3. Рекомендую периодически проверять и обновлять список разрешенных адресов

Примечание: Если вы используете динамические IP-адреса, рекомендую использовать более широкие подсети, проверить подсети которые выдаёт ваш провайдер можно к примеру на 2ip.ru.

После заполнения нажимаем Save и видим наше новое правило

Применение правил к хостам

  1. Перейдите в Dashboard > Proxy Hosts
  2. Найдите нужный хост
  3. Нажмите на три точки справа и выберите Edit
  4. В настройках хоста выберите созданный ACL
  5. Сохраните изменения

Примечание: После применения правил рекомендуется сразу же протестировать доступ.

Тестирование настроек

Для корректной проверки работы ACL:

  1. Используйте режим инкогнито в браузере:
    • Firefox: Ctrl + Shift + P
    • Chrome: Ctrl + Shift + N
  2. Проверьте следующие сценарии:
    • Доступ с разрешенного IP с правильными учетными данными
    • Доступ с разрешенного IP с неверными учетными данными
    • Доступ с неразрешенного IP (например, через VPN)

В случае неудачно попытки вы увидите страницу 404

Примечание: Всегда сохраняйте резервный доступ к серверу через SSH на случай, если что-то пойдет не так с настройками ACL. Вы также можете сделать резервную копию NPM перед конфигурацией ACL, если что-то пойдёт не так.

Ожидаемые результаты:

  • При корректных данных: успешный доступ к приложению
  • При некорректных данных: сообщение об ошибке доступа (403 Forbidden)

Советы по безопасности

  • Периодически проверяйте список IP
  • Меняйте пароли раз в несколько месяцев
  • Следите за неудачными попытками входа
  • Помните, что ACL — это базовый уровень защиты

Примечание: Ведите простой лог изменений в настройках — это поможет при troubleshooting.

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

Как сделать 301 и 302 редирект в Nginx Proxy Manager

Иногда бывает, что вы обновили структуру сайта, и старые страницы больше недоступны. Вместо того чтобы встречать пользователей страницей 404, настройте 301 редирект, чтобы автоматически перенаправлять их на новые адреса. Это не только удобно для посетителей, но и помогает сохранить SEO-позиции вашего сайта.

Что такое 301 и 302 редирект?

  • 301 редирект — постоянный. Сообщает поисковым системам, что страница навсегда перемещена.
  • 302 редирект — временный. Используется, если страница доступна временно в другом месте.

Настройка редиректов в NPM

  1. Откройте панель управления Nginx Proxy Manager.
  2. Перейдите в раздел Proxy Hosts.
  3. Выберите нужный домен, нажмите на троеточие и выберите Edit.
  4. Во всплывающем окне перейдите на вкладку Advanced.
  5. Впишите правила редиректа с использованием синтаксиса NGINX:Пример для 301 редиректа:rewrite ^/old-page$ /new-page permanent;

Примеры:

  • Перенаправление на новую страницу:rewrite ^/blog/$ /blog.html permanent;
  • Перенаправление со старой формы на новую:rewrite ^/drugaya_forma\.html$ /different-shape.html permanent;
  • Перенаправление удалённой страницы на 404:rewrite ^/deleted\.html$ /404.html permanent;

Что в итоге?

После сохранения изменений пользователи, заходящие на старые URL, будут перенаправлены на новые страницы. Всё работает, а штрафов от поисковых систем за исчезнувшие страницы не будет!

Категории:

Контейнеры,