Консолидирующий отчёт: настройка маршрутизации (lms.cdto.life) и правило для аналогичных задач

Дата: 2026-02-12
Контекст: добавление нового HTTPS-сайта (Moodle 4.5, lms.cdto.life) за существующей точкой входа BBB (HAProxy + Nginx).
Цель документа: глубокий анализ процесса, фиксация решений и итоговое правило для последующих аналогичных задач.


1. Архитектура маршрутизации (текущая производственная версия)

Трафик 80/443 направляется в BBB-CONT22-1 (10.218.14.37). Цепочка:

Клиент (браузер)
    → DNS: lms.cdto.life → 89.179.242.240
    → Роутер: проброс 80/443 → хост 192.168.1.112
    → Хост: iptables DNAT 80/443 → 10.218.14.37 (BBB-CONT22-1)
    → BBB: HAProxy *:443 (SSL-терминация, маршрутизация по Host)
    → BBB: Nginx 127.0.0.1:8443 (HTTP, виртуальные хосты по server_name)
    → Backend: контейнер приложения (например moodle 10.218.14.104:80)

Важно: между клиентом и Nginx:8443 стоит HAProxy с SSL. На порт 8443 приходит уже HTTP-запрос (без TLS). Поэтому в Nginx на 8443 переменная $scheme всегда http, а не https.


2. Слои конфигурации для нового домена (на примере lms.cdto.life)

