Skip to content

Protocols and Transports.fa

Iman edited this page Sep 6, 2026 · 3 revisions

پروتکل‌ها و ترابری‌ها

ویکی کاسپین

این راهنما از README موجود منتقل شده است. تاریخ اندازه‌گیری‌ها همان تاریخ اصلی است؛ این جابه‌جایی گزارش اجرای تازهٔ آزمون‌ها نیست. English | فارسی | Русский | 中文

چه چیزی را می‌توانید پیست کنید و چه چیزی رد می‌شود

کانفیگ را خودتان می‌آورید. این چیزی است که جعبه می‌پذیرد، برداشته‌شده از همان کدی که کارِ پذیرفتن را می‌کند و نه از یک فهرستِ آرزو. هر سطر در برابر internal/link و موتورِ پین‌شده اندازه‌گیری شده است.

کار می‌کند رد می‌شود
لینک‌های اشتراک vless:// vmess:// ss:// socks:// trojan:// hysteria2:// hy2:// tuic:// ssr:// wireguard:// anytls:// naive+https:// hysteria:// (نسخهٔ ۱)
سندهای پیست‌شده YAML مربوط به Clash و Clash.Meta، xray JSON خام، فهرستی از لینک‌ها هر کدام در یک خط، یک بلوکِ base64 اشتراک نشانیِ اینترنتیِ اشتراک، سندِ Clash پیچیده‌شده در base64، آرایهٔ JSON، متنی که خطِ اولش کامنت باشد
ترابری‌ها raw (که tcp هم نوشته می‌شود)، ws، grpc، httpupgrade، xhttpsplithttpkcp و mkcp h2، h3، http، quic، gun
امنیت none، tls، reality xtls (نوعِ قدیمی)، allowInsecure
flow در VLESS xtls-rprx-vision، xtls-rprx-vision-udp443، یا هیچ هر مقدارِ دیگری

h2 و h3 در آن ستونِ ردشده نامِ ترابری‌اند. خودِ HTTP/2 و HTTP/3 حمل می‌شوند: type=xhttp با security=tls، و ALPN در TLS تعیین می‌کند کدام‌یک. بخشِ HTTP/2 و HTTP/3 حمل می‌شوند، با نامی دیگر را ببینید.

شش چیز مردم را غافلگیر می‌کند، پس اینجا آمده‌اند و نه در پانویس:

فقط لینکِ اول به کار می‌رود. چهل سرور را پیست کنید، یکی پیکربندی می‌شود؛ پنل به شما می‌گوید چند تا پیدا کرده است. ss:// و socks:// به شکلِ base64 از اطلاعاتِ کاربر نیاز دارند و املای سادهٔ method:password@host رد می‌شود. REALITY فقط روی raw و xhttp و grpc کار می‌کند، پس جفت‌کردنش با WebSocket همان لحظهٔ پیست توسط موتور رد می‌شود و نه بعداً سرِ اتصال. security= اینجا باید با حروفِ کوچک نوشته شود، هرچند خودِ موتور اهمیتی نمی‌دهد، و TLS با حروفِ بزرگ به شما none گزارش می‌شود. پارامترِ plugin= روی لینکِ ss:// بدون گفتنِ چیزی نادیده گرفته می‌شود. و نشانیِ اینترنتیِ اشتراک رد می‌شود چون پنل هیچ چیزی از اینترنت نمی‌گیرد، که یک ویژگیِ عمدی است و نه قابلیتی که جا مانده باشد.

تصویرِ کامل، از جمله اینکه کدام‌یک از این‌ها بایتِ واقعی حمل کرده‌اند و کدام‌یک روی سخت‌افزار با ثبتِ آدرسِ خروجی سرتاسری اثبات شده‌اند، در بخشِ پروتکل‌ها و ترابری‌ها آمده است. این‌ها سه ادعای متفاوت‌اند و این پروژه نمی‌گذارد در هم بروند.

پروتکل‌ها و ترابری‌ها

