# ایتر ایتر یک کلاینت پروکسی در فضای کاربر برای Cloudflare WARP است. از دل یک شبکه‌ی فیلترشده یک تونل می‌سازد و یک پروکسی SOCKS5 محلی روی `127.0.0.1:1819` باز می‌کند. مرورگر، ترمینال یا پروکسی سیستم را به همان نشانی وصل کنید تا ترافیک از تونل بیرون برود. نه به دسترسی روت نیاز دارد و نه درایور شبکه نصب می‌کند. همه چیز درون خود پروسه اتفاق می‌افتد: تونل، یک پشته‌ی TCP/IP در فضای کاربر، و پروکسی. ## فهرست - [اجرا](#اجرا) - [پروتکل‌های انتقال](#پروتکلهای-انتقال) - [پیدا کردن نقطه‌ی اتصال](#پیدا-کردن-نقطهی-اتصال) - [مبهم‌سازی](#مبهمسازی) - [Zero Trust](#zero-trust) - [قواعد مسیریابی](#قواعد-مسیریابی) - [پروکسی بالادست](#پروکسی-بالادست) - [فایل‌های هویت](#فایلهای-هویت) - [استفاده از ایتر به‌عنوان کتابخانه](#استفاده-از-ایتر-بهعنوان-کتابخانه) - [متغیرهای محیطی](#متغیرهای-محیطی) ## اجرا `aether` را بدون آرگومان اجرا کنید تا چند سؤال بپرسد، یا فلگ بدهید تا چیزی نپرسد. هر فلگ یک متغیر محیطی معادل هم دارد، پس همان تنظیمات در کانتینر یا سرویس هم کار می‌کند. `aether --help` همه را فهرست می‌کند. ```sh aether aether --masque --scan balanced aether --wg --noize aggressive --bind 127.0.0.1:1080 ``` برای اطمینان از کار کردن: ```sh curl -x socks5h://127.0.0.1:1819 https://www.cloudflare.com/cdn-cgi/trace ``` پاسخ باید یک colo کلادفلر و `warp=on` نشان بدهد. برای کلاینت‌هایی که SOCKS نمی‌فهمند، یک پروکسی HTTP CONNECT هم اضافه کنید: ```sh aether --http-proxy 127.0.0.1:1820 ``` هر دو لیسنر روی همان تونل کار می‌کنند. آن‌ها را فقط وقتی به `0.0.0.0` ببندید که عمداً می‌خواهید تونل را با شبکه‌تان به اشتراک بگذارید؛ هیچ احراز هویتی روی تماس‌گیرنده‌ها انجام نمی‌شود. ## پروتکل‌های انتقال | انتقال | فلگ | حامل | | --- | --- | --- | | MASQUE | `--masque` (پیش‌فرض) | QUIC/HTTP-3 روی UDP 443 یا HTTP/2 روی TCP 443 | | WireGuard | `--wg` | وایرگارد روی UDP 2408 و پورت‌های جایگزین مستند | | WARP در WARP | `--gool` | یک تونل وایرگارد داخل تونل دیگر | MASQUE پیش‌فرض است چون شکل ترافیک HTTPS معمولی را دارد و کلادفلر هم آن را پروتکل اصلی می‌داند. وقتی QUIC روی UDP محدود شده ولی UDP ساده رد می‌شود، WireGuard را بردارید. `--gool` یک هاپ دوم اضافه می‌کند برای شبکه‌هایی که یک هندشیک WARP تنها را می‌شناسند؛ چون تأخیر اضافه می‌کند، آخرین گزینه باشد. MASQUE دو حامل دارد. HTTP/3 روی QUIC پیش‌فرض است. اگر UDP 443 کلاً بسته باشد، `--h2` همان تونل را روی TCP 443 می‌برد که از شبکه‌هایی که QUIC را دور می‌ریزند عبور می‌کند. ```sh aether --masque --h2 ``` ## پیدا کردن نقطه‌ی اتصال کلادفلر روی نشانی‌های لبه‌ی متعددی جواب می‌دهد و یک شبکه‌ی فیلترشده معمولاً بخشی از آن‌ها را می‌بندد، پس ایتر یک نشانی ثابت ندارد. رنج‌های مستند را جاروب می‌کند، کاندیداها را می‌سنجد و آن را که ترافیک واقعی را حمل می‌کند نگه می‌دارد. هندشیک تنها کافی نیست: هر کاندیدا باید یک بررسی داده‌ی سرتاسری را پاس کند تا پروکسی باز شود. | حالت | رفتار | | --- | --- | | `turbo` | روی اولین کاندیدایی که جواب بدهد می‌ایستد | | `balanced` | پیش‌فرض، چندتا جمع می‌کند و سریع‌ترین را برمی‌دارد | | `thorough` | کل رنج‌ها را جاروب می‌کند، وقتی همه چیز بسته به نظر می‌رسد | | `stealth` | پروب کم و همزمانی پایین، برای شبکه‌هایی که اسکن را می‌بینند | | `ironclad` | برای هر کاندیدا یک تونل کامل و یک درخواست HTTP واقعی | اگر نشانی خوبی را از قبل می‌دانید، اسکن را رد کنید: ```sh aether --peer 162.159.196.1:443 ``` آخرین نقطه‌ی سالم ذخیره می‌شود و `--quick-reconnect` بدون جاروب جدید از همان استفاده می‌کند. نقطه‌ای که همین حالا شکست خورده، مدتی در فهرست انتظار می‌ماند تا تلاش بعدی دوباره روی آن نیفتد. ## مبهم‌سازی بعضی شبکه‌ها بسته‌های اول یک هندشیک را انگشت‌نگاری می‌کنند. ایتر می‌تواند آن‌ها را پد و بازشکل کند تا تبادل ابتدایی با الگوی شناخته‌شده جور نشود. | پروفایل | چه وقت | | --- | --- | | `off` | شبکه بازرسی نمی‌کند | | `light` | مزاحمت خفیف، کمترین سرباری | | `balanced` | پیش‌فرض، نقطه‌ی شروع خوب | | `aggressive` | هندشیک دارد انگشت‌نگاری می‌شود | ```sh aether --noize aggressive ``` دو مورد فقط به MASQUE مربوط است: - `--fragment` روی حامل HTTP/2 پیام ClientHello را تکه می‌کند و بازرس‌هایی را که SNI را از یک بسته می‌خوانند خنثی می‌کند. `--fragment-size` و `--fragment-delay` تنظیمش می‌کنند. - `--ech auto` یک کانفیگ Encrypted Client Hello می‌گیرد و اگر شبکه اجازه بدهد SNI را کاملاً پنهان می‌کند. ## Zero Trust با `--team ` ایتر به‌عنوان یک دستگاه مدیریت‌شده در حساب Zero Trust سازمان شما ثبت می‌شود، به‌جای اینکه یک دستگاه مصرفی ناشناس بسازد. روی MASQUE و WireGuard هر دو کار می‌کند و یک هویت تیمی بین‌شان مشترک است، پس عوض کردن انتقال یک ظرفیت دستگاه دیگر مصرف نمی‌کند. سه راه ورود: | روش | فلگ | مناسب | | --- | --- | --- | | کد ایمیلی | `--access-email ` | کاربری که پشت کیبورد است | | توکن سرویس | `--access-id`, `--access-secret` | سرور و CI | | توکن آماده | `--access-token ` | توکنی که از قبل دارید | ```sh aether --team acme --access-email me@example.com ``` کلادفلر یک کد یک‌بارمصرف ایمیل می‌کند و ایتر آن را می‌پرسد. کد را می‌توان در ترمینال نوشت یا از ورودی استاندارد داد؛ کلاینت‌های دسکتاپ و اندروید از همین راه جواب می‌دهند. سه تلاش دارید. توکن حاصل تا پایان عمر پروسه نگه داشته می‌شود، پس اتصال دوباره سؤال را تکرار نمی‌کند. `--gateway` ترافیک HTTP و HTTPS را از پروکسی Gateway سازمان می‌برد تا فیلترینگ و لاگ آن اعمال شود. پیش‌فرض خاموش است چون یک هاپ داخل تونل اضافه می‌کند و مرورتان را ثبت می‌کند. اگر آن پروکسی از جواب دادن بیفتد، ایتر به خروج مستقیم از تونل برمی‌گردد و همه‌ی اتصال‌ها را نمی‌شکند. ## قواعد مسیریابی دو فهرست تعیین می‌کنند یک مقصد چه اجازه‌ای دارد. `--route-block` اتصال را کاملاً رد می‌کند. `--route-direct` آن را از رابط واقعی شما بیرون می‌فرستد نه از تونل، که همان چیزی است که اپ‌های بانکی، سرویس‌های شبکه‌ی محلی و سایت‌های داخلی که نشانی خارجی را قبول نمی‌کنند لازم دارند. اول block بررسی می‌شود، بعد direct، در غیر این صورت تونل. ```sh aether --route-block ads.example.com,port:25 --route-direct private,bank.ir ``` | ورودی | چه چیزی را می‌گیرد | | --- | --- | | `example.com` | خود نام و همه‌ی زیردامنه‌ها | | `full:example.com` | فقط همان نام دقیق | | `keyword:doubleclick` | هر نامی که شامل آن باشد | | `regexp:^ad[0-9]+` | یک عبارت باقاعده | | `10.0.0.0/8` | یک شبکه، یا یک نشانی تنها | | `port:25`, `port:3000-3010` | یک پورت یا یک بازه | | `private` | فضای شبکه‌ی محلی، لوپ‌بک و CGNAT | فهرست‌های بلند را در فایل بگذارید: ```ini [block] ads.example.com port:25 [direct] private bank.ir ``` ```sh aether --routes /etc/aether/routes.conf ``` قواعد روی TCP و UDP هر دو اعمال می‌شوند. قاعده‌ی جدا برای هر برنامه عمداً اینجا نیست: در حالت tun، ترافیک تا وقتی به ایتر برسد هویت برنامه‌اش را از دست داده، پس آن تفکیک کار کلاینت پلتفرم است. ### قواعد نام پشت tun قواعد نام وقتی هم که به پروکسی به‌جای نام یک نشانی داده می‌شود کار می‌کنند، یعنی همان کاری که tun انجام می‌دهد. ایتر نام را از server name در TLS یا هدر `Host` در اولین بایت‌ها برمی‌دارد و تصمیم را با آن می‌گیرد؛ اگر نامی پیدا نشود، قواعد نشانی و پورت مثل قبل اعمال می‌شوند. نام فقط برای تصمیم استفاده می‌شود، پس اتصال همچنان به همان نشانی‌ای می‌رود که کلاینت خواسته است. | متغیر | پیش‌فرض | کار | | --- | --- | --- | | `AETHER_ROUTE_SNIFF` | روشن | با `0` خاموش می‌شود | | `AETHER_ROUTE_SNIFF_MS` | `400` | چند میلی‌ثانیه منتظر آن بایت‌های اول بماند | ## پروکسی بالادست `--upstream` هر چیزی که ایتر باز می‌کند را از یک پروکسی دیگر می‌فرستد، یعنی روشی که با آن ایتر را پشت یک VPN یا پروکسی درحال‌اجرا زنجیر می‌کنید. ```sh aether --upstream socks5://127.0.0.1:1080 aether --upstream socks5://alice:s3cret@127.0.0.1:1080 aether --upstream http://proxy.example:8080 ``` اگر فقط `host:port` بنویسید، SOCKS5 فرض می‌شود. نشانی IPv6 را داخل کروشه بگذارید. رمزی که `@` یا `:` دارد را درصدکدگذاری کنید، یعنی `p@ss` می‌شود `p%40ss`. | پروکسی | چه چیزی را حمل می‌کند | | --- | --- | | SOCKS5 با UDP associate | همه‌ی پروتکل‌ها: MASQUE روی HTTP/3 و HTTP/2، وایرگارد، `gool` | | HTTP CONNECT | فقط حامل HTTP/2، چون CONNECT نمی‌تواند UDP حمل کند | با پروکسی HTTP، پرچم `--h2` را اضافه کنید تا کل تانل روی TCP بماند: ```sh aether --masque --h2 --upstream http://proxy.example:8080 ``` اسکن نقطه‌ی اتصال، تماس‌های ثبت‌نام و واکشی ECH هم از پروکسی رد می‌شوند. مقصدی که با `--route-direct` انتخاب شده رد نمی‌شود، چون کار آن قاعده دور زدن تانل است. همین تنظیم با `AETHER_UPSTREAM` هم در دسترس است. ## فایل‌های هویت در اجرای اول، ایتر یک دستگاه ثبت می‌کند و اعتبارنامه‌ها را کنار مسیر کانفیگ می‌نویسد، پیش‌فرض `aether.toml`. فایل را نگه دارید: حذفش یعنی ثبت یک دستگاه جدید. | فایل | محتوا | | --- | --- | | `aether.toml` | هویت وایرگارد | | `aether-masque.toml` | هویت MASQUE و گواهی‌اش | | `aether-team-.toml` | یک هویت برای هر تیم Zero Trust | | `aether-*-lastconn.toml` | آخرین نقطه‌ی سالم | با `--config`، `--wg-config` و `--masque-config` می‌توانید مسیرشان را عوض کنید. این فایل‌ها کلید خصوصی دارند و فقط برای مالک خواندنی نوشته می‌شوند. ### وقتی یک هویت دیگر پذیرفته نمی‌شود کلادفلر می‌تواند دستگاهی را که هنوز در فایل شما هست دیگر نپذیرد. در آن حالت هندشیک همچنان موفق می‌شود و ترافیکی رد نمی‌شود، پس ایتر هویت ذخیره‌شده را در شروع بررسی می‌کند و گزارش می‌دهد: ```text [-] cloudflare no longer accepts the saved identity for device [-] the tunnel will handshake but carry no traffic until this identity is replaced ``` بعد یک دستگاه تازه ثبت می‌کند و فایل را بازنویسی می‌کند. با `AETHER_REPROVISION=0` فقط به شما خبر داده می‌شود بدون اینکه چیزی جایگزین شود. تنها رد شدن از سمت API حساب به حساب می‌آید. آفلاین بودن یا خوردن به محدودیت نرخ هویت را دور نمی‌ریزد. ## استفاده از ایتر به‌عنوان کتابخانه جدا از باینری `aether`، این کریت `libaether.a` و `libaether.so` را هم با یک واسط C می‌سازد، تا یک برنامه‌ی میزبان بتواند هسته را لینک کند نه اینکه آن را به‌عنوان پروسه اجرا کند. کلاینت iOS به همین نیاز دارد، و یک برنامه‌ی Go هم می‌تواند از راه cgo از ایتر استفاده کند. ```sh cargo build --release # باینری و هر دو کتابخانه cargo build --release --bin aether # فقط باینری ``` واسط C دستگیره‌محور و مبتنی بر poll است نه callback، پس صدا زدنش از هر رانتایمی امن است. `aether_core_start` کل مسیر را اجرا می‌کند و یک دستگیره‌ی کار برمی‌گرداند، `aether_job_poll` وضعیت را می‌دهد و `aether_job_cancel` متوقفش می‌کند. برای مرحله‌های جداگانه هم توابع مستقل هست: هویت، ورود Zero Trust، اسکن نقطه‌ی اتصال، سنجش، و تونل. هر پاسخ JSON است، هر رشته‌ی برگشتی با `aether_string_free` آزاد می‌شود، و هیچ panic از مرز بیرون نمی‌زند. هدر آن در کلاینت اوبلیوین در `ios/Shared/aether.h` است. مسیر داده کانال‌محور است و هیچ کد دستگاه tun ندارد، پس برنامه‌ی میزبان بسته‌ها را مستقیم می‌دهد و می‌گیرد. ## متغیرهای محیطی هر فلگ یک متغیر معادل دارد. اگر هر دو ست شوند، فلگ برنده است. | متغیر | چه چیزی را تعیین می‌کند | | --- | --- | | `AETHER_SOCKS` | نشانی لیسنر SOCKS5 | | `AETHER_HTTP_PROXY` | نشانی لیسنر HTTP CONNECT | | `AETHER_PROTOCOL` | `masque`، `wg`، `gool` | | `AETHER_SCAN` | حالت اسکن | | `AETHER_NOIZE` | پروفایل مبهم‌سازی | | `AETHER_IP` | `4`، `6`، `dual` | | `AETHER_PEER`، `AETHER_WG_PEER` | تحمیل یک نقطه‌ی اتصال | | `AETHER_QUICK_RECONNECT` | استفاده از نقطه‌ی ذخیره‌شده | | `AETHER_MASQUE_HTTP2`، `AETHER_MASQUE_H2_PEER` | حامل HTTP/2 | | `AETHER_ECH` | `auto` یا یک کانفیگ base64 | | `AETHER_MASQUE_H2_FRAGMENT`، `_SIZE`، `_DELAY` | تکه‌کردن ClientHello | | `AETHER_MASQUE_STARTUP_SECS` | مهلت راه‌اندازی | | `AETHER_MASQUE_VALIDATE_SECS`، `AETHER_WG_VALIDATE_SECS` | مهلت بررسی داده | | `AETHER_MASQUE_NO_DATA_CHECK`، `AETHER_WG_NO_DATA_CHECK` | رد کردن بررسی داده | | `AETHER_MASQUE_RECONNECT_SECS`، `AETHER_WG_RECONNECT_SECS` | تأخیر اتصال دوباره | | `AETHER_WG_KEEPALIVE` | keepalive وایرگارد | | `AETHER_WG_NO_PROFILE_RETRY` | پروفایل‌های دیگر امتحان نشوند | | `AETHER_WG_ENDPOINT_COOLDOWN_SECS` | مدت کنار گذاشتن نقطه‌ی ناموفق | | `AETHER_DNS` | سرورهای DNS داخل تونل | | `AETHER_TEAM` | نام تیم Zero Trust | | `AETHER_ACCESS_EMAIL` | ایمیل برای کد یک‌بارمصرف | | `AETHER_ACCESS_CLIENT_ID`، `AETHER_ACCESS_CLIENT_SECRET` | توکن سرویس | | `AETHER_ACCESS_TOKEN` | توکن ورودی که از قبل دارید | | `AETHER_GATEWAY` | عبور HTTP از گیت‌وی سازمان | | `AETHER_ROUTE_BLOCK`، `AETHER_ROUTE_DIRECT`، `AETHER_ROUTES_FILE` | قواعد مسیریابی | | `AETHER_ROUTE_SNIFF`، `AETHER_ROUTE_SNIFF_MS` | خواندن نام از اولین بایت‌ها | | `AETHER_UPSTREAM` | خروج از یک پروکسی دیگر | | `AETHER_REPROVISION` | جایگزینی هویتی که کلادفلر نمی‌پذیرد | | `AETHER_CONFIG`، `AETHER_WG_CONFIG`، `AETHER_MASQUE_CONFIG` | مسیر فایل هویت | | `AETHER_TLS_GROUPS` | گروه‌های کلید TLS | | `AETHER_PERF_PROFILE` | `low`، `medium`، `high` | | `AETHER_LOG_LEVEL` | از `error` تا `trace` |