Настройка Nginx для 3x UI: рабочая конфигурация 2026 с WebSocket и HTTPS | AdminWiki

Настройка Nginx для 3x UI: рабочая конфигурация 2026 с WebSocket и HTTPS

01 августа 2026 15 мин. чтения
Содержание статьи

Вы развернули панель 3x UI на внутреннем порту и хотите предоставить к ней безопасный доступ извне. Прямой проброс порта панели наружу - плохая практика: вы теряете централизованный контроль над трафиком, не можете гибко управлять шифрованием и оставляете поверхность для атак открытой. Nginx в роли обратного прокси решает эти задачи: он принимает клиентские соединения по HTTPS и прозрачно передаёт трафик на бэкенд 3x UI. В этой инструкции приведён готовый конфиг Nginx с поддержкой WebSocket, корректной передачей URI и SSL от Let's Encrypt, а также проверками, важными для запуска в production.

Что получится. Панель будет открываться по адресу https://panel.example.com, а 3x UI останется доступной Nginx локально по адресу 127.0.0.1:PANEL_PORT. Для доступа к панели извне потребуются порты 80 и 443; фактический порт панели не следует открывать в файрволе. В примерах 54321 - это значение PANEL_PORT, которое нужно заменить на порт вашей установки.

Проверено на. Ubuntu 24.04 LTS, Nginx 1.26.x и 3x-ui 2.6.x, установленной штатным install-скриптом проекта; дата проверки - август 2026. Для другой версии 3x-ui перед применением конфигурации проверьте фактический порт, адрес прослушивания и параметры запуска панели.

Содержание

Зачем нужен обратный прокси для 3x UI

Обратный прокси - это прослойка между клиентом и сервером приложения. Когда вы настраиваете Nginx перед 3x UI, вы получаете три ключевых преимущества. Первое: SSL-терминация. Nginx обрабатывает HTTPS, разгружая панель от криптографических операций. Вы можете использовать один сертификат Let's Encrypt для десятка сервисов за прокси. Второе: унификация точки входа. Все запросы приходят на 80 и 443 порты одного IP-адреса, а Nginx маршрутизирует их по разным бэкендам на основе доменного имени. Это критично, когда на сервере крутятся несколько веб-приложений. Третье: безопасность. Если Nginx и панель работают на одном сервере, 3x UI рекомендуется привязать к 127.0.0.1:PANEL_PORT. Порт 54321 не является универсальным: это только распространённый пример. При локальной привязке панель недоступна из внешней сети, а запросы проходят через Nginx, где можно настроить rate limiting, фильтрацию по IP и fail2ban.

Типичный сценарий: у вас один VPS с публичным IP, на нём развёрнуты 3x UI, Zabbix и пара внутренних сервисов. Без прокси вам пришлось бы открывать три разных порта и настраивать SSL для каждого. С Nginx вы открываете только 443 порт для веб-доступа, а маршрутизация идёт по доменным именам - panel.example.com, zabbix.example.com. О том, как построить такую инфраструктуру с нуля, читайте в полном руководстве по настройке Nginx Reverse Proxy.

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

Перед началом настройки убедитесь, что у вас есть всё перечисленное ниже. Отсутствие любого пункта приведёт к ошибке на одном из этапов.

  • Сервер с Linux. Подойдёт Ubuntu 22.04/24.04 LTS, Debian 12 или RHEL 9. Все команды в статье приведены для Debian-семейства.
  • Установленный Nginx. Версия не ниже 1.24. Проверить: nginx -v. Если Nginx не установлен - apt update && apt install nginx -y.
  • Работающая панель 3x UI. Панель должна быть доступна локально. Определите PANEL_PORT по параметрам запуска или конфигурации вашей установки 3x-ui либо по слушающему сокету: sudo ss -ltnp | grep -E 'x-ui|3x-ui'. Если имя процесса не выводится, изучите полный вывод sudo ss -ltnp и сопоставьте порт со службой панели. Для примера с портом 54321 выполните curl -I http://127.0.0.1:54321. Коды 200, 301, 302 или 401 означают, что HTTP-бэкенд ответил; 301/302 возможны при перенаправлении, а 401 - при требовании авторизации.
  • Доменное имя. A-запись должна указывать на публичный IP вашего сервера. Если опубликована AAAA-запись, сервер и файрвол также должны принимать IPv6-трафик. Для тестов можно использовать /etc/hosts на клиентской машине, но для Let's Encrypt нужен реальный DNS.
  • Права root или sudo. Конфигурация Nginx и запуск certbot требуют привилегий.

