یک دستگاه آزمایشگاهی داشتم که تونلی از یک سایت دور را می‌پذیرفت و هم‌زمان به شبکه یک تأمین‌کننده هم شماره می‌گرفت. پروفایل خروجی هفته‌ها کار کرده بود. پس از افزودن سرور ورودی، پروفایل خروجی متصل شد و سپس در عرض چند ثانیه عبور ترافیک را متوقف کرد، یا با خطای «آدرس در حال استفاده است» از راه‌اندازی امتناع کرد. فایل‌های پیکربندی تغییر نکرده بودند؛ میزبان به‌سادگی یک فرایند دوم OpenVPN با نظر خودش درباره درگاه‌ها و مسیرها پیدا کرده بود.

این شکست تصادفی نیست و مشکل احراز هویت هم نیست. دو سرویس‌دهنده روی یک ماشین بر سر همان سوکت محلی و همان جدول مسیریابی رقابت می‌کنند و هرکدام دیرتر شروع کند یا دیرتر دوباره متصل شود معمولاً برنده می‌شود. دانستن اینکه کدام یک از این دو برخورد را دارید تعیین می‌کند اول کجا را نگاه کنید.

علامت را برعکس بخوانید

از زمانی شروع کنید که تونل می‌میرد. خطای bind هنگام راه‌اندازی به سمت شنونده اشاره می‌کند: چیزی از قبل آن درگاه را در اختیار دارد و OpenVPN به‌جای سهیم شدن در آن از راه‌اندازی امتناع می‌کند. تونلی که بالا می‌آید و سپس ساکت می‌شود به مسیریابی اشاره می‌کند، چون مسیری که نمونه دیگر نصب کرده می‌تواند بسته‌های اتصال بیرونی را از مسیرشان بیرون بکشد.

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

یک سوکت و یک دستگاه برای هر نمونه

سرور شنونده درگاه خود را bind می‌کند؛ کلاینت خروجی هم برای ترافیک کپسوله‌شده‌اش به یک درگاه محلی نیاز دارد. وقتی هر دو روی یک میزبان زندگی می‌کنند، رفتار پیش‌فرض کلاینت می‌تواند با درگاه سرور برخورد کند. درگاه محلی کلاینت را می‌توان ثابت کرد و جایی که همتای مقابل به درگاه مبدأ ثابت نیاز ندارد می‌توان از bind صرف‌نظر کرد:

lport 1195
nobind
dev tun1

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

nobind متعلق به سمت کلاینت است. سرور همچنان باید bind کند و گوش دهد، پس خط را در پیکربندی سرور کپی نکنید و bind را روی کلاینتی که همتای مقابلش بر درگاه مبدأ ثابت فیلتر می‌کند غیرفعال نکنید.

برای مسیر پیش‌فرض یک مالک انتخاب کنید

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

ip rule add from 10.9.0.2 table 120
ip route add default dev tun1 table 120
ip route get 10.9.0.2

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

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

با جدول تأیید کنید، نه با خط وضعیت

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

ip route show
ip route get 10.40.0.20
ss -lunp | grep 1194

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

درگاه‌ها، دستگاه‌ها، جدول‌ها و مالک مسیر را در دفترچه اجرای میزبان بنویسید. در غیر این صورت نفر بعدی که تونل سوم را اضافه می‌کند همان برخورد را دوباره کشف خواهد کرد و تنها شاهد قابل مشاهده اتصالی خواهد بود که کار می‌کند تا زمانی که سرویس‌دهنده کس دیگری دوباره راه‌اندازی شود.

مقالات مرتبط