پل زدن و NAT دو روش برای اتصال یک مهمان به VPN شما نیستند؛ آن‌ها تصمیم می‌گیرند پیش از آنکه تونلی وارد ماجرا شود، بسته‌های مهمان متعلق به چه کسی است. در حالت NAT، هایپروایزر ترافیک مهمان را بازنویسی می‌کند و آن را از کد سمت میزبان بیرون می‌فرستد، پس مهمان روی هر مسیری می‌رود که میزبان به آن کد می‌دهد. در حالت پل‌شده، مهمان هویت لایه پیوند خودش را روی بخش فیزیکی می‌گیرد و دروازه پیش‌فرض خودش را انتخاب می‌کند، که تونل میزبان را برایش بی‌ربط می‌کند، مگر اینکه روتر LAN همان کسی باشد که تونل می‌زند. من دست از این برداشتم که ماشین مجازی «روی VPN» است بردارم و شروع کردم به دیدنش به‌عنوان این پرسش که مسیر پیش‌فرض آن مهمان کجا اشاره می‌کند. آزمایش زیر برای هر حالت چند دقیقه وقت می‌برد و بدون حدس و گمان آن را روشن می‌کند.

NAT مهمان را پشت کد هایپروایزر نگه می‌دارد، همان‌جا که مسیرهای میزبان اعمال می‌شوند

در VirtualBox یک مهمان NAT روی 10.0.2.0/24 می‌نشیند، با دروازه مجازی در 10.0.2.2، پروکسی DNS در 10.0.2.3 و هیچ مسیر خودش به شبکه فیزیکی. بسته‌های خروجی را موتور NAT برمی‌دارد، بازنویسی می‌کند تا مبدأ میزبان باشد و به پشته IP میزبان می‌سپارد. از آنجا ترافیک مهمان یک جریان میزبان است و جست‌وجوی مسیر بر اساس مقصد انجام می‌شود: کلاینت تونل کامل که 0.0.0.0/1 و 128.0.0.0/1 را روی میزبان نصب می‌کند آن را می‌گیرد بدون اینکه هرگز بداند ماشین مجازی‌ای وجود دارد. فصل شبکه VirtualBox از Oracle این پیش‌فرض‌ها را فهرست می‌کند، اگر می‌خواهید آدرس‌ها را در ساخت خود تأیید کنید.

شبکه پیش‌فرض libvirt از 192.168.122.0/24 به همان جا می‌رسد، جایی که dnsmasq اجاره‌نامه پخش می‌کند و میزبان زیرشبکه را ماسک می‌کند، پس بسته‌های مهمان دوباره به تصمیم مسیریابی میزبان می‌رسند. استثنا کلاینتی است که ترافیک را بر اساس فرایند انتخاب می‌کند نه بر اساس مسیر. اگر فهرست تونل تقسیم‌شده فقط مرورگر شما را داشته باشد و هیچ چیز دیگر، موتور NAT در آن فهرست نیست و مهمان بدون تونل از ماشین بیرون می‌رود، در حالی که مرورگر میزبان هنوز پوشیده به نظر می‌رسد. همان زیرشبکه، نتیجه معکوس.

پل زدن جای خود مهمان را در LAN فیزیکی به او می‌دهد

به مهمان پل‌شده یک کارت شبکه مجازی متصل به آداپتور واقعی داده می‌شود، آدرس MAC خودش را می‌گیرد و اجاره DHCP را از شبکه فیزیکی می‌گیرد. دروازه پیش‌فرضش روتر LAN است نه هایپروایزر، و فریم‌هایش از همان آداپتور روی سیم می‌روند. مسیرهای تونل میزبان در جدول میزبان می‌مانند و هرگز پرسیده نمی‌شوند، چون فریم‌های مهمان هرگز به پشته IP میزبان وارد نمی‌شوند.

این دو طرفه است. mDNS و مرور SMB شروع به کار می‌کنند چون مهمان ترافیک پخش LAN را می‌بیند، و مهمان از ماشین‌های دیگر همان بخش قابل دسترس می‌شود بدون فایروال میزبان در میان. پل زدن همچنین راهی برای هل دادن مهمان از تونل موجود نیست: وصل کردن یک ماشین مجازی به رابط WireGuard یا OpenVPN میزبان کاری نیست که VirtualBox یا libvirt برایتان بکند. اگر مهمان پل‌شده باید از تونل بگذرد، تونل باید جایی در همان LAN پایان یابد.

آزمایشی که بحث را تمام می‌کند

همان بررسی‌ها را در هر دو حالت اجرا کنید و پاسخ‌ها را بنویسید:

  • روی میزبان، curl -s https://ifconfig.me آدرس عمومی v4 را می‌دهد.
  • در مهمان، همان فرمان، به‌علاوه ip route در لینوکس یا Get-NetRoute -DestinationPrefix 0.0.0.0/0 در ویندوز برای دروازه پیش‌فرض.
  • هویت مبدل: resolvectl status یا cat /etc/resolv.conf در مهمان، تا ببینید به 10.0.2.3 اشاره می‌کند یا به سروری در LAN.
  • خانواده آدرس: ip -6 addr show scope global و یک درخواست v6، چون تونل v4 هیچ چیزی درباره یک آدرس جهانی v6 که مهمان ممکن است داشته باشد نمی‌گوید.

