پرش به محتویات

finalmask

همهٔ قابلیت‌های هیدیفای

finalmask ماسک‌های finalmask در Xray-core را روی اتصال‌هایی که یک خروجی باز می‌کند اعمال می‌کند. ماسک بایت‌های روی سیم را تغییر می‌دهد: آن‌ها را تکه‌تکه می‌کند، بستهٔ نویز اضافه می‌کند، هدر می‌افزاید یا آن‌ها را در پروتکلی دیگر (DNS، ICMP، جریانی شبیه Minecraft و…) می‌پیچد. این فیلد finalmask در فیلدهای اتصال (dial) است؛ پس روی هر خروجی که اتصال می‌سازد (و روی سرورهای DNS و جاهای دیگری که فیلدهای اتصال را می‌پذیرند) قابل تنظیم است. JSON آن همان streamSettings.finalmask در Xray است.

چرا از آن استفاده کنیم

  • برای استفاده از سرور Xray که با ماسک‌های finalmask راه‌اندازی شده است: کلاینت باید همان ماسک‌ها را اعمال کند، وگرنه سرور ترافیک را نمی‌فهمد.
  • برای تغییر شکل اتصال روی سیم بدون تغییر پروتکل: تکه‌تکه کردن ClientHello در TLS (fragment)، فرستادن بسته‌های UDP بی‌معنا پیش از دست‌دهی WireGuard یا QUIC (noise)، یا مبهم‌سازی UDP با رمز (salamander).

چطور از فیلترینگ عبور می‌کند

فیلترها روی اولین بایت‌ها و بسته‌های اتصال، اندازه و زمان‌بندی آن‌ها تطبیق می‌دهند و ماسک‌ها دقیقاً همین را تغییر می‌دهند. fragment ClientHello را به تکه‌های کوچک می‌برد تا فیلتری که آن‌ها را سرهم نمی‌کند نتواند SNI را بخواند. noise اول بسته‌های تصادفی می‌فرستد تا جریان با دست‌دهی واقعی شروع نشود. ماسک‌های هدر و پوششی ترافیک را شبیه پروتکلی دیگر، یا شبیه بایت‌های تصادفی، می‌کنند.

ماسک‌هایی که فقط اندازه و زمان را تغییر می‌دهند (fragment، merge، oob، mirage، noise) با هر سروری کار می‌کنند. ماسک‌هایی که محتوا را تغییر می‌دهند (هدرها، salamander، sudoku، xdns، xicmp، xmc، mkcp-legacy، realm) همان ماسک را روی سرور لازم دارند، یعنی سرور Xray که برای آن تنظیم شده باشد. udphop سروری می‌خواهد که روی همهٔ پورت‌هایی که به آن‌ها می‌پرد گوش بدهد. وقتی فیلتر IP سرور را مسدود کرده باشد ماسک کمکی نمی‌کند، جز xdns: از راه resolverهای عمومی DNS به سرور می‌رسد و هرگز به نشانی خود سرور وصل نمی‌شود.

چطور کار می‌کند

  • ماسک‌های tcp هر اتصال TCP خروجی را می‌پوشانند و ماسک‌های udp هر سوکت UDP و اتصال UDP متصل را.
  • ماسک‌ها به ترتیب فهرست اجرا می‌شوند: اولین ماسک بایت‌هایی را که خروجی می‌نویسد می‌گیرد و خروجی آخرین ماسک روی سیم می‌رود. پاسخ‌ها به ترتیب برعکس از آن‌ها می‌گذرند.
  • ماسک‌ها زیر پروتکل و لایهٔ TLS آن قرار دارند، پس دقیقاً همان چیزی را می‌بینند که روی سیم می‌رود. با detour، اتصالی را می‌پوشانند که از طریق خروجی detour ساخته شده است.
  • اتصال، مثل Xray، از درون ماسک‌ها برقرار می‌شود. ماسکی که سوکت‌های خودش را باز می‌کند (xdns به resolverهایش، udphop به هر پورت تازه) آن‌ها را با dialer خروجی باز می‌کند؛ پس همان detour، اینترفیس و routing mark اتصال را می‌گیرند. xdns، xicmp و udphop جای سوکتِ رو به سرور را می‌گیرند و باید آخرین ماسک udp باشند.
  • فقط سمت کلاینت پیاده شده است: ورودی‌ها finalmask نمی‌گیرند.
  • ماسک‌ها همان کد Xray-core هستند (از Xray-core v26.10.31)، جز merge و oob که از Xray-core نسخهٔ patterniha آمده‌اند؛ رفتار و تنظیمات آن‌ها از مستندات finalmask در Xray پیروی می‌کند. ماسک filter در Xray که فقط برای ورودی است در دسترس نیست.

