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

AmneziaWG

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

AmneziaWG همان WireGuard است که پنهان‌سازی به آن اضافه شده. پیش از دست‌دادن، بسته‌های بی‌معنی (junk) می‌فرستد، پیام‌های دست‌دادن را با بایت‌های تصادفی بزرگ‌تر می‌کند و شمارهٔ ثابت نوع پیام‌های WireGuard را با شماره‌های دلخواه شما عوض می‌کند. این‌طور ترافیک دیگر به الگوی WireGuard نمی‌خورد. در کانفیگ، این endpoint با "type": "awg" تعریف می‌شود.

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

WireGuard ساده را به‌راحتی می‌توان شناخت و بست و بسیاری از شبکه‌ها همین کار را می‌کنند. اگر سرور WireGuard مسدود است ولی سرور AmneziaWG با همان کلیدها و peerها در دسترس است، از این endpoint استفاده کنید. سرور باید AmneziaWG را با همان مقادیر پنهان‌سازی اجرا کند. سرور WireGuard ساده بسته‌های تغییرکرده را نمی‌فهمد.

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

DPI ترافیک WireGuard را از بستهٔ اولش می‌شناسد: یک پیام شروع دست‌دادن ۱۴۸ بایتی که با نوع پیام 1 شروع می‌شود و پاسخ ۹۲ بایتی با نوع 2. AmneziaWG هر بخش این الگو را به هم می‌زند:

  • پیش از هر دست‌دادن چند بستهٔ بی‌معنی با اندازهٔ تصادفی فرستاده می‌شود، پس بستهٔ اول جریان، بستهٔ دست‌دادن نیست.
  • بایت‌های تصادفی جلوی پیام شروع و پاسخ، اندازهٔ آن‌ها را تغییر می‌دهند.
  • نوع‌های پیام دلخواه (h1 تا h4) جای مقادیر 1 تا 4 را می‌گیرند.
  • بسته‌های ویژهٔ اختیاری (i1 تا i5) کمک می‌کنند بسته‌های اول شبیه پروتکل دیگری باشند، مثلاً بستهٔ QUIC یا DNS که خودتان ضبط کرده‌اید.

این روش پنهان نمی‌کند که ترافیک، UDP به یک سرور است و وقتی همهٔ UDP مسدود یا کند شده کمکی نمی‌کند. رمزنگاری همان رمزنگاری WireGuard است.

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

  • این endpoint یک دستگاه کامل WireGuard است که روی کتابخانهٔ Go پروژهٔ AmneziaWG و از طریق فورک هیدیفای (github.com/hiddifydeveloper/amneziawg-go) ساخته شده.
  • پیش از هر پیام شروع دست‌دادن، اول بسته‌های i1 تا i5 (اگر تنظیم شده باشند) و بعد jc بستهٔ بی‌معنی با اندازهٔ تصادفی بین jmin و jmax بایت فرستاده می‌شود.
  • جلوی پیام شروع s1 بایت تصادفی و جلوی پاسخ s2 بایت تصادفی می‌آید. چهار نوع پیام با مقادیر h1 تا h4 نوشته می‌شوند.
  • دو طرف باید s1، s2 و h1 تا h4 یکسان داشته باشند، وگرنه بسته‌های هم را نمی‌فهمند. jc، jmin، jmax و i1 تا i5 فقط روی بسته‌هایی که یک طرف می‌فرستد اثر دارند.
  • endpoint می‌تواند به بیرون وصل شود (کلاینت با یک peer) و peerها را بپذیرد (با تنظیم listen_port). اتصال‌هایی که از یک peer می‌آیند مثل هر اتصال ورودی دیگری مسیریابی می‌شوند.
  • وقتی endpoint بالا آمد، هیدیفای بلافاصله روی آن تست URL اجرا می‌کند.

پیکربندی

{
  "endpoints": [
    {
      "type": "awg",
      "tag": "awg-out",
      "private_key": "<base64 private key>",
      "address": ["10.8.0.2/32"],
      "mtu": 1408,
      "awg": {
        "jc": 4,
        "jmin": 40,
        "jmax": 70,
        "s1": 15,
        "s2": 18,
        "h1": "1111111",
        "h2": "2222222",
        "h3": "3333333",
        "h4": "4444444"
      },
      "peers": [
        {
          "address": "203.0.113.10",
          "port": 51820,
          "public_key": "<base64 server public key>",
          "allowed_ips": ["0.0.0.0/0", "::/0"],
          "persistent_keepalive_interval": 25
        }
      ]
    }
  ]
}

فیلدهای endpoint

