دو چیز به‌عنوان یک خرابی گزارش می‌شوند: لپ‌تاپ به شبکه Wi-Fi دیگری رفته است، یا کابلی وصل شده در حالی که Wi-Fi روشن مانده است. کلاینت هنوز می‌گوید متصل است، نماد سالم به نظر می‌رسد و تونل چیزی حمل نمی‌کند. در زیر سطح، فقط سه قطعه وضعیت می‌توانند جابه‌جا شوند - پیوند، آدرس محلی، مسیر پیش‌فرض - و این‌که کدام جابه‌جا شده تعیین می‌کند تونل خودش بازیابی می‌شود یا به اتصال دوباره نیاز دارد. من آن‌ها را به همین ترتیب بررسی می‌کنم، چون تغییر تنظیمات حساب هرگز هیچ‌یک را درست نکرده است.

پیوند، آدرس و مسیر مستقل از هم جابه‌جا می‌شوند

جابه‌جایی بین نقاط دسترسی در همان شبکه معمولاً یک رویداد لایه L2 است. رادیو دوباره پیوند می‌گیرد، رابط آدرس و دروازه خود را نگه می‌دارد و چیزی که تونل به آن وابسته است عوض نمی‌شود، به همین دلیل قدم زدن در یک دفتر بزرگ گاهی بی‌توجه می‌ماند. پیوستن به SSID دیگر این‌طور نیست: رابط قدیمی ممکن است پایین بیاید، DHCP آدرس تازه، دروازه تازه و حل‌کننده‌های تازه می‌دهد و جریان بیرونی که تونل استفاده می‌کرد از بین می‌رود.

Ethernet شکل سومی اضافه می‌کند. Wi-Fi هرگز قطع نمی‌شود، پس هیچ رویداد پیوندی رخ نمی‌دهد، اما رابط سیمی با آدرس خودش ظاهر می‌شود و اغلب مسیر پیش‌فرض را بر اساس متریک می‌برد. تونل روی مسیری ادامه می‌دهد که دیگر ترجیح داده نمی‌شود، یا کلاینت سوکت خود را به همان شبکه بی‌سیمی که در آن شروع کرده میخ‌کوب می‌کند. از مرورگر هر دو یکسان به نظر می‌رسند: صفحه‌ها همان لحظه‌ای که کابل جا می‌افتد متوقف می‌شوند.

پس پرسش اول این نیست که آیا Wi-Fi عوض شده است. این است که آیا آدرسی که به آن بسته شده‌اید، یا مسیر تا نقطه پایانی، در حالی که تونل برپا بود عوض شده است.

سوکت بیرونی به آدرسی میخ شده که همین حالا ناپدید شد

هر تونل یک جریان بیرونی است: یک آدرس و پورت محلی که با آدرس و پورت سرور حرف می‌زند. در Linux این یک سوکت UDP بسته‌شده به مبدأ قدیمی است؛ وقتی رابطی که آدرس را دارد حذف می‌شود، ارسال‌ها یا با EADDRNOTAVAIL شکست می‌خورند یا از رابط تازه با مبدأیی بیرون می‌روند که سرور هرگز آن را ندیده است.

طرف دور میخ خودش را نگه می‌دارد. یک SA در IKEv2 بدون MOBIKE با جفت آدرس شناسایی می‌شود و یک OpenVPN نشست به آدرس همتایی که آموخته بسته می‌شود و یک نقشه NAT به آدرس خصوصی، پورت و آدرس عمومی‌ای تعلق دارد که آن را ساخته‌اند. پشت NAT دیگری بروید و هر پاسخ به نقشه‌ای فرستاده می‌شود که دیگر وجود ندارد. چیزی روی دستگاه شما بد پیکربندی نشده است؛ پنج‌تایی به شبکه‌ای اشاره می‌کند که ترک کرده‌اید.

پیش از نظریه‌پردازی وضعیت را بخوانید:

  • ss -unp آدرس و پورت محلی‌ای را نشان می‌دهد که هر سوکت تونل واقعاً دارد.
  • ip route get 203.0.113.10 آدرس مبدأ و دستگاهی را چاپ می‌کند که کرنل همین حالا برای نقطه پایانی استفاده می‌کرد.
  • wg show wg0 endpoints، swanctl --list-sas یا گزارش کلاینت آدرس همتایی را نشان می‌دهد که طرف دور فکر می‌کند با آن حرف می‌زند.

اگر آدرس سوکت و جست‌وجوی مسیر با هم نمی‌خوانند، شکست را پیدا کرده‌اید و هیچ تغییر اعتباری به آن دست نخواهد زد.

هر پروتکل با آدرس مبدأ تازه چه می‌کند

کلاینت‌ها تغییر را به درجات مختلف جذب می‌کنند و جدول چیزی است که آن را با پیکربندی کلاینت مقایسه می‌کنم، به‌جای حدس زدن از رفتار اتصال دوباره.

TunnelRecovery behaviourFailure signature
WireGuardUpdates the peer endpoint when an authenticated packet arrives from a new address; no handshake needed if traffic continues.Handshake current, no return traffic; wg show still lists the old endpoint.
IKEv2/IPsecMOBIKE (RFC 4555) moves the SA to the new address; without it the responder discards packets from an unknown source.DPD or keepalive timeouts, then a full rekey or a dead SA.
OpenVPN over UDP--float accepts a packet from a new source mid-session; otherwise the session stays tied to the original peer address.Idle until ping-restart fires, then a visible reconnect.
OpenVPN over TCPThe tunnel is a byte stream, so a changed source address breaks it outright.Immediate reset and a new connection attempt.

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