Чек-лист готовности:

  • ☐ Nginx установлен и запущен (systemctl status nginx)
  • ☐ Известны фактические адрес и PANEL_PORT панели 3x UI
  • ☐ Панель отвечает локально по адресу http://127.0.0.1:PANEL_PORT
  • ☐ A-запись домена указывает на IP сервера, а AAAA-запись проверена или отсутствует
  • ☐ Порт 80 и 443 открыты в файрволе
  • ☐ Есть доступ по SSH с правами root или sudo

Во всех фрагментах ниже используется тестовый стенд: Ubuntu 24.04, Nginx 1.26, панель 3x UI на порту 54321, домен panel.example.com. Значение 54321 в proxy_pass заменяйте на ваш PANEL_PORT.

Базовая конфигурация обратного прокси

Начнём с минимальной рабочей конфигурации. Она перенаправляет HTTP-запросы с Nginx на локальный порт панели 3x UI. Создайте файл /etc/nginx/sites-available/3x-ui:

server {
    listen 80;
    server_name panel.example.com;

    location / {
        proxy_pass http://127.0.0.1:54321;
        proxy_set_header Host $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:

ln -s /etc/nginx/sites-available/3x-ui /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx

Разберём директивы. proxy_pass http://127.0.0.1:54321; - точка назначения трафика. Nginx принимает запрос на 80 порту и транслирует его на локальный адрес панели. В рабочей конфигурации замените 54321 на фактический PANEL_PORT. Четыре заголовка proxy_set_header критичны: Host передаёт оригинальное доменное имя, чтобы панель знала, куда клиент обращался; X-Real-IP содержит IP клиента; X-Forwarded-For - цепочку прокси-серверов; X-Forwarded-Proto сообщает бэкенду, по какому протоколу пришёл запрос (http или https). Без этих заголовков панель 3x UI будет видеть все соединения как пришедшие с 127.0.0.1, что может исказить логирование и работу некоторых функций.

Корректная передача URI и заголовков

Поведение proxy_pass зависит от наличия завершающего слеша в URI. Это частая причина ошибок 404 после настройки прокси. Рассмотрим два варианта:

  • proxy_pass http://127.0.0.1:54321; - Nginx передаёт URI без изменений. Запрос к /panel/inbounds уйдёт как /panel/inbounds.
  • proxy_pass http://127.0.0.1:54321/; - Nginx заменяет часть location на слеш. Если location /app/, а запрос пришёл на /app/inbounds, бэкенд получит /inbounds.

Если панель 3x UI должна работать в корне домена, используйте вариант без завершающего слеша. Панель ожидает полные пути, и обрезание URI приведёт к битым ссылкам на статические ресурсы и API-эндпоинты. Дополнительно убедитесь, что заголовок X-Forwarded-Proto передаётся - панель может использовать его для формирования абсолютных URL в ответах API.

Базовый URL и path prefix

Конфигурация из статьи предполагает публикацию панели в корне домена: https://panel.example.com/. Если 3x UI настроена на path prefix, например /app/, настройте этот базовый URL и маршруты в самой панели, а затем согласуйте с ними location и proxy_pass. Один только rewrite в Nginx не гарантирует корректную работу статических файлов, API и ссылок, которые приложение формирует с учётом своего базового пути.

Настройка поддержки WebSocket

Интерфейс 3x UI может использовать WebSocket-соединения для мониторинга в реальном времени: графиков трафика, статуса подключений и логов. Без специальной настройки Nginx эти соединения могут обрываться или не устанавливаться. Прокси по умолчанию работает с HTTP/1.0, а WebSocket требует HTTP/1.1 и явного апгрейда соединения.

Сначала добавьте map в секцию http файла /etc/nginx/nginx.conf. На Debian-подобных системах его также можно поместить в отдельный файл в /etc/nginx/conf.d/, если этот каталог подключается внутри секции http. Не размещайте map внутри server или location:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

Затем добавьте в блок location / директивы для WebSocket:

location / {
    proxy_pass http://127.0.0.1:54321;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_set_header Host $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;
}

proxy_http_version 1.1 включает HTTP/1.1 для соединения с бэкендом. proxy_set_header Upgrade $http_upgrade пробрасывает заголовок апгрейда от клиента. Переменная $connection_upgrade из блока map передаёт Connection: upgrade только при запросе с заголовком Upgrade; для обычного HTTP-запроса она передаёт close. Такой вариант безопаснее, чем постоянная отправка Connection: upgrade для всех запросов.

HTTP/2 на внешнем соединении с браузером не требуется для работы WebSocket: критична настройка HTTP/1.1 между Nginx и бэкендом. Проверка работы WebSocket описана в разделе «Тестирование и устранение неполадок».

Обеспечение безопасного доступа через HTTPS

Панель 3x UI передаёт учётные данные и управляет VPN-подключениями. Передача этой информации по открытому HTTP недопустима. Let's Encrypt предоставляет бесплатные SSL-сертификаты; выпуск и обновление сертификата нужно проверить отдельно от настройки обратного прокси.

Установка и настройка Certbot

Установите certbot и плагин для Nginx. На Ubuntu 24.04 это делается одной командой:

apt update && apt install certbot python3-certbot-nginx -y

Перед выпуском сертификата проверьте, что домен резолвится в IP сервера и HTTP-01 challenge сможет дойти до этого экземпляра Nginx:

dig +short A panel.example.com
dig +short AAAA panel.example.com

Порт 80 должен быть доступен из интернета. Если перед сервером используется CDN, другой reverse proxy или балансировщик, он должен передавать запросы к /.well-known/acme-challenge/ на этот сервер. Опубликованная AAAA-запись также должна вести на доступный по IPv6 сервер; иначе проверка Let's Encrypt может завершиться ошибкой.

Если HTTP server-блок уже существует. Убедитесь, что базовая конфигурация из предыдущего раздела активна и server_name содержит ваш домен, затем запустите мастер:

certbot --nginx -d panel.example.com

Certbot найдёт блок server с соответствующим server_name и предложит включить редирект с HTTP на HTTPS. Выберите вариант с редиректом, если панель не должна быть доступна по HTTP.

Если это первичный выпуск и server-блока ещё нет. Сначала создайте и включите минимальный HTTP server-блок из раздела «Базовая конфигурация обратного прокси», проверьте его командой nginx -t и только затем запускайте certbot --nginx. Режим --standalone требует свободного порта 80, поэтому не используйте его одновременно с работающим Nginx без отдельного плана переключения.

Автоматическое обновление сертификата

Сертификаты Let's Encrypt действительны 90 дней. В распространённых пакетах certbot обычно устанавливается systemd-таймер, но его наличие и успешные запуски нужно подтвердить:

systemctl list-timers | grep certbot
systemctl status certbot.timer
journalctl -u certbot.service -n 100 --no-pager

Для тестового запуска обновления выполните:

certbot renew --dry-run

Успешный тест подтверждает, что правила обновления и проверка домена работают. Перезагрузка Nginx после фактического обновления зависит от использованного плагина certbot или настроенного deploy-hook; не следует считать её гарантированной без проверки. Если плагин не перезагружает Nginx, настройте deploy-hook с командой systemctl reload nginx в каталоге /etc/letsencrypt/renewal-hooks/deploy/ и проверьте журналы после первого обновления.

Финальная конфигурация Nginx для 3x UI

Ниже - полный конфигурационный файл, объединяющий HTTP-редирект, HTTPS с сертификатами Let's Encrypt, проксирование с заголовками и поддержку WebSocket. До его применения добавьте блок map из раздела WebSocket в секцию http. Скопируйте конфигурацию в /etc/nginx/sites-available/3x-ui, замените panel.example.com и 54321 на свои значения, затем выполните nginx -t && systemctl reload nginx.

# Редирект с HTTP на HTTPS
server {
    listen 80;
    server_name panel.example.com;
    return 301 https://$host$request_uri;
}

# Основной HTTPS-сервер
server {
    listen 443 ssl;
    # Необязательно для Nginx 1.25.1 и новее:
    # http2 on;
    server_name panel.example.com;

    # Сертификаты Let's Encrypt
    ssl_certificate /etc/letsencrypt/live/panel.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/panel.example.com/privkey.pem;

    # Безопасные параметры SSL
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;

    # Проксирование на 3x UI
    location / {
        proxy_pass http://127.0.0.1:54321;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $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;

        proxy_buffering off;
        # Нужны, только если proxy_cache включён выше по конфигурации
        proxy_cache_bypass $http_upgrade;
        proxy_no_cache $http_upgrade;

        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }
}

Директива http2 on; необязательна и не влияет на WebSocket 3x-ui. Для Nginx 1.24 не добавляйте её без проверки документации пакета: синтаксис включения HTTP/2 зависит от версии. proxy_buffering off полезна для потоковых данных и обновлений в реальном времени, но увеличивает число незабуференных соединений, поэтому не включайте её глобально без необходимости. proxy_cache_bypass и proxy_no_cache имеют смысл, если кеширование задано в родительском контексте: они исключают запросы с Upgrade из кеша.

proxy_read_timeout отсчитывается между последовательными операциями чтения от бэкенда, а не задаёт гарантированную продолжительность соединения. Значение 3600s - разумная отправная точка для долгоживущих соединений. Для действительно длительных WebSocket-сессий приложение должно отправлять ping или другие keepalive-сообщения; повышайте таймауты только после оценки нагрузки и поведения панели. proxy_send_timeout также ограничивает паузу между операциями отправки данных бэкенду.

Блок ssl_protocols и ssl_ciphers задаёт современный набор шифров для TLS 1.2. Набор шифров TLS 1.3 управляется Nginx и используемой криптобиблиотекой отдельно. Подробнее о выборе шифров и настройке TLS читайте в статье Nginx HTTPS в 2026 году: TLS 1.3, Let's Encrypt и безопасная конфигурация.

Тестирование и устранение неполадок

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

Проверка конфигурации и HTTPS. Сначала убедитесь, что Nginx принял конфигурацию, затем проверьте TLS-рукопожатие и ответ панели:

nginx -t
systemctl reload nginx
curl -vk https://panel.example.com/

Ключ -k в curl -vk нужен только для диагностики и позволяет увидеть ответ даже при проблеме с доверием к сертификату. После исправления сертификата повторите проверку без -k. В браузере по адресу https://panel.example.com должна открыться страница входа в 3x UI. Если страница не открывается, проверьте фактический адрес и порт панели, например для тестового стенда: ss -tlnp | grep 54321.

Проверка редиректа. Перейдите по http://panel.example.com. Вас должно автоматически перенаправить на HTTPS-версию. Код ответа - 301 Moved Permanently.

Проверка DNS, IPv6 и файрвола. Сверьте A- и AAAA-записи с адресами сервера командами dig +short A panel.example.com и dig +short AAAA panel.example.com. Если AAAA-запись существует, но Nginx или файрвол не обслуживают IPv6, удалите неверную запись либо настройте IPv6. Проверьте локальные правила через sudo ufw status или sudo nft list ruleset, а также security group у VPS-провайдера. Для панели должны быть доступны 80 и 443, но не PANEL_PORT из внешней сети.

Проверка работы WebSocket

Откройте инструменты разработчика в браузере (F12), перейдите на вкладку Network и выберите фильтр WS. Обновите страницу панели 3x UI. В списке должны появиться соединения со статусом 101 Switching Protocols. Это подтверждает, что апгрейд до WebSocket прошёл успешно. Если вы видите статус 200, убедитесь, что запрос действительно является WebSocket-запросом, затем проверьте proxy_http_version 1.1, proxy_set_header Upgrade, proxy_set_header Connection $connection_upgrade и блок map в секции http.

Типовые ошибки и их причины. Ниже — таблица с самыми частыми проблемами при настройке прокси для 3x UI:

Ошибка Причина Решение
502 Bad Gateway Nginx не может достучаться до бэкенда. Панель 3x UI не запущена, слушает на другом адресе или порту. Проверьте статус панели и соответствие адреса с портом в proxy_pass: sudo ss -ltnp. Значение 127.0.0.1:PANEL_PORT должно совпадать с настройкой панели.
504 Gateway Timeout Бэкенд зависает, не отвечает или соединение остаётся без данных дольше proxy_read_timeout. Проверьте журналы панели и Nginx. Для долгоживущих WebSocket-соединений настройте ping/keepalive в приложении и подберите proxy_read_timeout по фактической нагрузке.
NET::ERR_CERT_AUTHORITY_INVALID Сертификат не был выпущен для этого домена, истёк или клиент получает другой сертификат через CDN либо прокси. Запустите certbot certificates, проверьте DNS и цепочку прокси, затем перевыпустите сертификат при необходимости.
WebSocket не подключается (статус 200 вместо 101) Отсутствуют директивы WebSocket, блок map размещён не в секции http либо запрос не достигает WebSocket-эндпоинта. Добавьте map в http и все директивы WebSocket в location, затем проверьте конфигурацию командой nginx -t.

Логи Nginx - основной инструмент отладки. Начните с системного журнала и стандартного error.log:

journalctl -u nginx -n 100 --no-pager
tail -n 100 /var/log/nginx/error.log

Записи о upstream prematurely closed connection указывают на падение или преждевременное закрытие бэкенда. SSL_do_handshake() failed сигнализирует о проблемах с сертификатом или TLS. При необходимости включите подробное логирование для проблемного location; уровень debug доступен только в сборках Nginx с поддержкой отладки:

error_log /var/log/nginx/3x-ui-error.log debug;

Дополнительные рекомендации по безопасности

Базовая конфигурация закрывает основные риски. Следующие меры усилят защиту и характерны для production-окружений.

Ограничение доступа по IP. Если панель 3x UI используется только из офиса или через VPN, заблокируйте все остальные адреса. Добавьте в блок location:

allow 203.0.113.0/24;  # IP офисной сети
allow 198.51.100.5;     # IP администратора
deny all;

Nginx проверит IP до передачи запроса бэкенду. Неавторизованные адреса получат 403 Forbidden.

Скрытие версии Nginx. В главном конфигурационном файле /etc/nginx/nginx.conf добавьте в секцию http: server_tokens off;. Это уберёт версию Nginx из заголовков ответа и страниц ошибок, усложняя fingerprinting.

Интеграция с fail2ban. Настройте фильтр для отслеживания неудачных попыток входа в 3x UI через логи Nginx. При превышении порога fail2ban заблокирует IP на уровне iptables. Это дополнит встроенные механизмы защиты панели и снизит эффект от перебора паролей.

Нестандартный порт SSH. Смените порт SSH с 22 на другой, если сервер доступен из интернета. Это не относится напрямую к Nginx, но снижает количество автоматических атак на сервер в целом.

Готовые конфигурации Nginx для типовых задач - проксирования, балансировки, кеширования - собраны в материале рабочие конфигурации Nginx для стандартных задач 2026. Если вы проксируете несколько сервисов и нужна интеллектуальная маршрутизация по доменам или геолокации, изучите руководство по интеллектуальной маршрутизации в Nginx.

Частые вопросы (FAQ)

Почему не работает WebSocket после настройки прокси?

Проверьте, что в блоке location / есть proxy_http_version 1.1, proxy_set_header Upgrade $http_upgrade и proxy_set_header Connection $connection_upgrade. Также убедитесь, что блок map для $connection_upgrade расположен в секции http, а не внутри server или location. Для долгоживущих соединений начните с proxy_read_timeout 3600s и настройте ping/keepalive на стороне приложения.

Как обновить сертификат Let's Encrypt вручную?

Выполните команду certbot renew. Если хотите проверить механизм без реального обновления - используйте certbot renew --dry-run. После успешного обновления проверьте, был ли Nginx перезагружен плагином или deploy-hook, через journalctl -u nginx -n 100 --no-pager. При отсутствии перезагрузки настройте deploy-hook с командой systemctl reload nginx.

Что делать, если панель 3x UI доступна локально, но через Nginx отдаёт 502?

Проверьте, на каком адресе и порту слушает панель. Если она привязана к 127.0.0.1, а в proxy_pass указан другой адрес или порт, Nginx не сможет подключиться. Выполните sudo ss -ltnp и убедитесь, что адрес и PANEL_PORT совпадают с конфигурацией. Если панель слушает только ::1, используйте соответствующий IPv6-адрес в proxy_pass либо измените привязку панели.

Как узнать фактический порт и адрес прослушивания 3x-ui?

Сначала проверьте параметры запуска или конфигурацию вашей установки 3x-ui. Затем подтвердите результат на сервере: sudo ss -ltnp | grep -E 'x-ui|3x-ui'. Если имя процесса не отображается, используйте sudo ss -ltnp и сопоставьте слушающий сокет со службой панели. В proxy_pass должны быть указаны тот же IP-адрес и порт.

Можно ли оставить панель доступной только через localhost?

Да. Если Nginx и 3x UI работают на одном сервере, привязка панели к 127.0.0.1:PANEL_PORT предпочтительна: панель не будет доступна напрямую из внешней сети, а Nginx подключится к ней локально. Не открывайте PANEL_PORT в файрволе. Если Nginx расположен на другом хосте, localhost использовать нельзя: потребуется защищённая внутренняя сеть и ограничения доступа по IP.

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

Да, Let's Encrypt поддерживает мультидоменные сертификаты. При запуске certbot укажите все домены через -d: certbot --nginx -d panel.example.com -d zabbix.example.com. Сертификат будет выпущен для всех перечисленных доменов.

Вы настроили обратный прокси Nginx для 3x UI с поддержкой WebSocket и HTTPS. Панель доступна по защищённому соединению, а её порт не публикуется напрямую. После первого выпуска сертификата проверьте таймер certbot, deploy-hook и журналы Nginx, чтобы убедиться в корректном обновлении SSL.

Поделиться:
Сохранить гайд? В закладки браузера