فیلد نوع پیش‌فرض معنی
private_key string الزامی کلید خصوصی WireGuard شما، به‌صورت base64.
address فهرست prefix الزامی آدرس‌های این طرف داخل تونل، مثل 10.8.0.2/32.
mtu عدد 1408 MTU تونل.
listen_port عدد تصادفی پورت UDP برای گوش دادن. وقتی peerها به شما وصل می‌شوند آن را تنظیم کنید.
useIntegratedTun bool false به‌جای پشتهٔ شبکهٔ داخلی، یک رابط TUN واقعی در سیستم برای تونل می‌سازد.
awg object ندارد مقادیر پنهان‌سازی. پایین‌تر را ببینید.
peers فهرست ندارد peerها. پایین‌تر را ببینید.
mtu_discovery bool true MTUی را پیدا می‌کند که از شبکه و detour می‌گذرد، مثل endpoint ‏WireGuard: درخواست‌های ICMP echo از هر اندازه از درون تونل، و بزرگ‌ترین پاسخ‌گرفته MTU می‌شود. false همان mtu را نگه می‌دارد. با useIntegratedTun نه.
fallback_address فهرست IP ندارد نشانی‌های دیگر تنها peer، روی پورت خودش، که وقتی نشانی در حال استفاده دست‌دادنی نگیرد به نوبت امتحان می‌شوند، مثل endpoint ‏WireGuard. یک peer که با نشانی IP داده شده لازم دارد.
فیلدهای dialer فیلدهای معمول dialer خروجی، مثل detour و bind_interface.

فیلدهای پنهان‌سازی (awg)

هرجا گفته شده، مقدار باید با سرور یکی باشد. مقدار 0 یا "" آن بخش را مثل WireGuard ساده نگه می‌دارد.

فیلد نوع پیش‌فرض معنی
jc عدد 0 تعداد بسته‌های بی‌معنی پیش از هر دست‌دادن.
jmin عدد 0 کوچک‌ترین اندازهٔ بستهٔ بی‌معنی، به بایت.
jmax عدد 0 بزرگ‌ترین اندازهٔ بستهٔ بی‌معنی، به بایت. نباید از jmin کوچک‌تر باشد.
s1 عدد 0 بایت‌های تصادفی جلوی پیام شروع دست‌دادن. باید با سرور یکی باشد.
s2 عدد 0 بایت‌های تصادفی جلوی پاسخ دست‌دادن. باید با سرور یکی باشد. 148 + s1 باید با 92 + s2 فرق کند.
s3 عدد 0 بایت‌های تصادفی جلوی پاسخ cookie. باید با سرور یکی باشد.
s4 عدد 0 بایت‌های تصادفی جلوی هر بستهٔ داده. باید با سرور یکی باشد.
h1 string "" نوع پیام شروع دست‌دادن: یک عدد، یا بازهٔ "min-max" که هر بسته مقداری تصادفی از آن می‌گیرد. باید با سرور یکی باشد.
h2 string "" نوع پیام پاسخ دست‌دادن. باید با سرور یکی باشد.
h3 string "" نوع پیام cookie reply. باید با سرور یکی باشد.
h4 string "" نوع پیام بسته‌های داده. باید با سرور یکی باشد.
i1 … i5 string "" بسته‌های ویژه‌ای که به ترتیب پیش از هر دست‌دادن فرستاده می‌شوند. هر کدام از چند تگ ساخته می‌شود، پایین‌تر را ببینید.

چهار مقدار h باید با هم فرق داشته باشند و بازه‌هایشان با هم هم‌پوشانی نداشته باشد. هر کدام یک عدد بین 5 و 4294967295 یا بازه‌ای از این اعداد است.

AmneziaWG 3.x این تنظیم‌ها را اضافه می‌کند. بازه یک عدد یا "min-max" است و هر بار مقداری تصادفی از آن برداشته می‌شود.

فیلد نوع پیش‌فرض معنی
header_protection_key string "" ۶۴ رقم هگز. سرآیند پیام‌ها را رمز می‌کند تا نوع پیام‌ها خوانده نشود. در این حالت هر یک از s1 تا s4 باید دست‌کم 12 باشد. باید با سرور یکی باشد.
content_padding_addition بازه بایت‌های تصادفی که به هر بستهٔ داده اضافه می‌شود.
rekey_after_time بازه ثانیه‌ها تا دست‌دادن تازه.
rekey_timeout بازه ثانیه‌های انتظار برای پاسخ دست‌دادن پیش از تلاش دوباره.
reject_after_time بازه ثانیه‌هایی که پس از آن کلیدها دیگر به کار نمی‌روند.
keepalive_timeout بازه ثانیه‌های بی‌بسته پیش از فرستادن keepalive.
max_handshake_attempts بازه تعداد تلاش‌های دست‌دادن پیش از دست کشیدن.
random_trailers bool false بایت‌های تصادفی به انتهای بسته‌ها اضافه می‌کند.
disable_cookies bool false پاسخ‌های cookie را هنگام بار زیاد خاموش می‌کند.

مقدارهای خالی پیش‌فرض‌های amneziawg-go را نگه می‌دارند که با زمان‌بندی WireGuard یکی است.

هر بستهٔ i از چند تگ پشت سر هم ساخته می‌شود، مثلاً <b 0xc0ffee><r 16><t>:

تگ چه اضافه می‌کند
<b 0x…> همین بایت‌ها، به‌صورت hex.
<r N> N بایت تصادفی (حداکثر ۱۰۰۰).
<t> زمان فعلی Unix، ۸ بایت.
<c> یک شمارندهٔ بسته، ۸ بایت.
<wt N> بایتی اضافه نمی‌کند؛ پیش از فرستادن بسته N میلی‌ثانیه (حداکثر ۵۰۰۰) صبر می‌کند.

