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

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

چرا قلاب منتظر تونلی است که منتظر اوست

OpenVPN قلاب‌هایش را همگام فراخوانی می‌کند، درون همان فرایندی که بسته‌ها را جابه‌جا می‌کند. up زمانی فعال می‌شود که دستگاه tun یا tap وجود دارد اما پیش از افزودن هر مسیری، و route-up پس از مسیرها؛ هیچ‌یک از این دو لحظه تضمین نمی‌کند که طرف مقابل پاسخ دهد. تا وقتی اسکریپت هر یک از قلاب‌ها در حال اجراست، دیمن ارسال نمی‌کند، پس فرمانی که انتظار دارد ترافیک از تونل بگذرد منتظر تونلی است که منتظر آن فرمان است. همین انتظار دوری است که باعث می‌شود اجرای دستی موفق شود و قلاب به پایان مهلت برسد.

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

قلاب را بر اساس رویداد انتخاب کنید، نه بر اساس راحتی

up را به کاری ببندید که فقط دستگاه را می‌خواهد، route-up را به کاری که مسیر می‌خواهد، و client-connect و client-disconnect را نگه دارید برای وظایف هر مشتری در سمت سرور. پاک‌سازی هنگام قطع اتصال باید اجرای دوباره را تحمل کند، زیرا اتصال دوباره از طریق یک سطح پایدار همان توالی راه‌اندازی کامل را دنبال نمی‌کند. در سرور، client-connect هنگامی فعال می‌شود که مشتری احراز هویت می‌کند نه هنگامی که دیمن آغاز می‌شود، که ارزش تأیید دارد پیش از انتقال منطق به آنجا. اگر کار به چرخه عمر سرویس تعلق دارد و نه به یک اتصال، یک واحد systemd خانه بهتری از هر قلابی است.

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

سه راه برای جدا کردن کار

گزینه نخست این است که کمک‌کننده را از درون قلاب به پس‌زمینه بفرستید: آن را با setsid یا systemd-run --scope آغاز کنید، توصیف‌گرهای ارثی را ببندید و بی‌درنگ با صفر خارج شوید. دومی این است که قلاب یک فایل وضعیت کوچک بنویسد و یک زمان‌سنج systemd یا واحد مسیر بر پایه آن عمل کند، که قلاب را ساده نگه می‌دارد و سیاست تلاش دوباره را جایی می‌گذارد که گزارش وجود دارد. سومی این است که قلاب را کاملاً کنار بگذارید و کار را به واحدی منتقل کنید که پس از سرویس VPN مرتب شده، که پاسخ درست است وقتی کار اصلاً به‌ازای هر اتصال نیست. هر سه یک قاعده را شریک‌اند: قلاب باید پیش از آنکه به تونل نیاز پیدا کند بازگردد.

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

خرابی‌های جعبه شنی را از خرابی‌های چرخه عمر جدا کنید

وقتی اسکریپتی از اعلان root اجرا می‌شود و به‌عنوان سرویس شکست می‌خورد، علت معمولاً جعبه شنی است نه شبکه. ProtectHome محدودکننده، ProtectSystem فقط‌خواندنی، یا پوشه کاری‌ای که وجود ندارد می‌توانند اسکریپت یا داده‌هایش را دسترس‌ناپذیر کنند، و در میزبان SELinux فایل به بافتی هم نیاز دارد که اجرا را مجاز کند. واحد را با systemctl cat openvpn-server@server و گزارش را با journalctl -u openvpn-server@server -n 80 بخوانید، سپس به‌جای مهلت اتصال دنبال خطای مجوز یا بافت بگردید. غیرفعال کردن جعبه شنی باید آخرین حرکت باشد، نه نخستین.

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

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

مقالات مرتبط