تونل کامل دستگاه برای شبکههای تحت سانسور — پنج مسیر ترابری، هستهٔ Rust، رابط بومی اندروید
فارسی · English
برنامه MSN-GUARD یک کلاینت VPN بومی اندروید است که کل ترافیک گوشی را از پنج مسیر مستقل عبور میدهد. فرقش با اپهای پروکسی این است که آنها معمولاً فقط مرورگر را پوشش میدهند؛ اینجا کار در سطح VpnService خود اندروید انجام میشود. یعنی یک اینترفیس TUN ساخته میشود و هر بستهٔ TCP و UDP و QUIC — از هر اپی که روی گوشی نصب است — از داخل تونل رد میشود.
ساختار برنامه دو تکه است. یک هستهٔ شبکه به زبان Rust که خودش پروتکلها را پیاده کرده و با گیتوی مذاکره میکند، و یک لایهٔ Kotlin که چرخهٔ حیات VPN و رابط کاربری و کارهای مربوط به پلتفرم را به عهده دارد. دو مسیر آخر — Psiphon و Tor — هستهٔ خودشان را دارند و از طریق SOCKS محلی به همین TUN وصل میشوند. هیچ سرور واسطی از طرف ما وسط نیست؛ گوشی مستقیم با گیتوی بالادست حرف میزند.
نکتهای که این پروژه را از یک اپ عمومی جدا میکند این است: هدفش شبکههای ایران بوده و هر انتخاب پروتکلی که داخلش میبینید از اندازهگیری واقعی روی اپراتورهای داخلی بیرون آمده، نه از حدس و نه از مستندات. هرجا نتیجهٔ اندازهگیری با مستندات رسمی فرق داشت، اندازهگیری برنده شد.
دربارهٔ آنچه در این سند نوشته نشده. راهبرد اتصال — پارامترهای دستدهی، نحوهٔ انتخاب و رتبهبندی گیتوی، ترتیب نردبان، بودجههای زمانی و آن مقادیر مشخصی که باعث میشود یک نشست از فیلتر فعال جان سالم ببرد — حاصل یک دورهٔ طولانی و پرهزینهٔ آزمایش روی شبکههای واقعی است. این جزئیات آگاهانه اینجا منتشر نشدهاند. این سند توضیح میدهد برنامه چه میکند و چرا این شکل را دارد؛ نسخهٔ آمادهٔ عبور از فیلتر تحویل نمیدهد. عمر مفید یک دستاورد در این حوزه به این بستگی دارد که چقدر سریع کپی شود، و آنهایی که واقعاً کار میکنند نوشته نمیشوند.
| تونل کل دستگاه | با VpnService و TUN؛ همهٔ اپها بدون تنظیم اضافه پوشش میگیرند |
| پنج مسیر ترابری | پروتکلهای MASQUE روی HTTP/3، WireGuard، WARP-on-WARP، Psiphon و Tor |
| حالت Tor و Tor روی WARP | شبکهٔ Tor بهتنهایی، یا داخل تونل MASQUE برای شبکهای که خود Tor را بسته |
| انتخاب کشور خروج | ۲۷ کشور برای Tor و ۲۵ کشور برای Psiphon، با تعداد واقعی رله و سرور هر کدام |
| اتصال یککلیکی | فقط یک دکمه؛ انتخاب گیتوی و مذاکره و بازیابی همه خودکار انجام میشود |
| پشتیبانی واقعی UDP و QUIC | دیتاگرامها در فضای کاربر پل میشوند، پس ویدیو و بازی و تماس صوتی کار میکند |
| نمایش زندهٔ وضعیت | نشانی IP خروجی با پرچم کشور، مصرف داده، مدت اتصال و لاگ لحظهای |
| کاشی تنظیمات سریع | وصل و قطع کردن از Quick Settings بدون باز کردن برنامه |
| تونل تفکیکی | انتخاب اپهایی که باید بیرون تونل بمانند |
| قطعکن اضطراری | اگر تونل بیفتد، شبکه کامل قطع میشود تا ترافیک لو نرود |
| اجبار DNS | فقط resolver عمومی استفاده میشود و DNS اپراتور کامل کنار گذاشته میشود |
| اتصال تأییدشده | دایره تا وقتی ترافیک واقعاً رد نشده باشد، موفقیت اعلام نمیکند |
مسیر یک بستهٔ خروجی از اپ کاربر تا اینترنت:
۱. اپ کاربر بستهٔ خروجی را میفرستد.
۲. بسته وارد اینترفیس TUN اندروید میشود.
۳. پشتهٔ tun2socks همراه lwIP آن را در فضای کاربر ترمینیت میکند.
۴. سپس به SOCKS محلی روی loopback تحویل داده میشود.
۵. هستهٔ Rust کار رمزنگاری و کپسولهسازی را انجام میدهد.
۶. بسته به گیتوی بالادست میرود و از آنجا به اینترنت.
سه لایهٔ کد که این مسیر را میسازند:
لایهٔ Kotlin — رابط و چرخهٔ حیات
| فایل | کارش |
|---|---|
کلاس MainActivity |
رابط کاربری، کنسول اتصال، تنظیمات |
سرویس MsnGuardVpnService |
چرخهٔ حیات VPN، ساخت TUN، سرپرستی ترابری |
سرویس MsnGuardTileService |
کاشی تنظیمات سریع |
کلاس Tun2SocksManager |
مدیریت پروسهٔ بومی tun2socks |
کلاس TorManager |
راهاندازی tor، نوشتن torrc، نردبان حالتها و پلهای وابسته |
کلاس TorSocksFront |
پیشانی SOCKS برای Tor؛ همان جایی که DNS به DNSPort خود Tor میرود |
هستهٔ Rust — کامپایل میشود به libaether.so
| فایل | کارش |
|---|---|
فایل prober.rs |
پیدا کردن و رتبهبندی گیتویها |
فایل account.rs |
ثبتنام دستگاه و صدور گواهی |
فایل quic.rs |
ترابری QUIC و HTTP/3 |
فایل masque.rs |
کپسولهسازی CONNECT-IP |
فایل wireguard.rs |
دستدهی Noise و ترابری WireGuard |
فایل netstack.rs |
پل بستهٔ سطح TUN |
لایهٔ C — پردازش بسته
پشتهٔ badvpn tun2socks همراه با lwIP که TCP را در فضای کاربر ترمینیت میکند، و یک پل دیتاگرام جداگانه که ترافیک UDP و QUIC را روی loopback جابهجا میکند.
اینجا CONNECT-IP روی QUIC پیاده شده و پایهاش کتابخانهٔ quiche است. از دید شبکه، این ترافیک از یک اتصال HTTPS معمولی قابل تشخیص نیست — و دقیقاً همین هدف است، چون هیچ اثر انگشت پروتکلی خاصی برای DPI باقی نمیگذارد.
چهار نکته که ارزش گفتن دارند، بدون اینکه بگویند چطور:
- مقداری از هدر شبهاستاندارد که لبهٔ شبکه واقعاً قبول میکند، همان مقدار ثبتشده در استاندارد نیست. مقدار استاندارد مستقیم رد میشود. پیدا کردن آن گونهٔ درست با آزمون دوبخشی روی یک لبهٔ زنده انجام شد و هیچجای عمومی مستند نشده است.
- روی HTTP/2 این کار عملاً ممکن نیست. مسیر h2 هیچوقت آن قابلیتی را که این ترابری به آن وابسته است اعلام نمیکند، پس مذاکره پیش از شروع میمیرد. فقط HTTP/3 جواب میدهد. اینجا fallback روی HTTP/2 یک حالت تنزلیافته نیست، کد مرده است.
- ترتیب گیتویهای اولیه اندازهگیری شده است، نه الفبایی. بیشتر آدرسهای منتشرشده دستدهی را رد میکنند؛ فقط اقلیت کوچکی ترافیک را حمل میکنند و این رتبهبندی داخل بیلد جاسازی شده، نه در زمان اجرا کشف میشود.
- گیتویای که باید استفاده شود از یک پاسخ ثبتنام مشخص میآید — و پاسخ دومی هم وجود دارد که به همان اندازه معتبر به نظر میرسد و غلط است. استفاده از پاسخ اشتباه یک دستدهی تمیز به گیتویای میدهد که هرگز بستهٔ شما را حمل نخواهد کرد، و خواندن این خرابی از لاگ واقعاً سخت است.
یک بودجهٔ راهاندازی کوتاه و ثابت بر کل این توالی حاکم است. گیتویای که یکبار جواب داده و بعد سکوت کند کُند نیست، گیر کرده؛ اتصال مجدد از انتظار کشیدن بهتر است و برنامه منتظر نمیماند.
ترابری مستقیم با دستدهی کامل Noise، برای شبکههایی که UDP را نبستهاند. هرجا کار کند، سریعترین گزینه است و به همین ترتیب هم امتحان میشود.
یک قاعدهٔ گرانقیمت بر این مسیر حاکم است: همان سوکتی که اعتبارسنجی را پاس کرد، باید ترافیک را حمل کند. اعتبارسنجی یک تونل و بعد ساختن دوبارهٔ آن معادل هم نیستند، چون اپراتور میتواند یک جریان را بپذیرد و جریان بعدی که کاملاً شبیه آن است را دور بیندازد. برنامه دیگر این کار را نمیکند، و همین است که اتصال واقعی WireGuard را از اتصالی که فقط دستدهی میکند جدا میکند.
یک تونل WireGuard که داخل تونل WireGuard دیگری میرود. جایی به کار میآید که مسیر بیرونی در دسترس باشد ولی نقطهٔ پایانی درونی نه — که روی بعضی اپراتورها وضعیت واقعی است، و وقتی ترابری WireGuard وجود دارد پشتیبانیاش کمهزینه است.
پروتکل Psiphon با یک نردبان سهپلهای اجرا میشود که بر اساس زمان واقعیِ اتصال روی اپراتور خصمانه مرتب شده. این ترتیب همان چیزی نیست که پیشفرضهای خود Psiphon میدهند، و تفاوتش هم جزئی نیست.
دلیلش یک اندازهگیری است، و همین بخش بدون جزئیات هم ارزش فهمیدن دارد. روی بدترین اپراتور آزمایششده، هر دیال مستقیم در لایهٔ TCP شکست میخورد. نه reset میآید، نه هشدار TLS، نه خطای دستدهی — بستهها اصلاً نمیرسند، چون اپراتور آدرس سرورهای مربوطه را null-route کرده. پس هر راهبردی که یک آدرس سرور قابلبلاک ارائه بدهد از همان ابتدا مرده است، مهم نیست چقدر بودجه بگیرد. فقط کسر کوچکی از لیست سرور جاسازیشدهٔ خود ابزار از آن دسته راهبردی پشتیبانی میکند که از این وضع جان سالم میبرد، و همین باعث میشود ترتیب پیشفرض تمام بودجهاش را صرف زنگ زدن به آدرسهایی کند که هیچوقت جواب نمیدهند.
نردبان بر همین اساس چیده شده، هر پله بودجهٔ زمانی خودش را دارد، و پلهٔ برنده برای هر سیمکارت ذخیره میشود تا هر دستگاه از همان چیزی شروع کند که روی شبکهٔ خودش واقعاً کار میکند. راهبرد پلهها، ترتیب و بودجههایشان آگاهانه مستند نشده است.
کشور خروج هم قابل انتخاب است: ۲۵ کشور که در لیست سرور جاسازیشدهٔ خود Psiphon حضور دارند، با تعداد سرور هر کشور کنارش. جمع کل این لیست ۴۳۰ سرور است و آمریکا و کانادا هر کدام ۶۵ تا از آن را دارند.
نسخهٔ ۱.۵.۰ شبکهٔ Tor را بهعنوان پنجمین مسیر اضافه کرد. اینجا نه از Orbot استفاده میشود و نه از هیچ اپ واسطی؛ خود tor نسخهٔ 0.4.9.11 برای اندروید کراسکامپایل میشود و بههمراه lyrebird 0.8.1 — که obfs4 و meek_lite و snowflake را با هم سرو میکند — داخل APK قرار میگیرد. یعنی سه لایه رمزنگاری Tor روی کل ترافیک گوشی اعمال میشود، نه فقط روی مرورگر.
چهار حالت اتصال در دسترس است و یک حالت خودکار که خودش بینشان میگردد:
| حالت | چه میکند | کجا به کار میآید |
|---|---|---|
| حالت Auto | نردبان را از بالا امتحان میکند تا یکی وصل شود | پیشنهاد پیشفرض؛ سریعترین گزینه در عمل |
| حالت Direct | بدون پل، مستقیم به شبکهٔ Tor | شبکهای که Tor را نبسته باشد |
| پروتکل obfs4 | پلی که شکل ترافیک Tor را میپوشاند | جایی که Tor بلاک است ولی پلها اسکن نشدهاند |
| پروتکل Meek | ترافیک را سوار یک CDN میکند | سختترین حالت برای بلاک شدن، و کندترین |
| شبکهٔ Snowflake | پروکسیهای داوطلبانهٔ WebRTC | آخرین تیر ترکش وقتی بقیه جواب ندادهاند |
ترتیب نردبان خودکار همین است: Direct، بعد Meek، بعد obfs4، و آخر Snowflake. منطقش این است که Direct هرجا کار کند هم سریعتر وصل میشود و هم سریعتر کار میکند؛ Meek تقریباً همهجا وصل میشود چون از دید شبکه ترافیک HTTPS به سمت یک CDN است، ولی هر سلول یک رفتوبرگشت HTTP هزینه دارد. پلهای عمومی obfs4 اولین چیزی هستند که یک سانسورگر جدی اسکن میکند، و Snowflake پرنوسانترین پلهٔ این چهار تاست چون باید از طریق یک broker یک پروکسی داوطلب پیدا کند.
حالت Tor روی WARP. این گزینه Tor را داخل تونل MASQUE میاندازد: لایهٔ بیرونی WARP است و Tor داخلش بالا میآید. جایی به کار میآید که اپراتور خود دسترسی به شبکهٔ Tor را بسته باشد — از دید اپراتور شما فقط یک اتصال HTTPS دارید، و Tor از جایی شروع میشود که آن اتصال تمام میشود.
نکتهای که باید بدانید: فقط Direct و Meek اجازهٔ زنجیره شدن دارند. این محدودیت از اندازهگیری آمد، نه از احتیاط. روی سرور خودمان و از داخل یک SOCKS5 واقعی، Direct در ۱۲ تا ۱۵ ثانیه به ۱۰۰٪ رسید و Meek در ۳۶ ثانیه با ۷۵ دیال CDN که همه از پروکسی رد شدند. ولی obfs4 بین دو اجرای پشتسرهمِ همان پل یکبار روی ۱۰٪ و یکبار روی ۸۵٪ گیر کرد — آن هم بدون هیچ پروکسیای. پس دلیل حذفش این نیست که ثابت شد پروکسی به آن آسیب میزند؛ دلیلش این است که هیچوقت ثابت نشد روی این پلها اصلاً قابل اتکاست، و گذاشتن یک پلهٔ پرنوسان داخل تونلی که خودش یک دستدهی اضافه هزینه دارد فقط باعث میشود وقت خرابی نفهمید کدام لایه خراب شده. Snowflake هم broker و دیالهای WebRTC خودش را دارد که یک CONNECT ساده در SOCKS5 نمیتواند حملشان کند. هر دو بدون زنجیره کاملاً در دسترساند.
انتخاب کشور خروج در Tor. ۲۷ کشور در لیست هست و کنار هر کدام تعداد رلهٔ خروجی واقعیاش نوشته شده، چون همان عدد صادقترین پیشبینی است از اینکه انتخابتان محترم شمرده میشود یا نه. آمار از سرویس onionoo خود پروژهٔ Tor گرفته شده: ۳۲۷۵ رلهٔ خروجی فعال در ۵۲ کشور، که سه کشور اول بیش از دو سومش را در دست دارند. برش لیست روی پنج رله است — کشوری که یک یا دو رلهٔ خروجی دارد، کنترلی میشود که بیشتر وقتها کار نمیکند، و چنین کنترلی بهتر است اصلاً نباشد.
اینجا StrictNodes 0 تنظیم شده، یعنی انتخاب کشور یک ترجیح است نه یک تضمین؛ اگر Tor نتواند در آن کشور مداری بسازد، جای دیگری میرود. این آگاهانه است و رابط کاربری هم همین را میگوید: با StrictNodes 1 کشوری که چند رلهٔ خروجی دارد به بنبست تبدیل میشود — در آزمایش ما {gr} با این تنظیم ۴۲ دقیقه روی ۴۵٪ ماند و هیچوقت وصل نشد.
راستی یک چیز را از تجربه بگویم: حالت اتوماتیک تقریباً همیشه از انتخاب دستی کشور سریعتر است، چون Tor آزاد میماند نزدیکترین مدار سالم را بردارد.
بحث حلقهٔ مسیریابی. خود پروسهٔ تونل باید بیرون تونل خودش بماند، وگرنه ترافیکش به TUN برمیگردد و حلقه میسازد. بستهٔ خود برنامه از اینترفیسی که میسازد کنار گذاشته میشود. این خرابی بهجای خطا، به شکل یک توقف کامل و مرموز ظاهر میشود؛ پس بهتر است قبل از اینکه دنبالش در کد ترابری بگردید، از وجودش خبر داشته باشید.
مسئلهٔ UDP و QUIC. پشتهٔ lwIP فقط TCP را ترمینیت میکند. دیتاگرامها از یک پل جداگانه در فضای کاربر با سقف مشخصی از اتصال همزمان رد میشوند. بدون این، QUIC و بازی آنلاین و بیشتر تماسهای صوتی از کار میافتند در حالی که مرور معمولی TCP سالم به نظر میرسد — خرابیای که راحت با «تونل کُند» اشتباه گرفته میشود.
مقدار MTU. ثابت است و مقدارش با اندازهگیری انتخاب شده: هر مقدار کوچکتری باعث تکهتکه شدن بسته و افت محسوس سرعت روی مسیر MASQUE میشد.
پورت SOCKS. یک پورت ثابت روی loopback و غیرقابل تغییر. در حالت VPN هیچچیز بیرونی به آن بایند نمیشود، پس قابل تنظیم بودنش فقط جای خطا باز میکرد.
صف بستهٔ قبل از آماده شدن تونل. اندروید TUN را قبل از وجود داشتن تونل بالا میآورد، پس چند ثانیه ترافیک دستگاه پشت آن جمع میشود. رفتار قبلی این بود که همان لحظه که استریم باز میشد کل این انبوه بسته روی یک اتصال تازه ریخته میشد، در حالی که پنجرهٔ ازدحام هنوز روی مقدار اولیه بود — و پاسخ دستدهی مجبور میشد با آن سیل بر سر فضای پنجره رقابت کند و گرسنه میماند. الان این بستهها تا تأیید تونل کنار گذاشته میشوند و تعدادشان هم در لاگ میآید. این بزرگترین برد پروژه در کاهش تأخیر اتصال بود.
تشخیص رد هویتی. فقط خرابی واقعی احراز هویت باعث بیاعتبار شدن ثبتنام میشود. وضعیت «درخواست بدشکل» دقیقاً همان معنی را دارد و نه چیز دیگر. قاطی کردن این دو باعث میشد یک ثبتنام سالم بیدلیل دور ریخته شود و ثبتنام مجدد بیفایده راه بیفتد.
وضعیت صادق اتصال. رابط کاربری به دستدهی اعتماد نمیکند. بعد از اینکه ترابری موفقیت اعلام کرد، برنامه شمارندههای بایتی را که از داخل پل بسته میآیند تماشا میکند و اگر در یک بازهٔ کوتاه هیچچیز واقعاً جابهجا نشده باشد، دایره به حالت تنزل میرود و همین را میگوید. اپراتور میتواند دستدهی را جعل کند؛ عبور داده از تونل را نمیتواند.
آدرسدهی. اینترفیس TUN روی یک بازهٔ خصوصی قرار میگیرد، DNS به resolver عمومی اجبار میشود و DNS اپراتور کامل حذف میشود.
مسیر DNS در حالت Tor فرق دارد. روی چهار مسیر دیگر resolver عمومی اجبار میشود، ولی در Tor تنها resolver خودِ DNSPort تور است و هیچ آدرس عمومیای در لیست نیست. این تفاوت عمدی است: اگر یک resolver عمومی آنجا نوشته میشد، پرسوجوی DNS اپها بیرون از مدار و بهصورت واضح به کلادفلر میرفت و دقیقاً لو میداد کاربری که Tor روشن کرده دنبال چه سایتی است. تور هم برای بوتاسترپ به resolver عمومی نیازی ندارد، چون پلها با IP گرفته میشوند و بستهٔ خود برنامه بیرون TUN است.
سقف جدول UDP روی مسیر Tor. در حالت Tor فقط پرسوجوی DNS از پل دیتاگرام رد میشود و بقیهٔ UDP — یعنی QUIC و NTP و STUN — همانجا دور ریخته میشود. دلیلش این است که Tor از اساس UDP را حمل نمیکند، پس آن بستهها در هر صورت به مقصد نمیرسیدند؛ ولی وقتی به جدول تحویل داده میشدند هر جریان تازه یکی از ۲۵۶ خانهٔ جدول را برای همیشه میگرفت تا جدول پر شود و بعد پاسخهای DNS روی خانههای بازیافتشده بنشینند و اسمها وسط کار از کار بیفتند. اپها همانطور که همیشه میکنند به TCP برمیگردند.
آخرین APK را میتوانید از بخش Releases یا از artifact های Actions بگیرید. نسخهٔ فعلی 1.5.0 است و خود برنامه هم آپدیت را از همان صفحهٔ Releases چک میکند.
| معماری دستگاه | فایل |
|---|---|
| معماری ARM ۶۴ بیتی، یعنی اکثر گوشیهای امروزی | MSN-GUARD-v1.5.0-arm64-v8a.apk |
| معماری ARM ۳۲ بیتی، دستگاههای قدیمیتر | MSN-GUARD-v1.5.0-armeabi-v7a.apk |
حداقل نسخهٔ اندروید ۸.۰ یا همان API 26 است. موقع نصب اجازهٔ نصب از منبع نامشخص را بدهید و در اولین اتصال، درخواست مجوز VPN اندروید را تأیید کنید.
پیشنیازها: JDK 17 و Android SDK 36 و NDK نسخهٔ 26.3.11579264 و CMake نسخهٔ 3.22.1 و Rust نسخهٔ stable با هدفهای اندروید و cargo-ndk.
rustup target add aarch64-linux-android armv7-linux-androideabi
cargo install cargo-ndk
./gradlew assembleDebug -PtargetAbi=arm64-v8a,armeabi-v7aخروجی در app/build/outputs/apk/debug/ ساخته میشود. اسکریپت core/build-android.sh هستهٔ Rust را برای هر ABI کامپایل میکند و libaether.so را سر جایش میگذارد؛ خود Gradle این اسکریپت را صدا میزند و لازم نیست دستی اجرایش کنید.
هر push روی شاخهٔ master گردشکار build.yml را اجرا میکند و APK هر دو معماری را بهعنوان artifact آپلود میکند.
| مسیر | محتوا |
|---|---|
مسیر app/src/main/java/…/ |
کلاینت Kotlin |
فایل app/src/main/cpp/aether_jni.cpp |
پل JNI بین Kotlin و هستهٔ Rust |
پوشهٔ app/src/main/cpp/badvpn/ |
پشتهٔ tun2socks و lwIP، وندورشده |
پوشهٔ core/aether/src/ |
هستهٔ شبکهٔ Rust |
پوشهٔ core/quiche/ |
کتابخانهٔ QUIC و HTTP/3 کلادفلر، وندورشده |
پوشهٔ app/src/main/jniLibs/ |
باینریهای tor و lyrebird که CI ساخته و اینجا commit شدهاند |
مسیر tools/build-tor.sh |
کراسکامپایل tor برای اندروید |
مسیر tools/filter-geoip.py |
کوچک کردن دیتابیس GeoIP به همان کشورهایی که برنامه پیشنهاد میدهد |
پوشهٔ .github/workflows/ |
گردشکار ساخت در CI |
پوشهٔ docs/ |
مستندات و داراییهای برند |
آمار زبانهای مخزن با .gitattributes تصحیح شده است. پوشهٔ core/quiche و badvpn بهعنوان vendored علامت خوردهاند تا نوار زبانها کدی را نشان بدهد که برای این پروژه نوشته شده — یعنی Rust و Kotlin — نه آن ۷.۶ مگابایت کتابخانهٔ ثالثی که فقط برای build لازم است.
مسائل امنیتی مربوط به تونل یا اعتبارنامه یا ترافیک را در issue عمومی مطرح نکنید. راهنمای گزارش خصوصی در SECURITY.md آمده است.
هیچ اعتبارنامه و کلید و توکنی داخل این مخزن نگه داشته نمیشود. گواهی دستگاه در زمان اجرا روی خود گوشی صادر و ذخیره میشود.
درخواست برای پارامترهای مشخص اتصال، رتبهبندی گیتویها یا پیکربندی نردبان پاسخ داده نمیشود، نه در issue و نه هیچجای دیگر. منتشر کردنشان عمر همان چیزی را که قرار است باز کند کوتاه میکند، برای همهٔ کاربرانش.
این پروژه تحت GNU AGPL-3.0 منتشر شده است. کتابخانههای وندورشده مجوز خودشان را دارند:
- کتابخانهٔ quiche برای QUIC و HTTP/3 با مجوز BSD-2-Clause
- پروژهٔ badvpn برای tun2socks با مجوز BSD-3-Clause
- پشتهٔ lwIP بهعنوان TCP/IP با مجوز BSD-3-Clause
- هستهٔ تونل Psiphon با مجوز GPL-3.0
- نرمافزار Tor با مجوز BSD-3-Clause
- ابزار lyrebird برای obfs4 و meek و snowflake با مجوز BSD-2-Clause
توسعه و نگهداری: mbm110