Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(xray-core): new xray features #1302

Merged
merged 17 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion app/dashboard/public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
"hostsDialog.fragment.info": "Correct pattern: length,interval,packets",
"hostsDialog.fragment.info.attention": "Attention: currently, this feature only supported in streisand >= 1.6.12 and v2rayNG >= 1.8.16 (custom config)",
"hostsDialog.fragment.info.examples": "Examples:",
"hostsDialog.noise": "Noise pattern",
"hostsDialog.noise.info": "Correct pattern: packets,delay",
"hostsDialog.noise.info.attention": "Attention: currently, this feature only supported in streisand >= 1.6.32 and v2rayNG >= 1.8.39 (custom config)",
"hostsDialog.noise.info.examples": "Examples:",
"hostsDialog.host": "Request Host",
"hostsDialog.host.info": "By default, if a request host is set in the Xray config, this host is used. However, you can set a custom request host here if needed.",
"hostsDialog.host.multiHost": "To set multiple addresses, separate them with <badge>,</badge> Each time an address is chosen randomly.",
Expand Down Expand Up @@ -184,4 +188,4 @@
"usersTable.noUserMatched": "It seems there is no user matched with what you are looking for",
"usersTable.status": "status",
"usersTable.total": "Total"
}
}
7 changes: 6 additions & 1 deletion app/dashboard/public/locales/fa.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@
"hostsDialog.fragment.info": "length,interval,packet (e.g. 10-100,100-200,tlshello)",
"hostsDialog.fragment.info.attention": "توجه: در حال حاضر، این ویژگی فقط در streisand >= 1.6.12 و v2rayNG >= 1.8.16 (پیکربندی سفارشی) پشتیبانی می شود",
"hostsDialog.fragment.info.examples": "نمونه ها:",
"hostsDialog.noise": "الگو نویز",
"hostsDialog.noise.info": "packet,delay (e.g. rand:10-20,100-200)",
"hostsDialog.noise.info.attention": "توجه: در حال حاضر، این ویژگی فقط در streisand >= 1.6.32 و v2rayNG >= 1.8.39 (پیکربندی سفارشی) پشتیبانی می شود",
"hostsDialog.noise.info.examples": "نمونه ها:",