پیکربندی

یک خروجی VLESS که ClientHello آن تکه‌تکه می‌شود، و یک endpoint از نوع WireGuard که پیش از هر دست‌دهی نویز می‌فرستد:

{
  "outbounds": [
    {
      "type": "vless",
      "server": "example.com",
      "server_port": 443,
      "uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
      "tls": { "enabled": true, "server_name": "example.com" },
      "finalmask": {
        "tcp": [
          { "type": "fragment", "settings": { "packets": "tlshello", "length": "100-200", "delay": "10-20" } }
        ]
      }
    }
  ],
  "endpoints": [
    {
      "type": "wireguard",
      "tag": "wg",
      "address": ["10.0.0.2/32"],
      "private_key": "...",
      "peers": [{ "address": "203.0.113.1", "port": 51820, "public_key": "...", "allowed_ips": ["0.0.0.0/0"] }],
      "finalmask": {
        "udp": [
          { "type": "noise", "settings": { "noise": [{ "rand": "10-50", "delay": "5-10" }] } }
        ]
      }
    }
  ]
}
فیلد نوع پیش‌فرض معنا
finalmask.tcp array — ماسک‌های اتصال‌های TCP، به ترتیب.
finalmask.udp array — ماسک‌های UDP، به ترتیب.
finalmask.quicParams object — پذیرفته می‌شود تا کانفیگ‌های Xray بارگذاری شوند؛ استفاده نمی‌شود. پروتکل‌های QUIC در sing-box گزینه‌های خودشان را دارند.
…[].type string — نوع ماسک (پایین را ببینید). حروف کوچک و بزرگ فرقی ندارد.
…[].settings object {} تنظیمات ماسک، دقیقاً مثل Xray.

نوع‌های پشتیبانی‌شده:

نوع tcp udp کار تنظیمات اصلی
fragment بله — اولین نوشتن‌ها (یا ClientHello در TLS) را با تأخیر به تکه‌های کوچک می‌برد. پایین را ببینید
mirage بله — ClientHello در TLS را به دو رکورد TLS می‌شکند و آن‌ها را جداگانه یا در یک نوشتن می‌فرستد تا فیلتر نتواند نام سرور را تطبیق دهد. کتابخانهٔ Mirage ساختهٔ PoriyaVali. offset، layout
header-custom بله بله بایت‌های دلخواهی که سرور انتظار دارد (هدر پروتکل جعلی) اضافه می‌کند. TCP: clients، servers، errors؛ UDP: mode، client، server
sudoku بله بله مبهم‌سازی Sudoku با کلید رمز. password، ascii، customTable، customTables، paddingMin، paddingMax
merge بله — نوشتن‌های پشت سر هم را نگه می‌دارد و یک‌جا می‌فرستد، برای اولین نوشتن‌های اتصال. از Xray-core نسخهٔ patterniha. پایین را ببینید
oob بله — هر یک از اولین نوشتن‌ها را با یک بایت اضافه به‌صورت دادهٔ فوری (out-of-band) TCP می‌فرستد که سرور آن را کنار می‌گذارد و فیلتر ممکن است اشتباه بخواند. همان dialMode با شکل oob.<bytes> در Xray (نسخهٔ patterniha). پایین را ببینید
xmc بله — جریان را شبیه اتصال Minecraft می‌کند. hostname، profiles، password
noise — بله پیش از بسته‌های واقعی، بسته‌های تصادفی یا ثابت می‌فرستد؛ بستهٔ با type برابر exp از یک عبارت ساخته می‌شود. noise (فهرستی از rand، randRange، type، packet، delay)، reset، script
salamander — بله مبهم‌سازی Salamander در Hysteria2؛ با packetSize گونهٔ Gecko که اندازهٔ بسته‌ها را هم تغییر می‌دهد. password، packetSize (حداکثر ۲۰۴۸)
mkcp-legacy — بله هدرهای قدیمی بسته‌های mKCP (dns، dtls، srtp، utp، wechat، wireguard) یا لایهٔ AES-GCM آن. header، value
xdns — بله UDP را در درخواست‌های DNS به دامنهٔ سرور حمل می‌کند، از راه resolverهای DNS روی UDP، TCP یا DoH. پایین را ببینید
xicmp — بله UDP را در بسته‌های ICMP echo حمل می‌کند. ips، dgram
realm — بله از راه NAT hole punching با سرورهای STUN و یک نشانی rendezvous به طرف مقابل وصل می‌شود. url (realm:// یا realm+http://)، stunServers، tlsConfig
udphop — بله پرش پورت: جریان UDP را هر چند ثانیه، یا برای هر اتصال، به پورت دیگری از سرور و سوکت محلی دیگری می‌برد. پایین را ببینید

نوع ناشناخته، نوعی که فقط TCP است در udp (یا برعکس)، یا تنظیمات نادرست، خطای پیکربندی می‌دهد که نام ماسک را می‌گوید، مثل finalmask.tcp[0] fragment.

تنظیمات fragment:

فیلد نوع پیش‌فرض معنا
packets string — tlshello ClientHello را در TLS تکه می‌کند؛ بازه‌ای مثل "1-3" همان نوشتن‌های اتصال را تکه می‌کند.
length range — اندازهٔ هر تکه به بایت.
delay range 0 مکث میان تکه‌ها به میلی‌ثانیه.
lengths range list — یک طول برای هر تکه، به جای length.
delays range list — یک تأخیر برای هر تکه، به جای delay.
maxSplit range — بیشترین تعداد تکه‌ها.

بازه به شکل "from-to" یا یک عدد است؛ فهرست بازه آرایه‌ای از آن‌ها، یا تنها یکی است.

noise با "type": "exp"، packet را عبارتی از تکه‌ها می‌گیرد: <b 0x1700> بایت‌های ثابت به هگز، <r 10-20> بایت‌های تصادفی، <rc 8> حروف تصادفی، <rd 4> رقم‌های تصادفی، <t> مُهر زمان، <c> شمارنده و <n> یک nonce. script مسیر یک فایل محلی .lua است که به جای noise بسته‌ها را می‌سازد (Xray فعلاً اسکریپت درون‌خطی را خاموش کرده است).

تنظیمات xdns برای کلاینت:

فیلد نوع پیش‌فرض معنا
domains[].names فهرست رشته — دامنه‌های سرور؛ درخواست‌ها به زیردامنه‌های آن‌ها می‌روند. الزامی.
domains[].types فهرست عدد [16] نوع رکوردهای DNS که پرسیده می‌شوند: ۱ (A)، ۵ (CNAME)، ۱۶ (TXT)، ۲۸ (AAAA).
domains[].edns0 number 0 اندازهٔ UDP که با EDNS0 اعلام می‌شود. همین مقدار روی سرور می‌گذارد پاسخ بیشتر جا بگیرد: بدون آن هر پاسخ حدود ۵۰۰ بایت جا دارد که برای تکه‌های mKCP کم است.
domains[].lenLimit، labelLimit number 255، 63 بلندترین نام درخواست و برچسب.
resolvers[].addrs فهرست رشته — resolverها: 8.8.8.8 یا udp://8.8.8.8:53، tcp://9.9.9.9:53، https://1.1.1.1/dns-query. الزامی.
resolvers[].worker number 32 درخواست‌های هم‌زمان برای هر resolver.
resolvers[].tlsConfig object — TLS یک resolver از نوع DoH، مثل tlsSettings در Xray: serverName، alpn (["h3"] برای DoH روی QUIC)، fingerprint، pinnedPeerCertSha256، verifyPeerCertByName، echConfigList و مانند آن. برای https:// الزامی است.
resolvers[].quicConfig object — تنظیمات QUIC برای DoH روی h3، مثل quicParams در Xray.
extraPoll number 0 درخواست‌های خالی اضافه برای هر نوشتن، ۰ تا ۳، تا پاسخ‌ها زودتر برگردند.

تنظیمات نسخه‌های قدیمی‌تر Xray هنوز بارگذاری می‌شوند: "resolvers": ["t.example.com+udp://8.8.8.8:53"] به دامنهٔ t.example.com با resolver udp://8.8.8.8:53 تبدیل می‌شود، و {"name": ...} و {"type": ..., "addr": ...} به names و addrs.

تنظیمات udphop:

فیلد نوع پیش‌فرض معنا
mode string — با کاما جدا: intervalLocal سوکت محلی را، intervalRemote پورت سرور را در فاصله‌های زمانی عوض می‌کند، perConnRemote برای هر اتصال یک پورت سرور برمی‌گزیند. الزامی.
interval range 30 ثانیه‌های میان پرش‌ها، دست‌کم ۵.
remotePorts فهرست پورت — پورت‌های سرور برای پرش: "20000-20100,443".
remoteIPs فهرست رشته — نشانی‌ها یا پیشوندهای سرور که میانشان هم پرش می‌شود.

تنظیمات merge:

فیلد نوع پیش‌فرض معنا
times number 0 چند نوشتن ادغام‌شده فرستاده شود؛ پس از آن نوشتن‌ها مستقیم می‌روند. 0 یا کمتر یعنی در تمام عمر اتصال.
delayMs number 30 نوشتن نگه‌داشته‌شده وقتی می‌رود که این چند میلی‌ثانیه نوشتن تازه‌ای نیاید.
maxBytes number 16384 بایت‌های نگه‌داشته‌شده با رسیدن به این اندازه فوراً فرستاده می‌شوند.

تنظیمات oob:

فیلد نوع پیش‌فرض معنا
bytes فهرست عدد — یک بایت (۰ تا ۲۵۵) برای هر نوشتن: نوشتن i با bytes[i] به‌صورت دادهٔ فوری فرستاده می‌شود. الزامی.

تنظیمات mirage:

فیلد نوع پیش‌فرض معنی
offset عدد 5 اندازهٔ بایت‌های handshake در رکورد اول (۱ تا ۱۶۳۸۳). اندازهٔ امن به شبکه بستگی دارد: در ایران در ۲۰۲۶ اندازه‌های ۱، ۲، ۴ و ۵ عبور کردند و ۳ و ۶ به بالا رد شدند.
layout رشته separate separate هر رکورد را جداگانه می‌نویسد (آنچه همراه اول و ایرانسل در سپتامبر ۲۰۲۶ عبور دادند)؛ single هر دو را در یک نوشتن می‌فرستد (آنچه در اوت ۲۰۲۶ در ایران عبور کرد).

mirage فقط اولین نوشتن را تغییر می‌دهد، آن هم وقتی یک ClientHello کامل با نام سرور باشد؛ هر نوشتن اول دیگری بدون تغییر می‌رود. آن را آخرِ tcp بگذارید، یا بعد از ماسک‌هایی که ClientHello ساده لازم دارند. offset نامناسب می‌تواند باعث شود فیلتر کل اتصال را رد کند، حتی برای نام مجاز.

oob روی سوکت کار می‌کند، پس آن را آخرِ tcp بگذارید؛ dialMode=oob.0,32 در لینک اشتراک‌گذاری پس از ماسک‌های دیگر لینک به {"type": "oob", "settings": {"bytes": [0, 32]}} تبدیل می‌شود. به سوکت واقعی TCP نیاز دارد: از راه detour کاری نمی‌کند.

گزینه‌های مرتبط: tls_fragment خروجی به‌عنوان اولین ماسک fragment اضافه می‌شود. tls_tricks خود ClientHello را تغییر می‌دهد و ماسک نیست. tls_fragment را نمی‌توان با tcp_fast_open به کار برد.

همچنین ببینید


اخرین بروزرسانی: 26 فوریهٔ 2026

نظرات