Конфигурация хоста
Конфигурация прокси-хоста, переопределение значений, переменные формата и фильтрация
Документация по конфигурации хоста
Этот документ объясняет, как PasarGuard обрабатывает и управляет прокси-хостами. Он разработан, чтобы помочь новичкам понять, как работают конфигурации хостов, какие значения переопределяют значения по умолчанию для входящих соединений, и как хосты отображаются пользователям в подписках.
Содержание
- Обзор
- Основы конфигурации хоста
- Приоритет переопределения значений
- Поля хоста и их поведение
- Переменные формата для отображения пользователю
- Настройки транспорта
- Статус хоста и фильтрация
- Ограничения и ограничения API
- Частые сценарии
Обзор
Хосты в PasarGuard — это конфигурации прокси-серверов, которые:
- Переопределяют значения по умолчанию из конфигураций входящих соединений XRay
- Предоставляют адреса серверов, порты и настройки транспорта
- Отображают настраиваемые имена (remarks) пользователям в подписках
- Фильтруют какие пользователи могут видеть какие хосты на основе статуса
Процесс генерации подписки
Когда пользователь запрашивает подписку, PasarGuard:
- Проверяет доступные входящие соединения пользователя - Обрабатываются только хосты, чей
inbound_tagдоступен пользователю (через их группы) - Загружает все включенные хосты, соответствующие статусу пользователя
- Объединяет настройки хоста со значениями по умолчанию для входящих соединений (значения хоста имеют приоритет)
- Форматирует remarks и адреса хостов, используя переменные, специфичные для пользователя
- Случайным образом выбирает значения из списков (SNI, host, address, port) для каждого запроса
- Генерирует конфигурацию подписки
Требования к видимости хоста
Хост появится в подписке пользователя только если:
inbound_tagхоста назначен хотя бы одной из групп пользователя- Группы пользователя не отключены
- Хост не отключен (
is_disabled: false) - Фильтр
statusхоста (если установлен) включает статус пользователя
Основы конфигурации хоста
Обязательные поля
Каждый хост должен иметь:
| Поле | Тип | Описание |
|---|---|---|
remark | string | Отображаемое имя, показываемое пользователям (поддерживает переменные формата) |
inbound_tag | string | Должен соответствовать тегу из одной из ваших конфигураций ядра XRay. Важно: Это входящее соединение должно быть назначено группам пользователей, чтобы пользователи видели этот хост |
priority | integer | Порядок появления хостов в подписках (меньше = выше приоритет) |
Необязательные поля
Хосты могут переопределять значения по умолчанию для входящих соединений для:
- Настройки сети:
address,port,sni,host,path - Настройки безопасности:
security,alpn,fingerprint,allowinsecure - Настройки транспорта: Конфигурации, специфичные для сети (WebSocket, gRPC и т.д.)
- Расширенные функции: Настройки Mux, fragment, noise
- Параметры отображения:
status(какие статусы пользователей могут видеть этот хост)
Приоритет переопределения значений
При генерации подписок PasarGuard объединяет значения в следующем порядке:
Порядок приоритета (от высшего к низшему)
- Конфигурация хоста - Значения, установленные на хосте, переопределяют все
- Значения по умолчанию для входящих соединений - Значения из конфигурации входящих соединений XRay
- Системные значения по умолчанию - Встроенные резервные значения
Как работают переопределения
Итоговое значение = Значение хоста (если установлено) ИЛИ Значение входящего соединения (если существует) ИЛИ Значение по умолчанию системыЗначение хоста переопределяет входящее соединение:
- Входящее соединение имеет
sni: ["example.com"] - Хост имеет
sni: ["host1.com", "host2.com"] - Результат:
sni: ["host1.com", "host2.com"](значение хоста побеждает)
Значение входящего соединения используется, когда хост не установлен:
- Входящее соединение имеет
port: 443 - Хост имеет
port: null(не установлен) - Результат:
port: 443(используется значение входящего соединения)
Поля хоста и их поведение
Базовые сетевые поля
address (Набор строк)
- Назначение: IP-адреса сервера или доменные имена
- Переопределение: Значение хоста полностью заменяет значение входящего соединения
- Отображение: Случайным образом выбирается для каждого запроса подписки
- Переменные формата: Поддерживает
{SERVER_IP},{SERVER_IPV6},{USERNAME}и т.д. - Ограничение: Максимальная общая длина строки 256 символов
- Подстановочные знаки: Поддерживает
*, который заменяется случайной солью для каждого запроса
Пример:
{
"address": ["1.2.3.4", "server.example.com", "{SERVER_IP}"]
}port (Целое число)
- Назначение: Номер порта сервера
- Переопределение: Порт хоста заменяет порт входящего соединения
- Особенность: Если не установлен, использует порт входящего соединения (может быть одно целое число или строка, разделенная запятыми, например "8080,8443")
- Отображение: Если входящее соединение имеет несколько портов, один случайным образом выбирается для каждого запроса
Пример:
{
"port": 443 // Переопределяет порт входящего соединения
}
// ИЛИ
{
"port": null // Использует порт входящего соединения (может быть несколько)
}sni (Набор строк)
- Назначение: Server Name Indication для TLS
- Переопределение: Значение хоста заменяет список SNI входящего соединения
- Отображение: Случайным образом выбирается для каждого запроса подписки
- Ограничение: Максимальная общая длина строки 1000 символов
- Подстановочные знаки: Поддерживает
*, который заменяется случайной солью
Пример:
{
"sni": ["example.com", "*.example.com", "cdn.example.com"]
}host (Набор строк)
- Назначение: Заголовок host для транспортов HTTP/WebSocket
- Переопределение: Значение хоста заменяет список host входящего соединения
- Отображение: Случайным образом выбирается для каждого запроса подписки
- Ограничение: Максимальная общая длина строки 1000 символов
- Подстановочные знаки: Поддерживает
*, который заменяется случайной солью
Пример:
{
"host": ["example.com", "www.example.com"]
}path (Строка)
- Назначение: Путь для транспортов WebSocket, gRPC, HTTP
- Переопределение: Путь хоста заменяет путь входящего соединения, если установлен
- Переменные формата: Поддерживает
{PROTOCOL},{TRANSPORT},{USERNAME}и т.д. - По умолчанию: Использует путь входящего соединения, если путь хоста не установлен
Пример:
{
"path": "/{PROTOCOL}-{TRANSPORT}/path"
}Настройки безопасности
security (Enum: ProxyHostSecurity)
- Назначение: Тип безопасности TLS/Reality
- Опции:
inbound_default- Использовать безопасность из конфигурации входящего соединенияnone- Без шифрованияtls- Шифрование TLSreality- Протокол Reality
- Переопределение: Безопасность хоста заменяет безопасность входящего соединения (если не установлено
inbound_default)
Пример:
{
"security": "tls" // Переопределяет безопасность входящего соединения
}
// ИЛИ
{
"security": "inbound_default" // Использует безопасность входящего соединения
}alpn (Список ProxyHostALPN)
- Назначение: Application-Layer Protocol Negotiation
- Опции:
h3,h2,http/1.1 - Переопределение: Список ALPN хоста заменяет ALPN входящего соединения
- Особенность: Автоматически сортируется по приоритету (h3 → h2 → http/1.1)
- По умолчанию: Использует ALPN входящего соединения, если не установлено
Пример:
{
"alpn": ["h3", "h2", "http/1.1"]
}fingerprint (Enum: ProxyHostFingerprint)
- Назначение: Тип fingerprint TLS
- Переопределение: Fingerprint хоста заменяет fingerprint входящего соединения (если не установлено
none) - По умолчанию: Использует fingerprint входящего соединения (обычно
chromeдля Reality)
Пример:
{
"fingerprint": "chrome" // Переопределяет fingerprint входящего соединения
}
// ИЛИ
{
"fingerprint": "none" // Использует fingerprint входящего соединения
}allowinsecure (Boolean)
- Назначение: Разрешить небезопасные TLS-соединения
- Переопределение: Значение хоста заменяет значение входящего соединения, если установлено
- По умолчанию: Использует значение входящего соединения (обычно
false)
Пример:
{
"allowinsecure": false // Переопределяет настройку входящего соединения
}ech_config_list (String)
- Назначение: Конфигурация Encrypted Client Hello (ECH)
- Переопределение: Значение хоста заменяет значение входящего соединения, если установлено
- По умолчанию: Использует значение входящего соединения, если не установлено
Расширенные функции
use_sni_as_host (Boolean)
- Назначение: Использовать значение SNI в качестве заголовка host
- Поведение: Когда
true, выбранное значение SNI заменяет заголовок host - По умолчанию:
false
random_user_agent (Boolean)
- Назначение: Генерировать случайные заголовки User-Agent
- Поведение: Когда
true, случайный User-Agent добавляется к HTTP-заголовкам - По умолчанию:
false
http_headers (Словарь)
- Назначение: Пользовательские HTTP-заголовки
- Формат:
{"Header-Name": "value"} - Переопределение: Заголовки хоста добавляются в конфигурацию транспорта
Пример:
{
"http_headers": {
"X-Forwarded-For": "1.2.3.4",
"Custom-Header": "value"
}
}is_disabled (Boolean)
- Назначение: Временно отключить хост без удаления
- Поведение: Отключенные хосты исключаются из подписок
- По умолчанию:
false
status (Набор UserStatus)
- Назначение: Фильтр, какие статусы пользователей могут видеть этот хост
- Опции:
active,expired,limited,disabled,on_hold - Поведение: Если установлено, только пользователи с соответствующим статусом видят этот хост
- По умолчанию:
null(все пользователи могут видеть его)
Пример:
{
"status": ["active", "on_hold"] // Только пользователи active и on_hold видят это
}Переменные формата для отображения пользователю
Поля remark и address хоста поддерживают переменные формата, которые заменяются значениями, специфичными для пользователя, при генерации подписок.
Доступные переменные формата
| Переменная | Описание | Пример |
|---|---|---|
{SERVER_IP} | Публичный IPv4-адрес сервера | 1.2.3.4 |
{SERVER_IPV6} | Публичный IPv6-адрес сервера | 2001:db8::1 |
{USERNAME} | Имя пользователя пользователя | john_doe |
{PROTOCOL} | Имя протокола (vmess, vless и т.д.) | vless |
{TRANSPORT} | Тип транспорта (tcp, ws, grpc и т.д.) | ws |
{DATA_USAGE} | Использование данных пользователя (отформатировано) | 1.5 GB |
{DATA_LIMIT} | Лимит данных пользователя (отформатировано) | 100 GB или ∞ |
{DATA_LEFT} | Оставшиеся данные (отформатировано) | 98.5 GB или ∞ |
{DAYS_LEFT} | Дни до истечения срока | 30 или ∞ |
{EXPIRE_DATE} | Дата истечения срока (Григорианский календарь) | 2024-12-31 |
{JALALI_EXPIRE_DATE} | Дата истечения срока (Джалали) | 1403-10-11 |
{TIME_LEFT} | Время до истечения срока (отформатировано) | 30 days или ∞ |
{STATUS_EMOJI} | Эмодзи статуса пользователя | ✅, ⌛️, 🪫, ❌, 🔌 |
{USAGE_PERCENTAGE} | Процент использования данных | 15.5 или ∞ |
{ADMIN_USERNAME} | Администратор, создавший пользователя | admin |
Примеры переменных формата
Примеры Remark:
{
"remark": "{PROTOCOL}-{TRANSPORT} Server {STATUS_EMOJI}"
}
// Результат: "vless-ws Server ✅" (для активного пользователя){
"remark": "{USERNAME} - {DATA_LEFT} left"
}
// Результат: "john_doe - 98.5 GB left"{
"remark": "Server {SERVER_IP} - Expires {EXPIRE_DATE}"
}
// Результат: "Server 1.2.3.4 - Expires 2024-12-31"Примеры Address:
{
"address": ["{SERVER_IP}", "cdn-{USERNAME}.example.com"]
}
// Результат в случайном выборе: "1.2.3.4" или "cdn-john_doe.example.com"Отсутствующие переменные:
Если переменная формата недоступна (например, у пользователя нет срока истечения), она будет заменена на:
∞для полей даты/времени/лимита-для дат, когда пользователь находится в статусе on_hold<missing>для других отсутствующих переменных
Настройки транспорта
Хосты могут настраивать настройки транспорта, специфичные для сети, которые переопределяют значения по умолчанию для входящих соединений.
Настройки WebSocket
{
"transport_settings": {
"websocket_settings": {
"heartbeatPeriod": 30 // Интервал heartbeat в секундах
}
}
}Настройки gRPC
{
"transport_settings": {
"grpc_settings": {
"multi_mode": true, // Включить multi-mode
"idle_timeout": 60, // Таймаут простоя в секундах
"health_check_timeout": 20, // Таймаут проверки здоровья
"permit_without_stream": false, // Требовать stream
"initial_windows_size": 1048576 // Начальный размер окна
}
}
}Настройки KCP
{
"transport_settings": {
"kcp_settings": {
"header": "wechat-video", // Тип заголовка
"mtu": 1350, // Maximum Transmission Unit
"tti": 20, // Transmission Time Interval
"uplink_capacity": 5, // Пропускная способность uplink
"downlink_capacity": 20, // Пропускная способность downlink
"congestion": false, // Управление перегрузкой
"read_buffer_size": 2, // Размер буфера чтения
"write_buffer_size": 2 // Размер буфера записи
}
}
}Настройки TCP
{
"transport_settings": {
"tcp_settings": {
"header": "http", // Тип заголовка: "none" или "http"
"request": {
"method": "GET",
"version": "1.1",
"headers": {
"Host": ["example.com"]
}
},
"response": {
"status": "200",
"reason": "OK",
"version": "1.1"
}
}
}
}Настройки XHTTP/SplitHTTP
{
"transport_settings": {
"xhttp_settings": {
"mode": "auto", // auto, packet-up, stream-up, stream-one
"no_grpc_header": false, // Отключить заголовок gRPC
"x_padding_bytes": "1-100", // Диапазон байтов padding
"sc_max_each_post_bytes": 1048576, // Максимальные байты post
"sc_min_posts_interval_ms": 100, // Минимальный интервал между post
"xmux": {
"maxConcurrency": 8,
"maxConnections": 8,
"cMaxReuseTimes": 1,
"hMaxReusableSecs": 300,
"hMaxRequestTimes": 8,
"hKeepAlivePeriod": 15
},
"download_settings": 2 // ID другого хоста для загрузки
}
}
}Настройки загрузки
download_settings ссылается на ID другого хоста для функциональности загрузки XHTTP. Указанный хост не может иметь свой собственный хост загрузки (без вложенности).
Настройки Mux
{
"mux_settings": {
"xray": {
"enabled": true,
"concurrency": 8,
"xudpConcurrency": 8,
"xudpProxyUDP443": "reject" // reject, allow, skip
},
"sing_box": {
"enable": true,
"protocol": "smux", // smux, yamux, h2mux
"max_connections": 8,
"max_streams": 8,
"min_streams": 1,
"padding": false,
"brutal": {
"enable": true,
"up_mbps": 100,
"down_mbps": 100
}
},
"clash": {
// То же, что и sing_box, плюс:
"statistic": false,
"only_tcp": false
}
}
}Настройки Fragment
{
"fragment_settings": {
"xray": {
"packets": "tlshello", // или диапазон, например "1-10"
"length": "100-200", // Диапазон длины fragment
"interval": "10-20" // Диапазон интервала
},
"sing_box": {
"fragment": true,
"fragment_fallback_delay": "100ms",
"record_fragment": false
}
}
}Настройки Noise
{
"noise_settings": {
"xray": [
{
"type": "rand", // rand, str, base64, hex
"packet": "base64-encoded-data",
"delay": "10-20", // Диапазон задержки
"apply_to": "ip" // ip, ipv4, ipv6
}
]
}
}Статус хоста и фильтрация
Как работает фильтрация хоста
При генерации подписки хосты фильтруются в следующем порядке:
-
Проверка доступа к входящему соединению:
inbound_tagхоста должен быть доступен пользователю через его группы- Пользователи принадлежат группам
- Группам назначены теги входящих соединений
- Обрабатываются только хосты, чей
inbound_tagнаходится в доступных входящих соединениях пользователя (из всех его групп) - Отключенные группы исключаются из этой проверки
- Это первый и самый важный фильтр - если у пользователя нет доступа к входящему соединению через его группы, хост никогда не появится в его подписке
-
Проверка отключения: Хосты с
is_disabled: trueисключаются -
Проверка статуса: Если у хоста установлен
status, статус пользователя должен соответствовать одному из значений в наборе -
Сортировка по приоритету: Оставшиеся хосты сортируются по
priority(по возрастанию)
Понимание доступа к входящему соединению через группы
Как это работает:
- Пользователи назначаются группам
- Группам назначаются теги входящих соединений (связь многие-ко-многим)
- При генерации подписки PasarGuard собирает все теги входящих соединений из всех групп пользователя (исключая отключенные группы)
- Включаются только хосты, чей
inbound_tagсоответствует одному из этих доступных входящих соединений
Пример:
Пользователь "john" принадлежит:
- Группе "Premium" (inbound_tags: ["vless-443", "trojan-8443"])
- Группе "Standard" (inbound_tags: ["vmess-8080"])
Хосты:
- Хост A (inbound_tag: "vless-443") ✅ Появится (в группе Premium)
- Хост B (inbound_tag: "trojan-8443") ✅ Появится (в группе Premium)
- Хост C (inbound_tag: "vmess-8080") ✅ Появится (в группе Standard)
- Хост D (inbound_tag: "shadowsocks-9090") ❌ НЕ появится (не в любой группе)Нет групп = нет хостов
Если у пользователя нет групп или все его группы отключены, он не увидит хостов в своей подписке.
Примеры фильтрации по статусу
Хост виден всем пользователям:
{
"status": null // или пустой набор
}Хост виден только активным пользователям:
{
"status": ["active"]
}Хост виден активным и on_hold пользователям:
{
"status": ["active", "on_hold"]
}Сортировка по приоритету
Хосты сортируются по полю priority (меньшее число = выше приоритет):
{
"priority": 1 // Появляется первым в подписке
}{
"priority": 100 // Появляется позже в подписке
}Ограничения и ограничения API
Ограничения полей
| Поле | Ограничение | Описание |
|---|---|---|
remark | Должна быть допустимой строкой формата | Поддерживает переменные формата |
address | Максимальная общая длина строки 256 символов | Набор строк адресов |
sni | Максимальная общая длина строки 1000 символов | Набор строк SNI |
host | Максимальная общая длина строки 1000 символов | Набор строк host |
inbound_tag | Должен существовать в конфигурациях ядра | Проверяется на соответствие конфигурациям XRay |
Правила валидации
-
Валидация тега входящего соединения
inbound_tagдолжен существовать хотя бы в одной конфигурации ядра XRay- Проверяется при создании или изменении хостов
-
Валидация настроек загрузки
- Если установлен
xhttp_settings.download_settings, он должен ссылаться на допустимый ID хоста - Указанный хост не может быть тем же, что и текущий хост
- Указанный хост не может иметь свой собственный хост загрузки (без вложенности)
- Если установлен
-
Валидация переменной формата
remarkдолжна быть допустимой строкой формата- Недопустимые переменные формата вызовут ошибки
-
Валидация ALPN
- Список ALPN автоматически дедуплицируется
- Список ALPN автоматически сортируется по приоритету (h3 → h2 → http/1.1)
Конечные точки API
GET /api/host/{host_id}- Получить хост по IDGET /api/hosts- Список всех хостов (с пагинацией)POST /api/host/- Создать новый хостPUT /api/host/{host_id}- Изменить существующий хостDELETE /api/host/{host_id}- Удалить хостPUT /api/hosts- Массовое изменение хостов
Аутентификация
Все конечные точки требуют привилегий администратора sudo.
Частые сценарии
Сценарий 1: Переопределение порта входящего соединения
Проблема: Входящее соединение использует порт 443, но вы хотите, чтобы этот хост использовал порт 8443.
Решение:
{
"inbound_tag": "my-inbound",
"port": 8443, // Переопределяет порт входящего соединения
"remark": "Custom Port Server"
}Сценарий 2: Несколько значений SNI
Проблема: Вы хотите случайным образом выбирать из нескольких значений SNI для каждого запроса.
Решение:
{
"sni": ["example.com", "cdn.example.com", "www.example.com"]
}
// Каждый запрос подписки случайным образом выбирает одноСценарий 3: Имена серверов, специфичные для пользователя
Проблема: Вы хотите, чтобы каждый пользователь видел свое имя пользователя в адресе сервера.
Решение:
{
"address": ["{USERNAME}.example.com", "{SERVER_IP}"],
"remark": "Server for {USERNAME}"
}Сценарий 4: Видимость хоста на основе статуса
Проблема: Вы хотите, чтобы премиум-сервер был виден только активным пользователям.
Решение:
{
"remark": "Premium Server",
"status": ["active"], // Только активные пользователи видят это
"priority": 1 // Высокий приоритет
}Требуется доступ группы
inbound_tag хоста также должен быть назначен группам пользователя. Фильтр status работает только на хостах, которые уже доступны через группы.
Сценарий 4b: Доступ к хосту на основе группы
Проблема: Вы хотите, чтобы хост был виден только пользователям в определенных группах.
Решение:
- Создайте группу (например, "VIP Group")
- Назначьте
inbound_tagхоста этой группе - Назначайте пользователей этой группе только тех, кто должен видеть хост
// Конфигурация хоста
{
"inbound_tag": "vless-premium-443",
"remark": "VIP Server"
}
// Конфигурация группы (через API)
{
"name": "VIP Group",
"inbound_tags": ["vless-premium-443"] // Должен соответствовать inbound_tag хоста
}Пользователи в "VIP Group" увидят этот хост. Пользователи не в этой группе не увидят его, независимо от других настроек.
Сценарий 5: Переопределение типа безопасности
Проблема: Входящее соединение использует TLS, но вы хотите, чтобы этот хост использовал Reality.
Решение:
{
"security": "reality", // Переопределяет безопасность входящего соединения
"sni": ["reality.example.com"]
}Сценарий 6: Пользовательский путь с переменными
Проблема: Вы хотите, чтобы путь включал протокол и тип транспорта.
Решение:
{
"path": "/{PROTOCOL}/{TRANSPORT}/path"
}
// Результат: "/vless/ws/path"Сценарий 7: Несколько портов из входящего соединения
Проблема: Входящее соединение имеет порты "8080,8443,9090" и вы хотите использовать все из них.
Решение:
{
"port": null // Не устанавливайте порт, использует несколько портов входящего соединения
}
// Каждый запрос подписки случайным образом выбирает один портСценарий 8: XHTTP с хостом загрузки
Проблема: Вы хотите настроить XHTTP с хостом загрузки.
Решение:
{
"transport_settings": {
"xhttp_settings": {
"mode": "auto",
"download_settings": 5 // Ссылка на ID хоста 5
}
}
}Сценарий 9: Подстановочный знак SNI со случайной солью
Проблема: Вы хотите, чтобы SNI имел случайный поддомен для каждого запроса.
Решение:
{
"sni": ["*.example.com"]
}
// Каждый запрос: "a1b2c3d4.example.com" (случайная соль заменяет *)Сценарий 10: Сортировка по приоритету
Проблема: Вы хотите, чтобы определенные хосты появлялись первыми в подписках.
Решение:
// Хост с высоким приоритетом
{
"remark": "Primary Server",
"priority": 1
}
// Хост с более низким приоритетом
{
"remark": "Backup Server",
"priority": 100
}Резюме
Лучшие практики
- ✅ Значения хоста переопределяют значения по умолчанию для входящих соединений - Настройки хоста имеют приоритет над значениями по умолчанию для входящих соединений
- ✅ Доступ к входящему соединению через группы обязателен - Хосты появляются только если их
inbound_tagназначен группам пользователя - ✅ Используйте переменные формата в
remarkиaddressдля отображения, специфичного для пользователя - ✅ Несколько значений выбираются случайным образом - Значения SNI, host, address и port случайным образом выбираются для каждого запроса подписки
- ✅ Подстановочные знаки (
*) в SNI/host/address заменяются случайной солью - ✅ Фильтр
statusхоста определяет, какие пользователи могут видеть хост (но только если входящее соединение доступно через группы) - ✅
priorityхоста определяет порядок в подписках - ✅
inbound_tagдолжен существовать в ваших конфигурациях ядра XRay И быть назначен группам пользователей - ✅ Настройки транспорта переопределяют значения по умолчанию для входящих соединений для конкретных сетей
- ✅ Отключенные хосты (
is_disabled: true) исключаются из подписок - ✅ Переменные формата заменяются значениями, специфичными для пользователя, при генерации подписок
- ✅ Управление доступом на основе групп - Пользователи видят только хосты, чьи входящие соединения находятся в их назначенных группах
Для получения дополнительной информации о конфигурации XRay см. Конфигурация ядра.