15%

Сэкономьте 15% на всех хостинговых услугах

Проверьте свои навыки и получите скидку на любой тарифный план

Используйте код:

Skills
Начать
09.10.2024

Как настроить Nginx для прослушивания нескольких портов

Nginx может одновременно прослушивать несколько портов, добавляя несколько директив `listen` внутри одного или нескольких блоков `server` в своей конфигурации. Каждая директива `listen` привязывает Nginx к определённой комбинации IP/порт, позволяя одному экземпляру сервера обрабатывать HTTP, HTTPS и трафик пользовательских приложений на отдельных портах без запуска отдельных процессов.

Эта возможность необходима для мультитенантных сред, разделения портов staging/production, архитектур обратного прокси и маршрутизации микросервисов — всё это с одного экземпляра VPS Хостинга.

Предварительные требования

Перед началом убедитесь в следующем:

  • Nginx установлен и служба активна (`systemctl status nginx`)
  • У вас есть привилегии `root` или `sudo` на сервере
  • Вы понимаете разницу между `/etc/nginx/nginx.conf` (глобальная конфигурация) и `/etc/nginx/sites-available/` (блоки конфигурации для отдельных сайтов)
  • Правила брандмауэра (`ufw`, `iptables` или облачная группа безопасности) разрешают трафик на портах, которые вы намерены открыть
  • Действительные SSL-сертификаты доступны при настройке HTTPS-портов (самоподписанные или выданные CA)

Архитектура конфигурации Nginx: что нужно знать прежде всего

Nginx использует иерархическую модель конфигурации: контекст `http` содержит один или несколько блоков `server`, каждый из которых может содержать одну или несколько директив `listen`. Понимание этой иерархии позволяет избежать наиболее распространённых ошибок конфигурации.

Ключевые задействованные директивы:

  • `listen [address:]port [ssl] [http2] [default_server]` — привязывает блок сервера к определённому порту и необязательному IP
  • `server_name` — сопоставляет заголовок `Host` для маршрутизации запросов к правильному блоку
  • `default_server` — определяет, какой блок сервера обрабатывает запросы, не соответствующие ни одному другому `server_name`

Расположение файлов конфигурации по дистрибутивам:

ДистрибутивОсновной конфигКонфиги сайтов
Ubuntu / Debian`/etc/nginx/nginx.conf``/etc/nginx/sites-available/`
CentOS / RHEL / AlmaLinux`/etc/nginx/nginx.conf``/etc/nginx/conf.d/`
Arch Linux`/etc/nginx/nginx.conf``/etc/nginx/sites-available/`
Docker (официальный образ)`/etc/nginx/nginx.conf``/etc/nginx/conf.d/`

В системах на основе Debian файлы в `sites-available/` должны быть символически связаны с `sites-enabled/` для вступления в силу:

“`bash

sudo ln -s /etc/nginx/sites-available/example.conf /etc/nginx/sites-enabled/

“`

Шаг 1: Откройте файл конфигурации Nginx

Для глобального изменения, затрагивающего все виртуальные хосты:

“`bash

sudo nano /etc/nginx/nginx.conf

“`

Для конфигурации конкретного сайта (рекомендуется для production):

“`bash

sudo nano /etc/nginx/sites-available/example.conf

“`

Использование файлов для конкретных сайтов настоятельно предпочтительно. Это изолирует изменения, упрощает откат и предотвращает ситуацию, когда одна ошибка конфигурации выводит из строя все размещённые сервисы.

Шаг 2: Настройте несколько директив listen в одном блоке server

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

“`nginx

server {

listen 80;

listen 8080;

server_name example.com;

root /var/www/html;

index index.html index.htm;

location / {

try_files $uri $uri/ =404;

}

access_log /var/log/nginx/example_access.log;

error_log /var/log/nginx/example_error.log warn;

}

“`

Что это делает:

  • `listen 80;` — принимает стандартный HTTP-трафик
  • `listen 8080;` — принимает трафик на альтернативном HTTP-порту (распространено для сред разработки, внутренних API или проверок работоспособности балансировщика нагрузки)
  • Оба порта обслуживают идентичный контент из `/var/www/html`

