هیچ مشکلی در برنامه نیست و هیچ مشکلی در تونل نیست، و با این حال داشبورد بارگذاری نمی‌شود. وقتی سرویسی با network_mode: service:vpn اجرا می‌شود، فضای نام شبکه کانتینر VPN را به اشتراک می‌گذارد، یعنی شنونده و پورت‌های منتشرشده‌اش به آن فضای نام تعلق دارند نه به سرویس. سه تصمیم از این نتیجه می‌شود: برنامه کجا مقید می‌شود، کدام کانتینر پورت را منتشر می‌کند و مسیر مدیریت چقدر باریک است. اگر آن‌ها را به ترتیب اشتباه انجام دهید، هر تنظیم به‌تنهایی درست به نظر می‌رسد در حالی که ترکیب نمی‌تواند کار کند.

چه کسی صاحب فضای نام پورت است

در فضای نام مشترک، افزودن یک ورودی ports: به سرویس وابسته هیچ کار مفیدی نمی‌کند و چندین گزینه شبکه از نظر طراحی برای آن پشتیبانی نمی‌شود. به جای آن، روی کانتینری که صاحب فضای نام است منتشر کنید. همان کانتینر همانی است که آدرسش روی میزبان ظاهر می‌شود، پس نگاشت به‌صورت یک ورودی خوانده می‌شود نه یکی برای هر سرویس.

services:
  vpn:
    image: vpn-client-image
    cap_add: [NET_ADMIN]
    ports:
      - "127.0.0.1:8080:8080"
  app:
    network_mode: "service:vpn"

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

کاری کنید برنامه همان‌جا گوش دهد که فضای نام انتظار دارد

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

docker compose exec app ss -lntp
docker port vpn
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/

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

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

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

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

پورت مدیریت را باز کنید بدون اینکه همه‌چیز را باز کنید

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

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

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

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

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

مقالات مرتبط