استتار (ip، id، ib)

به‌جای نوشتن دستی i1، اولین بستهٔ فریب را می‌توان تولید کرد. با "ip": "quic"، ‏i1 یک بستهٔ Initial کلاینت QUIC v1 برای دامنهٔ id می‌شود: یک ClientHello واقعی و رمزگشایی‌شدنی TLS 1.3 برای آن دامنه با ALPN ‏h3، همان چیزی که مرورگر هنگام باز کردن اتصال HTTP/3 می‌فرستد. این بسته پیش از هر دست‌دادن از نو ساخته می‌شود، با شناسه‌های اتصال، random و key share تازه، پس سانسورچی هرگز یک بستهٔ تکراری نمی‌بیند.

"awg": { "jc": 4, "jmin": 40, "jmax": 70, "ip": "quic", "id": "www.google.com" }
فیلد نوع پیش‌فرض معنی
ip string "" پروتکلی که بسته شبیه آن می‌شود: quic، یا نام یک پیش‌تنظیم noise مثل sip، dns، stun، random یا quic-mimic.
id string "" دامنهٔ داخل بستهٔ فریب. با quic لازم است.
ib string "" نمایهٔ کلاینت: chrome، firefox یا curl، برای کانفیگ‌هایی که برای sing-box-lx نوشته شده‌اند پذیرفته می‌شود. این نسخه برای همه یک ClientHello شبیه مرورگر می‌فرستد.

هر ip دیگری نام یک پیش‌تنظیم noise است: بسته‌هایش i1، i2، … را پر می‌کنند و junk آن، اگر jc، jmin و jmax تنظیم نشده باشند، آن‌ها را؛ پس "awg": { "ip": "sip" } به‌تنهایی شبیه برقراری یک تماس VoIP است.

ip، id و ib جای i1 را می‌گیرند: کانفیگی که هر دو را داشته باشد بالا نمی‌آید. i2 تا i5 همچنان اعمال می‌شوند. سرور به تغییری نیاز ندارد: بستهٔ فریب را مثل همهٔ بسته‌های i نادیده می‌گیرد.

فیلدهای peer (peers)

فیلد نوع پیش‌فرض معنی
address string ندارد آدرس IP یا دامنهٔ سرور. دامنه یک بار هنگام شروع با resolver سیستم ترجمه می‌شود.
port عدد ندارد پورت UDP سرور.
public_key string الزامی کلید عمومی peer، به‌صورت base64.
preshared_key string ندارد کلید مشترک اختیاری، به‌صورت base64.
allowed_ips فهرست prefix ندارد آدرس‌هایی که به این peer فرستاده و از آن پذیرفته می‌شوند.
persistent_keepalive_interval عدد 0 فاصلهٔ بسته‌های keepalive به ثانیه. 0 آن را خاموش می‌کند.
name string ندارد نام کاربر برای اتصال‌های این peer. آمار و قاعده‌های auth_user این نام را می‌بینند.
reserved ۳ بایت ندارد در بایت‌های ۱ تا ۳ هر پیام نوشته می‌شود، همان جایی که WireGuard دارد؛ Cloudflare WARP آن را شناسهٔ کلاینت می‌خواند. به شکل [124, 245, 25] یا base64 نوشته می‌شود. لازم است s1 تا s4 برابر 0 باشند، header_protection_key نباشد، h1 تا h4 بین 1 و 255 باشند و فقط یک peer باشد. این بایت‌ها از پیام‌های دریافتی پاک می‌شوند.

نکته‌ها

  • این endpoint به برچسب ساخت with_awg نیاز دارد. نسخه‌های هیدیفای آن را دارند. بدون آن، اجرای کانفیگ با خطای «Awg is not included in this build, rebuild with -tags with_awg» متوقف می‌شود.
  • هر endpoint ‏AmneziaWG مقادیر خودش را دارد، پس endpointهای یک کانفیگ می‌توانند به سرورهایی با تنظیم‌های متفاوت وصل شوند.
  • اگر مقداری نامعتبر باشد (مثلاً jmax کوچک‌تر از jmin یا دو مقدار h یکسان)، endpoint بالا نمی‌آید و لاگ نام آن مقدار را می‌گوید.
  • سیستم ممکن است بسته‌های UDP این endpoint را تکه‌تکه (fragment) کند، همان‌طور که WireGuard رسمی می‌کند. برای خاموش کردن آن "udp_fragment": false را بگذارید.
  • endpoint warp وقتی در بلوک awg آن مقداری تنظیم شده باشد از همین endpoint استفاده می‌کند و با بسته‌های بی‌معنی و بقیهٔ مقادیر شما به Cloudflare WARP وصل می‌شود. سرورهای Cloudflare WireGuard ساده اجرا می‌کنند، پس تغییر s1 تا s4، h1 تا h4 یا header_protection_key دست‌دادن را خراب می‌کند. برای WARP فقط مقادیری را تنظیم کنید که روی بسته‌های کلاینت اثر دارند: jc، jmin، jmax و i1 تا i5.

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


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

نظرات