Изменения документа Stream (SNI-роутинг) в SWAG
Редактировал(а) Anton Krivchenkov 27.05.2026 18:05
От версии 1.1
отредактировано Anton Krivchenkov
на 27.05.2026 18:05
на 27.05.2026 18:05
Изменить комментарий:
К данной версии нет комментариев
К версии 2.1
отредактировано Anton Krivchenkov
на 27.05.2026 18:05
на 27.05.2026 18:05
Изменить комментарий:
К данной версии нет комментариев
Сводка
-
Свойства страницы (1 изменено, 0 добавлено, 0 удалено)
Подробности
- Свойства страницы
-
- Содержимое
-
... ... @@ -1,6 +1,7 @@ 1 1 # 📘 Гайд: Stream (SNI-роутинг) в SWAG — полная документация 2 2 3 -> **Актуально для:** SWAG (linuxserver/docker-swag) + nginx 1.25+ 3 +> **Актуально для:** SWAG (linuxserver/docker-swag) + nginx 1.25+ 4 +> 4 4 > **Последнее обновление:** 2026-05-27 5 5 6 6 --- ... ... @@ -8,17 +8,17 @@ 8 8 ## 📑 Содержание 9 9 10 10 1. [Что такое stream и зачем он нужен](#1-что-такое-stream-и-зачем-он-нужен) 11 - 2. [Как это работает (схема)](#2-как-это-работает-схема)12 - 3. [Какие проблемы решает](#3-какие-проблемы-решает)13 - 4. [Файловая структура — что куда класть](#4-файловая-структура--что-куда-класть)14 - 5. [Шаг 1: nginx.conf — добавить блок stream](#5-шаг-1-nginxconf--добавить-блок-stream)15 - 6. [Шаг 2: stream.conf — SNI-роутинг](#6-шаг-2-streamconf--sni-роутинг)16 - 7. [Шаг 3: default.conf — перевести http на порт 4443](#7-шаг-3-defaultconf--перевести-http-на-порт-4443)17 - 8. [Шаг 4: site-confs — все server слушают 4443](#8-шаг-4-site-confs--все-server-слушают-4443)18 - 9. [Боевой пример конфигурации](#9-боевой-пример-конфигурации)19 -1 0. [Проверка и отладка](#10-проверка-и-отладка)20 -1 1. [Типичные ошибки и решения](#11-типичные-ошибки-и-решения)21 -1 2. [Docker Compose — порты](#12-docker-compose--порты)12 +1. [Как это работает (схема)](#2-как-это-работает-схема) 13 +1. [Какие проблемы решает](#3-какие-проблемы-решает) 14 +1. [Файловая структура — что куда класть](#4-файловая-структура--что-куда-класть) 15 +1. [Шаг 1: nginx.conf — добавить блок stream](#5-шаг-1-nginxconf--добавить-блок-stream) 16 +1. [Шаг 2: stream.conf — SNI-роутинг](#6-шаг-2-streamconf--sni-роутинг) 17 +1. [Шаг 3: default.conf — перевести http на порт 4443](#7-шаг-3-defaultconf--перевести-http-на-порт-4443) 18 +1. [Шаг 4: site-confs — все server слушают 4443](#8-шаг-4-site-confs--все-server-слушают-4443) 19 +1. [Боевой пример конфигурации](#9-боевой-пример-конфигурации) 20 +1. [Проверка и отладка](#10-проверка-и-отладка) 21 +1. [Типичные ошибки и решения](#11-типичные-ошибки-и-решения) 22 +1. [Docker Compose — порты](#12-docker-compose--порты) 22 22 23 23 --- 24 24 ... ... @@ -32,50 +32,48 @@ 32 32 33 33 ### Это НЕ то же самое, что http-проксирование 34 34 35 -| Характеристика | `http { }` блок | `stream { }` блок | 36 -|---|---|---| 37 -| Уровень OSI | L7 (HTTP) | L4 (TCP/UDP) | 38 -| Видит ли HTTP-заголовки | ✅ Да | ❌ Нет | 39 -| Видит ли SNI | ✅ Да (после TLS) | ✅ Да (ssl_preread, без TLS) | 40 -| Terminates TLS | ✅ Да | ❌ Нет (передаёт дальше) | 41 -| Можно ли делать proxy_pass | ✅ Да | ✅ Да (TCP) | 36 +| Характеристика | `http { }` блок | `stream { }` блок | 37 +| -------------------------- | ---------------- | --------------------------- | 38 +| Уровень OSI | L7 (HTTP) | L4 (TCP/UDP) | 39 +| Видит ли HTTP-заголовки | ✅ Да | ❌ Нет | 40 +| Видит ли SNI | ✅ Да (после TLS) | ✅ Да (ssl_preread, без TLS) | 41 +| Terminates TLS | ✅ Да | ❌ Нет (передаёт дальше) | 42 +| Можно ли делать proxy_pass | ✅ Да | ✅ Да (TCP) | 42 42 43 43 --- 44 44 45 45 ## 2. Как это работает (схема) 46 46 47 -``` 48 - ┌─────────────────────────────────────────────────┐ 49 - │ SWAG Container │ 50 - │ │ 51 - Клиент ──── :443 ───► │ stream { │ 52 - (TLS ClientHello) │ ssl_preread on; ← читает SNI без decrypt │ 53 - │ map $ssl_preread_server_name $backend { │ 54 - │ nextcl.dev0ps.online → remnanode:8443 │ 55 - │ * (default) → 127.0.0.1:4443│ 56 - │ } │ 57 - │ proxy_pass $backend; │ 58 - │ } │ 59 - │ │ │ │ 60 - │ ▼ ▼ │ 61 - │ remnanode:8443 http { } :4443 │ 62 - │ (Reality/Xray, (SWAG, terminates │ 63 - │ TLS не трогаем) TLS, proxy_pass) │ 64 - │ │ │ 65 - │ ▼ │ 66 - │ site-confs/*.conf │ 67 - │ proxy-confs/*.conf │ 68 - └─────────────────────────────────────────────────┘ 69 -``` 48 + ┌─────────────────────────────────────────────────┐ 49 + │ SWAG Container │ 50 + │ │ 51 + Клиент ──── :443 ───► │ stream { │ 52 + (TLS ClientHello) │ ssl_preread on; ← читает SNI без decrypt │ 53 + │ map $ssl_preread_server_name $backend { │ 54 + │ nextcl.dev0ps.online → remnanode:8443 │ 55 + │ * (default) → 127.0.0.1:4443│ 56 + │ } │ 57 + │ proxy_pass $backend; │ 58 + │ } │ 59 + │ │ │ │ 60 + │ ▼ ▼ │ 61 + │ remnanode:8443 http { } :4443 │ 62 + │ (Reality/Xray, (SWAG, terminates │ 63 + │ TLS не трогаем) TLS, proxy_pass) │ 64 + │ │ │ 65 + │ ▼ │ 66 + │ site-confs/*.conf │ 67 + │ proxy-confs/*.conf │ 68 + └─────────────────────────────────────────────────┘ 70 70 71 71 ### Поток данных 72 72 73 73 1. **Клиент** подключается к порту **443** 74 - 2. **stream** блок принимает соединение и читает SNI из TLS ClientHello75 - 3. **map** выбирает бекенд на основе SNI:76 - -`nextcl.dev0ps.online` → `remnanode:8443` (проксирует TCP как есть, TLS не трогается)77 - -всё остальное → `127.0.0.1:4443` (передаёт в http-блок SWAG)78 - 4. **http** блок на порту **4443** терминирует TLS и делает HTTP-проксирование73 +1. **stream** блок принимает соединение и читает SNI из TLS ClientHello 74 +1. **map** выбирает бекенд на основе SNI: 75 + * `nextcl.dev0ps.online` → `remnanode:8443` (проксирует TCP как есть, TLS не трогается) 76 + * всё остальное → `127.0.0.1:4443` (передаёт в http-блок SWAG) 77 +1. **http** блок на порту **4443** терминирует TLS и делает HTTP-проксирование 79 79 80 80 --- 81 81 ... ... @@ -103,27 +103,25 @@ 103 103 104 104 ## 4. Файловая структура — что куда класть 105 105 106 -``` 107 -swag/nginx/ 108 -├── nginx.conf ← ГЛАВНЫЙ конфиг: добавить stream { } блок 109 -├── stream.conf ← НОВЫЙ ФАЙЛ: SNI-роутинг (L4) 110 -├── ssl.conf ← Без изменений 111 -├── site-confs/ 112 -│ ├── default.conf ← ИЗМЕНИТЬ: listen 443 → listen 4443 113 -│ └── dev0ps.online.conf ← ИЗМЕНИТЬ: listen 443 → listen 4443 114 -└── proxy-confs/ 115 - └── *.subdomain.conf ← ИЗМЕНИТЬ: listen 443 → listen 4443 116 -``` 105 + swag/nginx/ 106 + ├── nginx.conf ← ГЛАВНЫЙ конфиг: добавить stream { } блок 107 + ├── stream.conf ← НОВЫЙ ФАЙЛ: SNI-роутинг (L4) 108 + ├── ssl.conf ← Без изменений 109 + ├── site-confs/ 110 + │ ├── default.conf ← ИЗМЕНИТЬ: listen 443 → listen 4443 111 + │ └── dev0ps.online.conf ← ИЗМЕНИТЬ: listen 443 → listen 4443 112 + └── proxy-confs/ 113 + └── *.subdomain.conf ← ИЗМЕНИТЬ: listen 443 → listen 4443 117 117 118 118 ### Порядок действий 119 119 120 -| Шаг | Файл | Действие | 121 -|----- |------|----------|122 -| 1 | `nginx.conf` | Добавить `stream { include /config/nginx/stream.conf; }` | 123 -| 2 | `stream.conf` | Создать с SNI-роутингом | 124 -| 3 | `default.conf` | Заменить `listen 443 ssl` → `listen 4443 ssl` | 125 -| 4 | `site-confs/*.conf` | Заменить `listen 443 ssl` → `listen 4443 ssl` | 126 -| 5 | `proxy-confs/*.conf` | Заменить `listen 443 ssl` → `listen 4443 ssl` | 117 +| Шаг | Файл | Действие | 118 +| --- | -------------------- | -------------------------------------------------------- | 119 +| 1 | `nginx.conf` | Добавить `stream { include /config/nginx/stream.conf; }` | 120 +| 2 | `stream.conf` | Создать с SNI-роутингом | 121 +| 3 | `default.conf` | Заменить `listen 443 ssl` → `listen 4443 ssl` | 122 +| 4 | `site-confs/*.conf` | Заменить `listen 443 ssl` → `listen 4443 ssl` | 123 +| 5 | `proxy-confs/*.conf` | Заменить `listen 443 ssl` → `listen 4443 ssl` | 127 127 128 128 --- 129 129 ... ... @@ -157,9 +157,9 @@ 157 157 158 158 ### ⚠️ Критически важно 159 159 160 - -`stream { }` должен быть **на верхнем уровне** (не внутри `http { }`!)161 - -`stream { }` и `http { }` — это **параллельные** блоки одного уровня162 - -Внутри `stream { }` **нельзя** использовать http-директивы (`server_name`, `location`, `proxy_set_header` и т.д.)157 +* `stream { }` должен быть **на верхнем уровне** (не внутри `http { }`!) 158 +* `stream { }` и `http { }` — это **параллельные** блоки одного уровня 159 +* Внутри `stream { }` **нельзя** использовать http-директивы (`server_name`, `location`, `proxy_set_header` и т.д.) 163 163 164 164 --- 165 165 ... ... @@ -248,7 +248,8 @@ 248 248 } 249 249 ``` 250 250 251 -> **Полная замена:** везде в default.conf где `443` → заменить на `4443`. 248 +> **Полная замена:** везде в default.conf где `443` → заменить на `4443`. 249 +> 252 252 > Порт 80 оставить без изменений (HTTP → HTTPS редирект). 253 253 254 254 --- ... ... @@ -277,8 +277,10 @@ 277 277 } 278 278 ``` 279 279 280 -> **Массовая замена:** во ВСЕХ файлах заменить `listen 443 ssl` → `listen 4443 ssl` 281 -> и `listen [::]:443 ssl` → `listen [::]:4443 ssl` 278 +> **Массовая замена:** во ВСЕХ файлах заменить `listen 443 ssl` → `listen 4443 ssl` 279 +> 280 +> и `listen [::]:443 ssl` → `listen [::]:4443 ssl` 281 +> 282 282 > Порт 80 не трогать! 283 283 284 284 --- ... ... @@ -453,6 +453,7 @@ 453 453 ``` 454 454 455 455 **Ожидаемый вывод:** 456 + 456 456 ``` 457 457 nginx: the configuration file /etc/nginx/nginx.conf syntax is ok 458 458 nginx: configuration file /etc/nginx/nginx.conf test is successful ... ... @@ -471,6 +471,7 @@ 471 471 ``` 472 472 473 473 **Ожидаемый вывод:** 475 + 474 474 ``` 475 475 LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",...)) 476 476 LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:(("nginx",...)) ← stream ... ... @@ -611,4 +611,3 @@ 611 611 docker logs swag --tail 30 612 612 docker exec swag tail -30 /config/log/nginx/error.log 613 613 ``` 614 -