docs(.wiki,.tasks): close cms-port-leak-fix — URL Rewrite serverVariables на host IIS

Port :8089/:4443 утечка в admin URLs закрыта. URL Rewrite 2.1 + apphost
allowedServerVariables (HTTPS/SERVER_PORT/SERVER_PORT_SECURE) + Web.config rule
на X-Forwarded-Proto=https → set SERVER_PORT=443/SERVER_PORT_SECURE=1/HTTPS=on
ДО того как ASP.NET читает их в Url.SiteRoot(). Лечит все 11 cms (общий site
snolla). Path B (traefik http entrypoint :80→:8090) abandoned — Docker Desktop
WSL2 NAT quirk на host.docker.internal:80 возвращает 17-byte 301 plain text
независимо от traefik internals. Quirk не reproducible на Linux Docker (synology).

Side regression: pre-existing customErrors mode="off" lowercase в Web.config
пробудился после ASP.NET full-reload (мой rewrite-block edit) — fixed (Off).

Outside scope, open: emspb.snolla.com /admin/assets/<guid>/getList → 500 NullRef
в AssetsJsonViewModelBuilder.cs:22 (model null от GetFolderByPath). User
подтвердил «только этот site». Зафиксировано в snapshot open issue #8.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-19 18:43:03 +03:00
parent 3d5d61d5a5
commit 5d7a14c7d4
3 changed files with 181 additions and 20 deletions

View File

@@ -122,29 +122,15 @@ servers:
Docker Desktop резолвит `host.docker.internal` в IP хоста (обычно 172.x.x.1 из docker bridge perspective). Дальше Windows-host обрабатывает 18080 → VBox NAT → VM:80 → IIS → CMS.
## Pitfall 5: X-Forwarded headers НЕ настроены
## Pitfall 5: X-Forwarded не используется ASP.NET — port utечка в admin URLs (RESOLVED 2026-05-19)
Traefik отдаёт backend (IIS) запрос с заголовком `Host: snolla.com`, но **не** добавляет `X-Forwarded-Proto: https` / `X-Forwarded-Host`. Backend (IIS) считает, что получил HTTP-запрос, делает 301 redirect на канонический URL `http://www.<domain>:4443/`.
**Симптом:** CMS-admin генерирует URLs с internal IIS portом (`:8089` после attempt 2; ранее `:4443` от traefik) → browser HSTS auto-upgrade ломает TLS на нестандартном портe → admin SPA broken.
Симптом для клиента: видит URL с портом 4443 в адресной строке после редиректа.
**Root cause:** Traefik 2.x **шлёт** `X-Forwarded-Proto: https` / `X-Forwarded-Host` / `X-Forwarded-Port` по-default (когда entrypoint https). НО CMS-код (`MoreThenCms.Admin\Mis\Web\Mvc\UrlHelpers\UrlHelpers.cs`) читает **socket-level** `SERVER_PORT` / `SERVER_PORT_SECURE`, **игнорируя** X-Forwarded-* headers. На VM работало случайно потому что IIS binding `:80``SERVER_PORT=80` стрипалось whitelist'ом `{80,443}` в коде.
**Fix (TODO, не делали в emergency):**
**Fix:** URL Rewrite 2.1 + `<serverVariables>` rule на host IIS — переписывает `HTTPS`/`SERVER_PORT`/`SERVER_PORT_SECURE` на основе `X-Forwarded-Proto`. Детально в [[cms-server-port-leak-fix]].
```yaml
# data/custom/forwarded-headers-middleware.yml
http:
middlewares:
secure-headers:
headers:
customRequestHeaders:
X-Forwarded-Proto: https
customResponseHeaders:
X-Forwarded-Proto: ""
```
И применить middleware к каждому router (или к глобальному entrypoint-level через `--entrypoints.https.forwardedheaders.insecure=true` в command).
Plus на стороне IIS: установить ARR module + URL Rewrite, доверять `X-Forwarded-*` от 127.0.0.1 (host).
Path B (поменять traefik http entrypoint :80 inside container чтобы IIS-binding :80 не получал loop от Docker NAT) — **не работает** на Windows Docker Desktop из-за WSL2 NAT quirk, см. там же.
## DNS-01 challenge через REGRU