MOBIKE مذاکره می‌شود، فرض نمی‌شود. اگر سرور آن را ارائه نکند، کلاینت باید دوباره برپا کند و این واقعیتی است که از فهرست SA یا گزارش تأیید می‌کنید، نه چیزی که از چرخی گردان استنتاج کنید.

ترجیح مسیر راه را تعیین می‌کند، نه نماد Wi-Fi

وقتی هر دو رابط بالا هستند، کرنل بر اساس متریک و طول پیشوند انتخاب می‌کند. ip route show default نامزدها را فهرست می‌کند و ip route get 203.0.113.10 تصمیم واقعی را حل می‌کند، از جمله آدرس مبدأ. یک مسیر پیش‌فرض سیمی با متریک 100 و یک بی‌سیم با 600 یعنی نقطه پایانی همان لحظه‌ای که کابل جا می‌نشیند جابه‌جا می‌شود، در حالی که هر برنامه‌ای که پیش‌تر سوکتی باز کرده مبدأ قدیمی خود را نگه می‌دارد.

Windows همین کار را با متریک‌های خودکار رابط انجام می‌دهد، با سوگیری سرعت پیوند. Get-NetRoute -DestinationPrefix 0.0.0.0/0 نامزدها را مرتب می‌کند و Find-NetRoute -RemoteIPAddress 203.0.113.10 رابط و مبدأیی را برمی‌گرداند که پشته انتخاب می‌کرد. کلاینتی که سوکت بیرونی خود را به یک رابط می‌بندد پس از برگشتن متریک هم از آن استفاده می‌کند؛ این تصمیمی درباره بستن است، نه خطای مسیریابی.

Android تقسیم را دیدنی می‌کند: ConnectivityManager شبکه‌های موجود و یک پیش‌فرض جداگانه را گزارش می‌دهد و برنامه VPN که سوکتی را به شیء Network می‌بندد آن بستن را تا بستن دوباره نگه می‌دارد. در macOS، scutil --nwi رابط اصلی و ترتیبی را که سیستم استفاده می‌کرد چاپ می‌کند.

DNS، MTU و IPv6 همراه با اتصال جابه‌جا می‌شوند

اتصال تازه حل‌کننده‌های تازه می‌آورد. با systemd-resolved، DNS به‌ازای هر پیوند است، resolvectl status نشان می‌دهد کدام پیوند به یک نام پاسخ می‌دهد و شبکه مهمانی که حل‌کننده خودش را می‌دهد می‌تواند DNS هل‌داده‌شده توسط تونل را تا زمانی که پیوند دوباره ترجیح داده شود بی‌استفاده بگذارد. دروازه اسیر وضع را بدتر می‌کند: نخستین درخواست HTTPS را دروازه پاسخ می‌دهد نه نقطه پایانی، و کلاینت سروری مرده ثبت می‌کند.

MTU مسیر هم عوض می‌شود. Ethernet و Wi-Fi معمولاً 1500 بایت حمل می‌کنند، PPPoE مقدار 1492 و پیوندهای موبایل اغلب کمتر. تونلی که MTU کوچک‌تری را به ارث می‌برد روی بسته‌های بزرگ گیر می‌کند در حالی که درخواست‌های کوچک موفق می‌شوند، که به‌عنوان اتصالی نیمه‌شکسته خوانده می‌شود. ping -M do -s 1472 203.0.113.10 یک بسته 1500 بایتی با DF تنظیم‌شده می‌فرستد؛ سکوت یعنی مسیر از آنچه فرض کردید کوچک‌تر است.

IPv6 نیمه دیگر است. شبکه‌ای که پیشوند تازه می‌دهد مبدأیی را عوض می‌کند که کلاینت دوپشته استفاده می‌کرد و تونلی که فقط v4 است ترافیک v6 را تا رسیدن سیاست بیرون می‌گذارد. ip -6 route show default و ip -6 addr show پاسخ می‌دهند که آیا پیوند تازه اصلاً مسیر v6 دارد.

گذار را بازتولید کنید نه توصیف

یک درخواست بی‌خطر انتخاب کنید و همان سه فرمان را در دو سوی تغییر اجرا کنید: ip -br addr، ip route show default، ip route get 203.0.113.10. سپس ببینید آیا تونل هنوز بسته می‌فرستد - tcpdump -ni any udp port 51820 برای WireGuard، پورت متناظر برای هر چیز دیگر. بسته‌هایی که از مبدأ قدیمی بیرون می‌روند یعنی مشکل بستن. بسته‌هایی که از مبدأ تازه بدون پاسخ بیرون می‌روند یعنی طرف دور یا NAT میان راه.

یادداشت کنید کدام رویداد با نخستین خرابی هم‌زمان بود: پایین آمدن پیوند، تغییر آدرس یا تغییر مسیر پیش‌فرض. این‌ها به صاحبان مختلفی اشاره می‌کنند - کلاینتی که باید دوباره بسته شود، آدرسی که باید دوباره گرفته شود، یا مسیری که به یک فایل پیکربندی تعلق دارد نه به یک قاعده دائمی دور زدن.

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

مقالات مرتبط