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

چرا واحد چند ثانیه پس از یک شروع موفق غیرفعال می‌شود

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

نوع واحد را در کنار رفتار کلاینت بخوانید، پیش از آنکه به پیکربندی شبکه دست بزنید.

نوعی را انتخاب کنید که با کلاینت هم‌خوان باشد

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

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/bin/protonvpn-cli connect -f
ExecStop=/usr/bin/protonvpn-cli disconnect

oneshot همراه با RemainAfterExit=true واحد را پس از بازگشت فرمان فعال نگه می‌دارد، که با الگوی پیکربندی-و-خروج هم‌خوان است، و فرمان توقف خاموشی تمیزی به سرویس می‌دهد. کلاینتی که فورک می‌کند همان شکل را حفظ می‌کند اما به Type=forking نیاز دارد تا systemd فرزند را دنبال کند. Restart=on-failure، RestartSec=30 و یک StartLimitBurst محدود را تنظیم کنید تا قطعی ارائه‌دهنده به حلقه راه‌اندازی مجددی تبدیل نشود که خطا را زیر خاک ببرد.

هرگز نگذارید کلاینت تحت نظارت دیمن شود

ناظران بیرون از systemd به همان دیوار می‌خورند. اسکریپت اجرای runit که کلاینت دیمن‌شده را راه می‌اندازد بی‌درنگ به ناظر برمی‌گردد، و ناظر آن بازگشت را فروپاشی می‌خواند و نسخه دیگری راه می‌اندازد. هر ناظری انتظار دارد فرآیند پیش‌زمینه را در اختیار داشته باشد، همان‌گونه که sshd -D در جلو می‌ماند. برای فرمان‌های تحت نظارت پرچم دیمن را بردارید و کار پس‌زمینه را به ناظر بسپارید. اسکریپت‌های پوششی که پیش از وجود تونل برمی‌گردند همان سردرگمی را ایجاد می‌کنند.

فرآیندی که خود را جدا می‌کند برای هر چیزی که قرار بود آن را بپاید نامرئی است.

جلسه پایان می‌یابد و تونل را با خود می‌برد

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

کاربر سرویس نیمه دیگر همان مشکل است. کلیدی که مالک آن root است و حالت 0600 دارد برای واحدی که با حساب دیگری اجرا می‌شود ناخواناست، هر چه sudo در پوسته شما به دست آورده باشد.

systemctl cat openvpn-server@work
sudo chown -R openvpn:network /etc/openvpn/server
sudo find /etc/openvpn -type f -perm /077 -ls

وابستگان را پس از وجود آدرس بچینید

وقتی دیمن به آدرس تونلی که هنوز ساخته نشده بسته می‌شود، با Cannot assign requested address خارج می‌شود. راه‌حل، چیدن صریح است نه حلقه تلاش مجدد.

[Unit]
After=network.target [email protected]
Requires=sys-devices-virtual-net-wg0.device

After= کارها را می‌چیند، در حالی که Requires= روی واحد دستگاه وابسته را به وجود رابط گره می‌زند، که از تنها انتظار برای هدف شبکه قوی‌تر است. پس از ویرایش مدیر را دوباره بارگذاری کنید و سرویس وابسته را دوباره راه بیندازید، سپس ژورنالش را بخوانید به جای آنکه فرض کنید ترتیب اثر کرده است. خروجی کلاینت را با StandardOutput=journal یا گزینه‌ای برای لاگ به ژورنال بفرستید، زیرا کلاینت تحت نظارتی که در فایلی می‌نویسد که هیچ‌کس بازش نمی‌کند دقیقاً مانند یکی است که هرگز شروع نشده.

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

مقالات مرتبط