آدرس‌های عمومی یکسان یعنی مهمان روی مسیر میزبان است. آدرس مهمانی که با خروج معمول LAN می‌خواند یعنی نیست. قدمی که مردم جا می‌اندازند کنترل است: تونل میزبان را پایین بیاورید و درخواست مهمان را تکرار کنید. اگر مهمان به مرور ادامه دهد، هرگز به تونل میزبان وابسته نبوده است، هر چه نام حالت القا کند. در حالت NAT مهمان باید با پایین بودن تونل میزبان اینترنت را از دست بدهد، مگر اینکه کلاینت طوری تنظیم شده باشد که ترافیک بدون تونل را مجاز بداند، که خودش دانستنی است.

دو نشانه دروغ می‌گویند. پینگ موفق دسترس‌پذیری را ثابت می‌کند، نه مسیر خروج را. و DNS می‌تواند توسط پروکسی 10.0.2.3 از طریق مبدل میزبان پاسخ داده شود در حالی که TCP مسیر دیگری می‌رود، و این‌طور می‌شود صفحه‌ای که بارگذاری می‌شود و ورودی که هرگز کامل نمی‌شود.

کدام حالت به کار می‌خورد

حالت یک تصمیم مسیریابی است، پس آن را از روی نیاز انتخاب کنید نه از روی عادت:

RequirementMode that fits
Every guest flow must exit through the host tunnelNAT, with a host client that tunnels by route, verified from inside the guest
The guest needs its own VPN account or profileBridged, or NAT with a client running inside the guest, not both
The guest must serve SSH, SMB, or a dev server to the LANBridged; NAT needs a port forward, which does not change the outbound path
The guest must stay invisible to the LANNAT; a bridged guest is another host on the segment
The guest needs a real public IPv6 addressBridged; VirtualBox NAT mode has no IPv6 forwarding
Isolation from the LAN with access to the hostHost-only adapter, not NAT

ردیف اول جایی است که مردم گیر می‌افتند: NAT به‌همراه کلاینت تونل کامل میزبان واقعاً یک مهمان را می‌پوشاند، اما تنها تا وقتی کلاینت بر اساس مسیر تونل بزند و اتصال بالادست میزبان همان تونل باشد. کلاینت را به فهرست مجاز فقط برای مرورگر منتقل کنید و پوشش بدون هیچ خطایی در هیچ جا ناپدید می‌شود. ردیف چهارم اشتباه معکوس است: مهمانی که برای راحتی پل شده و بی‌صدا شروع می‌کند به پاسخ دادن به SMB یا SSH در LAN دفتر.

خرابی‌هایی که گردن VPN می‌افتند

در ویندوز ترجمه NAT داخل فرایند ماشین مجازی VirtualBox اجرا می‌شود، پس کلاینت به‌ازای برنامه نیاز دارد همان ایمیج دقیق در فهرستش باشد، نه یک قاعده کلی برای ماشین‌های مجازی. وقتی به‌روزرسانی کلاینت فهرست فرایندهایش را از نو می‌سازد، مهمان‌های NAT اول پوشش را از دست می‌دهند و گزارش شبیه ماشین مجازی‌ای خوانده می‌شود که به LAN می‌رسد ولی به اینترنت نه، در حالی که میزبان خوب است.

پل زدن روی Wi-Fi کلاسیک دیگر است. نقطه‌های دسترسی به‌ندرت فریم‌هایی با MAC مبدأ غریبه را هدایت می‌کنند، پس پل روی wlan0 یا کامل شکست می‌خورد یا کار می‌کند تا وقتی جداسازی کلاینت در AP شروع به انداختنش کند. VirtualBox آداپتور بی‌سیم را باز هم در فهرستش پیشنهاد می‌دهد. اگر میزبان روی Wi-Fi است و مهمان باید پل شود، برنامه بگذارید که آزمایشش کنید نه اینکه فرضش کنید.

MTU سومین است. مهمان پل‌شده MTU 1500 بایتی LAN را نگه می‌دارد، و اگر کلاینت WireGuard خودش را روی 1420 اجرا کند، دست‌دادن‌های بزرگ TLS متوقف می‌شوند در حالی که درخواست‌های کوچک موفق می‌شوند. زیر NAT، MTU تونل میزبان مشکل میزبان است، اما مهمان هنوز به 1500 باور دارد، و UDP با بیت don't-fragment تنظیم‌شده هم به همان شکل در سیاه‌چاله می‌افتد.

حالت را بنویسید و پس از هر تغییر آداپتور دوباره بررسی کنید

حالت، رابط میزبانی که پل استفاده می‌کند، دروازه پیش‌فرض مهمان، مبدل آن و آدرس‌های خروج v4 و v6 آن را ثبت کنید. همین ثبت است که خرابی بعدی را ارزان می‌کند: وقتی لپ‌تاپی از داک به Wi-Fi می‌رود، مهمان پل‌شده پل را به آداپتور فیزیکی دیگری دنبال می‌کند و ممکن است در زیرشبکه دیگری اجاره بگیرد، در حالی که مهمان NAT آدرس 10.0.2.x خود را نگه می‌دارد و بی‌صدا اتصال دیگری را به ارث می‌برد.

پیش از بستن تیکت، هر یک از این‌ها را تأیید کنید:

  • آدرس خروج مهمان با آدرس خروج میزبان فرق دارد، پس روی تونل میزبان نیست.
  • مبدل همان پروکسی 10.0.2.3 است یا سروری در LAN، و می‌دانید کدام پاسخ داد.
  • هیچ آدرس جهانی v6 در مهمان وجود ندارد، اگر طراحی تونل فقط v4 است.
  • با پایین بودن تونل میزبان، مهمان از مرور دست می‌کشد، یا حالا می‌دانید هرگز به آن وابسته نبوده است.
  • مهمان ترافیک پخش LAN را که به او مربوط نیست نمی‌بیند.

مقالات مرتبط