یک لینک اشتراک‌گذاری سه چیزِ جدا را حمل می‌کند، و جدا نگه داشتنشان کمک می‌کند: پروتکلِ پروکسی، ترابری‌ای (transport) که آن را حمل می‌کند، و لایهٔ رمزنگاری‌ای که دور آن ترابری پیچیده می‌شود. یک لینک VLESS روی WebSocket با TLS و یک لینک VLESS روی TCP ساده با REALITY، یک پروتکل واحدند که از دو راهِ متفاوت به یک نوع سرور می‌رسند. آن دو به شکل‌های متفاوتی شکست می‌خورند.

پروتکل‌های پروکسی همان هفت اسکیمی هستند که بالاتر آمد. بیشترِ مثال‌های این سند از VLESS استفاده می‌کنند، چون REALITY برای همان ساخته شده است. هیچ چیزِ این دستگاه مخصوص آن نیست. تجزیه‌کننده یک توصیف می‌سازد، internal/xcfg دورِ آن یک سندِ نرم‌افزار اتصال می‌چیند، و باقیِ دستگاه نمی‌داند دارد کدام پروتکل را حمل می‌کند.

ترابری‌ها از xray-core می‌آیند و در تجزیه‌کنندهٔ همراه‌شده نام برده شده‌اند:

  • tcp، که raw هم نوشته می‌شود
  • ws، برای WebSocket
  • httpupgrade
  • xhttp، پروتکلی که پیش‌تر SplitHTTP نام داشت. هر دو املا تجزیه می‌شوند
  • grpc
  • kcp و mkcp، برای mKCP

h2 و http و h3 و quic در این فهرست نیستند و لینکی که یکی از آن‌ها را بخواهد رد می‌شود، نه اینکه حمل شود. این‌ها در نسخه‌ای از موتور که اینجا پین شده حذف شده‌اند، و TestRemovedTransportsAreRefusedWithASentence در internal/link همان ردکردن را سرِ جایش نگه می‌دارد.

اینکه این ردکردن چقدر خوب خوانده می‌شود به مسیرِ ورود بستگی دارد. سندِ Clash که یکی از این‌ها را نام ببرد، جمله‌ای دربارهٔ ترابری می‌گیرد. همان ترابری در پارامترِ type= روی یک لینکِ اشتراک از تجزیه‌کنندهٔ همراه‌شده رد می‌شود و به شکلِ پیام کلیِ «چیزی در متنِ پیست‌شده لینکِ پروکسی‌ای نبود که این دستگاه بفهمد» بیرون می‌آید، که درست است و کمکی نمی‌کند. TestRemovedTransportInAURIIsReportedLessWell همین تفاوت را پین می‌کند تا یک شکافِ شناخته‌شده باشد نه یک غافلگیری.

HTTP/2 و HTTP/3 حمل می‌شوند، با نامی دیگر

اینکه type=h2 یا type=quic رد می‌شود به این معنا نیست که دستگاه نمی‌تواند آن‌ها را حرف بزند. یعنی املایش جابه‌جا شده است. XHTTP جای هر دو را گرفته و نسخهٔ HTTP خود را از ALPN در TLS انتخاب می‌کند، نه از نامِ ترابری:

چه می‌خواهید چه بنویسید
HTTP/3، که همان QUIC است type=xhttp با security=tls و alpn=h3 و mode=stream-one
HTTP/2 type=xhttp با security=tls و هر ALPN‌ای که دقیقاً h3 نباشد
QUIC بدونِ XHTTP یک لینکِ hysteria2:// که زیرش QUIC است و به alpn=h3 نیاز دارد

این کلیدها دست‌نخورده به موتور می‌رسند: internal/xcfg خروجی را به‌شکلِ JSON مبهم حمل می‌کند و هرگز بازش نمی‌کند، پس alpn و mode و xmux و بلوکِ تنظیمِ QUIC دقیقاً همان‌طور که پیست شده‌اند می‌رسند.

چهار نکته تعیین می‌کند که h3 بگیرید یا بی‌صدا چیزِ دیگری:

alpn باید دقیقاً یک مقدار باشد و آن مقدار باید h3 باشد. نوشتنِ alpn=h3,h2 بدونِ هیچ هشداری به شما HTTP/2 می‌دهد، چون موتور فهرستی با هر طولِ دیگری را درخواستِ نسخهٔ ۲ می‌گیرد. REALITY هر جا حاضر باشد HTTP/2 را تحمیل می‌کند، پس REALITY و h3 با هم جمع نمی‌شوند و جفت‌کردنشان به‌جای خطا به شما h2 می‌دهد. mode باید صریح نوشته شود، چون حالتِ پیش‌فرض به packet-up می‌رسد و نه به شکلِ stream-one که موتور آن را جانشینِ QUIC نام می‌برد. و downloadSettings، برای جداکردنِ مسیرِ بالا و پایین، همراهِ mode: stream-one رد می‌شود؛ آن ترکیب به stream-up نیاز دارد.

یک برخوردِ واژگانی هست که بهتر است صریح گفته شود، چون شبیهِ تناقض خوانده می‌شود: type=h3 رد می‌شود و alpn=h3 لازم است. این‌ها دو فیلدِ متفاوت‌اند. اولی نامِ ترابری‌ای است که دیگر وجود ندارد؛ دومی نامِ پروتکلی است که داخلِ TLS مذاکره می‌شود.

این پیکربندی‌ها را دستگاه می‌پذیرد و اعتبارسنجی می‌کند. هنوز از اینجا در برابرِ یک سرورِ واقعی رانده نشده‌اند، پس این سطر را توانِ موتور بدانید و نه چیزی که این پروژه دیدنش کرده باشد.

لایهٔ امنیت یکی از reality، tls، یا none است.

هر ترکیبی به یک اندازه مفید نیست. REALITY معمولاً با TCP ساده جفت می‌شود، چون کلِ روشش قرض گرفتنِ دست‌دادنِ TLS یک سایتِ واقعی است، پس پیچیدنش در یک لایهٔ TLS دیگر هدف را از بین می‌برد. WebSocket و HTTPUpgrade و XHTTP برای این هستند که در چشمِ چیزی که اتصال را بازرسی می‌کند شبیه ترافیک وبِ معمولی باشند، و معمولاً به همان دلیلی که یک وب‌سایت معمولی TLS دارد، با TLS جفت می‌شوند. WebSocket با security=none تنها شکلی است که باید دو بار به آن فکر کرد. روی سیم متنِ آشکار است، و فقط وقتی معقول است که چیز دیگری از پیش رمزنگاری را فراهم کرده باشد، مثل یک CDN که TLS را جلوی سرور خاتمه می‌دهد.

سه ادعای متفاوت، جدا از هم

تفکیکِ زیر مهم‌ترین چیز در این سند است. پیش از سطرها، عنوانِ ستون‌ها را بخوانید.

ادعا بر چه تکیه دارد چقدر می‌ارزد
تجزیه‌کننده آن را می‌پذیرد internal/link، و یک سندِ golden کامیت‌شدهٔ نرم‌افزار اتصال سند پایدار است. چیزی شماره‌گیری نشده
بایت حمل می‌کند test/tunnel، یک سرور واقعیِ xray-core روی loopback ترافیک از دلِ پروتکل عبور کرد. نه آدرس خروجی، نه دستگاه، نه اینترنت
سرتاسر اثبات شده است test/hardware، یک گوشیِ واقعی روی هات‌اسپات ترافیک واقعی از دستگاه بیرون رفت و آدرسِ خروجی گرفته و نام‌گذاری شد

چه چیزی از دلِ یک سرورِ واقعی بایت حمل کرده است

test/tunnel این را اضافه کرد. هر اسکیمی که تجزیه‌کننده می‌پذیرد، سرتاسر در برابر یک نمونهٔ واقعیِ xray-core رانده می‌شود که از وابستگیِ خودِ همین ماژول ساخته شده و با همان بارگذارنده‌ای بار می‌شود که internal/engine استفاده می‌کند. سمتِ کلاینت همان مسیرِ محصول است، بدون تغییر: link.Parse، بعد xcfg.Build، بعد engine.Engine.Start. هیچ کانفیگی دستی نوشته نمی‌شود.

