هنگام راه‌اندازی، یک واحد سوکت که نشانی ثابت VPN را مقید می‌کند ممکن است پیش از آنکه تونل آن را تخصیص دهد شکست بخورد و سرویس پشت آن هرگز شروع نشود. دو کلید شبیه راه‌حل به نظر می‌رسند و دو نیمهٔ متفاوت این مشکل را حل می‌کنند. FreeBind به systemd اجازه می‌دهد شنونده را در حالی که نشانی هنوز غایب است بسازد. After= فقط کارها را مرتب می‌کند، پس زمان شروع چیزها را تغییر می‌دهد بدون آنکه نشانی زودتر برسد.

دو مشکل متفاوت، دو کلید متفاوت

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

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

FreeBind: شنونده پیش از نشانی وجود دارد

FreeBind به هسته می‌گوید اتصال به یک نشانی غیرمحلی را مجاز بداند، تا systemd بتواند سوکت شنوا را هنگام راه‌اندازی بسازد و هر زمان برنامه شروع شد آن را به برنامه بسپارد. این نکتهٔ فعال‌سازی سوکت است و دلیلی که سوکت می‌تواند از سرویس پشت خود بیشتر بماند.

[Socket]
ListenStream=
ListenStream=10.8.0.1:8443
FreeBind=yes

تخصیص خالی پیش از افزودن مدخل جدید، مدخل‌های گوش دادن به‌ارث‌رسیده از واحد فروشنده را پاک می‌کند و این مانع می‌شود شنوندهٔ wildcard باقی‌مانده روی همهٔ واسط‌ها پاسخ دهد. نشانی و درگاه را با مقادیر خودتان جایگزین کنید و واحد مؤثر را بررسی کنید نه فقط فایل drop-in را. به‌جای ویرایش فایل بسته در جای خود از drop-in زیر نام واحد استفاده کنید، چون به‌روزرسانی بعدی بسته ویرایش را بازنویسی می‌کند و هیچ نشانی از قصد باقی نمی‌گذارد. سپس آن را با روند بازبارگذاری و راه‌اندازی مجددی که واحد سوکت انتظار دارد اعمال کنید.

مرجع سوکت systemd رفتار IPv4 و IPv6 پشت این گزینه را مستند می‌کند و جزئیات مهم آن است که به اتصال مربوط است نه به مسیریابی. هیچ چیز در آن نشانی تخصیص نمی‌دهد یا VPN را شروع نمی‌کند. FreeBind اجازه‌ای است که به شنونده داده می‌شود، نه جایگزینی برای واسط.

After= و Wants=: ترتیب به معنای آمادگی نیست

ترتیب و الزام دو محور جداگانه‌اند و اشتباه گرفتن آن‌ها واحدهایی می‌سازد که به ترتیب درست شروع می‌شوند و باز هم شکست می‌خورند. After=vpn-client.service فقط یعنی اگر هر دو کار شروع شوند، این یکی منتظر شروع آن دیگری می‌ماند. نه VPN را می‌کشد و نه منتظر می‌ماند که VPN اتصال را تمام کند.

دستورهای الزام مانند Wants= و Requires= فعال‌سازی را بر عهده دارند و در آنچه هنگام شکست وابستگی رخ می‌دهد تفاوت دارند: یکی ادامه می‌دهد و دیگری می‌ایستد. هیچ‌یک نمی‌دانند تونل متصل چه معنایی دارد. یک فرایند VPN می‌تواند بدون نشانی تخصیص‌یافته فعال باشد، یا با نشانی تخصیص‌یافته و بدون مسیر تا همتا، و هر دو حالت وابستگی را برمی‌آورند. اگر برنامه به وجود نشانی نیاز دارد، آن شرط را صریح مدل کنید به‌جای آنکه شروع فرایند را اثبات آمادگی بدانید.

با systemctl cat و systemctl show -p After -p Wants -p Requires بررسی کنید واحد واقعاً چه اعلام می‌کند. drop-in از سه پوشهٔ متفاوت می‌توانند دستورهایی بیفزایند که هرگز ننوشته‌اید، و systemd فقط واحد مؤثر را می‌خواند.

کاری که network-online.target نمی‌کند

واحدی که پس از network-online.target مرتب شده باشد منتظر می‌ماند تا مدیر شبکه شبکه را قابل استفاده اعلام کند، که یک نقطهٔ همگام‌سازی هنگام راه‌اندازی است نه شرطی پیوسته. دربارهٔ بالا بودن یک تونل مشخص چیزی نمی‌گوید و وقتی VPN در میانهٔ بعدازظهر دوباره متصل شود دیگر فعال نمی‌شود. تلقی کردن آن به‌عنوان پایشگر اتصال مجدد رایج‌ترین بدخوانی این هدف است.

پروژهٔ systemd این تفاوت را مستقیماً مستند می‌کند و نتیجهٔ عملی آن است که هر چیزی که به نشانی تونل نیاز دارد باید خودش مالک وابستگی باشد. واحدی که منتظر network-online می‌ماند و سپس نشانی تونل را مقید می‌کند تنها زمانی درست است که تونل تصادفاً اول بالا بیاید، و این تصادف است نه طراحی.

چرخهٔ عمری را که واقعاً برگزیده‌اید بیازمایید

راه‌اندازی تمیز، درخواست پس از پدیدار شدن نشانی، و رفتار پس از افتادن و بازگشت VPN را بیازمایید. این سه حالت شنوندهٔ کارآمد را از سرویس کارآمد جدا می‌کنند.

systemd-analyze verify myapp.socket
systemctl cat myapp.socket
ss -ltn "sport = :8443"

فرمان نخست خطاهای فایل واحد را پیش از راه‌اندازی مجدد می‌گیرد، دومی واحد ادغام‌شده را نشان می‌دهد و سومی اثبات می‌کند شنونده وجود دارد و روی کدام نشانی است. شنونده‌ای روی نشانی wildcard در جایی که انتظار نشانی تونل داشتید همان باقی‌مانده‌ای است که ListenStream خالی باید برمی‌داشت. فرمان سوم را پس از اتصال مجدد VPN تکرار کنید تا ببینید نشانی جابه‌جا شده است یا نه.

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

مقالات مرتبط