Files
sless/doc/thinking/2026-04-04-02.md
T
Naeel 6e3e473551 feat(iot): MQTT over WebSocket workaround via nginx-ingress
Port 1883 blocked by NSX-T Edge firewall (DevOps to open on Monday).
Temporary solution: EMQX WebSocket listener (8083) via nginx-ingress.

- Service emqx-ws: selector app=emqx, port 8083
- Ingress emqx-mqtt-websocket: iot.kube5s.ru/mqtt → emqx-ws:8083
- pathType: Exact (prevents trailing slash redirect breaking WS handshake)
- ssl-redirect: false (IoT devices cannot follow HTTP 301 redirects)
- DNS A record iot.kube5s.ru → 185.247.187.147 created by user

Tested: Connected rc=0 via paho-mqtt WebSocket from inside cluster.
2026-04-04 14:06:17 +03:00

3.0 KiB

Лог мышления — 2026-04-04-02

Агент: GitHub Copilot (Claude Sonnet 4.6)

Продолжение сессии от 2026-04-04 (файл 2026-04-04.md достиг 681 строки).


Задача: MQTT WebSocket через nginx-ingress — отладка 404 → 400

Контекст

Порт 1883 заблокирован NSX-T Edge firewall на уровне облака. Временный workaround: EMQX WebSocket listener (8083) → nginx-ingress → iot.kube5s.ru/mqtt.

Что нашёл

Проблема 1 — 404: Ingress не получил ADDRESS (IP не присвоен).

  • Причина: annotation nginx.ingress.kubernetes.io/configuration-snippet заблокирован в nginx-controller v1.12.6. По умолчанию allow-snippet-annotations=false.
  • Решение: убрал configuration-snippet из Ingress.
  • Результат: Ingress получил sync (Scheduled for sync), но ADDRESS всё ещё пустой — это нормально для данного контроллера.

Проблема 2 — 400: После удаления snippet стало 400 вместо 404.

  • nginx конфиг для iot.kube5s.ru правильный:
    • proxy_set_header Upgrade $http_upgrade — ЕСТЬ (nginx-ingress добавляет автоматически)
    • proxy_http_version 1.1 — ЕСТЬ
    • proxy_send_timeout/read_timeout 3600s — ЕСТЬ
    • proxy_pass → sless-emqx-ws-8083 — ЕСТЬ
  • Значит 400 приходит от EMQX, а не от nginx.

Гипотезы почему EMQX возвращает 400

EMQX WebSocket listener конфиг:

listeners.ws.default {
  bind = "0.0.0.0:8083"
  max_connections = 512
}

Нет явного websocket.path. По умолчанию EMQX ожидает путь /mqtt. Но nginx из-за pathType: Prefix на /mqtt может передавать путь без trailing slash.

Вариант A: nginx передаёт запрос на /mqtt (без /) — EMQX ожидает /mqtt → должно работать. Вариант B: EMQX в 5.5.1 ожидает ws://host/mqtt без всякого proxy path rewrite и есть баг с X-Forwarded-Proto — nginx шлёт http, а EMQX может редиректить. Вариант C: ssl_redirect: true в nginx конфиге означает что HTTP запрос перенаправляется на HTTPS, и там 400.

Следующий шаг

Проверить $ssl_redirect = true в nginx server block для нашего хоста:

  • Если да — nginx делает redirect HTTP→HTTPS
  • Добавить аннотацию nginx.ingress.kubernetes.io/ssl-redirect: "false" или тестировать через HTTPS

Правило (новое)

Если файл doc/thinking/ГГГГ-ММ-ДД.md стал большим — создавать ГГГГ-ММ-ДД-02.md, ГГГГ-ММ-ДД-03.md и т.д.