پروتکل ترابری امنیت یک درخواست HTTP را حمل می‌کند
VLESS tcp (raw) none بله
VMess tcp (raw) none بله
Shadowsocks، aes-256-gcm tcp (raw) none بله
SOCKS tcp (raw) none بله
Trojan tcp (raw) TLS، سنجاق‌شده با digest بله
Hysteria2، و نام مستعارِ hy2 QUIC TLS، سنجاق‌شده با digest بله

چهار کنترل جلوی قبول شدنِ درخواستی را که از تونل رد نشده می‌گیرند، و هر چهار تا اجرا می‌شوند نه اینکه در متن ادعا شوند. به کلاینت هرگز گفته نمی‌شود مبدأ کجاست؛ به او یک نامِ .invalid و پورتِ یک طعمه داده می‌شود. آن نام قابل ترجمه نیست، و اگر resolver ای روی دستگاه با این حال جوابش را بدهد، مجموعهٔ آزمون بلند می‌گویدش. مبدأ بررسی می‌کند درخواست به کجا خطاب شده بود، نه فقط اینکه رسیده است. طعمه ضربه‌های خودش را می‌شمارد، و یک درخواستِ تونل‌شده نباید حتی یکی به آن اضافه کند. TestEveryCarriageProofCanFail و TestTheProofRejectsARequestThatDidNotGoThroughTheTunnel همان‌هایی هستند که این کنترل‌ها را از قصد به شاهد تبدیل می‌کنند.

هر سطر را تنگ بخوانید. هر سطر جز Hysteria2 روی TCP خام اجرا می‌شود. هیچ سطری REALITY را نمی‌راند، چون سمتِ سرورِ آن به یک هدفِ دست‌دادنِ واقعی نیاز دارد. Shadowsocks فقط aes-256-gcm است، چون رمزهای 2022 مسیرِ کدِ دیگری دارند. هر سطر یک درخواست TCP حمل می‌کند و UDP associate خاموش است. همه چیز روی loopback است، پس هیچ آدرسِ خروجی‌ای گرفته نمی‌شود و نمی‌تواند گرفته شود.

TestEveryProtocolTheParserAcceptsIsDrivenEndToEnd فهرستِ اسکیم‌های پذیرفته‌شده را از کدِ internal/link می‌خواند، پس اسکیمِ هشتم بدون یک سطر در اینجا اضافه نمی‌شود.

واقعاً چه چیزی روی سخت‌افزار اثبات شده است

جدول زیر چیزی است که ترافیکِ واقعی از آن عبور کرده و آدرسِ خروجی‌اش گرفته شده. این نه آن چیزی است که تجزیه‌کننده می‌پذیرد، و نه آن چیزی که مجموعهٔ آزمونِ loopback حمل می‌کند.

پروتکل ترابری امنیت سرتاسر اثبات شده
VLESS tcp (raw) REALITY بله، روی سه سرور جداگانه
VLESS ws (WebSocket) none، به‌علاوهٔ VLESS Encryption بله
VLESS ws (WebSocket) TLS بله، از راه یک CDN
VLESS httpupgrade TLS بله، از راه یک CDN
VLESS xhttp TLS بله
VMess، Trojan، Shadowsocks، SOCKS، Hysteria2 هر کدام هر کدام نه

هر کدام از این‌ها با راندنِ یک مرورگر واقعی روی یک گوشیِ واقعیِ وصل به هات‌اسپات اثبات شده است. آدرسِ خروجی از دو منبعِ مستقل گرفته و با سروری که پیکربندی نام می‌برد تطبیق داده شد. سه سرور متفاوت به کار رفت و هر کدام آدرس متفاوتی برگرداند، پس خواندنی که تکراری یا از حافظهٔ نهان باشد را نمی‌شود با تونلِ سالم اشتباه گرفت.

