Files
admin/.wiki/concepts/snolla-local-admin-https-binding.md
vitya 5a93ac780c wiki(snolla): ingest local admin HTTPS binding — self-signed wildcard *.snolla.com on IIS :443
Локальный .NET-админ snolla на HTTPS: pilorama98.snolla.com/admin 404 (не в hosts → VDS)
→ ERR_CONNECTION_CLOSED (HSTS upgrade, нет 443). Fix: IIS-native self-signed wildcard
*.snolla.com на :443 + Trusted Root (без traefik — acme.json пуст, лишний слой). Рабочий
entry-point /admin/account/login (голый /admin → canonical на public — предсуществующее
поведение CMS). +index.md (2 строки, design-док ранее не индексирован) + log.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-29 09:14:29 +03:00

58 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Локальный .NET-админ snolla — HTTPS на IIS :443 (self-signed wildcard)
type: concept
tags: [snolla, morethencms, iis, admin, https, self-signed, certificate, local, pilorama98]
related: [[snolla-local-admin-and-on-snolla-migration-design]], [[traefik-on-windows-docker-desktop]], [[docker-host-loopback-detect]], [[stostayer-admin-minio-config]]
updated: 2026-07-29
---
# Локальный .NET-админ snolla — HTTPS на IIS :443 (self-signed wildcard)
Реализация 2026-07-29 поверх design-дока [[snolla-local-admin-and-on-snolla-migration-design]] (Task A). Design предполагал **http-only** локальную админку (нет traefik → без URL Rewrite → ходим по http). На практике браузер апгрейдил `http``https` (HSTS, закешированный с прошлых заходов на VDS, или Chrome/Edge «Always use secure connections») → локальный IIS без 443 → `ERR_CONNECTION_CLOSED`. Постановка wildcard self-signed прямо на IIS-сайт `snolla` :443 решает это без traefik.
## Решение: IIS-native HTTPS, НЕ traefik
Рассматривали оживление локального traefik ([[traefik-on-windows-docker-desktop]]). Отклонено:
- Локальный `acme.json` пуст — LE-сертификата на `snolla.com` нет → traefik ради self-signed не нужен (IIS умеет сам).
- Traefik как TLS-терминатор перед локальным IIS = лишний слой со всеми готчами: NAT-loopback ([[docker-host-loopback-detect]]), сломанный docker.sock provider, file-provider не watch'ит, `SERVER_PORT` leak → нужен URL Rewrite, acme.json perms 0777.
- Бэкенд теперь на том же хосте (локальный IIS), не в VBox-VM — reverse-proxy не несёт смысла.
IIS сам терминирует TLS → `SERVER_PORT=443` чисто, X-Forwarded не нужен, port-leak'ов нет.
## Что сделано
### 1. hosts — добавлен pilorama98.snolla.com
Symptom: `https://pilorama98.snolla.com/admin` → 404. Корень: `pilorama98.snolla.com` **не был в hosts-override** → реальный DNS → VDS `89.253.255.94` → traefik без роута → 404 (404 прилетал с VDS, не с локального). Системный прокси `127.0.0.1:10808` (xray) маскировал «server 127.0.0.1» в curl, но реальный backend был VDS.
`pilorama98` — реальный сайт в `dbo.Sites` (Alias=`pilorama98`, PrimaryDomain=`pilorama98.ru`, Live=True, Production=False, SiteId `37e67fc4-…`), просто не входил в тираж-5 из design-дока. Catch-all обслужит любой сайт из DB при добавлении в hosts.
Строка hosts теперь:
```
127.0.0.1 tandemmebel.snolla.com labtools.snolla.com labtoolspro.snolla.com emspb.snolla.com kupimknigi.snolla.com internal.snolla.com pilorama98.snolla.com
```
(правка hosts требует elevation — через `Start-Process -Verb RunAs`; `Set-Content` из не-elevated шелла = `UnauthorizedAccess`; по памяти `Get-Content -Raw` мог опустошить файл → читаем по строкам).
### 2. Self-signed wildcard cert на IIS :443
Скрипт (elevated, UAC):
- `New-SelfSignedCertificate -Subject '*.snolla.com' -DnsName '*.snolla.com','snolla.com' -CertStoreLocation Cert:\LocalMachine\My -NotAfter +10y -TextExtension @('2.5.29.37={text}1.3.6.1.5.5.7.3.1')` — гоча: `-DnsName` конфликтует с ручным SAN TextExtension `2.5.29.17` (параметр противоречит SAN) → SAN генерится через `-DnsName`, оставляем только EKU serverAuth.
- Копия в `Cert:\LocalMachine\Root` (Trusted Root) через `X509Store('Root','LocalMachine')` → браузер доверяет, HSTS удовлетворён.
- `New-WebBinding -Name snolla -Protocol https -Port 443 -IPAddress '*'` + `$bind.AddSslCertificate($thumb,'My')` + Stop/Start-Website (без restart binding не активируется).
- Cert thumbprint: `6E2212B4C13BD28E2FF680322F11741193E8C619`, SAN `DNS:*.snolla.com, DNS:snolla.com`, 10 лет.
Wildcard покрывает **все** alias'ы сразу — pilorama98, kupimknigi, internal, tandemmebel, labtools, labtoolspro, emspb и любой будущий.
### 3. Доступ
- `https://<alias>.snolla.com/admin/account/login` → 200, форма входа SNOLLA (title `SNOLLA`, password-поле, `<form action="/admin/login">`). Покрытие верифицировано: pilorama98, kupimknigi, internal, tandemmebel → 200.
- **Голый `/admin` → 302 `/login` → 301 `https://www.<PrimaryDomain>/`** (canonical на public-домен). Это **предсуществующее поведение CMS** (подтверждено оператором: «так и было» на RUVDS), не поломка миграции. Рабочий entry-point = `/admin/account/login` напрямую (закладка).
- `on.snolla.com` → 404: в hosts стоит `internal.snolla.com` (реальный alias сайта `on` в DB = `internal`, Title="Internal Site"), не `on`. Design-док писал `on` — фактический alias `internal`.
## Trade-off
Self-signed, не LE. Допустимо: админка локальная, FW inbound 80/443 закрыт, публично не торчит. Если позже нужен real-LE — traefik DNS-01 через REGRU (креды `OpeItcLoc03` в compose-env, см. [[traefik-on-windows-docker-desktop]] § DNS-01), но это отдельная задача и весь traefik-стек.
## Повторяемость
Cert в Trusted Root переживает перезагрузку. При регенерации (например, истёк/потерян) — тот же скрипт: почистить старые `*.snolla.com` в My/Root, создать заново, бинд. `SslFlags=0` (без SNI) — один catch-all сайт, один wildcard cert на все Host-header'ы.
## Связано
- [[snolla-local-admin-and-on-snolla-migration-design]] — исходный design (Task A http-only, Task B on.snolla.com→VDS).
- [[stostayer-admin-minio-config]] — родственный локальный .NET-админ (:8090), тот же движок MoreThenCms.
- [[traefik-on-windows-docker-desktop]] — почему traefik отклонён.