شبیهساز اندروید و VPN میزبان: عکس فوری DNS و توضیح NAT
مهمان پشت NAT شبیهساز مینشیند و فهرست DNS کپیشده در زمان بوت را نگه میدارد. تونل را پیش از بوت برقرار کنید، سپس حل نام را از داخل مهمان آزمایش کنید.
وقتی شبیهساز به سروری build نمیرسد که مرورگر میزبان آن را بیمشکل باز میکند، پرسش سودمند این نیست که آیا VPN کار میکند. بلکه این است که کدام یک از دو سازوکار را مهمان ندارد. دستگاه مجازی پشته شبکه خودش را پشت NAT شبیهساز اجرا میکند، و فهرست حلکنندههای آن نسخهای است که هنگام بوت گرفته شده، پس تونلی که بعداً بالا بیاید مسیر میزبان را عوض میکند بیآنکه چیزی را که مهمان میپرسد عوض کند. فهم این دو لایه تقریباً هر گونه از این مشکل را توضیح میدهد.
مهمان پشتهای جداگانه پشت NAT ثابت است
شبکه QEMU در حالت کاربر مهمان را روی 10.0.2.15، دروازه را روی 10.0.2.2 و سرویس DNS را روی 10.0.2.3 تا 10.0.2.6 قرار میدهد. ترافیک خروجی مهمان را هسته میزبان ارسال نمیکند؛ به سوکتهایی در سمت میزبان ترجمه میشود، یکی برای هر اتصال مهمان، و آن سوکتها از فضای نشانی میزبان بیرون میروند. به همین دلیل اتصال مهمان تصمیم مسیریابی میزبان را در لحظه ساخته شدن به ارث میبرد، و به همین دلیل مهمان هیچ ورودی در جدول مسیریابی ندارد که تونل شما را نام ببرد.
همین سازوکار یک راه خروج سودمند به مهمان میدهد. 10.0.2.2 نامی دیگر برای رابط حلقه بازگشتی میزبان است، پس سرویسی که روی 127.0.0.1 در لپتاپ گوش میدهد از مهمان روی آن نشانی در دسترس است. هر چیزی که کلاینت فقط روی حلقه بازگشتی عرضه کند از این راه در دسترس است، و این پایه چیدمان واسطهای است که در ادامه توضیح داده میشود.
آنچه مهمان نمیتواند انجام دهد مشاهده شبکه میزبان است چنان که گویی فضای نامی روی آن است. پلی نیست، جدول مسیریابی مشترکی نیست و حلکننده به ارث رسیدهای نیست؛ فقط سرویس NAT که بستههایش را میپذیرد و عکس فوریای که راهانداز هنگام شروع دستگاه مجازی گرفته است.
DNS یک عکس فوری است، نه نمای زنده
هنگام راهاندازی شبیهساز فهرست حلکنندههای میزبان را میخواند و تا چهار سرور به مهمان میدهد که روی نشانیهای 10.0.2.3 تا 10.0.2.6 عرضه میشوند. اگر تونل در آن لحظه پایین بود، عکس فوری هر حلکننده عمومیای را دارد که لپتاپ استفاده میکرد، و مهمان تا پایان عمر از آن میپرسد. نامهای عمومی حل میشوند، نامهای داخلی شکست میخورند، و هر نشانهای به VPN اشاره میکند در حالی که مقدار کهنه واقعی فهرستی از حلکنندههاست که دقایقی پیش از بالا آمدن تونل ثبت شده است.
پس اصلاح از راه ترتیب افسانه نیست. نخست تونل را وصل کنید، سپس شبیهساز را دوباره راهاندازی کنید، و بوت سرد را بر بازگرداندن عکس فوری ترجیح دهید، زیرا تصویر بوت سریع میتواند با وضعیت حلکننده و مسیریابی که پیشتر ذخیره کرده بازگردد. اگر میخواهید ببینید مهمان اکنون چه استفاده میکند، از دستگاه بپرسید نه از میزبان:
adb shell dumpsys connectivity | grep -i -A2 dns
adb shell ping -c 1 build.internal.exampleشبیهساز در زمان راهاندازی حلکننده صریح را هم میپذیرد، که وقتی دقیقاً میدانید مهمان باید از کدام سرور استفاده کند سودمند است و وقتی آن سرور عمومی است خطرناک:
emulator -avd Pixel_API_34 -dns-server 203.0.113.53حلکننده عمومی نسخهای از ناحیه داخلی ندارد، پس سنجاق کردن یکی مشکل ترتیب را به شکست دائمی تبدیل میکند. اگر نمایه DNS خصوصی را تحمیل میکند، بگذارید تونل آن را تأمین کند و مهمان را سرد بوت کنید به جای اینکه نشانی را سختکد کنید.
مسیریابی در زمان اتصال از میزبان پیروی میکند
چون اتصالهای مهمان به سوکتهای میزبان تبدیل میشوند، تصمیم مسیریابی هنگام ساخت سوکت گرفته میشود. بالا بودن تونل پیش از درخواست یعنی درخواست بر پایه مسیرهای نمایه از تونل بیرون میرود. نمایه تونل تقسیمی که فقط پیشوندهای برگزیده را حمل میکند با خیال راحت زیرشبکه خصوصی شما را بیرون میگذارد، پس دسترسیپذیری میزبان فرضی درباره مهمان است، نه نتیجه. اتصالهای موجود مهمان مسیری را که با آن ساخته شدهاند نگه میدارند، به همین دلیل کلاینتی که دوباره وصل میشود همیشه دانلود گیرکرده در شبیهساز را درست نمیکند.
راستیآزمایی به رابط میزبان تعلق دارد، نه به آمار مهمان:
sudo tcpdump -ni tun0 'host 203.0.113.10'اگر درخواست مهمان روی رابط تونل دیده شود، مسیریابی کار میکند و مشکل بالاتر است. اگر روی رابط فیزیکی دیده شود، نمایه آن پیشوند را پوشش نمیدهد، و هیچ بازپیکربندی در سمت مهمان آن را عوض نمیکند.
وقتی کلاینت فقط واسطه حلقه بازگشتی عرضه میکند
برخی کلاینتهای تجاری هیچ تونل سیستمی نمیسازند. آنها یک شنونده HTTP یا SOCKS روی 127.0.0.1 عرضه میکنند و انتظار دارند برنامهها از آن استفاده کنند. مهمان آن سوکت را مستقیم نمیبیند، اما میتوان به شبیهساز گفت از آن استفاده کند، یا از طریق کنترلهای گسترده (تنظیمات، سپس واسطه، حالت دستی، میزبان 127.0.0.1 و پورتی که کلاینت چاپ میکند) یا در زمان راهاندازی:
emulator -avd Pixel_API_34 -http-proxy http://127.0.0.1:8080پورت را از پنجره کلاینت کپی کنید؛ پورت حدسی بیصدا شکست میخورد و مانند تونل شکسته به نظر میرسد. به یاد داشته باشید این چه چیزی را پوشش میدهد: تنظیم واسطه HTTP را برنامههای واسطهآگاه رعایت میکنند، و سوکتهای خام آن را کاملاً نادیده میگیرند. اگر بار کاری یک باینری بومی باشد که اتصالهای خودش را باز میکند، مسیر واسطه با تونل همارز نیست و مقایسه باید صریح انجام شود.
نتیجه را از داخل مهمان اثبات کنید
حل نام را با دو آزمون در همان نشست از مسیریابی جدا کنید. نامی که شکست میخورد در حالی که نشانی عددی پاسخ میدهد مشکل عکس فوری DNS است، و اصلاح آن ترتیب یا حلکننده صریح است. اگر هر دو شکست بخورند به مسیریابی یا سیاست اشاره دارد، و بررسی بعدی این است که آیا برنامه در نمایه کاری با محدودیتهای شبکه خودش اجرا میشود.
سرانجام بدانید روی کدام مهمان آزمایش میکنید. تصاویر بسیار کهنه شبیهساز بدون پشتیبانی tun که کلاینت VPN سمت مهمان لازم دارد عرضه میشدند، پس هیچ نمایهای هرگز نمیتوانست آنجا کار کند؛ تصاویر کنونی آن را دارند. کلاینتی که روی تصویر کنونی شکست میخورد مشکل کلاینت یا نمایه است، و بازسازی تونل میزبان نتیجه را عوض نمیکند.