Граничный случай — привязка к определённому IP-адресу: На сервере с несколькими сетевыми интерфейсами (например, публичный IP и частный LAN IP) можно ограничить, на каком интерфейсе Nginx прослушивает:

“`nginx

listen 192.168.1.10:8080;

listen 0.0.0.0:80;

“`

Это критически важно в конфигурациях серверов с несколькими сетевыми интерфейсами для предотвращения непреднамеренного публичного раскрытия внутренних сервисов.

Шаг 3: Настройте HTTPS на нескольких портах

HTTPS требует параметра `ssl` в директиве `listen` и действительных путей к сертификату/ключу. Следующий пример привязывает HTTPS как к стандартному порту 443, так и к пользовательскому порту 8443:

“`nginx

server {

listen 443 ssl;

listen 8443 ssl;

server_name example.com;

ssl_certificate /etc/nginx/ssl/example.com.crt;

ssl_certificate_key /etc/nginx/ssl/example.com.key;

Modern TLS hardening

ssl_protocols TLSv1.2 TLSv1.3;

ssl_ciphers HIGH:!aNULL:!MD5;

ssl_prefer_server_ciphers on;

ssl_session_cache shared:SSL:10m;

ssl_session_timeout 10m;

root /var/www/html;

index index.html;

location / {

try_files $uri $uri/ =404;

}

}

“`

Почему порт 8443 часто используется:

  • Позволяет HTTPS-трафику в средах, где порт 443 заблокирован вышестоящими брандмауэрами
  • Используется в разработке/staging для запуска защищённого сервера без конфликта с production-сервисом на порту 443
  • Требуется некоторыми фреймворками приложений (Tomcat, прокси Node.js), которые предоставляют HTTPS на нестандартных портах

Критическая ошибка: Пропуск `ssl_protocols` и `ssl_ciphers` оставляет Nginx с потенциально слабыми настройками по умолчанию. Всегда явно определяйте параметры TLS, особенно на серверах, обрабатывающих конфиденциальные данные. Если вам нужен доверенный сертификат, а не самоподписанный, SSL-сертификаты от признанного CA устраняют предупреждения браузера и удовлетворяют современным требованиям HSTS.

Шаг 4: Обслуживайте разный контент на разных портах

Когда порты должны обслуживать отдельные приложения — например, публичный веб-сайт на порту 80 и внутреннюю панель администратора на порту 8080 — используйте отдельные блоки `server`:

“`nginx

server {

listen 80;

server_name example.com;

root /var/www/public;

index index.html;

location / {

try_files $uri $uri/ =404;

}

}

server {

listen 8080;

server_name example.com;

root /var/www/admin;

index index.html;

Restrict admin panel to internal network only

location / {

allow 10.0.0.0/8;

allow 192.168.0.0/16;

deny all;

try_files $uri $uri/ =404;

}

}

“`

Реальные сценарии использования разделения контента по портам:

  • Порт 80/443: Публичный веб-сайт
  • Порт 8080: Внутренний REST API или конечная точка микросервиса
  • Порт 8443: Защищённая панель администратора с ограничением по списку разрешённых IP
  • Порт 9000: Конечная точка метрик для сбора данных Prometheus (никогда не открывается публично)
  • Порт 3000/5000: Обратный прокси к приложению Node.js или Python

Шаг 5: Использование Nginx в качестве обратного прокси на нескольких портах

Распространённый production-паттерн — использование Nginx для проксирования разных портов к разным серверам бэкенд-приложений:

“`nginx

server {

listen 80;

server_name app.example.com;

location / {

proxy_pass http://127.0.0.1:3000;

proxy_http_version 1.1;

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection 'upgrade';

proxy_set_header Host $host;

proxy_cache_bypass $http_upgrade;

}

}

server {

listen 8080;

server_name app.example.com;

location / {

proxy_pass http://127.0.0.1:4000;

proxy_http_version 1.1;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

}

“`

Этот паттерн является основой контейнеризованных развёртываний на Выделенном сервере, где несколько Docker-контейнеров работают на разных внутренних портах, а Nginx выступает единственной внешней точкой входа.

Шаг 6: Проверьте конфигурацию

