Привет, мой друг! Сегодня поднимаем Nginx Proxy Manager reverse-proxy с графическим интерфейсом внутри Docker контейнера. Прокачаем свой скилл, потренируемся, и настроим рабочий reverse-proxy в пару кликов!
Содержание
- Минимальные требования
- Что такое Nginx Proxy Manager
- Подготовка к работе
- Конфигурация Docker Compose
- Настройка и установка NPM
- Конфигурация ACL
Минимальные требования
Для достижения результата нам потребуется:
- Сервер с root-доступом (я использую этот хостинг).
- Установленный Docker и Docker Compose для управления контейнерами.
- 20-30 минут свободного времени для развертывания и настройки.
- Запастись терпением и энтузиазмом для освоения нового!
Что такое Nginx Proxy Manager
Nginx Proxy Manager — это удобный инструмент для управления обратным проксированием, основанный на Nginx. Он обладает интуитивно понятным веб-интерфейсом, который значительно упрощает процесс настройки.
Основная задача NPM — проксирование ваших приложений на нужный домен или поддомен, фактически связывая контейнер с доменом. Это позволяет легко управлять доступом и маршрутизацией.
Существуют два основных способа привязки (проксирования) доменов:
- По порту — самый простой метод, но он имеет недостаток: порт будет открыт наружу.
- По хостнейму — более безопасный и продвинутый способ, при котором наружу открываются только три порта: 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 protected]
- Пароль: changeme
После успешной авторизации система предложит настроить вашу учетную запись. Вам нужно будет указать:
- Имя пользователя
- Актуальный email (он будет использоваться как логин)
- Новый пароль
Важно: Настоятельно рекомендуется использовать реальный email-адрес. Он может понадобиться для восстановления доступа и получения важных уведомлений о безопасности.
В появившемся окне смены пароля введите текущий пароль (changeme) и установите новый надежный пароль. При выборе пароля старайтесь использовать комбинацию букв разного регистра, цифр и специальных символов.
Обновляем записи DNS
Для проксирования приложений нам потребуется настроить DNS-записи домена. Если у вас еще нет своего домена, вы можете получить его бесплатно на Freenom или приобрести на популярных регистраторах домена Reg.ru, Nic.ru и так далее.
В качестве примера я покажу процесс настройки в панели Reg.ru, но принцип будет аналогичным для любого регистратора доменов.
Важно: После создания DNS-записи требуется время на её распространение. Обычно это занимает 5-10 минут, но в некоторых случаях может занимать до 72 часов. Это время называется «временем DNS propagation» для DNS-записей.
Начнем с проксирования панели управления NPM на поддомен npm.example.com. Для этого выполним следующие шаги:
- Заходим в панель управления Reg ru
- Переходим в раздел Домены
- Выбираем нужный домен
- Нажимаем на DNS-серверы и управление зоной
- Создаем новую A-запись со следующими параметрами:
- В поле Subdomain указываем: npm
- В поле IP Address вписываем: IP-адрес вашего сервера
- Нажимаем кнопку Save
Совет: Пока ждете обновления DNS, можете проверить статус распространения записей с помощью онлайн-инструментов DNS-проверки или командой
dig
в терминале
Вариант №1: Проксируем приложение через NPM по порту
Этот способ проще в реализации, но имеет особенность: помимо доступа через проксируемый домен, приложение остается доступным через внешний порт контейнера. Давайте настроим проксирование пошагово:
- Откройте веб-панель NPM
- Перейдите в раздел Proxy Hosts
- Нажмите 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-сертификат:
- Нажмите на три точки справа от хоста
- Выберите Edit
- Перейдите на вкладку SSL
- Нажмите кнопку Request a new SSL Certificate
- Заполните необходимую информацию и нажмите 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 может сменится. Это поможет избежать случайной блокировки.
Создание правил доступа
- В панели управления NPM перейдите в раздел Access Lists
- Нажмите кнопку Add Access List
- В появившейся форме вы увидите два основных метода аутентификации:
- Аутентификация по учетным данным (Login + Password)
- Аутентификация по IP-адресу
Примечание: Рекомендуется использовать оба метода аутентификации — так надежнее.
Настройка режима проверки
Важным элементом является переключатель Satisfy Any:
- Отключено: пользователь должен пройти все проверки (например, логин/пароль и проверка IP).
- Включен: достаточно пройти любую из настроенных проверок
Функция Pass Auth to Host позволяет передавать данные аутентификации на ваш бэкэнд-сервер. Это полезно для приложений, которым нужно знать, кто именно авторизован.
Примечание: Если вы настроили проверку IP и логина/пароля, с включённым Satisfy Any пользователь получит доступ, выполнив хотя бы одно условие. Режим «Satisfy Any» может быть полезен, но в продакшене рекомендуется держать его выключенным.
Настройка учетных данных
Во вкладке Authorization:
- Добавьте пары логин/пароль для авторизованных пользователей
- Для добавления нескольких пользователей используйте кнопку Add
- Рекомендуется использовать сложные пароли и уникальные логины для каждого пользователя
Примечание: Храните учетные данные в безопасном месте.
Настройка IP-фильтрации
Во вкладке Access:
- Укажите разрешенные IP-адреса в одном из форматов:
- Одиночный IP:
xxx.xxx.xxx.xxx
- Подсеть:
xxx.xxx.xxx.xxx/24
- Одиночный IP:
- Можно добавить несколько адресов или подсетей
- Рекомендую периодически проверять и обновлять список разрешенных адресов
Примечание: Если вы используете динамические IP-адреса, рекомендую использовать более широкие подсети, проверить подсети которые выдаёт ваш провайдер можно к примеру на 2ip.ru.
После заполнения нажимаем Save и видим наше новое правило
Применение правил к хостам
- Перейдите в Dashboard > Proxy Hosts
- Найдите нужный хост
- Нажмите на три точки справа и выберите Edit
- В настройках хоста выберите созданный ACL
- Сохраните изменения
Примечание: После применения правил рекомендуется сразу же протестировать доступ.
Тестирование настроек
Для корректной проверки работы ACL:
- Используйте режим инкогнито в браузере:
- Firefox:
Ctrl + Shift + P
- Chrome:
Ctrl + Shift + N
- Firefox:
- Проверьте следующие сценарии:
- Доступ с разрешенного 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
- Откройте панель управления Nginx Proxy Manager.
- Перейдите в раздел Proxy Hosts.
- Выберите нужный домен, нажмите на троеточие и выберите Edit.
- Во всплывающем окне перейдите на вкладку Advanced.
- Впишите правила редиректа с использованием синтаксиса 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, будут перенаправлены на новые страницы. Всё работает, а штрафов от поисковых систем за исчезнувшие страницы не будет!