Архитектура

Топология сервисов

Автономный режим (без домена)

Internet


┌──────────────────────────────────────┐
│ Server                               │
│                                      │
│  Port 443: HAProxy (SNI router)      │
│  ┌──────────────────────────────┐    │
│  │ SNI = reality_sni            │    │
│  │  → Port 10443: Xray (Reality)│    │
│  │                              │    │
│  │ SNI = server IP              │    │
│  │  → Port 8443: Caddy (TLS)   │    │
│  │     ├─ /info-path → page    │    │
│  │     ├─ /panel-path → 3x-ui  │    │
│  │     └─ /xhttp-path → Xray   │    │
│  └──────────────────────────────┘    │
│                                      │
│  Port 80: Caddy (ACME challenges)    │
│                                      │
│  Docker: 3x-ui                       │
│  ├─ Reality inbound (port 10443)     │
│  └─ XHTTP inbound (localhost port)   │
│                                      │
│  Caddy: IP cert (ACME shortlived)    │
│  HAProxy: TCP SNI, no TLS terminate  │
└──────────────────────────────────────┘

HAProxy не завершает TLS. Он читает имя хоста SNI из TLS Client Hello и пересылает необработанный TCP-поток на соответствующий бэкенд.

Caddy запрашивает сертификат Let’s Encrypt IP через профиль ACME shortlived (6-дневное действие, автоматическое обновление). При невозможности выпуска сертификата IP использует самоподписанный сертификат.

XHTTP работает на порту localhost и обратно проксируется Caddy — дополнительного внешнего порта не требуется.

Режим домена

Internet


┌──────────────────────────────────────┐
│ Server                               │
│                                      │
│  Port 443: HAProxy (SNI router)      │
│  ┌──────────────────────────────┐    │
│  │ SNI = reality_sni            │    │
│  │  → Port 10443: Xray (Reality)│    │
│  │                              │    │
│  │ SNI = domain                 │    │
│  │  → Port 8443: Caddy (TLS)   │    │
│  │     ├─ /info-path → page    │    │
│  │     ├─ /panel-path → 3x-ui  │    │
│  │     ├─ /xhttp-path → Xray   │    │
│  │     └─ /ws-path → Xray WSS  │    │
│  └──────────────────────────────┘    │
│                                      │
│  Docker: 3x-ui                       │
│  ├─ Reality inbound (port 10443)     │
│  ├─ XHTTP inbound (localhost port)   │
│  └─ WSS inbound (localhost port)     │
│                                      │
│  Caddy: domain cert (Let's Encrypt)  │
│  HAProxy: TCP SNI, no TLS terminate  │
└──────────────────────────────────────┘

Режим домена добавляет VLESS+WSS как резервный путь CDN. Трафик проходит через CDN Cloudflare через WebSocket, что позволяет соединению работать даже если IP-адрес сервера заблокирован.

Как работает протокол Reality

  1. Сервер генерирует пару ключей x25519. Открытый ключ используется с клиентами, приватный ключ остаётся на сервере.
  2. Клиент подключается к порту 443 с TLS Client Hello содержащим домен маскировки (например, www.microsoft.com) в качестве SNI.
  3. Для любого наблюдателя это выглядит как обычное HTTPS-соединение с microsoft.com.
  4. Если проверяющий отправит свой собственный Client Hello, сервер проксирует соединение на реальный microsoft.com — проверяющий видит действительный сертификат.
  5. Если клиент включает действительную аутентификацию (полученную из ключа x25519), сервер устанавливает VLESS-туннель.
  6. uTLS делает Client Hello идентичным Chrome в каждом байте, преодолевая TLS fingerprinting.

Назначение портов

ПортСервисРежим
443HAProxy (SNI router)Все
80Caddy (ACME challenges)Все
10443Xray Reality (внутренний)Все
8443Caddy TLS (внутренний)Все
localhostXray XHTTPКогда XHTTP включён
localhostXray WSSРежим домена
20533x-ui panel (внутренний)Все

Порты XHTTP и WSS видны только на localhost — Caddy обратно проксирует их на порт 443.

Конвейер подготовки

ШагНазначение
1InstallPackagesПакеты ОС
2EnableAutoUpgradesАвтоматические обновления
3SetTimezoneUTC
4HardenSSHАутентификация только по ключу
5ConfigureBBRTCP congestion control
6ConfigureFirewallUFW: 22 + 80 + 443
7InstallDockerDocker CE
8Deploy3xui3x-ui контейнер
9ConfigurePanelУчётные данные панели
10LoginToPanelAPI аутентификация
11CreateRealityInboundVLESS+Reality
12CreateXHTTPInboundVLESS+XHTTP
13CreateWSSInboundVLESS+WSS (домен)
14VerifyXrayПроверка здоровья
15InstallHAProxySNI маршрутизация
16InstallCaddyTLS + reverse proxy
17DeployConnectionPageQR коды + страница

Жизненный цикл учётных данных

  1. Генерация: случайные учётные данные (пароль панели, ключи x25519, UUID клиента)
  2. Сохранение локально: ~/.meridian/credentials/<IP>/proxy.yml — сохраняется ДО применения к серверу
  3. Применение: пароль панели изменён, входящие точки созданы
  4. Синхронизация: учётные данные скопированы в /etc/meridian/proxy.yml на сервере
  5. Повторные запуски: загружены из кэша, не регенерированы (идемпотентно)
  6. На разных машинах: загружены с сервера через SSH
  7. Удаление: удалены как с сервера, так и с локальной машины
On this page