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

به هر پروفایل پورت محلی خودش را بدهید

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

Local Port 0

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

فایل‌های پروفایل اعتبارنامه دارند، پس مجوزها بخشی از طراحی‌اند نه کار خانه. فایلی که همه می‌توانند بخوانند و زیر /etc/vpnc است، راز گروه را به هر کاربر محلی می‌دهد. حالت را روی 0600 با مالکیت root نگه دارید، و بگذارید اسکریپت‌ها فایل را به‌عنوان root بخوانند به‌جای آنکه رازها را در آرگومان‌ها کپی کنند. به همین دلیل هم اسکریپت بررسی هرگز نباید محتوای فایل را در گزارش بنویسد.

برای هر پروفایل یک سرویس را بررسی کنید، نه نشانی تونل را

درخواست پژواک به نشانی خود تونل بیشتر اثبات می‌کند که واسط وجود دارد. چیزی درباره اینکه میزبان پشت آن هنوز به برنامه‌ای که تونل را توجیه می‌کند می‌رسد یا نه نمی‌گوید. واسط می‌تواند بالا باشد در حالی که مسیر پس از آن از پیش رفته است.

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

#!/bin/bash
set -eu
if ! nc -z -w 2 10.63.7.20 8443; then
  /usr/sbin/vpnc-connect ops.conf
fi

آن را به نام /usr/local/bin/ensure-vpn-ops.sh ذخیره کنید، اجراپذیرش کنید، و برای هر پروفایل فقط با تغییر هدف بررسی و نام پیکربندی تکرار کنید. بررسی‌ای که به یک پرسش پروتکلی پاسخ می‌دهد از دروازه‌هایی جان سالم به در می‌برد که پژواک را می‌ریزند اما همچنان سرویس‌هایی را که برای کاربران مهم‌اند عبور می‌دهند.

بررسی‌ها را زنجیره کنید تا هرگز مسابقه ندهند

اسکریپت اتصال مجدد همراه بسته می‌تواند بررسی‌های شما را به ترتیب فراخوانی کند، و ترتیب تمام ماجراست. دو فراخوانی vpnc-connect که با هم اجرا شوند جدول مسیریابی را به ترتیبی بازنویسی می‌کنند که کسی کنترلش نمی‌کند، و اینگونه است که یک پروفایل سالم مسیرش را از دست می‌دهد.

فراخوانی‌ها را در پیش‌زمینه نگه دارید، کمی تأخیر تثبیت برای واسط زیرین بیفزایید، و زنجیره را از جدول cron روت زمان‌بندی کنید، چون تنها روت می‌تواند مسیرهای تونل را بازنویسی کند:

#!/bin/bash
sleep 20
/usr/local/bin/ensure-vpn-ops.sh
/usr/local/bin/ensure-vpn-lab.sh

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

گزارش را بپایید، سپس یکی را عمداً بشکنید

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

سپس عمداً یک تونل را بشکنید و ببینید چه می‌شود. یک پروفایل را متوقف کنید و تأیید کنید کدام فرایندها و مسیرها هنوز حضور دارند:

pgrep -a vpnc
ip -4 route show | grep -E '10[.]63|10[.]90'
tail -n 5 /var/log/ensure-vpn.log

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

آنچه نگهبان نباید انجام دهد

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

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

مقالات مرتبط