Skip to content

بروتوكول VLESS

VLESS هو بروتوكول وكيل خفيف يستخدم مصادقة قائمة على UUID. يفوض sing-box تنسيق بيانات VLESS إلى مكتبة sing-vmess/vless.

المصدر: protocol/vless/، sing-vmess/vless/

بنية الوارد (Inbound)

go
type Inbound struct {
    inbound.Adapter
    ctx       context.Context
    router    adapter.ConnectionRouterEx
    logger    logger.ContextLogger
    listener  *listener.Listener
    users     []option.VLESSUser
    service   *vless.Service[int]     // خدمة VLESS من sing-vmess
    tlsConfig tls.ServerConfig
    transport adapter.V2RayServerTransport
}

البناء

go
func NewInbound(ctx, router, logger, tag, options) (adapter.Inbound, error) {
    // 1. إنشاء غلاف موجه UoT (معالجة UDP-over-TCP)
    inbound.router = uot.NewRouter(router, logger)

    // 2. إنشاء غلاف موجه mux (معالجة تعدد الإرسال)
    inbound.router = mux.NewRouterWithOptions(inbound.router, logger, options.Multiplex)

    // 3. إنشاء خدمة VLESS مع قائمة المستخدمين
    service := vless.NewService[int](logger, adapter.NewUpstreamContextHandlerEx(
        inbound.newConnectionEx,        // معالج TCP
        inbound.newPacketConnectionEx,   // معالج UDP
    ))
    service.UpdateUsers(indices, uuids, flows)

    // 4. تكوين TLS (اختياري)
    inbound.tlsConfig = tls.NewServerWithOptions(...)
    // متوافق مع kTLS فقط عندما: لا يوجد نقل، لا يوجد mux، لا يوجد تدفق (Vision)

    // 5. نقل V2Ray (اختياري: WS، gRPC، HTTP، إلخ)
    inbound.transport = v2ray.NewServerTransport(ctx, ..., inbound.tlsConfig, handler)

    // 6. مستمع TCP
    inbound.listener = listener.New(...)
}

تدفق الاتصال

اتصال TCP → [مصافحة TLS] → VLESS Service.NewConnection()

                                   فك تشفير رأس VLESS
                                   مصادقة UUID
                                   استخراج الوجهة

                                   newConnectionEx() / newPacketConnectionEx()

                                   تعيين البيانات الوصفية (Inbound، User)

                                   router.RouteConnectionEx()

عند تكوين نقل V2Ray:

اتصال TCP → Transport.Serve() → معالج النقل → [TLS تمت معالجته مسبقاً] → خدمة VLESS

توافق kTLS

يتم تفعيل kTLS (TLS على مستوى النواة) عندما:

  • لا يوجد نقل V2Ray (TCP خام + TLS)
  • لا يوجد تعدد إرسال
  • لا يوجد تدفق Vision (جميع المستخدمين لديهم تدفق فارغ)

هذا يسمح للنواة بمعالجة تشفير TLS لأداء أفضل.

بنية الصادر (Outbound)

go
type Outbound struct {
    outbound.Adapter
    logger          logger.ContextLogger
    dialer          N.Dialer
    client          *vless.Client        // عميل VLESS من sing-vmess
    serverAddr      M.Socksaddr
    multiplexDialer *mux.Client
    tlsConfig       tls.Config
    tlsDialer       tls.Dialer
    transport       adapter.V2RayClientTransport
    packetAddr      bool     // استخدام ترميز packetaddr
    xudp            bool     // استخدام ترميز XUDP (افتراضي)
}

تدفق الاتصال

go
func (h *vlessDialer) DialContext(ctx, network, destination) (net.Conn, error) {
    // 1. إنشاء اتصال النقل
    if h.transport != nil {
        conn = h.transport.DialContext(ctx)
    } else if h.tlsDialer != nil {
        conn = h.tlsDialer.DialTLSContext(ctx, h.serverAddr)
    } else {
        conn = h.dialer.DialContext(ctx, "tcp", h.serverAddr)
    }

    // 2. مصافحة البروتوكول
    switch network {
    case "tcp":
        return h.client.DialEarlyConn(conn, destination)
    case "udp":
        if h.xudp {
            return h.client.DialEarlyXUDPPacketConn(conn, destination)
        } else if h.packetAddr {
            packetConn = h.client.DialEarlyPacketConn(conn, packetaddr.SeqPacketMagicAddress)
            return packetaddr.NewConn(packetConn, destination)
        } else {
            return h.client.DialEarlyPacketConn(conn, destination)
        }
    }
}

البيانات المبكرة (Early Data)

تؤجل DialEarlyConn مصافحة VLESS حتى أول عملية كتابة. يتم إرسال رأس VLESS مع أول حزمة بيانات، مما يقلل عدد الرحلات ذهاباً وإياباً.

تعدد الإرسال (Multiplex)

عند تفعيل تعدد الإرسال:

go
outbound.multiplexDialer = mux.NewClientWithOptions((*vlessDialer)(outbound), logger, options.Multiplex)

يغلف عميل mux متصل VLESS. تتشارك اتصالات منطقية متعددة في اتصال VLESS واحد.

ترميز حزم UDP

يدعم VLESS ثلاثة أوضاع لترميز UDP:

XUDP (افتراضي)

عنونة لكل حزمة -- كل حزمة UDP تحمل عنوان وجهتها الخاص. يتيح NAT من نوع Full-Cone.

go
h.client.DialEarlyXUDPPacketConn(conn, destination)

PacketAddr

مشابه لـ XUDP لكن يستخدم تنسيق بيانات مختلف (packetaddr.SeqPacketMagicAddress).

القديم (Legacy)

ترميز حزم VLESS بسيط -- جميع الحزم تذهب إلى نفس الوجهة.

go
h.client.DialEarlyPacketConn(conn, destination)

التكوين

json
{
  "inbounds": [{
    "type": "vless",
    "listen": ":443",
    "users": [
      { "uuid": "...", "name": "user1", "flow": "" }
    ],
    "tls": { ... },
    "transport": { "type": "ws", "path": "/vless" },
    "multiplex": { "enabled": true }
  }],
  "outbounds": [{
    "type": "vless",
    "server": "example.com",
    "server_port": 443,
    "uuid": "...",
    "flow": "",
    "packet_encoding": "xudp",
    "tls": { ... },
    "transport": { "type": "ws", "path": "/vless" },
    "multiplex": { "enabled": true }
  }]
}

الاختلافات الرئيسية عن VLESS في Xray-core

الجانبXray-coresing-box
Vision/XTLSدعم كامل (unsafe.Pointer)غير مدعوم
تنسيق البياناتتشفير مدمجمكتبة sing-vmess/vless
Fallbackمدمج (name←ALPN←path)غير مدعوم (استخدم مستمعاً منفصلاً)
XUDPمدمج مع GlobalIDXUDP من sing-vmess
Muxإطارات mux مدمجةsing-mux (قائم على smux)
تدفق البياناتPipe Reader/Writerتمرير net.Conn
الاتصال المسبقمجمع اتصالاتغير مدمج

تنسيق البيانات (من sing-vmess)

رأس الطلب

[1B Version=0x00]
[16B UUID]
[1B Addons length (N)]
[NB Addons protobuf]
[1B Command: 0x01=TCP, 0x02=UDP, 0x03=Mux]
[Address: Port(2B) + Type(1B) + Addr(var)]

رأس الاستجابة

[1B Version=0x00]
[1B Addons length]
[NB Addons]

تنسيق البيانات متوافق مع VLESS في Xray-core.