مقایسه Cockpit و Webmin برای مدیریت سرور لینوکس
تفاوت اصلی Cockpit و Webmin در نحوه مدیریت سرور است. Cockpit برای مشاهده وضعیت و Webmin برای ویرایش فایلهای پیکربندی است. چرا نباید این پنلها را روی پورت عمومی باز بگذارید؟
مقایسه Cockpit و Webmin: پاسخ کوتاه
Cockpit و Webmin هر دو پنلهای تحت وب برای مدیریت سرور لینوکسی از طریق مرورگر هستند، اما به نیازهای متفاوتی پاسخ میدهند. Cockpit در مخازن رسمی توزیع لینوکس شما عرضه میشود و وضعیت ماشین را از طریق systemd، journald، polkit و udisks میخواند؛ بنابراین، ابزاری است که به شما کمک میکند سروری را که همچنان از طریق SSH مدیریت میکنید، مشاهده کنید. Webmin قدیمیتر و بسیار گستردهتر است: این ابزار فایلهای پیکربندی Apache، BIND، Postfix، MariaDB و دهها سرویس دیگر را که Cockpit هرگز به آنها دست نمیزند، مستقیماً ویرایش میکند و برای انجام این کار، وبسرور اختصاصی خود را با دسترسی root اجرا میکند.
اگر به دنبال مشاهده زنده وضعیت یک سرور، خواندن لاگها و دسترسی به ترمینال اضطراری هستید، Cockpit را نصب کنید. اگر به ویرایشگری مبتنی بر فرم برای سرویسی نیاز دارید که نمیخواهید آن را بهصورت دستی پیکربندی کنید، Webmin را نصب کنید. هیچکدام را روی پورت عمومی با ورود رمز عبور قرار ندهید. اگر در حال حاضر بیش از 2 یا 3 سرور را مدیریت میکنید، پاسخ صادقانه این است که از هیچکدام استفاده نکنید؛ چرا که ترکیب SSH و Ansible مقیاسپذیری بسیار بهتری نسبت به هر نوع پنل مدیریتی دارد.
آنچه هر پنل واقعاً میتواند تغییر دهد
نصب پایه Cockpit کوچک است و بیشتر بخشهای آن بستههای مجزایی هستند که میتوانید آنها را نصب نکنید:
- سرویسها و تایمرهای systemd: شروع، توقف، فعالسازی و خواندن فایل unit
- ژورنال، با قابلیت فیلتر بر اساس unit و اولویت، که در
journalctlبا انتخابگر تاریخ همراه است - حسابهای کاربری محلی، عضویت در گروهها و کلیدهای SSH مجاز
- مدیریت فضای ذخیرهسازی با
cockpit-storaged: پارتیشنها، گروههای حجمی LVM، فایلسیستمها و نقاط اتصال (mount points) - کانتینرها با
cockpit-podman، که فقط Podman را مدیریت میکند - بهروزرسانی بستهها با
cockpit-packagekit - نمودارهای CPU، حافظه، دیسک و شبکه با
cockpit-pcp - یک ترمینال root در تب مرورگر
دو بخش در Ubuntu VPS ممکن است خراب به نظر برسند که در واقع اینطور نیست. صفحه Networking در Cockpit یک رابط کاربری برای NetworkManager است، اما ایمیجهای Ubuntu server از netplan با systemd-networkd استفاده میکنند، بنابراین این صفحه خالی است یا وجود ندارد. برای بازگرداندن آن، NetworkManager را روی یک سرور از راه دور نصب نکنید، زیرا کنترل رابط شبکه را به دست میگیرد و یک اشتباه در آن باعث قطع دسترسی SSH شما میشود. کنترلهای فایروال در Cockpit رابطی برای firewalld هستند، در حالی که Ubuntu از ufw استفاده میکند، بنابراین هیچ کنترلی روی فایروال نخواهید داشت. همچنان باید sudo ufw status را در ترمینال اجرا کنید.
Webmin گستره بسیار بیشتری را پوشش میدهد، زیرا مجموعهای از ماژولهای مخصوص هر سرویس است تا یک برنامه واحد:
- پیکربندی Apache، nginx، BIND، Postfix، Dovecot، MariaDB، PostgreSQL و Samba از طریق فرمها
- کاربران، گروهها و سهمیههای دیسک (disk quotas)
- وظایف cron و ساعت سیستم
- بهروزرسانی بستهها، به همراه یک مدیریت فایل با قابلیت آپلود و دانلود
- رابطهای فایروال، شامل یکی برای iptables و دیگری برای firewalld
- پشتیبانگیری از فایلهای پیکربندی و ماژولهای کلاستر که تغییرات را به سایر سرورهای Webmin اعمال میکنند
Webmin فایلهای واقعی را در مسیر /etc ویرایش میکند. هیچ دیتابیس پنهانی پشت این فرمها وجود ندارد، بنابراین اگر /etc تحت کنترل نسخه (version control) باشد، اجرای sudo git -C /etc diff پس از ذخیره یک فرم، دقیقاً نشان میدهد که ماژول چه تغییری ایجاد کرده است. این سریعترین راه برای یادگیری عملکرد واقعی هر صفحه در Webmin است. راهنمای نصب و اولین ورود به Webmin درخت ماژولها را با جزئیات بررسی میکند. Virtualmin و Usermin محصولات جداگانهای هستند که بر پایه همان موتور ساخته شدهاند و برای میزبانی اشتراکی و کاربران نهایی طراحی شدهاند؛ آنها تمام مواردی که در اینجا درباره سطح دسترسی (exposure) گفته شد را به ارث میبرند.
نحوه احراز هویت هر یک
Cockpit فاقد پایگاه داده کاربری اختصاصی است. صفحه ورود آن از پشته PAM (ماژولهای احراز هویت قابل اتصال) در /etc/pam.d/cockpit استفاده میکند، بنابراین حسابهای کاربری همان حسابهای یونیکس شما و رمزهای عبور همان رمزهای عبور یونیکس شما هستند. دسترسی root بهصورت پیشفرض رد میشود زیرا /etc/cockpit/disallowed-users آن را در لیست سیاه قرار داده است. اقدامات دارای سطح دسترسی بالا از طریق polkit انجام میشوند و رابط کاربری پیش از اعمال هر تغییری، مجدداً رمز عبور شما را درخواست میکند؛ به همین دلیل است که سربرگ صفحه تا زمانی که سطح دسترسی خود را ارتقا ندهید، عبارت "Limited access" را نمایش میدهد.
این طراحی یک پیامد برای سیستمهای امنسازیشده (hardened) دارد. اگر طبق ورود SSH فقط با کلید و غیرفعالسازی احراز هویت با رمز عبور عمل کرده باشید، ممکن است حساب کاربری هیچ رمز عبور قابل استفادهای نداشته باشد؛ در نتیجه ورود به Cockpit رد میشود در حالی که ssh همچنان کار میکند. این مورد را روی سرور بررسی کنید:
sudo passwd -S deployخروجی که با deploy L شروع شود به این معنی است که رمز عبور قفل شده است، بنابراین PAM چیزی برای پذیرش ندارد و هیچ رمز عبوری که وارد کنید کار نخواهد کرد. P به این معنی است که یک رمز عبور قابل استفاده تنظیم شده است. صفحه ورود خودِ Cockpit کلیدهای SSH را نمیپذیرد. کلیدها تنها زمانی استفاده میشوند که Cockpit از ماشینی که به آن وارد شدهاید، به میزبان دیگری متصل شود.
Webmin کاربران خود را در /etc/webmin/miniserv.users نگه میدارد که از /etc/passwd جدا است، اگرچه میتوان آن را طوری تنظیم کرد که با حسابهای یونیکس احراز هویت کند. کاربری در Webmin که به تمام ماژولها دسترسی دارد، در آن ماشین root محسوب میشود، فارغ از اینکه shell ورود او چه باشد. Webmin دارای پشتیبانی داخلی از TOTP (رمز عبور یکبار مصرف مبتنی بر زمان) و قابلیت مسدودسازی میزبانها پس از تلاشهای ناموفق مکرر برای ورود است که هر دو در بخش Webmin Configuration فعال میشوند. Cockpit تنها در صورتی از عامل دوم (2FA) پشتیبانی میکند که آن را به PAM اضافه کنید، برای مثال با استفاده از libpam-google-authenticator.
نحوه بهروزرسانی هر یک
نرمافزار Cockpit توسط توزیع لینوکس شما بستهبندی میشود. در Ubuntu 24.04 این برنامه از مخازن اصلی (archive) ارائه میشود و پروژه بالادستی برای دریافت نسخه جدیدتر، استفاده از مخزن backports را توصیه میکند:
. /etc/os-release
sudo apt update
sudo apt install -t ${VERSION_CODENAME}-backports cockpit
sudo systemctl status cockpit.socket
apt policy cockpitدستور apt policy نسخه نصبشده و مخزنی که از آن دریافت شده است را نمایش میدهد. اگر در backports نسخه جدیدتری وجود نداشته باشد، apt بهطور خودکار از نسخه موجود در مخزن اصلی استفاده میکند که مشکلی ندارد. خروجی cockpit.socket باید شامل active (listening) باشد. اصلاحات امنیتی سپس از طریق همان دستور unattended-upgrades که برای هسته سیستم (kernel) اجرا میکنید، از طرف ناشری که از قبل به آن اعتماد دارید، دریافت میشوند.
نرمافزار Webmin در مخازن رسمی Ubuntu وجود ندارد. نصب رسمی آن ابتدا مخزن اختصاصی و کلید امضای Webmin را به سیستم اضافه میکند:
curl -o webmin-setup-repo.sh https://raw.githubusercontent.com/webmin/webmin/master/webmin-setup-repo.sh
sudo sh webmin-setup-repo.sh
sudo apt-get install webmin --install-recommendsپیش از اجرای آن اسکریپت، محتوای آن را مطالعه کنید، زیرا با دسترسی root اجرا میشود. از آن لحظه به بعد، هر دستور apt upgrade روی سرور، بستهها را از مخزن Webmin نیز دریافت میکند؛ بنابراین شما ناشر دومی را با سطح دسترسی root به سیستم خود اضافه کردهاید. این هزینه واقعی استفاده از Webmin است و یک مثال روشن برای آن وجود دارد: آسیبپذیری CVE-2019-15107 یک backdoor در چندین بسته نسخه 1.9x بود که امکان اجرای دستورات بدون احراز هویت را فراهم میکرد. این آسیبپذیری به این دلیل به دست کاربران رسید که میزبان ساخت (build host) پروژه مورد نفوذ قرار گرفته بود، نه مخزن سورسکد آن. بستهبندی توسط توزیعهای لینوکسی، وقوع چنین اتفاقی را غیرممکن نمیکند، اما یک مرحله ساخت و بازبینی اضافه میکند که شما خودتان مسئول نگهداری آن نیستید.
چرا هیچکدام نباید روی پورت عمومی باشند
Cockpit روی پورت TCP 9090 و Webmin روی پورت TCP 10000 گوش میدهند؛ هر دو از TLS (امنیت لایه انتقال) با گواهی خودامضا (self-signed) استفاده میکنند، بنابراین اولین چیزی که میبینید یک هشدار مرورگر است. ایجاد و اعتماد به گواهی خودامضا توضیح میدهد که این هشدار چه چیزی را به شما میگوید و چه چیزی را نمیگوید. هر دو پورت دائماً اسکن میشوند و هر دو پنل به دسترسی root ختم میشوند، بنابراین یک رمز عبور حدسزدهشده یا تکراری به معنای نفوذ کامل به سرور است.
الگوی امن این است که پنل را به localhost محدود کنید و از طریق یک تونل SSH به آن دسترسی داشته باشید. برای Cockpit، واحد socket را بازنویسی (override) کنید:
sudo systemctl edit cockpit.socket[Socket]
ListenStream=
ListenStream=127.0.0.1:9090وجود ListenStream= خالی در خط اختصاصی خود الزامی است. systemd تنظیمات لیست را به انتهای لیست قبلی اضافه میکند، بنابراین بدون این کار، واحد تنظیمات اصلی 0.0.0.0:9090 را حفظ کرده و آدرس جدید را به آن میافزاید، در نتیجه پنل شما همچنان عمومی باقی میماند. بازنویسی را اعمال کنید و بررسی کنید چه چیزی در حال گوش دادن است:
sudo systemctl daemon-reload
sudo systemctl restart cockpit.socket
sudo ss -lntp | grep 9090خروجی باید 127.0.0.1:9090 را نشان دهد. آدرس *:9090 یا 0.0.0.0:9090 به این معنی است که بازنویسی اعمال نشده است. اکنون تونل را از دستگاه خود باز کنید و به https://localhost:9090 بروید:
ssh -N -L 9090:127.0.0.1:9090 deploy@203.0.113.10پورت محلی را با پورت راه دور برابر نگه دارید. Cockpit هدر Origin مرورگر را با آدرسی که تصور میکند در حال سرویسدهی به آن است مقایسه میکند، بنابراین تونل از پورت محلی 9999 صفحه ورود را بارگذاری میکند اما در مرحله ورود شکست میخورد و journalctl -u cockpit مبدأ رد شده را ثبت میکند. اگر به پورت محلی متفاوتی نیاز دارید، آن را در /etc/cockpit/cockpit.conf مشخص کنید:
[WebService]
Origins = https://localhost:9999 https://127.0.0.1:9999برای اعمال تغییرات، با sudo systemctl restart cockpit.socket راهاندازی مجدد کنید. برای Webmin تنظیم معادل در /etc/webmin/miniserv.conf قرار دارد:
bind=127.0.0.1sudo systemctl restart webmin
sudo ss -lntp | grep 10000
ssh -N -L 10000:127.0.0.1:10000 deploy@203.0.113.10Webmin همچنین هدر Referer را در ارسال فرمها بررسی میکند و درخواستهایی که به نظر میرسد از میزبان دیگری میآیند را رد میکند؛ این همان چیزی است که باعث شکست تلاش اولیه برای استفاده از reverse proxy میشود. خط referers= در همان فایل جایی است که نام میزبان پروکسی را مجاز میکنید و webprefix= جایی است که به Webmin میگویید تحت چه مسیری (path) اجرا میشود.
استفاده از یک reverse proxy احراز هویتشده گزینه دیگر است: nginx در جلو قرار میگیرد و یک لایه ورود یکپارچه Authentik عملیات ورود را انجام میدهد. این روش کار میکند و دومین گزینه برتر است. پنل همچنان به عنوان root پشت پروکسی اجرا میشود و شما اکنون به جای یک در، باید از دو در ورودی نگهداری کنید. تونل هیچ سرویس گوشدهندهای را به اینترنت اضافه نمیکند و از همان کلید SSH که قبلاً از آن محافظت کردهاید، استفاده مجدد میکند.
کدام پنل مدیریتی برای سروری که در حال حاضر سرویسهای عملیاتی (Production) را اجرا میکند مناسب است؟
Cockpit، به دو دلیل که هنگام وابستگی دیگران به آن ماشین اهمیت پیدا میکنند. این پنل به صورت socket-activated است؛ بنابراین cockpit-ws تنها زمانی اجرا میشود که یک نشست (Session) باز باشد و هیچ daemon دائمی با دسترسی root روی یک پورت منتظر نماند. همچنین، این پنل مالک هیچچیز نیست: با حذف بسته (Package) آن، تمام سرویسها دقیقاً مانند قبل به کار خود ادامه میدهند، زیرا Cockpit هیچ پیکربندی اختصاصی برای خود ذخیره نمیکند. پروسه miniserv.pl در Webmin، فارغ از اینکه کسی وارد سیستم شده باشد یا خیر، همواره در حافظه مقیم میماند. هزینه حافظه مصرفی سرویس خود را با systemctl status webmin بررسی کنید؛ این دستور میزان حافظه مقیم (Resident Memory) پروسه در حال اجرا را نمایش میدهد.
اگر به ماژولهای DNS یا ایمیل Webmin نیاز دارید، آنها را روی سرور مجزایی قرار دهید. یک سرور Webmin که تنها یک وظیفه دارد و به 127.0.0.1 محدود شده است، یک ریسک کنترلشده محسوب میشود. اما اشتراکگذاری یک میزبان (Host) توسط Webmin با اپلیکیشنهای در دسترس عموم، چنین وضعیتی ندارد. پیش از نصب هر یک از این پنلها، کارهای پایه را انجام دهید: ده دقیقه اول روی یک VPS جدید شامل تنظیم کاربر غیر-root و فایروالی است که هر دو پنل فرض میکنند از قبل وجود دارد.
وقتی پاسخ هیچکدام نیست
پنل مدیریتی برای هر سرور بهصورت دستی است و هیچ سابقهای از اینکه چه چیزی تغییر کرده یا چرا، باقی نمیگذارد. این وضعیت برای یک سرور قابلقبول است. در 5 سرور، شما در حال تکرار کارهای خود هستید و در 20 سرور، حدس میزنید کدام سرور تغییرات را دریافت نکرده است. Cockpit میتواند میزبانهای دیگر را از طریق SSH به یک نشست اضافه کند، اما نسخههای اخیر این قابلیت را بهصورت پیشفرض غیرفعال کردهاند و به AllowMultiHost=yes در /etc/cockpit/cockpit.conf نیاز دارند؛ با این حال، همچنان مجبورید یک تغییر مشابه را 5 بار کلیک کنید.
جایگزین این روش، استفاده از SSH ساده به همراه پیکربندی در یک مخزن git است. مدیریت چندین سرور لینوکس از یک مکان ساختار این تنظیمات را پوشش میدهد و اولین Ansible playbook همان قانون فایروال را روی همه میزبانها از طریق یک فایل اعمال میکند که میتوانید آن را به عنوان یک diff بررسی کنید. کار با کانتینرها نیز به همین صورت است: docker compose up -d از طریق SSH با استفاده از فایلی در git، همانطور که در راهنمای اصول Docker Compose آمده، بسیار بهتر از کلیک کردن در هر پنلی است؛ ضمن اینکه Cockpit اساساً Docker را مدیریت نمیکند.
از پنل برای کارهایی استفاده کنید که ترمینال در آنها ضعیف است، مانند خواندن نمودار معیارها یا تشخیص اینکه کدامیک از 40 واحد دچار خطا شده است. برای هر کاری که بیش از دو بار انجام میدهید، از کد استفاده کنید.
حالتهای شکست و پیامهایی که مشاهده خواهید کرد
Cockpit رمز عبوری را که SSH میپذیرد، رد میکند. حساب کاربری فقط با کلید (key-only) است. sudo passwd -S alice در فیلد دوم L را چاپ میکند، بنابراین PAM رمز عبوری برای بررسی ندارد. با استفاده از sudo passwd alice یک رمز عبور تنظیم کنید، یا آن حساب را برای SSH نگه دارید و با کاربری دیگر وارد Cockpit شوید.
Cockpit حتی با رمز عبور صحیح، دسترسی root را رد میکند. /etc/cockpit/disallowed-users مقدار root را فهرست میکند. با یک کاربر معمولی که دسترسی sudo دارد وارد شوید. این مسیرِ در نظر گرفته شده است، زیرا polkit در این حالت ثبت میکند که کدام شخص دسترسی خود را ارتقا داده است.
Cockpit صفحه Networking یا Firewall را نشان نمیدهد. این صفحات به NetworkManager و firewalld نیاز دارند. یک VPS با توزیع Ubuntu از netplan به همراه systemd-networkd و ufw استفاده میکند، بنابراین این صفحات ظاهر نمیشوند. هیچ مشکلی وجود ندارد و راهحل این است که به استفاده از ufw از طریق SSH ادامه دهید.
صفحه ورود Cockpit از طریق تونل بارگذاری میشود، اما ورود با شکست مواجه میشود. پورت محلی شما با پورت راه دور متفاوت است، بنابراین بررسی Origin شکست میخورد و journalctl -u cockpit آن را نشان میدهد. پورتها را یکسان کنید یا در /etc/cockpit/cockpit.conf مقدار Origins را تنظیم کنید.
ارسال فرمهای Webmin پس از قرار دادن آن پشت یک پروکسی با شکست مواجه میشود. بررسی Referer آنها را رد میکند. نام میزبان پروکسی را به referers= در /etc/webmin/miniserv.conf اضافه کنید و هنگامی که پنل تحت یک مسیر (path) ارائه میشود، webprefix= را تنظیم کنید.
مطمئن نیستید که آیا یک پنل در معرض دید (exposed) قرار دارد یا خیر. sudo ss -lntp | grep -E '9090|10000' این موضوع را از خود سرور پاسخ میدهد و Webmin هر تلاش برای ورود را در /var/webmin/miniserv.log ثبت میکند؛ فایلی که ارزش دارد پس از هر تغییر در نحوه گوش دادن (listening) سرویس، آن را بررسی کنید.
FAQ
آیا Cockpit برای یک VPS اوبونتو بهتر است یا Webmin؟
برای اکثر کاربران، Cockpit گزینه بهتری است؛ زیرا از مخازن رسمی اوبونتو نصب میشود، همراه با سایر بخشهای سیستم بهروزرسانی میشود و تنها زمانی که نشست مرورگر باز باشد، اجرا میگردد. اگر به ویرایشگر فرممحور برای سرویسهایی که Cockpit پشتیبانی نمیکند (مانند BIND یا Postfix) نیاز دارید، Webmin را انتخاب کنید؛ اما در نظر داشته باشید که وبسرور آن همیشه با دسترسی root اجرا میشود و بهروزرسانیهای آن از مخازن اختصاصی خود Webmin دریافت میشوند.
آیا میتوانم Cockpit و Webmin را همزمان روی یک سرور اجرا کنم؟
بله. این دو از پورتهای متفاوتی (9090 و 10000) استفاده میکنند و با هم تداخلی ندارند، زیرا هر دو مستقیماً فایلهای سیستم را ویرایش میکنند و مالکیت انحصاری بر سیستم ندارند. با این حال، این کار توصیه نمیشود. هر پنل یک نقطه ورود با دسترسی root روی همان ماشین است و شما با این کار، سطح ریسک امنیتی را برای صرفهجویی در چند کلیک، دوبرابر میکنید. اگر هر دو را نصب کردید، هر دو را روی 127.0.0.1 محدود کنید و از طریق SSH tunnel به آنها دسترسی داشته باشید.
آیا باز کردن پورت 9090 یا 10000 روی اینترنت امن است؟
خیر، اگر از ورود با رمز عبور استفاده میکنید. هر دو پنل به دسترسی root ختم میشوند و هر دو پورت در عرض چند ساعت پس از باز شدن، توسط اسکنرهای خودکار شناسایی میشوند. پنل را روی 127.0.0.1 محدود کنید، سپس دستور ssh -N -L 9090:127.0.0.1:9090 user@host را اجرا کرده و به https://localhost:9090 بروید. با sudo ss -lntp | grep 9090 تأیید کنید که خروجی باید 127.0.0.1:9090 باشد، نه 0.0.0.0:9090. استفاده از یک reverse proxy با احراز هویت، گزینه دوم قابلقبول است.
چرا ورود به Cockpit شکست میخورد در حالی که SSH با کلید کار میکند؟
Cockpit از طریق PAM و با رمز عبور یونیکس احراز هویت میکند و صفحه ورود آن کلیدهای SSH را نمیپذیرد. در سرورهای امنسازیشده (hardened)، حساب کاربری اغلب رمز عبور معتبری ندارد. دستور sudo passwd -S youruser را اجرا کنید: وجود L در فیلد دوم به این معنی است که رمز عبور قفل شده است؛ بنابراین PAM چیزی برای پذیرش ندارد و تمام تلاشها رد میشوند. با استفاده از sudo passwd youruser یک رمز عبور تنظیم کنید یا از حساب کاربری دیگری برای پنل استفاده کنید.
آیا Cockpit کانتینرهای Docker را مدیریت میکند؟
خیر. صفحه کانتینر در Cockpit از cockpit-podman میآید و Podman را مدیریت میکند. ماژول قدیمی Docker سالها پیش حذف شد و دیگر بازنخواهد گشت. اگر سرویسهای شما تحت Docker اجرا میشوند، آنها را با یک فایل compose در سیستم کنترل نسخه و از طریق SSH مدیریت کنید و اجازه دهید Cockpit بخشهای سیستمی پیرامون آنها، مانند journal و دیسکها را مدیریت کند.