VPN اندروید بدون روت: مالکیت رضایت، مسیرها و مسدودسازی
رضایت، رابط TUN و سیاست مسدودسازی سیستم سه مجوز متفاوت هستند. پیش از بررسی یک برنامه VPN اندروید مشخص کنید هر یک متعلق به کدام مؤلفه است.
روت چیزی نیست که به یک برنامه VPN اندروید امکان دهد ترافیک را حمل کند، نشتها را مسدود کند یا از راهاندازی مجدد جان سالم به در ببرد. مردم همه اینها را در «برنامه مجوز VPN دارد» خلاصه میکنند، که سه سازوکار جدا را پنهان میکند: رضایتی که کاربر میدهد، رابط بستهای که سیستم ایجاد میکند، و سیاست مسدودسازی پلتفرم که تعریف آن کار برنامه نیست. بررسی یک طراحی VPN اندروید یعنی پرسیدن اینکه یک ادعا واقعاً بر کدام یک از این سه تکیه دارد، چون هر یک مالک و حالت شکست متفاوتی دارد.
رضایت از طریق یک فعالیت سیستمی میآید
VpnService.prepare() چیزی اعطا نمیکند. وقتی رضایت وجود ندارد، یک intent به فعالیت رضایت سیستم برمیگرداند و برنامه آن گفتگو را باز میکند تا کاربر سرویس را تأیید کند. راهاندازی فرایند خود برنامه، افزودن مجوز به مانیفست، یا نمایش صفحه سفارشی «فعالسازی VPN» این اجازه را ایجاد نمیکند.
این اجازه دامنه هم دارد. به یک بسته در یک نمایه کاربری تعلق دارد، بنابراین نسخه شخصی و نسخه کاری دو تصمیم جدا هستند، و مالک دستگاه میتواند نمایه مدیریتشده را متفاوت از نمایه شخصی آماده کند. اگر گفتگو هرگز ظاهر نشود و prepare() مقدار null برگرداند، رضایت از قبل برای آن بسته در آن نمایه وجود دارد؛ این شاهدی بر قابلاعتماد بودن برنامه نیست، فقط نشان میدهد اجازه برقرار است.
رابط درخواستی است که سیستم برآورده میکند
پس از رضایت، برنامه با VpnService.Builder توصیف میکند چه میخواهد: نشانیها، مسیرها، سرورهای DNS، MTU و در صورت پشتیبانی، برنامههایی که باید شامل یا حذف شوند. establish() از سیستم میخواهد رابط تونل را بسازد و ترافیک منطبق را به آن هدایت کند. تصمیم مسیریابی متعلق به سیستم است؛ برنامه توصیفگر فایل را میگیرد و سپس باید با بستهها کاری مفید انجام دهد.
| What you observe | Who actually owns it |
|---|---|
| VPN consent dialog | The system, triggered by prepare() |
| Routes, DNS and app lists | The app requests them; the system applies them |
| One active VPN per profile | The platform; a new service replaces the old one |
| Always-on and block-without-VPN | Device policy enforced by the platform |
این جدول معماری را در یک جا نشان میدهد. برنامه در پردازش بسته مشارکت دارد؛ مالک رابط، جدول مسیریابی یا تعداد سرویسهایی که میتوانند اجرا شوند نیست.
سوکت تونل باید از تونل خودش فرار کند
اتصالی که ترافیک رمزنگاریشده را حمل میکند خودش یک سوکت است. اگر به رابطی که برنامه تازه ساخته است بازگردانده شود، تونل به تونل وابسته میشود و متوقف میشود. VpnService.protect() آن سوکت را به شبکه زیرین میبندد تا از ضبط عبور کند، و به همین دلیل یک کارخواه درست سوکت بیرونی خود را پیش از نخستین دستدهی محافظت میکند.
adb shell dumpsys connectivity | grep -i -A5 vpn
adb shell settings get global always_on_vpn_app
adb shell settings get global always_on_vpn_lockdown
این فرمانها شبکه VPN نصبشده، بسته همیشهروشن و اینکه قفل تنظیم شده است یا نه را نشان میدهند. آنها مشاهداتی فقط-خواندنی هستند: اگر مقادیر با آنچه طراحی ادعا میکند همخوان نباشد، ادعا درباره رابط برنامه است نه وضعیت سیستم.
مسدودسازی ممکن است متعلق به پلتفرم باشد
اندروید سیاستی را مستند میکند که اتصالاتی را که از VPN استفاده نمیکنند مسدود میکند. آن اعمال، قرارداد پلتفرم است، نه برنامهای که در حلقه اتصال را دوباره امتحان میکند. کلید آن در تنظیمات VPN دستگاه با نام مسدود کردن اتصالات بدون VPN قرار دارد، و روی دستگاه مدیریتشده مالک دستگاه میتواند آن را برای کل نمایه روشن کند. این تفاوت هنگام ارزیابی یک ادعای بازاریابی مهم است: کارخواه میتواند نماد قفل نشان دهد و تهاجمی دوباره متصل شود در حالی که ترافیک مستقیم هنوز ممکن است، یا برنامههای پوششدادهشده میتوانند آفلاین بمانند چون سیستم قفل را اعمال میکند.
نماد قفل را برنامه رسم میکند، پس فقط ثابت میکند برنامه باور دارد متصل است. اینکه برنامه دیگری دسترسی شبکهاش را از دست بدهد را پلتفرم تعیین میکند، بنابراین بررسی مفید این است که ببینید آن برنامه در حالی که تونل برقرار است شکست میخورد.
برچسب «همیشه روشن» فروشگاه برنامه هم جایگزین آن قرارداد نمیشود. همیشهروشن و قفل تنظیمات دستگاه هستند، اغلب توسط مالک دستگاه اعمال میشوند، و رفتارشان برای برنامههای مستثنی را پلتفرم تعریف میکند. تنظیم را بخوانید، نه نشان را.
چهار پرسش برای بازبینی طراحی
نخست، چه کسی رضایت داد: کدام بسته، کدام نمایه، و آیا کاربر بود یا سیاست دستگاه مدیریتشده؟ دوم، برنامه چه خواست: کدام مسیرها، کدام خانوادههای نشانی، کدام برنامههای شامل یا مستثنی؟ سوم، وقتی تونل در دسترس نیست چه میشود: سیستم مسدود میکند یا ترافیک به شبکه زیرین بازمیگردد؟ چهارم، برنامه با بستههایی که دریافت میکند چه میکند؟
پرسش چهارم همانی است که مدل مجوزها نمیتواند پاسخ دهد. رضایت و رابط TUN ثابت میکنند برنامه میتواند ترافیک دریافت کند، نه اینکه آن را رمزنگاری میکند، طرف مقابل را احراز هویت میکند یا پاک بازیابی میشود. اینها ویژگیهای پیادهسازیاند و بازبینی صادقانه وقت خود را همانجا میگذارد.
درخواست روت بیضرورت با نامیدن نتیجه به «کلید کشتار» مشروع نمیشود، و گفتگوی رضایت یک ممیزی امنیتی نیست. سه اجازه را جدا نگه دارید تا هر ادعا قابل بررسی شود.