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 تازه، پس سانسورچی هرگز یک بستهٔ
تکراری نمیبیند.
| فیلد | نوع | پیشفرض | معنی |
|---|---|---|---|
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.