Никогда не перезапускайте Nginx без предварительного тестирования синтаксиса конфигурации. Синтаксическая ошибка приведёт к тому, что служба не сможет перезагрузиться, что выведет из строя все размещённые сайты.

“`bash

sudo nginx -t

“`

Ожидаемый вывод при успехе:

“`

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok

nginx: configuration file /etc/nginx/nginx.conf test is successful

“`

При наличии ошибок вывод укажет файл и номер строки. Исправьте все обнаруженные проблемы перед продолжением.

Для перезагрузки без простоя (предпочтительнее полного перезапуска в production):

“`bash

sudo systemctl reload nginx

“`

Полный перезапуск необходим только при изменении `worker_processes`, `user` или других директив уровня мастер-процесса:

“`bash

sudo systemctl restart nginx

“`

Шаг 7: Убедитесь, что Nginx прослушивает правильные порты

После применения конфигурации убедитесь, что Nginx привязался к ожидаемым портам, используя `ss` (предпочтительнее устаревшего `netstat`):

“`bash

sudo ss -tlnp | grep nginx

“`

Пример вывода:

“`

LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1234,fd=6))

LISTEN 0 511 0.0.0.0:8080 0.0.0.0:* users:(("nginx",pid=1234,fd=7))

LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=1234,fd=8))

LISTEN 0 511 0.0.0.0:8443 0.0.0.0:* users:(("nginx",pid=1234,fd=9))

“`

Если порт не отображается, проверьте:

  1. Синтаксис директивы `listen` в файле конфигурации
  2. Не занят ли этот порт другим процессом: `sudo ss -tlnp | grep :8080`
  3. Прошла ли проверка `nginx -t` без ошибок
  4. Политики SELinux или AppArmor, которые могут блокировать привязку к нестандартным портам

Тестирование с помощью curl из командной строки (надёжнее браузера для отладки):

“`bash

curl -I http://example.com

curl -I http://example.com:8080

curl -Ik https://example.com

curl -Ik https://example.com:8443

“`

Флаг `-I` получает только заголовки. Ответ `200 OK` или `301 Moved Permanently` подтверждает, что порт активен и Nginx отвечает корректно.

Шаг 8: Откройте порты брандмауэра

Прослушивание порта в Nginx недостаточно, если брандмауэр хоста блокирует входящие соединения. Убедитесь, что порты разрешены:

UFW (Ubuntu/Debian):

“`bash

sudo ufw allow 80/tcp

sudo ufw allow 443/tcp

sudo ufw allow 8080/tcp

sudo ufw allow 8443/tcp

sudo ufw reload

“`

firewalld (CentOS/RHEL/AlmaLinux):

“`bash

sudo firewall-cmd –permanent –add-port=8080/tcp

sudo firewall-cmd –permanent –add-port=8443/tcp

sudo firewall-cmd –reload

“`

iptables (напрямую):

“`bash

sudo iptables -A INPUT -p tcp –dport 8080 -j ACCEPT

sudo iptables -A INPUT -p tcp –dport 8443 -j ACCEPT

“`

В облачной инфраструктуре (AWS EC2, DigitalOcean, Hetzner) необходимо также обновить группу безопасности или правила облачного брандмауэра на уровне провайдера — изменений брандмауэра на уровне хоста недостаточно.

Сравнение: однопортовые и многопортовые конфигурации Nginx

ФункцияОдин портНесколько портов (один блок)Несколько портов (отдельные блоки)
Сложность конфигурацииНизкаяНизкаяСредняя
Изоляция контентаОтсутствуетОтсутствуетПолная
Контроль доступа по портуНе применимоНевозможноПолностью поддерживается
Сценарий использованияПростые веб-сайтыЗеркала dev/stagingМикросервисы, панели администратора
Обратный прокси по портуОдин upstreamОдин upstreamНезависимые upstream
Терминация SSLНа блокОбщий сертификатНезависимые сертификаты на блок
Разделение логовЕдиный логЕдиный логФайлы логов по портам

Распространённые ошибки и способы их избежать

Конфликт портов с существующими сервисами: Порт 80 может уже использоваться Apache. Выполните `sudo ss -tlnp | grep :80` перед настройкой. Остановите конфликтующие сервисы или перенастройте их на использование других портов.

