diff --git a/app/dashboard/public/statics/locales/en.json b/app/dashboard/public/statics/locales/en.json index a20a4dab9..f8a09fdae 100644 --- a/app/dashboard/public/statics/locales/en.json +++ b/app/dashboard/public/statics/locales/en.json @@ -37,6 +37,7 @@ "hostsDialog.addHost": "Add host", "hostsDialog.advancedOptions": "Advanced options", "hostsDialog.allowinsecure": "Allow Insecure", + "hostsDialog.useSniAsHost": "Use sni as host", "hostsDialog.alpn": "ALPN", "hostsDialog.apply": "Apply", "hostsDialog.currentServer": "IP Address of current server", diff --git a/app/dashboard/public/statics/locales/fa.json b/app/dashboard/public/statics/locales/fa.json index a85930811..734e1c215 100644 --- a/app/dashboard/public/statics/locales/fa.json +++ b/app/dashboard/public/statics/locales/fa.json @@ -42,6 +42,7 @@ "hostsDialog.addHost": "افزودن هاست", "hostsDialog.advancedOptions": "تنظیمات پیشرفته", "hostsDialog.allowinsecure": "Allow Insecure", + "hostsDialog.useSniAsHost": "استفاده از sni به عنوان هاست", "hostsDialog.alpn": "ALPN", "hostsDialog.apply": "اعمال", "hostsDialog.currentServer": "IP کنونی سرور", diff --git a/app/dashboard/public/statics/locales/ru.json b/app/dashboard/public/statics/locales/ru.json index 4ad11a232..2a57c5f7d 100644 --- a/app/dashboard/public/statics/locales/ru.json +++ b/app/dashboard/public/statics/locales/ru.json @@ -37,6 +37,7 @@ "hostsDialog.addHost": "Добавить хост", "hostsDialog.advancedOptions": "Дополнительные опции", "hostsDialog.allowinsecure": "Allow Insecure", + "hostsDialog.useSniAsHost": "Use sni as host", "hostsDialog.alpn": "ALPN", "hostsDialog.apply": "Применить", "hostsDialog.currentServer": "IP текущего сервера", @@ -188,4 +189,4 @@ "usersTable.noUserMatched": "Похоже, нет пользователя, соответствующего вашему запросу", "usersTable.status": "Статус", "usersTable.total": "Всего" -} +} \ No newline at end of file diff --git a/app/dashboard/public/statics/locales/zh.json b/app/dashboard/public/statics/locales/zh.json index e418593a7..59ead3914 100644 --- a/app/dashboard/public/statics/locales/zh.json +++ b/app/dashboard/public/statics/locales/zh.json @@ -37,6 +37,7 @@ "hostsDialog.addHost": "添加主机", "hostsDialog.advancedOptions": "高级选项", "hostsDialog.allowinsecure": "允许不安全连接", + "hostsDialog.useSniAsHost": "Use sni as host", "hostsDialog.alpn": "ALPN", "hostsDialog.apply": "保存", "hostsDialog.currentServer": "当前服务器的 IP 地址", @@ -189,4 +190,4 @@ "usersTable.status": "状态", "usersTable.sortByExpire": "按过期时间排序", "usersTable.total": "总共" -} +} \ No newline at end of file diff --git a/app/dashboard/src/components/HostsDialog.tsx b/app/dashboard/src/components/HostsDialog.tsx index fc1d26f56..10e7e1842 100644 --- a/app/dashboard/src/components/HostsDialog.tsx +++ b/app/dashboard/src/components/HostsDialog.tsx @@ -152,6 +152,7 @@ const hostsSchema = z.record( security: z.string(), alpn: z.string(), fingerprint: z.string(), + use_sni_as_host: z.boolean().default(false), }) ) ); @@ -212,6 +213,7 @@ const AccordionInbound: FC = ({ security: "inbound_default", alpn: "", fingerprint: "", + use_sni_as_host: false, }); }; const duplicateHost = (index: number) => { @@ -1067,6 +1069,33 @@ const AccordionInbound: FC = ({ + + + {t("hostsDialog.useSniAsHost")} + + + {accordionErrors && + accordionErrors[index]?.use_sni_as_host && ( + + { + accordionErrors[index]?.use_sni_as_host + ?.message + } + + )} + + None: + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('hosts', sa.Column('use_sni_as_host', sa.Boolean(), server_default='0', nullable=False)) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('hosts', 'use_sni_as_host') + # ### end Alembic commands ### diff --git a/app/db/models.py b/app/db/models.py index f29d10296..4d7f44bb2 100644 --- a/app/db/models.py +++ b/app/db/models.py @@ -263,6 +263,7 @@ class ProxyHost(Base): fragment_setting = Column(String(100), nullable=True) noise_setting = Column(String(2000), nullable=True) random_user_agent = Column(Boolean, nullable=False, default=False, server_default='0') + use_sni_as_host = Column(Boolean, nullable=False, default=False, server_default="0") class System(Base): diff --git a/app/models/proxy.py b/app/models/proxy.py index 001363dcf..959061df9 100644 --- a/app/models/proxy.py +++ b/app/models/proxy.py @@ -4,7 +4,7 @@ from typing import Optional, Union from uuid import UUID, uuid4 -from pydantic import field_validator, ConfigDict, BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field, field_validator from app.utils.system import random_password from xray_api.types.account import ( @@ -13,7 +13,7 @@ TrojanAccount, VLESSAccount, VMessAccount, - XTLSFlows + XTLSFlows, ) FRAGMENT_PATTERN = re.compile(r'^((\d{1,4}-\d{1,4})|(\d{1,4})),((\d{1,3}-\d{1,3})|(\d{1,3})),(tlshello|\d|\d\-\d)$') @@ -154,6 +154,7 @@ class ProxyHost(BaseModel): fragment_setting: Optional[str] = Field(None, nullable=True) noise_setting: Optional[str] = Field(None, nullable=True) random_user_agent: Union[bool, None] = None + use_sni_as_host: Union[bool, None] = None model_config = ConfigDict(from_attributes=True) @field_validator("remark", mode="after") diff --git a/app/subscription/share.py b/app/subscription/share.py index dda57d105..32cf692d7 100644 --- a/app/subscription/share.py +++ b/app/subscription/share.py @@ -292,6 +292,9 @@ def process_inbounds_and_tags( else: path = inbound.get("path", "").format_map(format_variables) + if host.get("use_sni_as_host", False) and sni: + req_host = sni + host_inbound.update( { "port": host["port"] or inbound["port"], diff --git a/app/xray/__init__.py b/app/xray/__init__.py index 5b9e6c52c..57c69af5b 100644 --- a/app/xray/__init__.py +++ b/app/xray/__init__.py @@ -10,10 +10,8 @@ from app.xray.node import XRayNode from config import XRAY_ASSETS_PATH, XRAY_EXECUTABLE_PATH, XRAY_JSON from xray_api import XRay as XRayAPI -from xray_api import exceptions +from xray_api import exceptions, types from xray_api import exceptions as exc -from xray_api import types - core = XRayCore(XRAY_EXECUTABLE_PATH, XRAY_ASSETS_PATH) @@ -64,6 +62,7 @@ def hosts(storage: dict): "fragment_setting": host.fragment_setting, "noise_setting": host.noise_setting, "random_user_agent": host.random_user_agent, + "use_sni_as_host": host.use_sni_as_host, } for host in inbound_hosts if not host.is_disabled ]