سطری که اثبات نشده، ادعای خراب بودن نیست. ادعای این است که هیچ‌کس ندیده بسته‌ای از سرِ دیگر بیرون بیاید، که چیزِ دیگری است و تنها چیزی است که این پروژه شاهد می‌داند. سندِ نرم‌افزار اتصالی که هر ترابری تولید می‌کند به‌عنوان یک فایل golden سنجاق شده است، پس تغییر در نحوهٔ ساخته شدنش به شکل یک diff دیده می‌شود. این ثابت می‌کند سند پایدار است و دربارهٔ اینکه ترابری وصل می‌شود یا نه چیزی نمی‌گوید.

چرا سطری که ترابری‌اش امنیت ندارد باز هم رمزنگاری‌شده است

ستون security در بالا دربارهٔ لایه‌ای است که دورِ ترابری پیچیده می‌شود، و none در آنجا به معنی «بدون رمزنگاری» نیست. یعنی نه TLS و نه REALITY. دقت در این مورد می‌ارزد، چون خواندنش به شکل دیگر نگران‌کننده است و خواندنش با سخاوتِ بیش از حد بدتر.

VLESS به‌تنهایی هیچ رمزنگاری‌ای حمل نمی‌کند. پروتکلی بی‌حالت است که انتظار دارد لایهٔ زیرینش محرمانگی را فراهم کند، که معمولاً REALITY یا TLS است. یک لینک VLESS روی WebSocket با security=none و هیچ چیزِ دیگر، روی سیم متنِ آشکار می‌بود، و آدرسِ خروجی اثبات می‌شد در حالی که هر بسته برای هر چیزی که روی مسیر بود خواندنی بود.

آنچه آن سطر را امن می‌کند VLESS Encryption است، که در پارامترِ encryption= لینک حمل می‌شود. این یک تبادلِ کلیدِ ترکیبی است، ML-KEM-768 برای مقاومتِ پساکوانتومی همراه با X25519، که در خودِ لایهٔ VLESS اعمال می‌شود نه زیرِ آن. پس ترافیک رمزنگاری‌شده است، و چیزی آن را رمز کرده که ساخته شده تا در برابرِ مهاجمی که امروز ضبط می‌کند و بعداً کامپیوترِ کوانتومی دارد امن بماند. لینکی که هم encryption=none و هم security=none دارد، هیچ‌کدام را ندارد، و همین ترکیب است که باید رد شود.

این همان Noise Protocol Framework (noiseprotocol.org) نیست. نه در این دستگاه، نه در تجزیه‌کنندهٔ همراه‌شدهٔ لینک، و نه در نرم‌افزار اتصال، هیچ چیز Noise را پیاده نمی‌کند. واژهٔ "noise" در پیکربندیِ xray-core برای چیزِ دیگری می‌آید، یعنی پر کردنِ ترافیک با بایت‌های تصادفی تا شکلش روی سیم عوض شود، که مبهم‌سازی است و دست‌دادن نیست. آنچه به این سطر محرمانگی می‌دهد VLESS Encryption است، و نام اهمیت دارد چون آن دو تضمین‌های متفاوتی می‌دهند.

اندازه‌گیری شده، نه فرض‌شده، در 2026-08-30. این بسته outbound را فیلد به فیلد بازنمی‌سازد. آنچه را تجزیه‌کننده تولید کرده دوباره سریال می‌کند، و تنظیماتِ پروتکل به شکلِ یک بلوکِ مبهم همراهش می‌آیند. به همین دلیل است که آن پارامتر زنده می‌ماند. و به همین دلیل هم هست که اگر روزی زنده نماند هیچ چیز نمی‌شکند: هیچ فیلدی گم نمی‌شود، هیچ نوعی عوض نمی‌شود، و هیچ آزمون دیگری متوجه نمی‌شود، در حالی که تونل ترافیکِ کاربر را آشکار حمل می‌کند و همهٔ بررسی‌ها هنوز سبزند. TestVLESSEncryptionSurvivesIntoTheEngineDocument در internal/link همان نگهبان است، و پیش از آنکه نگه داشته شود، دیده شد که دقیقاً در برابرِ همان تنزلِ بی‌سروصدا شکست می‌خورد.