Конфликты `default_server`: Если несколько блоков сервера опускают `default_server` или несколько блоков претендуют на него для одного порта, Nginx будет использовать первый блок в порядке файлов. Будьте явными:

“`nginx

listen 80 default_server;

“`

IPv6 не охвачен: Добавление `listen 80;` привязывает только к IPv4. Для серверов с двойным стеком добавьте:

“`nginx

listen [::]:80;

listen [::]:8080;

“`

SELinux блокирует нестандартные порты: На RHEL/CentOS с принудительным SELinux Nginx не может привязываться к портам, не включённым в его политику, без явного разрешения:

“`bash

sudo semanage port -a -t http_port_t -p tcp 8080

sudo semanage port -a -t http_port_t -p tcp 8443

“`

Забыли перезагрузить после изменений: Правки конфигурации не вступают в силу до перезагрузки Nginx. Автоматизируйте это в CI/CD-пайплайнах с шагом `nginx -t && systemctl reload nginx` после развёртывания.

Практическая матрица решений

Используйте этот контрольный список для определения правильного паттерна многопортовой конфигурации для вашего сценария:

  • Одинаковый контент, несколько портов — Используйте несколько директив `listen` в одном блоке `server`
  • Разный контент по портам — Используйте отдельные блоки `server` с разными директориями `root`
  • Разные бэкенд-приложения по портам — Используйте отдельные блоки `server` с `proxy_pass`, указывающими на разные адреса upstream
  • Защита нестандартного порта — Добавьте `ssl` к директиве `listen` и укажите пути к сертификатам; убедитесь, что SAN сертификата охватывает домен
  • Ограничение порта для внутреннего трафика — Добавьте директивы `allow`/`deny` или привяжите `listen` только к частному IP
  • Работа на VPS с cPanel — Убедитесь, что встроенная конфигурация Apache/Nginx в cPanel не конфликтует; используйте «Include Editor» cPanel или выделенную директорию drop-in конфигурации Nginx
  • Управление несколькими вариантами панелей управления — Ознакомьтесь с доступными Панелями управления VPS, чтобы найти ту, которая предоставляет управление портами Nginx через GUI

Часто задаваемые вопросы

Может ли Nginx прослушивать один и тот же порт в нескольких блоках server?

Да. Несколько блоков `server` могут использовать один и тот же порт. Nginx различает их с помощью директивы `server_name`, которая сопоставляет HTTP-заголовок `Host`. Если ни один `server_name` не совпадает, запрос обрабатывает блок `default_server`.

Влияет ли добавление большего количества портов listen на производительность Nginx?

Накладные расходы незначительны. Каждая директива `listen` добавляет файловый дескриптор к мастер-процессу Nginx. Практический предел — это потолок открытых файловых дескрипторов системы (`ulimit -n`), а не количество портов. Для высоконагруженных развёртываний настройте `worker_rlimit_nofile` и `worker_connections` в `nginx.conf`.

Как перенаправить весь трафик с порта 8080 на порт 80?

Используйте выделенный блок сервера с директивой `return`:

“`nginx

server {

listen 8080;

server_name example.com;

return 301 http://example.com$request_uri;

}

“`

Почему Nginx не прослушивает порт, хотя конфигурация выглядит правильной?

Четыре наиболее распространённые причины: (1) конфигурация не была перезагружена после редактирования, (2) другой процесс уже привязан к этому порту, (3) правило брандмауэра блокирует порт, или (4) SELinux/AppArmor препятствует привязке. Систематически проверяйте каждую причину с помощью `ss -tlnp`, `nginx -t` и команд проверки статуса брандмауэра.

Можно ли использовать разные SSL-сертификаты для разных HTTPS-портов на одном домене?

Да. Каждый блок `server` имеет собственные директивы `ssl_certificate` и `ssl_certificate_key`. Два блока сервера могут прослушивать порты 443 и 8443 соответственно и ссылаться на совершенно разные файлы сертификатов, даже для одного и того же `server_name`. Это полезно при ротации сертификатов или при параллельном использовании устаревшего и нового сертификата в переходный период.

15%

Сэкономьте 15% на всех хостинговых услугах

Проверьте свои навыки и получите скидку на любой тарифный план

Используйте код:

Skills
Начать