"hostsDialog.host": "هاست درخواست",
"hostsDialog.host.info": "به‌طور پیش‌فرض، اگر هاست درخواستی در پیکربندی *** تنظیم شده باشد، این هاست استفاده می‌شود. اما می‌توانید یک هاست درخواستی متفاوت در اینجا قرار دهید.",
"hostsDialog.host.multiHost": "برای تنظیم چند آدرس، با <badge>,</badge> از هم جدا کنید. هر دفعه آدرسی به صورت تصادفی قرار داده می‌شود.",
Expand Down Expand Up @@ -189,4 +194,4 @@
"usersTable.noUserMatched": "به‌نظر میرسه کاربری که جستجو کردید، وجود ندارد",
"usersTable.status": "وضعیت",
"usersTable.total": "مجموع"
}
}
6 changes: 5 additions & 1 deletion app/dashboard/public/locales/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
"hostsDialog.fragment.info": "length,interval,packet (e.g. 10-100,100-200,tlshello)",
"hostsDialog.fragment.info.attention": "Attention: currently, this feature only supported in streisand >= 1.6.12 and v2rayNG >= 1.8.16 (custom config)",
"hostsDialog.fragment.info.examples": "Examples:",
"hostsDialog.noise": "Шумовой паттерн",
"hostsDialog.noise.info": "packet,delay (e.g. rand:10-20,100-200)",
"hostsDialog.noise.info.attention": "Attention: currently, this feature only supported in streisand >= 1.6.32 and v2rayNG >= 1.8.39 (custom config)",
"hostsDialog.noise.info.examples": "Examples:",
"hostsDialog.host": "Host",
"hostsDialog.host.info": "По умолчанию, если в конфигурации XRAY задан запрашиваемый хост, то он и будет использоваться. Однако, если необходимо, вы можете установить здесь пользовательский запрашиваемый хост.",
"hostsDialog.host.multiHost": "Чтобы установить несколько адресов, разделяйте их с помощью <badge>,</badge>. Каждый раз будет выбран случайный адрес.",
Expand Down Expand Up @@ -184,4 +188,4 @@
"usersTable.noUserMatched": "Похоже, нет пользователя, соответствующего вашему запросу",
"usersTable.status": "Статус",
"usersTable.total": "Всего"
}
}
4 changes: 4 additions & 0 deletions app/dashboard/public/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
"hostsDialog.fragment.info": "length,interval,packet (e.g. 10-100,100-200,tlshello)",
"hostsDialog.fragment.info.attention": "请注意: 当前特性仅支持 streisand >= 1.6.12 and v2rayNG >= 1.8.16 (自定义配置)",
"hostsDialog.fragment.info.examples": "示例:",
"hostsDialog.noise": "噪声模式",
"hostsDialog.noise.info": "packet,delay (e.g. rand:10-20,100-200)",
"hostsDialog.noise.info.attention": "Attention: currently, this feature only supported in streisand >= 1.6.32 and v2rayNG >= 1.8.39 (custom config)",
"hostsDialog.noise.info.examples": "Examples:",
"hostsDialog.host": "请求主机",
"hostsDialog.host.info": "默认情况下,如果在 Xray 配置中设置了请求主机,则使用该主机。但是,如果需要,您可以在此处设置自定义请求主机。",
"hostsDialog.host.multiHost": "使用 <badge>,</badge> 作为分隔符设置多个地址,使用时,每次随机选择一个地址。",
Expand Down
71 changes: 69 additions & 2 deletions app/dashboard/src/components/HostsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ import {
proxyHostSecurity,
} from "constants/Proxies";
import { useHosts } from "contexts/HostsContext";
import { FC, useEffect, useRef, useState } from "react";
import { motion } from "framer-motion";
import { FC, useEffect, useState } from "react";
import {
Controller,
FormProvider,
Expand All @@ -67,7 +68,6 @@ import { useDashboard } from "../contexts/DashboardContext";
import { DeleteIcon } from "./DeleteUserModal";
import { Icon } from "./Icon";
import { Input as CustomInput } from "./Input";
import { motion } from "framer-motion";

export const DublicateIcon = chakra(DocumentDuplicateIcon, {
baseStyle: {
Expand Down Expand Up @@ -147,6 +147,7 @@ const hostsSchema = z.record(
allowinsecure: z.boolean().nullable().default(false),
is_disabled: z.boolean().default(true),
fragment_setting: z.string().nullable(),
noise_setting: z.string().nullable(),
random_user_agent: z.boolean().default(false),
security: z.string(),
alpn: z.string(),
Expand Down Expand Up @@ -206,6 +207,7 @@ const AccordionInbound: FC<AccordionInboundType> = ({
allowinsecure: false,
is_disabled: false,
fragment_setting: "",
noise_setting: "",
random_user_agent: false,
security: "inbound_default",
alpn: "",
Expand Down Expand Up @@ -999,6 +1001,71 @@ const AccordionInbound: FC<AccordionInboundType> = ({
)}
</FormControl>

<FormControl
isInvalid={
!!(
accordionErrors &&
accordionErrors[index]?.noise_setting
)
}
>
<FormLabel
display="flex"
pb={1}
alignItems="center"
gap={1}
justifyContent="space-between"
m="0"
>
<span>{t("hostsDialog.noise")}</span>

<Popover isLazy placement="right">
<PopoverTrigger>
<InfoIcon />
</PopoverTrigger>
<Portal>
<PopoverContent p={2}>
<PopoverArrow />
<PopoverCloseButton />
<Text fontSize="xs" pr={5}>
{t("hostsDialog.noise.info")}
</Text>
<Text fontSize="xs" pr={5} pt={2} pb={1}>
{t("hostsDialog.noise.info.examples")}
</Text>
<Text fontSize="xs" pr={5}>
rand:10-20,10-20
</Text>
<Text fontSize="xs" pr={5}>
rand:10-20,10-20&base64:7nQBAAABAAAAAAAABnQtcmluZwZtc2VkZ2UDbmV0AAABAAE=,10-25
</Text>
<Text fontSize="xs" pr={5} pt="3">
{t("hostsDialog.noise.info.attention")}
</Text>
</PopoverContent>
</Portal>
</Popover>
</FormLabel>
<Input
size="sm"
borderRadius="4px"
placeholder="Noise settings by pattern"
{...form.register(
hostKey + "." + index + ".noise_setting"
)}
/>
{accordionErrors &&
accordionErrors[index]?.noise_setting && (
<Error>
{
accordionErrors[index]?.noise_setting
?.message
}
</Error>
)}
</FormControl>


<FormControl
isInvalid={
!!(
Expand Down
43 changes: 30 additions & 13 deletions app/db/crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,39 @@
from sqlalchemy.orm import Query, Session, joinedload
from sqlalchemy.sql.functions import coalesce

from app.db.models import (JWT, TLS, Admin, Node, NodeUsage, NodeUserUsage,
NotificationReminder, Proxy, ProxyHost,
ProxyInbound, ProxyTypes, System, User,
UserTemplate, UserUsageResetLogs)
from app.db.models import (
JWT,
TLS,
Admin,
Node,
NodeUsage,
NodeUserUsage,
NotificationReminder,
Proxy,
ProxyHost,
ProxyInbound,
ProxyTypes,
System,
User,
UserTemplate,
UserUsageResetLogs
)
from app.models.admin import AdminCreate, AdminModify, AdminPartialModify
from app.models.node import (NodeCreate, NodeModify, NodeStatus,
NodeUsageResponse)
from app.models.node import NodeCreate, NodeModify, NodeStatus, NodeUsageResponse
from app.models.proxy import ProxyHost as ProxyHostModify
from app.models.user import (ReminderType, UserCreate,
UserDataLimitResetStrategy, UserModify,
UserResponse, UserStatus, UserUsageResponse)
from app.models.user import (
ReminderType,
UserCreate,
UserDataLimitResetStrategy,
UserModify,
UserResponse,
UserStatus,
UserUsageResponse
)
from app.models.user_template import UserTemplateCreate, UserTemplateModify
from app.utils.helpers import (calculate_expiration_days,
calculate_usage_percent)
from app.utils.helpers import calculate_expiration_days, calculate_usage_percent
from app.utils.notification import Notification
from config import (NOTIFY_DAYS_LEFT, NOTIFY_REACHED_USAGE_PERCENT,
USERS_AUTODELETE_DAYS)
from config import NOTIFY_DAYS_LEFT, NOTIFY_REACHED_USAGE_PERCENT, USERS_AUTODELETE_DAYS


def add_default_host(db: Session, inbound: ProxyInbound):
Expand Down Expand Up @@ -139,6 +155,7 @@ def update_hosts(db: Session, inbound_tag: str, modified_hosts: List[ProxyHostMo
is_disabled=host.is_disabled,
mux_enable=host.mux_enable,
fragment_setting=host.fragment_setting,
noise_setting=host.noise_setting,
random_user_agent=host.random_user_agent,
) for host in modified_hosts
]
Expand Down
28 changes: 28 additions & 0 deletions app/db/migrations/versions/a9cfd5611a82_add_noise_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""add noise settings

Revision ID: a9cfd5611a82
Revises: 2313cdc30da3
Create Date: 2024-09-04 18:55:55.167589

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'a9cfd5611a82'
down_revision = '2313cdc30da3'
branch_labels = None
depends_on = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('hosts', sa.Column('noise_setting', sa.String(), nullable=True))
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('hosts', 'noise_setting')
# ### end Alembic commands ###
1 change: 1 addition & 0 deletions app/db/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ class ProxyHost(Base):
is_disabled = Column(Boolean, nullable=True, default=False)
mux_enable = Column(Boolean, nullable=False, default=False, server_default='0')
fragment_setting = Column(String(100), nullable=True)
noise_setting = Column(String(), nullable=True)
random_user_agent = Column(Boolean, nullable=False, default=False, server_default='0')


Expand Down
14 changes: 13 additions & 1 deletion app/models/proxy.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import json
import re
from enum import Enum
from typing import Optional, Union
from uuid import UUID, uuid4
import re

from pydantic import BaseModel, Field, validator

Expand All @@ -18,6 +18,9 @@

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)$')

NOISE_PATTERN = re.compile(
r'^(rand:(\d{1,4}-\d{1,4}|\d{1,4})|str:.+|base64:.+)(,(\d{1,4}-\d{1,4}|\d{1,4}))?(&(rand:(\d{1,4}-\d{1,4}|\d{1,4})|str:.+|base64:.+)(,(\d{1,4}-\d{1,4}|\d{1,4}))?)*$')


class ProxyTypes(str, Enum):
# proxy_type = protocol
Expand Down Expand Up @@ -149,6 +152,7 @@ class ProxyHost(BaseModel):
is_disabled: Union[bool, None] = None
mux_enable: Union[bool, None] = None
fragment_setting: Optional[str] = Field(None, nullable=True)
noise_setting: Optional[str] = Field(None, nullable=True)
random_user_agent: Union[bool, None] = None

class Config:
Expand Down Expand Up @@ -180,6 +184,14 @@ def validate_fragment(cls, v):
)
return v

@validator("noise_setting", check_fields=False)
def validate_noise(cls, v):
if v and not NOISE_PATTERN.match(v):
raise ValueError(
"Noise setting must be like this: packet,delay (rand:10-20,100-200)."
)
return v


class ProxyInbound(BaseModel):
tag: str
Expand Down
6 changes: 3 additions & 3 deletions app/subscription/clash.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def make_node(self,

if type == 'shadowsocks':
type = 'ss'
if network == 'tcp' and headers == 'http':
if network in ('tcp', 'raw') and headers == 'http':
network = 'http'
if network == 'httpupgrade':
network = 'ws'
Expand Down Expand Up @@ -233,7 +233,7 @@ def make_node(self,
elif network == 'h2':
net_opts = self.h2_config(path=path, host=host)

elif network == 'tcp':
elif network in ('tcp', 'raw'):
net_opts = self.tcp_config(path=path, host=host)

else:
Expand Down Expand Up @@ -369,7 +369,7 @@ def add(self, remark: str, address: str, inbound: dict, settings: dict):
elif inbound['protocol'] == 'vless':
node['uuid'] = settings['id']

if inbound['network'] in ('tcp', 'kcp') and inbound['header_type'] != 'http' and inbound['tls'] != 'none':
if inbound['network'] in ('tcp', 'raw', 'kcp') and inbound['header_type'] != 'http' and inbound['tls'] != 'none':
node['flow'] = settings.get('flow', '')

elif inbound['protocol'] == 'trojan':
Expand Down
11 changes: 8 additions & 3 deletions app/subscription/share.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@
if TYPE_CHECKING:
from app.models.user import UserResponse

from config import (ACTIVE_STATUS_TEXT, DISABLED_STATUS_TEXT,
EXPIRED_STATUS_TEXT, LIMITED_STATUS_TEXT,
ONHOLD_STATUS_TEXT)
from config import (
ACTIVE_STATUS_TEXT,
DISABLED_STATUS_TEXT,
EXPIRED_STATUS_TEXT,
LIMITED_STATUS_TEXT,
ONHOLD_STATUS_TEXT
)

SERVER_IP = get_public_ip()
SERVER_IPV6 = get_public_ipv6()
Expand Down Expand Up @@ -298,6 +302,7 @@ def process_inbounds_and_tags(
or inbound.get("allowinsecure", ""),
"mux_enable": host["mux_enable"],
"fragment_setting": host["fragment_setting"],
"noise_setting": host["noise_setting"],
"random_user_agent": host["random_user_agent"],
}
)
Expand Down
Loading