WireGuard: افزودههای هیدیفای
هیدیفای چند قابلیت به endpoint اصلی WireGuard ("type": "wireguard") اضافه کرده: بستههای جعلی
«noise» پیش از هر دستدادن، نام کاربر برای هر peer، بازیابی خودکار وقتی سوکت UDP از کار میافتد، و
روشن بودن پیشفرض تکهتکه شدن (fragment) بستههای UDP. بقیهٔ این endpoint مثل sing-box اصلی کار
میکند و در مستندات همان پروژه آمده. این صفحه فقط بخشهای هیدیفای را میگوید.
چرا از آن استفاده کنیم
- Noise وقتی شبکه WireGuard را از بستهٔ اولش مسدود میکند کمک میکند. با هر سرور WireGuard معمولی کار میکند، چون سرور بستههای جعلی را دور میریزد.
- نام کاربر peerها وقتی WireGuard را بهعنوان سرور اجرا میکنید، آمار جدا برای هر کاربر و
قاعدههای مسیریابی
auth_userرا ممکن میکند. - بازیابی تونل را پس از خواب دستگاه، منقضی شدن نگاشت NAT یا قطع شدن جریان از طرف شبکه خودش برمیگرداند، بدون اینکه منتظر تغییر شبکه بماند.
- تکهتکه شدن UDP کمک میکند WireGuard داخل تونل دیگری با MTU کوچکتر هم کار کند.
چطور از فیلترینگ عبور میکند
بسیاری از فیلترها فقط چند بستهٔ اول یک جریان UDP را نگاه میکنند. اگر آنها شبیه دستدادن WireGuard نباشند، جریان عبور میکند یا چیز دیگری تشخیص داده میشود. با روشن بودن noise، کلاینت پیش از هر پیام شروع دستدادن چند بستهٔ جعلی به سرور میفرستد:
- در حالت پیشفرض، بستهها بایتهای تصادفیاند با سرآیندی که شبیه شروع یک بستهٔ QUIC است.
- در حالت
quic، بستهها بستههای Initial واقعی QUIC نسخهٔ ۱ به نامی هستند که درsniمیدهید. فیلتری که Initialهای QUIC را رمزگشایی کند (هر کسی میتواند، کلیدها از خود بسته به دست میآیند) یک ClientHello معتبر TLS 1.3 برای آن نام با ALPNh3میبیند. پس جریان شبیه شروع یک اتصال HTTP/3 به نظر میرسد.
Noise خود بستههای WireGuard را تغییر نمیدهد. فیلتری که کل جریان را بخواند هنوز میتواند دستدادن را پس از noise پیدا کند. برای این حالت از AmneziaWG استفاده کنید. وقتی UDP مسدود است هم noise کمکی نمیکند.
چطور کار میکند
Noise
- پیش از هر پیام شروع دستدادن، از جمله تلاشهای دوباره، کلاینت
countبستهٔ جعلی میفرستد و بین آنهاdelayمیلیثانیه صبر میکند. بعد دستدادن را میفرستد. - در حالت پیشفرض هر بسته اینطور ساخته میشود: یک بایت که بهتصادف از
headerانتخاب میشود (اگر تنظیم شده باشد)، بایتهای00 00 00 01 08، ۸ بایت تصادفی، بایتهای00 00 44 D0و بعدsizeبایت تصادفی. - در حالت
quicبستهٔ اول ClientHello را دارد و بقیه قابهای PING را، همانطور که ارسال دوبارهٔ QUIC انجام میشود. هر بسته دستکم تا ۱۲۰۰ بایت پر میشود.sizeوheaderاستفاده نمیشوند. - در حالت
rawهر بسته به اندازهٔsizeبایت تصادفی است، بدون سرآیند، مثل noise تصادفی Xray و بستههای junk در AmneziaWG. packetsاول و همانطور که هستند فرستاده میشوند: قالبهایی با نحوi1تاi5در AmneziaWG، مثل یک پرسوجوی DNS (<r 2><b 0x0100…>) یا یکINVITEدر SIP، تا بستههای ویژهٔ پیکربندیهای AmneziaWG بهعنوان noise ساده در WireGuard هم کار کنند.modeی که نام یک پیشتنظیم noise باشد (sip،dns،stun،random،quic-mimic،dns-cloudflare، ...) همان پیشتنظیم را میفرستد: بستههایش، سپس junk آن.count،size،delayوsniکه کنارش تنظیم شوند اولویت دارند وpacketsپس از بستههای پیشتنظیم میآیند.quicبدونcountمثل پیشتنظیمquic۲ تا ۴ بستهٔ Initial میفرستد.- برای peerی که با دامنه تعریف شده، noise به همهٔ آدرسهایی که آن دامنه به آنها ترجمه میشود فرستاده میشود.
- اگر فرستادن یک بستهٔ noise شکست بخورد، در لاگ ثبت و رد میشود و هرگز جلوی دستدادن را نمیگیرد.
نام کاربر peerها
WireGuard بستهای را از یک peer فقط وقتی میپذیرد که آدرس مبدأ آن در allowed_ips همان peer باشد.
پس آدرس مبدأ یک اتصال نشان میدهد کدام peer آن را فرستاده. وقتی یک peer مقدار name دارد، اتصالهایی
که از آدرسهای آن میآیند همین نام کاربر را میگیرند، درست مثل کاربر یک ورودی VLESS یا Trojan. اگر
allowed_ips چند peer نامدار همپوشانی داشته باشد، دقیقترین prefix برنده است.
بازیابی (wireguard-go هیدیفای)
این endpoint روی نسخهٔ هیدیفای از wireguard-go (replace/wireguard-go) اجرا میشود که اینها را
اضافه میکند:
- پورت تازه پس از دستدادنهای ناموفق. دستدادنی که از یک سوکت مدام شکست میخورد بهندرت درست
میشود. پس از ۳ پیام شروع بیپاسخ (حدود ۱۵ ثانیه) وقتی peer نشست معتبری ندارد، یا وقتی یک دورهٔ
دستدادن کنار گذاشته میشود، سوکت روی یک پورت تصادفی تازه دوباره باز میشود و یک جریان UDP تازه
ساخته میشود. اگر
listen_portتنظیم شده باشد همان حفظ میشود. این کار حداکثر هر ۹۰ ثانیه یک بار انجام میشود. - باز کردن دوباره وقتی دریافت شکست میخورد. اگر سوکت خطای دائمی یا ده خطای پشت سر هم بدهد، یک ثانیه بعد دوباره باز میشود. پیش از این، تونل تا تغییر شبکه دیگر چیزی دریافت نمیکرد.
- حفظ IPv4 بدون IPv6. وقتی endpoint سوکتهایش را خودش باز میکند (بدون
detour) و سوکت IPv6 باز نمیشود (IPv6 خاموش است یا رابط انتخابشده IPv6 ندارد)، endpoint با IPv4 به کار ادامه میدهد. پیش از این، اصلاً بالا نمیآمد. - انتظارهای محدود. وصل شدن اتصال UDP از طریق
detourپس از ۱۵ ثانیه رها و دوباره امتحان میشود، پس یک detour گیرکرده تونل را قفل نمیکند. اتصالهای TCP داخل تونل هم بهجای حدود یک دقیقه پس از ۱۵ ثانیه رها میشوند.
نشانیهای جایگزین
یک peer را اغلب میشود با بیش از یک نشانی رسید (WARP با نشانیهای IPv4 و IPv6)، و مسیر شاید فقط
برخی را برساند: شبکه یا پروکسی بی IPv6، یا تونلی که برای بستههای بزرگتر IPv6 کوچک است. با
fallback_address، وقتی بستهها فرستاده شدهاند ولی در ۱۵ ثانیه دستدادنی برنگشته، endpoint به نشانی
بعدی میفرستد، و همینطور به نوبت؛ endpoint بیکار دست نمیخورد. وقتی مسیر عوض شود (اتصال detour دوباره
ساخته شود، شبکه عوض شود)، دوباره از نشانی خود peer، که ترجیح دارد، شروع میکند. با detour و بدون آن
کار میکند. hiddify-core هاپ خروجی WARP با نشانی IPv6 را روی نشانی IPv4 میگذارد و نشانی IPv6 را
اینجا نگه میدارد.
تکهتکه شدن UDP
این endpoint حالا اجازه میدهد سیستم بستههای UDP آن را تکهتکه کند، همانطور که WireGuard رسمی
میکند. پیش از این پرچم «don't fragment» گذاشته میشد و بستهای بزرگتر از MTU مسیر (مثلاً WireGuard
داخل تونل دیگر) دور ریخته میشد. برای رفتار قبلی "udp_fragment": false را بگذارید.
کشف MTU
هر endpoint فقط وقتی کار میکند که همهٔ لایههای زیرش بستههایش را برسانند: شبکه، و detour اگر
باشد (WARP درون WARP، یا WireGuard از راه یک پروکسی). بستهای که برای یکی از آنها بزرگ باشد بیصدا گم میشود و
اتصالها روی اولین بستهٔ کامل گیر میکنند.
- وقتی endpoint شروع میشود، و هر بار که مسیرش شاید عوض شده باشد (شبکه عوض شده، یا اتصالش از راه
detour دوباره ساخته شده چون selector زیر آن عوض شده یا سوکت بازیابی شده)، درخواستهای ICMP echo از درون تونل به
1.1.1.1(بدون آدرس IPv4، به2606:4700:4700::1111) میفرستد: از هر اندازه یکی، از 576 (برای IPv6 از 1280) تاmtuبا گام 16، همه با هم. هر کدام یک بستهٔ تونل به همان اندازه است. بزرگترین اندازهای که پاسخ بگیرد MTU تونل میشود، معمولاً در کمتر از یک ثانیه. - روی مسیر تازه اول کلیدهای نشست را کنار میگذارد و دستدادن تازهای شروع میکند، همان کاری که WireGuard وقتی endpoint یک peer عوض شود میکند. وگرنه سرور حدود ۱۵ ثانیه به مسیر قبلی میفرستد.
- وقتی MTU پایین میآید، اتصالهای TCP که پیشتر از این endpoint ساخته شده بودند بسته میشوند تا برنامهها با بستههای اندازه دوباره وصل شوند: سمت سرورِ چنین اتصالی همچنان بستههایی میفرستد که گم میشوند. به بستهٔ بزرگتر از MTU، مثل یک روتر در مسیر، با ICMP «packet too big» پاسخ داده میشود.
- اگر کوچکترین درخواست هم پاسخ نگیرد (سروری که ICMP را دور میاندازد، یا مسیری به مقصد نیست)، MTU
همان مقدار پیکربندی میماند. کشف هیچوقت MTU را بالاتر از
mtuنمیبرد، پسmtuرا بزرگترین مقداری بگذارید که لایهٔ اول میبرد. - بهطور پیشفرض، با
detourو بدون آن، روشن است؛"mtu_discovery": falseخاموشش میکند. با"system": trueاجرا نمیشود.
پیکربندی
{
"endpoints": [
{
"type": "wireguard",
"tag": "wg-out",
"address": ["10.8.0.2/32"],
"private_key": "<base64 private key>",
"peers": [
{
"address": "203.0.113.10",
"port": 51820,
"public_key": "<base64 server public key>",
"allowed_ips": ["0.0.0.0/0", "::/0"]
}
],
"noise": {
"fake_packet": {
"enabled": true,
"count": "2-4",
"delay": "5-15",
"mode": "quic",
"sni": "www.google.com"
}
}
}
]
}
فیلدهای noise (noise.fake_packet)
| فیلد | نوع | پیشفرض | معنی |
|---|---|---|---|
enabled |
bool | false |
پیش از هر دستدادن بستهٔ جعلی بفرستد. |
count |
بازه | ندارد | تعداد بستهها. تا وقتی 0 باشد چیزی فرستاده نمیشود. |
size |
بازه | ندارد | تعداد بایتهای تصادفی هر بسته در حالت پیشفرض. در حالت پیشفرض تا وقتی 0 باشد چیزی فرستاده نمیشود. |
delay |
بازه | 0 |
میلیثانیهٔ انتظار بین دو بستهٔ جعلی. |
mode |
string | "" |
"" برای بستههای تصادفی پس از یک سرآیند کوتاه، "raw" برای بستههای تصادفی بدون سرآیند، "quic" برای بستههای Initial واقعی QUIC، یا نام یک پیشتنظیم noise: "sip"، "dns"، "stun"، "random"، "quic-mimic"، "dns-cloudflare"، "dns-www-cloudflare". |
packets |
list of strings | ندارد | قالبهایی که اول و بهترتیب فرستاده میشوند، با نحو i1 تا i5 در AmneziaWG: <b 0xHEX>، <r N>، <rc N>، <rd N>، <t>، <qi SNI>. قالبی که ساخته نشود پیکربندی را نامعتبر میکند. |
sni |
string | "www.google.com" |
نام سرور در ClientHello بستهٔ QUIC. فقط با "mode": "quic" استفاده میشود. |
header |
فهرست بایت | ندارد | فقط در حالت پیشفرض: هر بسته با یکی از این بایتها، به انتخاب تصادفی، شروع میشود. آن را بهصورت عدد مثل [192, 193, 194] یا رشتهٔ base64 بنویسید. |
no_modify |
bool | false |
فقط در حالت پیشفرض: بستهها را دقیقاً همانطور که ساخته شدهاند بفرستد و بایتهای reserved peer را در آنها ننویسد. حالت quic همیشه همین کار را میکند. |
بازه را میتوان بهصورت عدد (3)، رشته ("2-4" یا "3") یا شیء ({"from": 2, "to": 4}) نوشت.
هر دو سر بازه شامل میشوند و هر بسته مقدار تصادفی تازهای میگیرد. from نباید از to بزرگتر باشد.
فیلد peer
| فیلد | نوع | پیشفرض | معنی |
|---|---|---|---|
name |
string | ندارد | نام کاربر برای اتصالهای این peer. آمار و قاعدههای مسیریابی auth_user این نام را میبینند. |
پیشفرض فیلد dialer
| فیلد | نوع | پیشفرض | معنی |
|---|---|---|---|
udp_fragment |
bool | true |
اجازه میدهد سیستم بستههای UDP وایرگارد را تکهتکه کند. پیشفرض sing-box اصلی برای این endpoint false است. |
فیلد endpoint
| فیلد | نوع | پیشفرض | معنی |
|---|---|---|---|
mtu_discovery |
bool | true |
MTUی را پیدا میکند که از لایههای زیر تونل میگذرد (کشف MTU را ببینید). false همان mtu را نگه میدارد. |
fallback_address |
فهرست IP | ندارد | نشانیهای دیگر تنها peer، روی پورت خودش، که به نوبت امتحان میشوند وقتی نشانی در حال استفاده دستدادنی نگیرد (نشانیهای جایگزین را ببینید). یک peer که با نشانی IP داده شده لازم دارد. |
نکتهها
- endpoint
warpهم همین بلوکnoiseرا میپذیرد و آن را به اتصال WireGuard خود میدهد. - endpoint
wireguardبا بلوکawgبالا نمیآید: برای پنهانسازی AmneziaWG از endpointawgیا بلوکawgدر endpoint warpاستفاده کنید. - Noise با هر سرور WireGuard کار میکند و سرور به تغییری نیاز ندارد.