Слой Файл / место Что сделать
1 DNS Панель домена cdto.life A-запись: lms → 89.179.242.240 (TTL 300). Без этого — NXDOMAIN.
2 iptables Уже настроены Проброс 80/443 на BBB; для нового домена менять не требуется.
3 HAProxy (BBB) config/snapshots/haproxy-bbb-*.cfg → деплой в BBB Добавить acl host_<name> hdr(host) -i <домен> и включить в use_backend nginx-8443 if ... or host_<name>.
4 Nginx (BBB) config/nginx/bbb-https-routing.conf Новый server { listen 127.0.0.1:8443; server_name <домен>; location / { proxy_pass http://<IP>:<порт>; proxy_set_header X-Forwarded-Proto https; ... } }. Критично: для бэкендов за HAProxy:443 передавать явно X-Forwarded-Proto https, а не $scheme (на 8443 $scheme = http).
5 Контейнер приложения Nginx/Apache в контейнере Виртуальный хост с server_name; для PHP-приложений (Moodle, WordPress и т.п.) — передать в backend признак HTTPS по заголовку от прокси (см. ниже).

3. Проблемы при настройке lms.cdto.life и решения

3.1. DNS (NXDOMAIN)

  • Симптом: «Не удаётся найти этот сайт», браузер не резолвит lms.cdto.life.
  • Причина: не было A-записи для lms.cdto.life.
  • Решение: A-запись lms → 89.179.242.240 в панели DNS домена cdto.life.

3.2. Циклическое перенаправление (ERR_TOO_MANY_REDIRECTS)

  • Симптом: «Циклическое перенаправление» / «Сайт выполнил переадресацию слишком много раз».
  • Причина:
  • Клиент открывает https://lms.cdto.life.
  • Запрос до Moodle доходит по HTTP (прокси).
  • Moodle видит $_SERVER['HTTPS'] не установленным и отдаёт редирект на https://lms.cdto.life.
  • Браузер снова запрашивает https://… → цикл.

  • Решения (два места):

  • Точка входа (BBB). В Nginx на 8443 для бэкенда lms.cdto.life задать явно proxy_set_header X-Forwarded-Proto https; (не $scheme), т.к. на 8443 соединение от HAProxy — по HTTP.

  • Контейнер приложения (moodle). В Nginx перед PHP передать признак HTTPS от прокси:
    • map $http_x_forwarded_proto $fe_https { default off; https on; }
    • В location ~ \.php: fastcgi_param HTTPS $fe_https; и при необходимости fastcgi_param HTTP_X_FORWARDED_PROTO $http_x_forwarded_proto;

3.3. «Not found» (Exception - Not found) на главной странице

  • Симптом: вместо главной Moodle — страница с ошибкой «Not found».
  • Причина: В Nginx использовалось try_files $uri /r.php. При внутреннем редиректе на /r.php в PHP попадал REQUEST_URI=/r.php; роутер Moodle извлекал пустой путь и не находил маршрут для корня.
  • Решение: Передавать путь в r.php через rewrite:
  • try_files $uri $uri/ @moodle;
  • location @moodle { rewrite ^(.*)$ /r.php$1 last; }
  • В итоге для запроса / в PHP приходит REQUEST_URI=/r.php/, путь для роутера — /.

4. Итоговое правило для последующих аналогичных задач

Когда добавляется новый HTTPS-сайт за той же точкой входа (BBB: HAProxy → Nginx:8443 → бэкенд-контейнер):

4.1. Чек-лист перед запуском

  • [ ] DNS: A-запись домена на внешний IP сервера (89.179.242.240).
  • [ ] Контейнер бэкенда: создан, статический IP в LXD-сети, приложение слушает нужный порт (например 80).
  • [ ] Save-state: при изменении маршрутизации/конфигов выполнен scripts/save-state-before-migration.sh [метка] и закоммит (см. BACKUP-BEFORE-CHANGES.md).

4.2. Точка входа (BBB-CONT22-1)

  1. HAProxy: добавить acl по Host и включить домен в условие use_backend nginx-8443. Файл-образец: config/snapshots/haproxy-bbb-2026-01-23.cfg. После правок — деплой в BBB, перезагрузка HAProxy.
  2. Nginx (bbb-https-routing.conf):
  3. Новый server { listen 127.0.0.1:8443; server_name <домен>; ... }.
  4. В location /: proxy_pass http://<IP_контейнера>:<порт>; и стандартные заголовки.
  5. Обязательно: proxy_set_header X-Forwarded-Proto https; (не $scheme), т.к. на 8443 трафик от HAProxy приходит по HTTP.
  6. Деплой: lxc file push config/nginx/bbb-https-routing.conf BBB-CONT22-1/etc/nginx/sites-available/bbb-https-routing.conf, затем nginx -t && systemctl reload nginx в контейнере.

4.3. Контейнер приложения

  1. Виртуальный хост: server_name = домен, root/index при необходимости.
  2. Если приложение на PHP и ожидает HTTPS (редиректы, ссылки):
  3. В Nginx: map $http_x_forwarded_proto $fe_https { default off; https on; }
  4. В блоке FastCGI для PHP: fastcgi_param HTTPS $fe_https; и при необходимости fastcgi_param HTTP_X_FORWARDED_PROTO $http_x_forwarded_proto;
  5. Если приложение использует front controller с путём (как Moodle r.php): не делать только try_files $uri /script.php — иначе в PHP попадёт REQUEST_URI=/script.php и путь будет пустой. Использовать передачу пути (например rewrite ^(.*)$ /script.php$1 last в именованной location).

4.4. Проверка

  • Открыть https://<домен> в браузере (лучше режим инкогнито или очистить cookies для домена).
  • Убедиться: нет циклических редиректов, главная и внутренние страницы открываются, после входа сессия сохраняется (при необходимости).

4.5. Альтернативная точка входа (nginx-reverse-proxy)

Если в будущем трафик будет направляться в nginx-reverse-proxy (10.218.14.200), а не в BBB: там клиент подключается к Nginx по HTTPS, поэтому $scheme уже https и можно использовать proxy_set_header X-Forwarded-Proto $scheme;. Правило «явно передавать https» нужно только когда перед Nginx стоит ещё один прокси с SSL-терминацией (как HAProxy перед Nginx:8443).


5. Ссылки на конфиги и документацию

Назначение Путь
Маршрутизация Nginx в BBB config/nginx/bbb-https-routing.conf
Пример HAProxy (BBB) config/snapshots/haproxy-bbb-2026-01-23.cfg
Nginx в контейнере Moodle config/nginx/moodle-lms-cdto-life.conf
DNS и типовые проблемы lms docs/setup/moodle-lms-dns.md
Первый вход в Moodle docs/setup/moodle-first-login.md
Сохранение состояния перед изменениями docs/operations/BACKUP-BEFORE-CHANGES.md
Рабочая архитектура, точка входа docs/host-server-passport.md, docs/setup/services-config.md

Итог: настройка маршрутизации для нового HTTPS-сайта за BBB требует согласованной настройки DNS, HAProxy, Nginx в BBB и Nginx/веб-сервера в контейнере. Ключевой момент — передача схемы HTTPS в бэкенд на всех этапах (явно X-Forwarded-Proto https в точке входа при многоступенчатом прокси и передача в PHP/приложение в контейнере). Для приложений с front controller (Moodle и аналоги) — корректная передача пути запроса в скрипт (через rewrite), а не только fallback на один URI.

AI Denkart, технический директор
2026-02-12