اسکنر و noise در WARP
یک endpoint از نوع WARP چطور در شبکهای که آن را مسدود میکند راهی پیدا میکند: اسکنر endpoint دنبال نشانی و پورتی از کلادفلر میگردد که پاسخ بدهد، noise پیش از هر دستدادن WireGuard چند بستهٔ فریب میفرستد، جستوجوی noise وقتی noise پیکربندیشده پاسخی نمیگیرد noiseهای آماده را امتحان میکند، و حالت auto میان WireGuard، AmneziaWG و MASQUE مسابقه میگذارد. این صفحه توضیح میدهد اینها چطور با هم کار میکنند. فیلدها در صفحهٔ WARP فهرست شدهاند.
چرا از آن استفاده کنیم
- بسیاری از فیلترها WARP را از روی نخستین بستههای یک جریان مسدود میکنند: بستهٔ آغاز دستدادن WireGuard بهسادگی شناخته میشود (اندازهٔ ثابت، بایتهای اول ثابت). noise چیزی را که جریان با آن شروع میشود عوض میکند.
- فیلترها برخی نشانیها یا پورتهای کلادفلر را مسدود میکنند و برخی را نه؛ اسکنر یکی را که کار میکند پیدا میکند و برای هر شبکه به خاطر میسپارد.
- noiseی که در یک شبکه کار میکند ممکن است در شبکهٔ دیگر شکست بخورد. جستوجوی noise یکی را پیدا میکند که در همین شبکه کار کند، و آن را هم به خاطر میسپارد.
- حالت auto همین کار را برای تونل میکند: در شبکهای که UDP کند شده ممکن است MASQUE ببرد، و جای دیگر WireGuard.
چطور از فیلتر عبور میکند
فیلتری که یک جریان UDP را از روی نخستین بستههایش دستهبندی میکند، اول چیز دیگری میبیند:
| noise | آنچه فیلتر اول میبیند |
|---|---|
| تصادفی (پیشفرض) | بستههای کوتاهی که مثل سرآیند بلند QUIC شروع میشوند، سپس بایت تصادفی |
raw |
بایتهای تصادفی با اندازههای تصادفی، بدون هیچ ساختاری |
quic |
یک بستهٔ Initial واقعی QUIC نسخهٔ ۱، با ClientHello در TLS برای www.google.com |
packets |
هر چه قالبها بسازند: یک پرسوجوی DNS، یک درخواست SIP، یک بستهٔ QUIC |
دستدادن WireGuard در همان جریان پس از آن میآید. فیلتری که فقط به آغاز جریان نگاه میکند آن را عبور میدهد؛ فیلتری که کل جریان را زیر نظر دارد هنوز میتواند WireGuard را پیدا کند، و آنوقت MASQUE (اتصال HTTPS به کلادفلر) راه خروج است.
چطور کار میکند
حالتهای noise
noise در endpointهای wireguard و warp (noise.fake_packet) پیش از هر بستهٔ آغاز دستدادن فرستاده
میشود: به تعداد count بسته با فاصلهٔ تصادفی delay میان آنها:
- حالت پیشفرض (بدون
mode): هر بسته یک بایت ازheader(یا هیچ)، بایتهای00 00 00 01 08، ۸ بایت تصادفی،00 00 44 D0و سپس به اندازهٔsizeبایت تصادفی است. این از GFW-knocker آمده و مثل سرآیند بلند QUIC شروع میشود. raw: به اندازهٔsizeبایت تصادفی و دیگر هیچ. این همان noise در WARP برای Xray (wnoise=random) و بستههای junk در AmneziaWG است.quic: بستههای Initial واقعی QUIC برایsni(پیشفرضwww.google.com): اولی ClientHello را دارد و بقیه قابهای PING را، همانطور که ارسال دوبارهٔ QUIC انجام میشود.packets: قالبهایی که اول و بهترتیب فرستاده میشوند، با نحوi1تاi5در AmneziaWG:<b 0xHEX>بایتها،<r N>بایت تصادفی،<rc N>حرف و رقم تصادفی،<rd N>رقم تصادفی،<t>زمان Unix (۴ بایت)،<qi SNI>یک Initial در QUIC. سپس بستههایcountحالت انتخابشده.
با awg، AmneziaWG به جای آن noise خودش را میفرستد: i1 تا i5، سپس به تعداد jc بستهٔ junk با
اندازهٔ jmin تا jmax بایت. کلادفلر فقط پیامهای استاندارد WireGuard را میپذیرد، پس برای WARP
سرآیندهای h1 تا h4 در AmneziaWG ۱ تا ۴ و s1 تا s4 صفر میمانند: فقط بستههای پیش از دستدادن
تغییر میکنند.
پیشتنظیمهای noise
از پیکربندیهای WARP که کار میکنند گرفته شدهاند (لینکهای Xray و پیکربندیهای «WG Mimic» در AmneziaWG). هر کدام هم بهعنوان noise در WireGuard و هم بهعنوان تنظیمهای AmneziaWG کار میکند.
| پیشتنظیم | پیش از دستدادن چه میفرستد | شبیه چیست |
|---|---|---|
xray-random |
۵ بستهٔ تصادفی ۵ تا ۱۰ بایتی با فاصلهٔ ۲ تا ۵ میلیثانیه | چیز خاصی نیست: بستههای ریز اثرانگشت مبتنی بر اندازه را میشکنند |
quic |
۲ تا ۴ بستهٔ Initial در QUIC برای www.google.com |
آغاز یک اتصال HTTP/3 به گوگل |
dns-google |
۳ پرسوجوی DNS برای google.com (A، AAAA، HTTPS)، هر کدام با شناسهٔ تصادفی، سپس ۶ بستهٔ junk ۵۶ تا ۱۶۰ بایتی |
ترافیک DNS |
dns-cloudflare |
۲ پرسوجوی DNS برای cloudflare.com (A، AAAA)، سپس ۹ بستهٔ junk ۸۱ تا ۲۲۴ بایتی |
ترافیک DNS به کلادفلر |
dns-www-cloudflare |
۲ پرسوجوی DNS برای www.cloudflare.com (A، AAAA)، سپس ۶ بستهٔ junk ۴۳ تا ۱۰۹ بایتی |
ترافیک DNS به کلادفلر |
quic-mimic |
یک Initial ضبطشده در QUIC (۱۲۱۰ بایت: ۲۷۶ ضبطشده، ۹۳۴ تصادفی) و یک بسته با سرآیند کوتاه، سپس ۴ بستهٔ junk ۶۰ تا ۱۹۹ بایتی | یک اتصال QUIC |
sip |
یک INVITE در SIP و پاسخ 100 Trying آن، سپس ۱۰ بستهٔ junk ۴۲ تا ۲۲۴ بایتی |
برقراری یک تماس VoIP |
stun |
۲ درخواست Binding در STUN، هر کدام با شناسهٔ تراکنش تصادفی، سپس ۴ بستهٔ junk ۴۰ تا ۱۲۰ بایتی | کلاینت تماس تصویری یا WebRTC که آدرسش را بررسی میکند |
بهعنوان تنظیمهای AmneziaWG، قالبهای یک پیشتنظیم به i1، i2، … و junk آن به jc، jmin، jmax
تبدیل میشوند؛ quic به بستههای <qi www.google.com> تبدیل میشود. حالت awg بدون تنظیمهای awg از
dns-google استفاده میکند.
این پیشتنظیمها فقط برای WARP نیستند: هر endpoint از نوع WireGuard یکی از آنها را
بهعنوان mode نویز میگیرد ("mode": "sip") و هر endpoint از نوع AmneziaWG بهعنوان ip
("ip": "sip"). dns و random نام کوتاه dns-google و xray-random هستند.
اسکنر endpoint
با scanner.enabled، WARP پیش از اتصال، endpointها (نشانی و پورت) را با یک دستدادن واقعی WireGuard با
کلید خود دستگاه، پس از همان noiseی که تونل خواهد فرستاد و از طریق dialer همین endpoint (پس detour
اعمال میشود) امتحان میکند. endpointها به این ترتیب امتحان میشوند: آنهایی که در این شبکه کار کردهاند
بهترتیب امتیاز؛ سپس آنهایی که جای دیگر امتیاز خوب گرفتهاند؛ سپس نشانیهای تصادفی در cidrs روی
ports؛ و کمترین امتیازها در آخر. اسکن وقتی تمام میشود که endpointی با امتیاز ۳ یا بیشتر پاسخ دهد، یا ۴
endpoint پاسخ داده باشند، و بهترین به کار میرود. امتیازها (۱۰- تا ۱۰ برای هر endpoint و شبکه) در فایل
کش نگه داشته میشوند؛ هر شبکه با نوع رابط، کشور و بازهٔ نشانی عمومیاش نامگذاری میشود. پس از تغییر
شبکه، و وقتی ترافیک خارج میشود ولی ۳ دقیقه دستدادنی انجام نشده، endpoint در حال استفاده دوباره امتحان
و اگر دیگر پاسخ ندهد جایگزین میشود.
برای MASQUE، اسکنر با یک دستدادن TLS به endpointهای MASQUE امتحان میکند، جداگانه روی HTTP/3 و HTTP/2.
جستوجوی noise
با scanner.search_noise، اسکنر دنبال noise هم میگردد:
- با noiseی که پیشتر در این شبکه عبور کرده، اگر باشد، اسکن میکند.
- اگر هیچ endpointی پاسخ ندهد، با noise پیکربندیشده (
noise، یا تنظیمهایawg). - اگر باز هیچ، با هر پیشتنظیم
noise_presets(بهطور پیشفرض همه، به ترتیب بالا)، هر کدام روی حداکثر ۱۶ endpoint: endpointهایی که پاسخدادنشان معلوم است اول میآیند، پس چند تا برای فهمیدن کافی است. - اولین noiseی که پاسخ بگیرد به کار میرود: تونل با آن شروع میشود و برای آن شبکه ذخیره میشود تا دفعهٔ بعد آنجا اول امتحان شود.
probe همیشه همان چیزی را میفرستد که تونل میفرستد، پس noiseی که probe را عبور دهد تونل را هم عبور میدهد. هر جستوجو حداکثر به اندازهٔ تعداد پیشتنظیمها ضرب در ۱۶ probe هزینه دارد که ۸ تا ۸ تا همزمان اجرا میشوند.
حالت auto
با "mode": "auto"، WARP یک دستگاه WireGuard، یک دستگاه AmneziaWG و یک دستگاه MASQUE برای خودش دارد و با
مسابقه میان سه تونل شروع میکند:
- همزمان یک دستدادن با هر کدام، به endpoint خود دستگاه: WireGuard با
noiseهمین endpoint، AmneziaWG با تنظیمهایawgآن (یاdns-google)، MASQUE با یک دستدادن TLS. برای هر کدام دو بار در ۵ ثانیه. - سریعترینی که پاسخ داده تونل درونی میشود. هنگام مسابقه
WARP · Auto 🔍 Searching...نشان داده میشود، سپسWARP · WG،WARP · AWGیاWARP · MASQUE. - تونل انتخابشده سپس مثل حالت خودش کار میکند: اسکنر و جستوجوی noise برای آن اعمال میشوند (اسکنر WireGuard برای WireGuard و AmneziaWG، اسکنر MASQUE برای MASQUE).
- تونل انتخابشده ۲۰ ثانیه فرصت دارد وصل شود. پاسخ به یک دستدادن ثابت نمیکند که تونل ترافیک را عبور میدهد: وقتی وصل نشود، مسابقه بدون آن دوباره انجام میشود، و وقتی همهٔ تونلها شکست خورده باشند از نو شروع میکند.
- وقتی هیچکدام پاسخ نداده، WireGuard به کار میرود تا اسکنر و جستوجوی noise هنوز بتوانند endpoint و noiseی پیدا کنند.
- وقتی
detourی که گروه است به عضو دیگری برود، مسابقه دوباره انجام میشود: پراکسی تازه ممکن است تونل دیگری را بهتر عبور دهد، یا فقط یکی را (پراکسی بدون UDP، مثل SOCKS4، فقط MASQUE روی HTTP/2 را عبور میدهد). پس از selectorی که کاربر عوض کرده، فوراً؛ پس از گروهی که خودش جابهجا شده (URL test، balancer)، حداکثر هر ۳۰ ثانیه، با تونلی تازه کنار تونل فعلی که فقط پس از وصل شدن جای آن را میگیرد (نگاه کنید به detour گروهی). تغییر شبکه شکستخوردهها را فراموش میکند. - تا وقتی endpoint ۳ دقیقه متصل نبوده، حداکثر هر ۱۰ دقیقه دوباره مسابقه میدهد و به تونل دیگری که پاسخ دهد میرود.
مسابقه از noise پیکربندیشده استفاده میکند، نه پیشتنظیمها: جستوجوی noise درون تونلی اجرا میشود که انتخاب شده است.
پیکربندی
جستوجوی endpoint و noise، با حالت auto:
{
"experimental": {
"cache_file": { "enabled": true, "store_warp_config": true }
},
"endpoints": [
{
"type": "warp",
"tag": "warp",
"mode": "auto",
"noise": {
"fake_packet": { "enabled": true, "mode": "quic", "count": "2-4", "delay": "10-30" }
},
"scanner": { "enabled": true, "search_noise": true }
}
]
}
فقط چند پیشتنظیم، به این ترتیب:
"scanner": { "enabled": true, "search_noise": true, "noise_presets": ["dns-google", "sip", "quic-mimic"] }
یک noise شبیه DNS برای WireGuard ساده، که دستی نوشته شده:
"noise": {
"fake_packet": {
"enabled": true,
"packets": ["<r 2><b 0x0100000100000000000106676f6f676c6503636f6d00000100010000291000000000000000>"],
"mode": "raw",
"count": "6",
"size": "56-160"
}
}
| فیلد | کجا | معنی |
|---|---|---|
scanner.enabled |
warp | دنبال endpointی بگرد که پاسخ دهد، و در صورت خرابی جایگزین کن. |
scanner.search_noise |
warp | دنبال پیشتنظیم noiseی هم بگرد که عبور کند. |
scanner.noise_presets |
warp | پیشتنظیمهایی که بهترتیب امتحان میشوند؛ خالی یعنی همه. نام ناشناخته پیکربندی را نامعتبر میکند. |
noise.fake_packet.mode |
warp، wireguard | ""، raw یا quic. |
noise.fake_packet.packets |
warp، wireguard | قالبهایی که اول فرستاده میشوند، با نحو i1 تا i5 در AmneziaWG. |
mode |
warp | wg، awg، masque یا auto. |
فیلدهای دیگر اسکنر (ports، cidrs، max_rtt، timeout، count، concurrency) در صفحهٔ
WARP هستند.
نکتهها
- امتیازها و noise پیداشده در فایل کش نگه داشته میشوند؛ بدون
cache_file، هر شروع از صفر اسکن میکند. - وقتی
serverتنظیم شده باشد، اسکنر خاموش است. - noise در برابر فیلتری که همهٔ UDP یا همهٔ بازههای WARP کلادفلر را مسدود کند کمکی نمیکند: آنوقت حالت
auto، یا
masqueباvhttpبرابرauto(HTTP/2 روی TCP)، راه است.