نامِ گواهی‌ای که نخواند، و اصلاحی که سمتِ کلاینت است

یک نتیجه ثبت کردن دارد، چون ایرادی است که این دستگاه به‌درستی حاضر نمی‌شود رویش سرپوش بگذارد. دو پیکربندی به آدرسِ خودِ سرور اشاره می‌کردند در حالی که نامِ TLS مربوط به CDN جلوی آن را حمل می‌کردند. نرم‌افزار اتصال گزارش داد:

transport/internet/httpupgrade: failed to dial request ...
  tls: failed to verify certificate: x509: certificate is valid for
  <the apex>, not <the cdn subdomain>

این واقعاً گواهی‌ای است که با نامِ درخواست‌شده نمی‌خواند، و رد کردنش همان رفتاری است که می‌خواهید. پذیرفتنش یعنی تونل را هر چیزی که هر گواهی‌ای در دست دارد بتواند خاتمه بدهد.

علت و اصلاح هر دو سمتِ کلاینت هستند، و هیچ تغییری در سرور لازم نیست. یک لینکِ اشتراک‌گذاری دو نام حمل می‌کند که مردم فکر می‌کنند باید یکی باشند و نیستند:

  • sni نامی که TLS گواهی را در برابرِ آن اعتبارسنجی می‌کند
  • host نامی که سرور درخواست را بر اساس آن مسیریابی می‌کند، یک هدر HTTP

لینک‌های ناموفق نامِ CDN را در هر دو حمل می‌کردند. از راه CDN این کار می‌کند، چون CDN گواهیِ آن نام را دارد. وقتی مستقیم به مبدأ اشاره کند نمی‌تواند، چون مبدأ فقط گواهیِ دامنهٔ اصلی را دارد. sni را روی نامی بگذارید که گواهی واقعاً حمل می‌کند، و host را همان نامی بگذارید که سرور بر اساس آن مسیریابی می‌کند:

sni=example.com          host=cdn.example.com

اندازه‌گیری شده در 2026-08-30. دو لینکی که با خطای گواهیِ بالا شکست خورده بودند، بعد از همان یک تغییر هر دو وصل شدند. آدرس‌های خروجی از دو منبعِ مستقل گرفته و با سرورهای خودشان تطبیق داده شد، و در همان اجرا، بررسیِ نشتِ DNS و بررسیِ fail-closed هم قبول شدند.

پس اگر ترابری‌ای فقط وقتی مستقیم به مبدأ اشاره می‌کند شکست می‌خورد، پیش از آنکه به ترابری شک کنید، sni را با نام‌های جایگزینِ موضوعِ گواهیِ مبدأ مقایسه کنید. openssl s_client -connect <address>:443 -servername <name> چاپ می‌کند سرور واقعاً چه ارائه می‌دهد.

پنل لینکِ پیست‌شده می‌گیرد، نه تصویر

انداختنِ یک تصویر QR در طراحی، بخش 5.2، توصیف شده و پیاده نشده است. internal/panel/qr فقط رمزگذار است، و هیچ هندلری در internal/panel بارگذاریِ multipart نمی‌خواند. کدِ QR ای که پنل تولید می‌کند همانی است که گوشی برای وصل شدن به هات‌اسپات اسکن می‌کند. internal/panel/view.go آن را با qr.Encode و qr.WiFiJoin می‌سازد، پس نه کتابخانهٔ تصویری در کار است و نه سرویس راه دور.

English: HTTP/2, HTTP/3 | English | فارسی: HTTP/2, HTTP/3 | فارسی | Русский: HTTP/2, HTTP/3 | Русский | 中文: HTTP/2, HTTP/3 | 中文

Clone this wiki locally