امنیت Docker چیست؟ چکلیست امنسازی Docker برای سرورهای وب
امنیت Docker مجموعهای از روشهای دفاعی برای محافظت از کانتینرها، ایمیجها، شبکهها و سرور میزبان در برابر نفوذ و دسترسی غیرمجاز است. تنظیمات نادرست Docker Socket، اجرای کانتینرها با مجوزهای بالا، انتشار پورتهای حساس و استفاده از ایمیجهای آسیبپذیر از مهمترین خطرات امنیتی محسوب میشوند. برای امنسازی Docker باید اصل حداقل دسترسی، جداسازی شبکه، مدیریت Secrets، محدودسازی منابع و پایش امنیتی اجرا شود.
امنیت Docker به مجموعهای از تنظیمات، سیاستها و روشهای دفاعی گفته میشود که از کانتینرها، ایمیجها، شبکههای داخلی و سرور میزبان در برابر دسترسی غیرمجاز، نشت اطلاعات و سوءاستفاده از منابع محافظت میکنند. برای امنسازی Docker در سرورهای وب باید دسترسیها را محدود کرد، کانتینرها را با حداقل مجوز اجرا کرد، شبکه و فایلسیستم را ایمن ساخت و نظارت امنیتی مستمر داشت.
مقدمه: چرا امنیت Docker برای سرورهای وب اهمیت دارد؟
Docker یکی از پرکاربردترین فناوریهای Containerization یا کانتینرسازی است که به توسعهدهندگان و مدیران سرور اجازه میدهد برنامهها را همراه با وابستگیهای موردنیازشان در محیطهایی مستقل اجرا کنند.
این فناوری استقرار برنامههای تحت وب را سادهتر کرده و مدیریت سرویسهایی مانند Nginx، Apache، PHP، Node.js، MySQL، PostgreSQL و Redis را بهبود داده است.
بااینحال، استفاده از کانتینر بهتنهایی امنیت سرور را تضمین نمیکند.
تصور کنید یک وبسایت فروشگاهی را با Docker اجرا کردهاید. وبسرور، پایگاه داده و سرویس کش در کانتینرهای جداگانه قرار دارند. در ظاهر، سرویسها از یکدیگر تفکیک شدهاند؛ اما اگر پورت پایگاه داده به اینترنت متصل باشد، کانتینری با دسترسی Root اجرا شود یا Docker Socket در اختیار برنامه قرار بگیرد، مهاجم ممکن است از یک ضعف امنیتی برای دسترسی به اطلاعات یا حتی منابع سرور میزبان استفاده کند.
نکته مهم این است که کانتینرهای Docker برخلاف ماشینهای مجازی سنتی، از کرنل سیستمعامل میزبان استفاده میکنند. بنابراین مرز امنیتی میان کانتینر و میزبان مطلق نیست و آسیبپذیریهای کرنل، تنظیمات اشتباه یا مجوزهای بیشازحد میتوانند این مرز را تضعیف کنند.
امنیت Docker باید در چند سطح بررسی شود:
- امنیت سیستمعامل و کرنل میزبان
- امنیت Docker Engine و Docker Daemon
- امنیت ایمیجها و زنجیره تأمین نرمافزار
- مدیریت کاربران و مجوزهای کانتینر
- امنیت شبکه و پورتهای منتشرشده
- حفاظت از دادهها، Volumeها و اطلاعات محرمانه
- کنترل منابع و جلوگیری از اختلال سرویس
- ثبت رویدادها، پایش و پاسخگویی به رخدادهای امنیتی
در این راهنما، روشهای امنسازی Docker برای سرورهای وب را از مفاهیم اولیه تا تنظیمات عملی محیط Production بررسی میکنیم. 
Docker چیست و چگونه کار میکند؟
Docker بستری برای ساخت، توزیع و اجرای برنامهها در قالب کانتینر است. هر کانتینر شامل برنامه و وابستگیهای ضروری آن میشود و میتواند در محیطی نسبتاً مستقل از سایر کانتینرها فعالیت کند.
تفاوت Docker Image و Container
برای درک امنیت Docker ابتدا باید دو مفهوم مهم را بشناسیم.
Docker Image یا ایمیج داکر: بستهای است که فایلهای برنامه، کتابخانهها، تنظیمات و اجزای لازم برای اجرای سرویس را شامل میشود.
Docker Container یا کانتینر: نمونه اجرایی یک ایمیج است که با تنظیمات مشخصی روی Docker Engine اجرا میشود.
بهعنوان مثال، یک ایمیج Nginx میتواند مبنای اجرای چند کانتینر وبسرور باشد. هر کانتینر منابع، شبکه و تنظیمات اجرایی مخصوص خود را خواهد داشت.
امنیت ایمیج و امنیت کانتینر به یکدیگر وابستهاند، اما یکسان نیستند. ممکن است ایمیجی سالم باشد ولی با تنظیمات ناامن اجرا شود؛ یا کانتینری محدودشده از ایمیجی دارای آسیبپذیری شناختهشده استفاده کند.
نقش Docker Engine و Docker Daemon
Docker Engine زیرساخت اصلی مدیریت کانتینرهاست.
Docker Daemon که معمولاً با نام dockerd شناخته میشود، مسئول انجام عملیات اصلی مانند ایجاد کانتینر، مدیریت شبکه، تخصیص منابع و ارتباط با ذخیرهسازی است.
ابزار Docker CLI نیز دستورات مدیریتی را به Daemon ارسال میکند.
ازآنجاکه Docker Daemon در حالت معمول با مجوزهای بالای سیستمی فعالیت میکند، حفاظت از رابط مدیریتی آن اهمیت بسیار زیادی دارد.
نقش Namespaces و Cgroups در جداسازی کانتینرها
Docker برای ایجاد جداسازی از قابلیتهای کرنل لینوکس استفاده میکند.
Namespaces مشخص میکنند هر پردازش چه بخشهایی از محیط سیستم را مشاهده کند. برای مثال، میتوان فضای پردازشها، شبکه، نقاط اتصال فایلسیستم و شناسه کاربران را تا حدی از یکدیگر جدا کرد.
Control Groups یا Cgroups امکان مدیریت و محدودسازی مصرف منابعی مانند پردازنده، حافظه و تعداد پردازشها را فراهم میکنند.
این دو فناوری از پایههای اصلی ایزولهسازی هستند؛ بااینحال، جایگزین سیاستهای امنیتی مانند کنترل دسترسی، مدیریت آسیبپذیری و محافظت از کرنل نمیشوند. 
مهمترین تهدیدات امنیتی Docker کداماند؟
برای طراحی یک راهبرد مناسب امنیت Docker باید ابتدا مسیرهای احتمالی نفوذ و نقاط حساس زیرساخت را شناخت.
فرار از کانتینر یا Container Escape
Container Escape زمانی رخ میدهد که یک فرایند بتواند از محدودیتهای امنیتی کانتینر عبور کند و به منابعی خارج از محدوده مجاز خود دسترسی پیدا کند.
چنین اتفاقی ممکن است در نتیجه آسیبپذیری کرنل، خطای نرمافزارهای Container Runtime یا تنظیمات بسیار پرمجوز رخ دهد.
اجرای کانتینر با مجوزهای گسترده، دسترسی به دستگاههای میزبان یا غیرفعالکردن کنترلهای امنیتی میتواند پیامد یک آسیبپذیری را شدیدتر کند.
استفاده از ایمیجهای آلوده یا آسیبپذیر
همه ایمیجهای موجود در رجیستریهای عمومی الزاماً امن نیستند.
برخی ممکن است شامل کتابخانههای قدیمی، ابزارهای غیرضروری، اطلاعات محرمانه یا بستههای دارای آسیبپذیری باشند.
در حملات Supply Chain یا زنجیره تأمین، مهاجم تلاش میکند از مسیر وابستگیها، مخازن یا فرایند ساخت نرمافزار به سیستم هدف آسیب برساند.
دسترسی غیرمجاز به Docker API
Docker API قابلیت مدیریت کانتینرها را فراهم میکند.
اگر این رابط بدون احراز هویت و کنترل دسترسی مناسب در شبکه قرار بگیرد، مهاجم ممکن است بتواند عملیات مدیریتی خطرناکی را اجرا کند.
دسترسی غیرمجاز به Docker Daemon در حالت Rootful میتواند پیامدهایی در سطح کل سرور داشته باشد.
افشای اطلاعات محرمانه
رمز عبور پایگاه داده، کلیدهای API، توکنهای دسترسی و کلیدهای خصوصی نباید در ایمیج یا مخزن کد قرار بگیرند.
ذخیره نادرست این اطلاعات میتواند باعث افشای آنها از طریق تاریخچه ساخت، فایلهای تنظیمات، لاگها یا دسترسی غیرمجاز به محیط اجرا شود.
حملات اختلال سرویس و مصرف منابع
یک برنامه آسیبپذیر یا کانتینر معیوب ممکن است میزان زیادی CPU، RAM، فضای ذخیرهسازی یا تعداد پردازشها را مصرف کند.
در سرورهایی که چند وبسایت را میزبانی میکنند، این وضعیت میتواند بر عملکرد سایر سرویسها نیز تأثیر بگذارد.
امنیت سرور میزبان؛ اولین مرحله امنسازی Docker
امنیت Docker از سیستمعامل میزبان آغاز میشود.
اگر Host سیستمعامل ضعیف، آسیبپذیر یا دارای تنظیمات مدیریتی ناامن باشد، محدودسازی کانتینرها نمیتواند تمام خطرات را جبران کند.
بهروزرسانی سیستمعامل و کرنل
نصب وصلههای امنیتی یکی از اقدامات اصلی محافظت از سرور است.
برای سرورهای مبتنی بر Ubuntu یا Debian میتوان وضعیت بستهها را با دستورات زیر بررسی کرد:
sudo apt update
apt list --upgradable
پس از بررسی تغییرات و سازگاری سرویسها، بهروزرسانی طبق برنامه نگهداری انجام میشود.
sudo apt upgrade
در محیط Production بهتر است پیش از تغییرات مهم، نسخه پشتیبان و برنامه بازگشت به وضعیت قبلی آماده باشد.
بهروزرسانی کرنل ممکن است نیازمند راهاندازی مجدد سرور باشد؛ بنابراین صرف نصب بسته جدید همیشه به معنای فعالشدن وصله امنیتی نیست.
ایمنسازی دسترسی SSH
برای مدیریت سرور Docker معمولاً از SSH استفاده میشود.
اقدامات پیشنهادی عبارتاند از:
- استفاده از کلید SSH بهجای رمز عبور در صورت امکان
- محدودکردن دسترسی مستقیم Root
- فعالسازی احراز هویت چندعاملی در زیرساختهای پشتیبانیشده
- محدودسازی دسترسی مدیریتی با فایروال یا VPN
- حذف حسابهای غیرضروری
- ثبت و بررسی ورودهای ناموفق
- اعمال بهروزرسانیهای امنیتی OpenSSH
در صورت استفاده از Fail2Ban نیز میتوان تلاشهای ورود مکرر ناموفق را شناسایی و طبق سیاست تعریفشده محدود کرد.
Fail2Ban جایگزین تنظیمات صحیح SSH نیست، بلکه یک لایه دفاعی تکمیلی محسوب میشود.
حذف سرویسهای غیرضروری
هر سرویس فعال میتواند یک نقطه ورود احتمالی ایجاد کند.
برای بررسی پورتهای در حال گوشدادن روی سیستم لینوکسی میتوان از دستور زیر استفاده کرد:
sudo ss -lntup
خروجی باید با فهرست سرویسهای مجاز سرور مقایسه شود.
اگر سرویسی به دسترسی اینترنتی نیاز ندارد، بهتر است فقط روی شبکه داخلی یا رابط محلی در دسترس باشد. 
امنیت Docker Daemon و محافظت از Docker Socket
یکی از حساسترین بخشهای امنیت Docker، محافظت از رابط مدیریتی Docker Daemon است.
Docker Socket چیست؟
در بسیاری از نصبهای معمول لینوکس، Docker CLI از طریق مسیر زیر با Daemon ارتباط برقرار میکند:
/var/run/docker.sock
این فایل Socket رابط ارتباطی با Docker API است.
در نصب Rootful معمول، کاربری که امکان کنترل کامل این Socket را داشته باشد، عملاً میتواند عملیات بسیار قدرتمندی روی Docker Host انجام دهد.
به همین دلیل، دسترسی به Docker Socket باید مشابه دسترسی مدیریتی حساس در نظر گرفته شود.
چرا نباید Docker Socket را داخل کانتینر Mount کنیم؟
گاهی برای مدیریت خودکار سرویسها، Socket میزبان در اختیار یک کانتینر قرار میگیرد.
این طراحی ممکن است برای ابزارهای مدیریتی ضروری باشد، اما خطر امنیتی قابلتوجهی ایجاد میکند.
اگر برنامه داخل کانتینر آسیبپذیر باشد، مهاجم ممکن است از دسترسی Docker API برای انجام عملیات فراتر از اختیارات معمول برنامه استفاده کند.
حتی Mount کردن Socket بهصورت Read-Only الزاماً دستورات Docker API را فقطخواندنی نمیکند؛ زیرا یک اتصال برقرارشده همچنان میتواند درخواستهای تغییردهنده ارسال کند.
راهکار مناسب: از دراختیارگذاشتن مستقیم Docker Socket به برنامههای عمومی، افزونههای نامطمئن و سرویسهای غیرضروری خودداری کنید.
اگر ابزار مدیریتی واقعاً به API نیاز دارد، باید معماری دسترسی، احراز هویت، محدودسازی عملیات و سطح اعتماد آن بهصورت مستقل ارزیابی شود.
بررسی عضویت کاربران در گروه Docker
در نصب Rootful، عضویت در گروه docker معمولاً دسترسی بسیار قدرتمندی به Daemon میدهد.
برای بررسی اعضای این گروه میتوان از دستور زیر استفاده کرد:
getent group docker
فقط کاربران و سرویسهای کاملاً مورداعتماد باید این دسترسی را داشته باشند.
افزودن یک کاربر معمولی به گروه Docker نباید بهعنوان روشی بیخطر برای حذف نیاز به sudo تلقی شود.
محافظت از Docker API در شبکه
Docker Daemon نباید بدون کنترل امنیتی مناسب از طریق TCP در اینترنت عمومی قابلدسترسی باشد.
برای مدیریت از راه دور، استفاده از اتصال SSH و Docker Context یا ارتباط محافظتشده با TLS و سیاستهای دسترسی مناسب، گزینههای قابلبررسی هستند.
در محیطهایی که امکان محدودکردن دسترسی به شبکه مدیریتی خصوصی وجود دارد، نباید رابط مدیریتی مستقیماً در معرض اینترنت عمومی قرار گیرد.
اجرای Docker بهصورت Rootless؛ کاهش دسترسیهای سیستمی
یکی از روشهای مهم امنسازی Docker، بررسی امکان استفاده از Rootless Mode است.
تفاوت Rootful و Rootless Docker
در حالت Rootful، Docker Daemon معمولاً با اختیارات Root اجرا میشود.
اما در حالت Rootless، هم Daemon و هم کانتینرها در چارچوب یک کاربر غیرروت و User Namespace اجرا میشوند.
این طراحی میتواند پیامد برخی آسیبپذیریها یا خطاهای مربوط به Daemon و Runtime را کاهش دهد.
البته Rootless به معنای مصونیت کامل نیست؛ زیرا کانتینرها همچنان از کرنل میزبان استفاده میکنند.
تفاوت Rootless با User Namespace Remapping
قابلیت userns-remap شناسه کاربران داخل کانتینر را به شناسههای غیرممتاز روی میزبان نگاشت میکند.
برای مثال، کاربر Root داخل کانتینر میتواند روی Host به یک UID غیرروت تبدیل شود.
تفاوت اصلی این است که در userns-remap، خود Docker Daemon همچنان میتواند با اختیارات Root فعالیت کند؛ اما Rootless سطح دسترسی Daemon را نیز کاهش میدهد.
آیا Rootless برای همه سرورهای وب مناسب است؟
خیر. انتخاب این حالت باید بر اساس نیاز واقعی سرویس انجام شود.
برخی محدودیتهای عملیاتی ممکن است به دسترسی به پورتهای پایین، مدیریت شبکه، قابلیتهای کرنل، Cgroups یا شیوه ذخیرهسازی مربوط باشند.
همچنین پشتیبانی از امکانات مختلف میتواند به نسخه Docker، توزیع لینوکس و تنظیمات میزبان وابسته باشد.
بنابراین پیش از انتقال یک سرور Production به Rootless باید سازگاری برنامه، ابزار مانیتورینگ، پروکسی معکوس و سیستم پشتیبانگیری بررسی شود.
محدودسازی مجوزهای کانتینر با اصل Least Privilege
اصل Least Privilege یا حداقل سطح دسترسی میگوید هر پردازش باید فقط مجوزهایی را دریافت کند که برای وظیفه خود نیاز دارد.
این اصل یکی از مهمترین پایههای امنیت Docker است.
اجرای برنامه با کاربر غیرروت
اجرای پردازش اصلی کانتینر با کاربر Root میتواند پیامد دسترسی غیرمجاز را افزایش دهد.
در بسیاری از برنامههای وب، نیازی وجود ندارد که پردازش اصلی با شناسه کاربر صفر اجرا شود.
در Dockerfile میتوان پس از آمادهسازی فایلها و تنظیم مجوزهای ضروری، کاربر اجرایی غیرممتاز تعریف کرد.
نمونه مفهومی:
USER 10001:10001
البته پیش از استفاده باید مالکیت فایلها، مجوز اجرای برنامه و مسیرهای موردنیاز برای نوشتن بررسی شوند.
استفاده از USER بهتنهایی جایگزین User Namespace، کنترل Capabilities و سایر لایههای امنیتی نیست.
Linux Capabilities چیست؟
در لینوکس، اختیارات مدیریتی میتوانند به قابلیتهای کوچکتری به نام Capabilities تقسیم شوند.
برنامهها معمولاً به تمام قابلیتهای مدیریتی نیاز ندارند.
برای کاهش سطح دسترسی کانتینر میتوان قابلیتهای غیرضروری را حذف کرد.
برای نمونه:
docker run --cap-drop ALL ...
این دستور یک نمونه از سیاست حذف قابلیتهاست و باید با سایر پارامترهای معتبر اجرای کانتینر تکمیل شود.
برخی سرویسها برای عملکرد صحیح ممکن است به قابلیت مشخصی نیاز داشته باشند. در این صورت فقط همان قابلیت باید پس از بررسی امنیتی اضافه شود.
چرا استفاده از Privileged خطرناک است؟
گزینه --privileged محدودیتهای امنیتی متعددی را کاهش میدهد و قابلیتها و دسترسیهای گستردهای در اختیار کانتینر قرار میدهد.
برای اکثر وبسایتها، APIها، سرویسهای PHP، پایگاه داده و برنامههای معمول چنین مجوزی ضروری نیست.
اگر اجرای یک برنامه فقط با Privileged امکانپذیر است، باید علت وابستگی آن بررسی شود.
ممکن است مشکل از مجوز فایلها، تنظیمات Runtime یا طراحی نامناسب برنامه باشد.
جلوگیری از افزایش امتیازات
قابلیت no-new-privileges از کسب امتیازات جدید توسط پردازش و فرزندان آن از مسیرهایی مانند فایلهای Setuid جلوگیری میکند.
در Docker Compose میتوان از تنظیم زیر استفاده کرد:
security_opt:
- no-new-privileges:true
این گزینه یک لایه دفاعی مفید است، اما تمام روشهای سوءاستفاده از مجوزها یا آسیبپذیریهای برنامه را مسدود نمیکند.
استفاده از Seccomp، AppArmor و SELinux در امنیت Docker
Docker میتواند از سازوکارهای امنیتی کرنل برای محدودکردن رفتار پردازشهای داخل کانتینر استفاده کند.
Seccomp چیست؟
Seccomp قابلیتی در لینوکس است که امکان محدودسازی System Callها یا فراخوانیهای سیستمی را فراهم میکند.
برنامهها برای دسترسی به منابع سیستمعامل از System Call استفاده میکنند.
با استفاده از سیاست Seccomp میتوان برخی عملیات غیرضروری یا حساس را برای پردازشهای کانتینر محدود کرد.
Docker دارای پروفایل پیشفرض Seccomp است که برای بسیاری از برنامههای معمول نقطه شروع مناسبی محسوب میشود.
غیرفعالکردن این محافظ بدون دلیل فنی مشخص توصیه نمیشود.
نقش AppArmor
AppArmor یکی از Linux Security Moduleهاست که میتواند دسترسی برنامهها به فایلها و برخی منابع سیستم را بر اساس سیاستهای امنیتی کنترل کند.
در محیطهایی که AppArmor فعال و بهدرستی یکپارچه شده است، کانتینرها میتوانند از پروفایل پیشفرض Docker استفاده کنند.
برای سرویسهای حساستر میتوان سیاست اختصاصی طراحی کرد؛ اما این کار به شناخت دقیق رفتار برنامه نیاز دارد.
SELinux چه تفاوتی دارد؟
SELinux نیز یک سازوکار Mandatory Access Control یا کنترل دسترسی اجباری است.
این فناوری با استفاده از برچسبها و سیاستهای امنیتی میتواند دسترسی پردازشها به منابع را محدود کند.
SELinux بهویژه در برخی توزیعهای خانواده Red Hat کاربرد گسترده دارد.
در زمان استفاده از Volumeها باید برچسبگذاری امنیتی فایلها و تنظیمات Host نیز با سیاستهای SELinux هماهنگ باشد.
بهترین روش استفاده از این محافظتها
برای سرورهای وب، نقطه شروع مناسب معمولاً حفظ پروفایلهای امنیتی پیشفرض و محدودکردن بیشتر مجوزها بر اساس نیاز واقعی برنامه است.
در صورت بروز مشکل سازگاری، بهتر است ابتدا علت آن بررسی شود؛ نه اینکه تمام محافظتهای امنیتی غیرفعال شوند.
امنیت Docker Image و جلوگیری از آسیبپذیریهای زنجیره تأمین
امنیت یک کانتینر از مرحله انتخاب یا ساخت ایمیج آغاز میشود.
استفاده از منابع معتبر
ایمیجهای پایه باید از ناشران قابلاعتماد و رجیستریهای معتبر انتخاب شوند.
اما معتبر بودن ناشر به معنای نداشتن آسیبپذیری نیست.
پیش از استفاده از هر ایمیج باید وضعیت نگهداری، چرخه انتشار، وابستگیها و وصلههای امنیتی آن بررسی شود.
چرا استفاده از تگ Latest مناسب نیست؟
تگ latest الزاماً به معنای امنترین یا پایدارترین نسخه نیست.
این تگ ممکن است در زمانهای مختلف به نسخههای متفاوتی اشاره کند و بازتولید دقیق استقرار را دشوار سازد.
برای محیط Production بهتر است نسخه مشخصی انتخاب شود و در صورت نیاز، ایمیج با Digest معتبر تثبیت گردد.
تثبیت Digest از تغییر ناخواسته محتوای ایمیج جلوگیری میکند؛ اما بهروزرسانی امنیتی را بهصورت خودکار انجام نمیدهد.
بنابراین باید فرایندی برای شناسایی نسخههای جدید، بررسی آسیبپذیریها و جایگزینی آگاهانه ایمیج وجود داشته باشد.
اسکن امنیتی ایمیجها
Image Scanning یکی از بخشهای ضروری امنیت Docker است.
ابزارهایی مانند Trivy، Docker Scout و Grype میتوانند در شناسایی آسیبپذیریهای شناختهشده وابستگیها و اجزای ایمیج کمک کنند.
اسکن امنیتی باید در چند مرحله انجام شود:
- پیش از انتشار ایمیج جدید
- در فرایند CI/CD
- پیش از استقرار در Production
- بهصورت دورهای برای ایمیجهای در حال استفاده
- پس از انتشار هشدار امنیتی مهم درباره یک وابستگی
نتایج اسکن باید بر اساس شدت آسیبپذیری، امکان بهرهبرداری، مسیر دسترسی و اهمیت دارایی اولویتبندی شوند.
وجود یک CVE لزوماً به معنای قابلسوءاستفادهبودن آن در شرایط اجرای هر برنامه نیست؛ همانطور که نبود CVE شناختهشده نیز امنیت کامل را اثبات نمیکند.
اهمیت SBOM در امنیت ایمیج
SBOM مخفف Software Bill of Materials و به معنای فهرست اجزای نرمافزار است.
این فهرست مشخص میکند محصول از چه کتابخانهها و وابستگیهایی استفاده میکند.
وجود SBOM به تیم امنیت کمک میکند هنگام انتشار یک آسیبپذیری جدید، سریعتر تشخیص دهد کدام ایمیجها و سرویسها ممکن است تحت تأثیر قرار گرفته باشند.
در زیرساختهای حساس، بررسی اصالت ایمیج و امضای دیجیتال آن نیز میتواند بخشی از فرایند استقرار باشد.
امنسازی Dockerfile و فرایند Build
فایل Dockerfile مشخص میکند ایمیج چگونه ساخته شود.
اشتباه در این فایل میتواند باعث ورود ابزارهای غیرضروری، اطلاعات حساس یا تنظیمات ناامن به محیط Production شود.
استفاده از Multi-Stage Build
در روش Multi-Stage Build مراحل ساخت برنامه از محیط نهایی اجرا تفکیک میشوند.
برای مثال، یک برنامه Node.js ممکن است برای Build به ابزارهای توسعه نیاز داشته باشد؛ اما نسخه نهایی نباید تمام ابزارهای کامپایل و بستههای توسعه را همراه داشته باشد.
با جداسازی مراحل میتوان تعداد اجزای ایمیج نهایی و سطح حمله احتمالی را کاهش داد.
حذف فایلهای غیرضروری
ایمیج Production نباید بیدلیل شامل موارد زیر باشد:
- فایلهای آزمایشی
- کلیدهای خصوصی
- پوشههای توسعه غیرضروری
- فایلهای پشتیبان پایگاه داده
- اطلاعات محیط محلی توسعهدهندگان
- خروجیهای Debug حساس
- فایلهای محرمانه مخزن Git
فایل .dockerignore میتواند از ورود ناخواسته برخی فایلها به Build Context جلوگیری کند.
البته این فایل بهتنهایی ابزار مدیریت اطلاعات محرمانه نیست و باید در کنار سیاست مناسب مدیریت Secrets استفاده شود.
جلوگیری از قرارگرفتن رمزها در لایههای ایمیج
نباید رمز عبور یا توکن دسترسی را مستقیماً داخل Dockerfile قرار داد.
همچنین استفاده از ARG یا ENV برای انتقال Secrets در زمان Build ممکن است باعث باقیماندن اطلاعات در فراداده یا خروجیهای ساخت شود.
برای نیازهای محرمانه زمان Build، قابلیت BuildKit Secrets انتخاب مناسبتری است.
در این حالت، اطلاعات حساس بهصورت موقت برای دستور موردنیاز در دسترس قرار میگیرند و نباید در فایلهای خروجی ذخیره شوند. 
امنیت شبکه Docker و جلوگیری از دسترسی غیرمجاز
امنیت شبکه یکی از مهمترین موضوعات برای مدیران سرورهای وب است.
پیکربندی اشتباه شبکه میتواند سرویسهایی را که باید فقط داخلی باشند، در معرض دسترسی عمومی قرار دهد.
تفاوت شبکه Bridge و Host
در حالت Bridge، کانتینرها معمولاً به یک شبکه مجازی Docker متصل میشوند.
شبکههای Bridge تعریفشده توسط کاربر امکان جداسازی منطقی سرویسها و کنترل بهتر ارتباط میان آنها را فراهم میکنند.
در حالت Host Network، کانتینر از فضای شبکه میزبان استفاده میکند و بخشی از جداسازی شبکهای را از دست میدهد.
برای اکثر معماریهای وب، استفاده از شبکههای اختصاصی Bridge گزینه قابلبررسی مناسبی است.
چرا انتشار پورتها خطرناک است؟
در Docker، انتشار پورت با گزینه -p انجام میشود.
اگر یک سرویس بدون تعیین رابط مشخص روی پورت میزبان منتشر شود، ممکن است روی همه آدرسهای قابلاستفاده میزبان در دسترس قرار گیرد.
برای مثال، یک پنل مدیریتی یا برنامه داخلی ممکن است ناخواسته از اینترنت قابلدسترسی شود.
در محیطی که سرویس فقط باید توسط Reverse Proxy محلی استفاده شود، میتوان پورت را به Loopback محدود کرد.
نمونه:
docker run -p 127.0.0.1:8080:8080 my-web-app
این نمونه فرض میکند برنامه داخل کانتینر روی پورت 8080 گوش میدهد.
محدودسازی اتصال به 127.0.0.1 دسترسی معمول از رابطهای خارجی میزبان را کاهش میدهد.
بااینحال، سیاستهای مسیریابی خاص، نسخه Docker و تنظیمات شبکه باید در ارزیابی امنیتی لحاظ شوند.
چرا نباید پورت پایگاه داده عمومی باشد؟
در یک معماری رایج، MySQL یا PostgreSQL فقط باید در دسترس برنامههایی باشد که واقعاً به آن نیاز دارند.
انتشار مستقیم پورت پایگاه داده روی اینترنت، سطح حمله را افزایش میدهد.
حتی اگر رمز عبور قدرتمند باشد، وجود یک سرویس حساس در اینترنت میتواند احتمال سوءاستفاده از آسیبپذیریهای ناشناخته، خطای احراز هویت یا تنظیمات اشتباه را افزایش دهد.
راهکار مناسب، قرار دادن پایگاه داده در شبکه اختصاصی و خودداری از انتشار پورت آن روی میزبان است؛ مگر زمانی که یک نیاز مدیریتی مشخص با کنترلهای مناسب وجود داشته باشد.
طراحی شبکههای جداگانه برای برنامههای وب
در یک معماری سهلایه میتوان از چند محدوده شبکه استفاده کرد:
لایه ورودی: Reverse Proxy یا وبسروری که درخواستهای کاربران را دریافت میکند.
لایه برنامه: کانتینرهای اصلی اپلیکیشن که منطق کسبوکار را اجرا میکنند.
لایه داده: پایگاه داده، کش و سرویسهای نگهداری اطلاعات.
در این طراحی، پایگاه داده نباید بهصورت مستقیم به شبکه عمومی متصل شود.
همچنین سرویسها باید فقط به شبکههایی متصل شوند که برای ارتباط مجاز به آنها ضروری است.
استفاده از شبکه اختصاصی به معنی اعمال خودکار تمام سیاستهای Zero Trust نیست. کنترل ارتباطات خروجی، هویت سرویسها و مجوزهای داخلی نیز باید بررسی شود.
تعامل Docker با UFW و فایروال لینوکس
یکی از اشتباهات رایج در امنیت Docker، تصور این است که فعالبودن UFW بهتنهایی تمام پورتهای منتشرشده Docker را کنترل میکند.
Docker برای مدیریت شبکههای Bridge و انتشار پورتها از قواعد Packet Filtering و NAT استفاده میکند.
در برخی پیکربندیهای معمول، ترافیک منتشرشده به کانتینر پیش از عبور از مسیرهایی که UFW برای کنترل ترافیک ورودی استفاده میکند، هدایت میشود.
بنابراین ممکن است یک پورت Docker برخلاف انتظار مدیر سرور قابلدسترسی باشد.
برای مقابله با این مشکل باید تعامل نسخه و Backend فایروال Docker با iptables یا nftables بررسی شود.
در پیادهسازیهای مبتنی بر iptables، زنجیره DOCKER-USER میتواند برای سیاستهای فیلترگذاری مناسب باشد. در Backend مبتنی بر nftables باید از سازوکارها و قواعد متناظر استفاده شود.
نکته مهم: دستکاری بدون بررسی قواعد Docker یا غیرفعالکردن مدیریت فایروال آن ممکن است باعث قطع ارتباط سرویسها یا ایجاد مسیرهای ناامن شود.
محدودکردن ارتباطات خروجی
امنیت شبکه فقط به پورتهای ورودی محدود نمیشود.
اگر یک برنامه وب آسیب ببیند، ارتباط خروجی نامحدود ممکن است برای اتصال به سرویسهای غیرمجاز یا انتقال اطلاعات مورد سوءاستفاده قرار گیرد.
در سرویسهای حساس میتوان دسترسی خروجی را بر اساس نیاز واقعی برنامه محدود کرد.
برای مثال، یک پایگاه داده داخلی معمولاً نیازی ندارد بتواند به هر مقصدی در اینترنت متصل شود.
امنیت Volumeها و فایلسیستم کانتینر
دادههای پایدار در Docker معمولاً داخل Volume یا Bind Mount ذخیره میشوند.
اگر این منابع با مجوزهای اشتباه در اختیار کانتینر قرار گیرند، آسیبپذیری برنامه ممکن است به دسترسی غیرمجاز به دادههای میزبان منجر شود.
تفاوت Volume و Bind Mount
Docker Volume سازوکاری برای ذخیره و مدیریت دادههای پایدار خارج از لایه قابلنوشتن کانتینر است.
Bind Mount مسیری از فایلسیستم میزبان را در اختیار کانتینر قرار میدهد.
هیچکدام ذاتاً امنیت کامل ندارند.
انتخاب روش ذخیرهسازی باید بر اساس نیاز برنامه، مدیریت مجوزها، پشتیبانگیری و میزان دسترسی به Host انجام شود.
استفاده از Mount فقطخواندنی
زمانی که کانتینر فقط به خواندن فایل نیاز دارد، بهتر است دسترسی نوشتن حذف شود.
در Docker Compose میتوان برای بعضی Mountها از حالت Read-Only استفاده کرد.
volumes:
- ./config:/app/config:ro
در این نمونه، برنامه داخل کانتینر امکان تغییر معمول فایلهای مسیر پیکربندی را از طریق آن Mount ندارد.
البته حفاظت واقعی به مجوزهای میزبان، دیگر مسیرهای دسترسی و تنظیمات اجرا نیز وابسته است.
فایلسیستم Read-Only برای کانتینر
در برخی برنامههای وب میتوان Root Filesystem کانتینر را فقطخواندنی کرد.
read_only: true
این گزینه از تغییر معمول فایلهای لایه اصلی کانتینر جلوگیری میکند.
برای برنامههایی که نیازمند فایل موقت هستند، میتوان مسیرهای مشخصی را با tmpfs یا Volume مناسب فراهم کرد.
اجرای این سیاست بدون بررسی نیازهای برنامه ممکن است باعث اختلال در Cache، Session، آپلود فایل یا پردازشهای موقت شود.
محدودکردن دسترسی به فایلهای حساس Host
Mount کردن مسیرهای حساس میزبان در کانتینر باید تا حد امکان ممنوع باشد.
بهویژه دسترسی به فایلهای مربوط به احراز هویت، پیکربندی سرویسهای سیستمی و مسیرهای مدیریتی Host باید با حساسیت بالا بررسی شود.
اگر برنامه به یک فایل یا پوشه مشخص نیاز دارد، نباید برای راحتی، مسیرهای بسیار گسترده در اختیار آن قرار گیرد.
مدیریت Secrets و اطلاعات حساس در Docker
یکی از مهمترین اصول امنیت Docker، تفکیک اطلاعات محرمانه از کد و ایمیج است.
چرا Environment Variable همیشه بهترین گزینه نیست؟
متغیرهای محیطی روش رایجی برای انتقال تنظیمات برنامه هستند.
بااینحال، ذخیره رمز عبور و توکن در Environment Variable میتواند در بعضی شرایط خطر افشای اطلاعات را افزایش دهد.
برای مثال، کاربران دارای مجوز مدیریتی Docker، ابزارهای اشکالزدایی، گزارشهای خطا یا فرایندهای ثبت پیکربندی ممکن است به این اطلاعات دسترسی پیدا کنند.
به همین دلیل، اطلاعات بسیار حساس بهتر است با سازوکارهای اختصاصی مدیریت Secrets و کنترل دسترسی منتقل شوند.
استفاده از Docker Compose Secrets
Docker Compose امکان تعریف Secrets و ارائه آنها به سرویسهای مجاز را فراهم میکند.
این اطلاعات معمولاً به شکل فایل در مسیر /run/secrets/ داخل کانتینر قابلدسترسی میشوند.
برنامه باید از خواندن رمز از فایل پشتیبانی کند یا برای آن سازگار شده باشد.
باید توجه داشت که در Docker Compose معمولی، Secret مبتنی بر فایل لزوماً روی میزبان رمزنگاری نمیشود و ممکن است بهصورت Mount در اختیار کانتینر قرار گیرد.
در مقابل، سازوکار Secrets در Docker Swarm ویژگیهای مدیریتی و حفاظتی متفاوتی دارد.
بنابراین صرف نوشتن عبارت secrets در فایل Compose، امنیت کامل داده محرمانه را تضمین نمیکند.
اصول نگهداری امن Secrets
برای حفاظت از اطلاعات محرمانه بهتر است این اقدامات انجام شوند:
- نگهداری رمزها خارج از مخزن عمومی کد
- محدودکردن مجوز فایلهای Secret روی میزبان
- استفاده از Secret Manager مناسب در زیرساختهای بزرگتر
- تعریف مجوز مستقل برای هر سرویس
- چرخش دورهای و مبتنی بر ریسک کلیدهای حساس
- حذف Secrets قدیمی پس از جایگزینی
- جلوگیری از ثبت رمزها در Log
- بررسی افشای احتمالی اطلاعات در مخازن و Artifactهای Build
برای اطلاعات بسیار حساس، راهکارهایی مانند Vault یا سرویسهای مدیریت اسرار ارائهدهندگان زیرساخت ابری نیز قابلبررسی هستند.
جلوگیری از اختلال سرویس با محدودسازی منابع Docker
استفاده نامحدود از منابع میتواند پایداری سرورهای وب را تهدید کند.
در معماریهایی که چند کانتینر روی یک Host اجرا میشوند، مشکل یک سرویس ممکن است بر سایر برنامهها تأثیر بگذارد.
محدودکردن RAM
تعیین Memory Limit کمک میکند مصرف حافظه هر کانتینر در محدوده مشخصی کنترل شود.
برای مثال:
mem_limit: 512m
این مقدار باید متناسب با رفتار واقعی برنامه و نیازهای پیک مصرف انتخاب شود.
اگر محدودیت بیشازحد پایین باشد، برنامه ممکن است با خطای کمبود حافظه یا OOM Kill مواجه شود.
محدودکردن CPU
برای کنترل سهم پردازنده میتوان از قابلیتهای مدیریت CPU استفاده کرد.
نمونه:
cpus: "1.0"
این تنظیم به معنای محدودسازی ظرفیت مصرف پردازنده مطابق سازوکار Docker و Cgroups است، نه اختصاص دائمی یک هسته فیزیکی.
محدودکردن تعداد پردازشها
محدودیت PID از افزایش بیرویه تعداد پردازشها جلوگیری میکند.
pids_limit: 128
این محدودیت میتواند در کاهش پیامد برخی خطاهای برنامه یا مصرف غیرعادی منابع مؤثر باشد.
سیاست Restart مناسب
راهاندازی مجدد خودکار سرویسها برای افزایش دسترسپذیری مفید است.
اما سیاست Restart باید با توجه به علت خرابی، محدودیت منابع و سامانه نظارت انتخاب شود.
Restart مداوم برنامه معیوب بدون هشدار یا بررسی علت ممکن است مشکل اصلی را پنهان کند.
محدودسازی منابع همچنین جایگزین محافظت در برابر حملات حجیم DDoS نیست؛ زیرا چنین حملاتی ممکن است پیش از رسیدن درخواستها به کانتینر، ظرفیت شبکه را اشباع کنند.
امنسازی Docker Compose برای سرورهای وب
Docker Compose ابزار تعریف و مدیریت چند سرویس کانتینری در یک فایل پیکربندی است.
در پروژههای وب، معمولاً برنامه، وبسرور، پایگاه داده و سرویس کش با استفاده از Compose مدیریت میشوند.
نمونه پیکربندی امنیتی Docker Compose
نمونه زیر یک الگوی آموزشی برای یک برنامه وب داخلی است که پشت Reverse Proxy میزبان قرار میگیرد.
services:
web:
image: registry.example.com/web/app@sha256:REPLACE_WITH_VALID_DIGEST
user: "10001:10001"
read_only: true
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
init: true
pids_limit: 128
mem_limit: 512m
cpus: "0.75"
tmpfs:
- /tmp:rw,nosuid,nodev,size=64m
ports:
- "127.0.0.1:8080:8080"
networks:
- web_net
restart: "on-failure:5"
logging:
driver: local
options:
max-size: "10m"
max-file: "3"
networks:
web_net:
driver: bridge
این فایل یک الگوی آموزشی است، نه پیکربندی آماده اجرای هر برنامه.
آدرس ایمیج و Digest باید با مقادیر واقعی و معتبر جایگزین شوند. همچنین برنامه باید با شناسه کاربر انتخابشده، پورت داخلی، فایلسیستم فقطخواندنی و محدودیتهای تعیینشده سازگار باشد.
بررسی ویژگیهای امنیتی نمونه
کاربر غیرروت: پردازش برنامه با UID و GID مشخص اجرا میشود.
فایلسیستم فقطخواندنی: تغییر فایلهای اصلی کانتینر محدود میشود.
حذف Capabilities: قابلیتهای اضافی لینوکس حذف میشوند.
ممانعت از افزایش امتیاز: امکان کسب مجوزهای جدید از مسیرهای مشخص محدود میشود.
محدودیت منابع: حافظه، CPU و تعداد پردازشها در چارچوب سیاست تعیینشده قرار میگیرند.
پورت محلی: سرویس بهجای انتشار عمومی، روی Loopback میزبان منتشر میشود.
چرخش لاگ: حجم ذخیرهسازی لاگهای محلی کنترل میشود.
اعتبارسنجی پیکربندی Compose
پیش از اجرای سرویسها باید ساختار فایل بررسی شود.
docker compose config
این دستور میتواند به شناسایی خطاهای ساختاری و مشاهده پیکربندی نهایی کمک کند.
توجه کنید که خروجی آن ممکن است مقادیر متغیرها یا اطلاعات حساس را نمایش دهد؛ بنابراین نباید بدون بررسی در لاگ عمومی یا سامانه نامطمئن منتشر شود.
اعتبارسنجی نحوی بهتنهایی ثابت نمیکند تنظیمات امنیتی صحیح هستند. اجرای آزمایشی و تست عملکرد نیز ضروری است.
معماری امن Docker برای Nginx، PHP و پایگاه داده
سرورهای وب معمولاً از چند سرویس مرتبط استفاده میکنند.
برای مثال، یک وبسایت PHP ممکن است شامل Nginx، PHP-FPM، MySQL و Redis باشد.
نقش Reverse Proxy
Reverse Proxy درخواستهای کاربران را دریافت کرده و آنها را به سرویسهای داخلی منتقل میکند.
این لایه میتواند برای مدیریت HTTPS، مسیریابی درخواستها، محدودسازی نرخ و اعمال بعضی سیاستهای امنیتی استفاده شود.
در طراحی مناسب، فقط سرویسهایی که واقعاً باید درخواست عمومی دریافت کنند در معرض شبکه بیرونی قرار میگیرند.
جداسازی لایه برنامه از پایگاه داده
برنامه PHP باید به پایگاه داده از طریق شبکه کنترلشده دسترسی داشته باشد.
پایگاه داده نباید برای ارتباط با برنامه الزاماً روی پورت عمومی میزبان منتشر شود.
همچنین حساب پایگاه داده متعلق به برنامه باید فقط مجوزهای موردنیاز را داشته باشد.
برای نمونه، اگر یک سرویس فقط به خواندن داده نیاز دارد، اختصاص مجوزهای مدیریتی کامل پایگاه داده به آن منطقی نیست.
محافظت از Redis
Redis در بسیاری از برنامههای وب برای Cache، Session و صفهای پردازشی استفاده میشود.
این سرویس نیز نباید بدون دلیل در معرض اینترنت عمومی قرار بگیرد.
استفاده از شبکه داخلی، کنترل دسترسی، احراز هویت مناسب و تنظیم سیاستهای پایداری داده متناسب با کاربرد، از نکات مهم امنیت Redis محسوب میشوند.
ملاحظات Docker برای وردپرس
در استقرار وردپرس با Docker باید به مسیرهای قابلنوشتن، آپلود فایلها، افزونهها و مدیریت بهروزرسانی توجه ویژه داشت.
فایلسیستم کاملاً Read-Only ممکن است با برخی عملیات عادی وردپرس ناسازگار باشد.
راهکار مناسب آن است که معماری انتشار و بهروزرسانی از ابتدا مشخص شود و فقط مسیرهای ضروری دارای مجوز نوشتن باشند.
همچنین مجوز فایلهای پیکربندی، اطلاعات اتصال پایگاه داده و دسترسی PHP-FPM به فایلهای برنامه باید کنترل شود.
امنیت کانتینر جایگزین امنیت خود وردپرس، افزونهها و قالبها نیست.
نقش HTTPS، WAF و محافظت لایه برنامه
یکی از اشتباهات رایج این است که جداسازی کانتینرها را معادل حفاظت کامل از برنامه وب در نظر بگیریم.
درحالیکه آسیبپذیریهای لایه برنامه میتوانند مستقل از Docker وجود داشته باشند.
استفاده از HTTPS
ارتباط کاربران با وبسایت باید با TLS مناسب محافظت شود.
مدیریت صحیح گواهیها، تمدید بهموقع و غیرفعالسازی پروتکلها و الگوریتمهای ناامن اهمیت دارد.
اگر TLS روی Reverse Proxy خاتمه پیدا میکند، ارتباطات داخلی حساس نیز باید با توجه به مدل تهدید ارزیابی شوند.
استفاده از WAF
Web Application Firewall یا WAF میتواند برخی الگوهای درخواست مشکوک را شناسایی و مطابق سیاست امنیتی محدود کند.
WAF ممکن است در Reverse Proxy، لبه شبکه یا سرویس ابری قرار بگیرد.
بااینحال، WAF نمیتواند تمام ضعفهای کدنویسی را جبران کند.
حفاظت در برابر XSS و CSRF
حملات XSS معمولاً به اجرای محتوای غیرمجاز در مرورگر کاربران مرتبط هستند.
CSRF نیز میتواند باعث شود مرورگر کاربر احرازشده، درخواست ناخواستهای به برنامه ارسال کند.
برای کاهش این خطرات باید از اعتبارسنجی ورودی، خروجیگذاری امن، سیاست مناسب Cookie، توکنهای ضد CSRF و کنترل دسترسی سمت سرور استفاده کرد.
این اقدامات باید در سطح برنامه انجام شوند؛ Docker بهتنهایی مانع چنین آسیبپذیریهایی نمیشود.
ثبت لاگ و مانیتورینگ امنیتی Docker
بدون نظارت امنیتی، ممکن است رفتار مشکوک یا اختلال یک کانتینر برای مدت طولانی شناسایی نشود.
مدیریت حجم لاگها
اگر لاگها بدون محدودیت ذخیره شوند، فضای دیسک میزبان ممکن است پر شود.
این وضعیت میتواند عملکرد Docker و سایر سرویسها را مختل کند.
Docker از Logging Driverهای مختلف پشتیبانی میکند.
در بسیاری از استقرارها، استفاده از درایور local با قابلیت چرخش لاگ میتواند گزینه مناسبی باشد.
همچنین میتوان لاگها را به سامانه متمرکز ارسال کرد.
چه رویدادهایی باید ثبت شوند؟
در سرورهای مهم بهتر است رویدادهای زیر قابلردیابی باشند:
- ایجاد و حذف کانتینر
- تغییر تنظیمات حساس
- راهاندازی مجدد غیرمنتظره
- توقف مکرر سرویس
- خطاهای احراز هویت
- تلاش برای دسترسی غیرمجاز
- تغییر غیرعادی مصرف منابع
- ارتباطات شبکه مشکوک
- اجرای پردازشهای غیرمنتظره
- تغییرات غیرمجاز فایلهای حساس
حفظ زمانبندی صحیح رویدادها و هماهنگی ساعت سرورها نیز برای بررسی رخدادها ضروری است.
استفاده از ابزارهای Runtime Security
ابزارهایی مانند Falco میتوانند رفتار پردازشها و رویدادهای مرتبط با کانتینر را برای شناسایی فعالیتهای غیرعادی بررسی کنند.
برای مثال، اجرای یک برنامه غیرمنتظره در کانتینری که فقط باید یک سرویس وب مشخص را اجرا کند، میتواند نیازمند بررسی باشد.
سامانه پایش باید هشدارهای قابلاقدام تولید کند و از ایجاد تعداد زیاد هشدارهای کماهمیت جلوگیری شود.
تمرکز بر امنیت لاگها
لاگها نباید حاوی رمزهای عبور، توکنهای کامل یا اطلاعات محرمانه غیرضروری باشند.
همچنین سطح دسترسی به سامانه ثبت رویداد باید محدود و مدت نگهداری دادهها مشخص باشد.
برای بررسی حوادث امنیتی، بهتر است لاگها به محلی منتقل شوند که دستکاری آنها از طریق یک کانتینر آسیبدیده دشوار باشد.
چکلیست عملی بررسی امنیت Docker
برای ارزیابی اولیه امنیت Docker در سرورهای وب میتوان مجموعهای از بررسیهای غیرمخرب انجام داد.
این دستورات وضعیت موجود را نمایش میدهند و به مدیر سرور کمک میکنند تنظیمات را با خطمشی امنیتی مقایسه کند.
بررسی نسخه Docker
docker version
نسخه Docker Engine باید با انتشارهای پشتیبانیشده و وصلههای امنیتی قابلاستفاده مقایسه شود.
مشاهده تنظیمات امنیتی Engine
docker info
در خروجی، بخش Security Options و اطلاعات Runtime، Storage Driver و تنظیمات مرتبط را بررسی کنید.
فهرست کانتینرها و پورتها
docker ps
برای نمایش خلاصه نام، ایمیج و پورتها:
docker ps --format 'table .Names\t.Image\t.Ports'
هدف این بررسی، شناسایی سرویسهایی است که ممکن است بدون نیاز، پورت عمومی داشته باشند.
بررسی تنظیمات یک کانتینر
docker inspect CONTAINER_NAME
در خروجی میتوان اطلاعات مهمی مانند Mountها، تنظیمات شبکه، کاربر اجرایی و محدودیتهای منابع را مشاهده کرد.
خروجی کامل Inspect ممکن است اطلاعات حساس داشته باشد و نباید بدون بررسی منتشر شود.
بررسی شبکهها
docker network ls
برای مشاهده مشخصات یک شبکه:
docker network inspect NETWORK_NAME
باید بررسی شود که هر کانتینر فقط عضو شبکههای ضروری باشد.
بررسی Volumeها
docker volume ls
این دستور فهرست Volumeهای Docker را نمایش میدهد.
بررسی مالکیت دادهها، نیاز واقعی هر Volume و برنامه پشتیبانگیری نیز ضروری است.
بررسی منابع مصرفی
docker stats
این دستور اطلاعات مصرف CPU و حافظه و برخی شاخصهای دیگر کانتینرها را نمایش میدهد.
مصرف غیرعادی باید با رفتار معمول برنامه مقایسه شود.
بررسی رویدادها
docker events --since 1h
این دستور میتواند برای مشاهده رویدادهای اخیر Docker مفید باشد.
البته برای پایش پایدار و تحلیل تاریخی نباید فقط به مشاهده دستی رویدادها متکی بود. 
چکلیست کامل امنسازی Docker برای محیط Production
برای آمادهسازی یک سرور وب مبتنی بر Docker، اقدامات زیر را بهترتیب اولویت بررسی کنید.
مرحله اول: امنیت پایه سرور
- سیستمعامل و کرنل وصلههای امنیتی ضروری را دریافت کرده باشند.
- دسترسی SSH با سیاست مدیریتی مناسب محافظت شود.
- حسابهای غیرضروری حذف یا غیرفعال شوند.
- دسترسی Root مستقیم محدود شود.
- سرویسهای غیرضروری متوقف شوند.
- فایروال میزبان و فایروال شبکه بالادستی بررسی شوند.
- نسخه پشتیبان قابلبازیابی در دسترس باشد.
مرحله دوم: امنیت Docker Engine
- Docker Engine از نسخه پشتیبانیشده استفاده کند.
- دسترسی Docker Socket فقط برای موجودیتهای مورداعتماد مجاز باشد.
- اعضای گروه Docker بازبینی شوند.
- Docker API بدون حفاظت مناسب در اینترنت منتشر نشده باشد.
- امکان استفاده از Rootless یا User Namespace بررسی شود.
- تنظیمات Daemon با سیاست امنیتی سازمان هماهنگ باشند.
مرحله سوم: امنیت کانتینرها
- پردازشهای برنامه تا حد امکان با کاربر غیرروت اجرا شوند.
- قابلیتهای غیرضروری لینوکس حذف شوند.
- کانتینرهای معمول با Privileged اجرا نشوند.
- سیاست
no-new-privilegesدر سرویسهای سازگار فعال باشد. - محافظتهای Seccomp و AppArmor یا SELinux بدون دلیل غیرفعال نشده باشند.
- Mountهای Host به حداقل برسند.
- فایلسیستم و مسیرهای فقطخواندنی مشخص شوند.
- محدودیت CPU، حافظه و PID بر اساس نیاز اعمال شود.
مرحله چهارم: امنیت شبکه و داده
- پورتهای منتشرشده فهرست و بازبینی شوند.
- پایگاه داده و Redis بدون نیاز در اینترنت عمومی قرار نگیرند.
- شبکههای سرویسها بر اساس نقش تفکیک شوند.
- ارتباطات ورودی و خروجی ضروری مشخص باشند.
- تعامل Docker با فایروال میزبان آزمایش شود.
- اطلاعات حساس از ایمیج و مخزن کد جدا شوند.
- دسترسی فایلهای Secret محدود باشد.
- Volumeها دارای سیاست پشتیبانگیری و بازیابی باشند.
مرحله پنجم: نگهداری و نظارت
- ایمیجها از منابع معتبر دریافت شوند.
- اسکن آسیبپذیری در چرخه انتشار انجام شود.
- نسخه ایمیجها قابلردیابی باشد.
- برای بهروزرسانی ایمیجهای تثبیتشده برنامه وجود داشته باشد.
- لاگها دارای محدودیت حجم و سیاست نگهداری باشند.
- رویدادهای امنیتی مهم پایش شوند.
- هشدار مصرف غیرعادی منابع فعال باشد.
- فرایند پاسخ به حادثه مستند و آزمایش شده باشد.
این چکلیست پایه مناسبی برای Hardening است؛ اما جایگزین ارزیابی اختصاصی معماری، تست امنیتی برنامه و بررسی الزامات هر سازمان نمیشود.
اولویتبندی اقدامات امنیتی Docker
همه ضعفهای امنیتی سطح خطر یکسانی ندارند.
برای مثال، افشای Docker API در اینترنت عمومی معمولاً باید با فوریت بسیار بیشتری نسبت به اصلاح یک تنظیم کمخطر مربوط به ثبت لاگ بررسی شود.
اقدامات با اولویت بحرانی
- حذف دسترسی عمومی ناامن به Docker API
- جلوگیری از دسترسی غیرمجاز به Docker Socket
- حذف کانتینرهای Privileged غیرضروری
- جلوگیری از انتشار عمومی سرویسهای حساس
- تعویض Secrets افشاشده
- نصب وصلههای بحرانی دارای خطر بهرهبرداری مرتبط
اقدامات با اولویت بالا
- اجرای برنامهها با کاربر غیرروت
- محدودسازی Capabilities
- بررسی Mountهای حساس
- فعالسازی سیاستهای مناسب شبکه
- اسکن ایمیجهای Production
- فعالسازی مانیتورینگ امنیتی
- بررسی دسترسیهای مدیریتی
اقدامات بهبود مستمر
- استانداردسازی Dockerfileها
- تولید و نگهداری SBOM
- افزایش پوشش اسکن در CI/CD
- بهینهسازی مدیریت لاگ
- آزمون دورهای بازیابی
- بررسی انطباق با معیارهای Hardening
- بازبینی منظم معماری شبکه و مجوزها
اولویت هر اقدام باید با توجه به احتمال وقوع، میزان مواجهه، حساسیت دادهها و اثر احتمالی بر کسبوکار تعیین شود.
اشتباهات رایج در امنیت Docker
بخش مهمی از ضعفهای امنیت Docker ناشی از تصمیمهای پیکربندی است، نه لزوماً پیچیدگی فناوری.
تصور اینکه کانتینر بهتنهایی امن است
جداسازی کانتینر یک لایه دفاعی مهم است؛ اما ضعفهای برنامه، تنظیمات نادرست و آسیبپذیریهای Host همچنان میتوانند خطرساز باشند.
اجرای همه سرویسها با Root
بسیاری از برنامههای وب برای اجرای معمول به دسترسی Root نیاز ندارند.
عدم تفکیک مجوزها میتواند آثار یک نفوذ احتمالی را افزایش دهد.
استفاده مداوم از Latest
اتکا به تگهای متغیر، کنترل نسخه و بازتولید دقیق استقرار را دشوار میکند.
راهکار بهتر، ثبت نسخه معتبر همراه با چرخه مشخص بهروزرسانی است.
انتشار تمام پورتها
انتشار مستقیم پورت برنامه، پایگاه داده، Cache یا ابزارهای مدیریتی بدون نیاز واقعی، سطح حمله را افزایش میدهد.
ذخیره رمز عبور در Dockerfile
این روش ممکن است اطلاعات حساس را در لایهها، فراداده یا Artifactهای ساخت باقی بگذارد.
غیرفعالکردن Seccomp برای رفع خطا
ممکن است یک برنامه با سیاست امنیتی موجود ناسازگار باشد.
راهحل اصولی، شناسایی دقیق محدودیت و اعمال استثنای حداقلی است، نه حذف کامل محافظت.
نادیدهگرفتن فایلهای پشتیبان
Volumeهای Docker ممکن است اطلاعات بسیار مهمی داشته باشند.
حذف کانتینر، خرابی دیسک یا خطای مدیریتی میتواند موجب ازبینرفتن دادههایی شود که نسخه پشتیبان قابلبازیابی ندارند.
اعتماد کامل به فایروال UFW
قواعد شبکه Docker ممکن است با مسیر پردازش ترافیک UFW تعامل متفاوتی داشته باشند.
بنابراین دسترسی واقعی پورتها باید از دید شبکه خارجی نیز بررسی شود.
فعالکردن تمام محدودیتها بدون تست
Hardening نباید باعث ازکارافتادن برنامه شود.
اعمال تنظیمات امنیتی باید با آزمایش سازگاری، ارزیابی اثر و امکان بازگشت همراه باشد.
پایش مداوم و پاسخ به حادثه در Docker
حتی اگر تمام تنظیمات اولیه بهدرستی انجام شوند، امنیت Docker نیازمند نگهداری مستمر است.
ایجاد خط مبنای امنیتی
Security Baseline مجموعهای از وضعیتهای مجاز و موردانتظار زیرساخت است.
برای مثال، میتوان مشخص کرد هر سرویس مجاز است از چه ایمیجی استفاده کند، با کدام کاربر اجرا شود، به چه شبکههایی متصل باشد و چه Mountهایی داشته باشد.
با داشتن خط مبنا، شناسایی تغییرات غیرمنتظره آسانتر میشود.
مدیریت تغییرات
تغییر Dockerfile، Compose، نسخه ایمیج و تنظیمات شبکه باید قابلردیابی باشد.
بهتر است تغییرات از مسیر بازبینی کد و فرایند انتشار کنترلشده انجام شوند.
استفاده از Infrastructure as Code نیز میتواند به کاهش تغییرات دستی و ثبت سوابق کمک کند.
اقدامات اولیه هنگام مشاهده رفتار مشکوک
اگر رفتار یک کانتینر مشکوک به نظر میرسد، تصمیمگیری باید بر اساس شدت حادثه و حساسیت سامانه انجام شود.
اقدامات دفاعی اولیه میتواند شامل موارد زیر باشد:
- ثبت زمان و نشانههای حادثه
- اطلاعرسانی به مسئولان فنی
- حفظ شواهد و لاگهای مرتبط
- بررسی ارتباطات شبکه و پردازشهای غیرعادی
- محدودسازی دسترسی کانتینر آسیبدیده در صورت ضرورت
- بررسی احتمال افشای Secrets
- بازیابی سرویس از ایمیج و داده قابلاعتماد
- اصلاح علت اصلی پیش از بازگشت کامل به سرویس
در حوادث مهم نباید بدون بررسی شواهد، تمام کانتینرها و دادههای مرتبط حذف شوند؛ زیرا ممکن است اطلاعات لازم برای تحلیل حادثه از بین برود.
آزمایش دورهای بازیابی
وجود نسخه پشتیبان بهتنهایی کافی نیست.
باید امکان بازیابی Volumeها، پایگاه داده، پیکربندی شبکه و اطلاعات ضروری بررسی شود.
همچنین بهتر است زمان بازیابی و میزان داده قابلازدسترفتن با نیاز کسبوکار هماهنگ باشد.
استاندارد CIS Docker Benchmark چه کمکی میکند؟
CIS Docker Benchmark مجموعهای از توصیهها و کنترلهای امنیتی برای بررسی پیکربندی Docker ارائه میکند.
این معیار میتواند برای ساخت چکلیست ارزیابی و شناسایی تفاوت میان وضعیت موجود و سیاست امنیتی مطلوب مفید باشد.
موضوعات موردتوجه چنین چارچوبهایی معمولاً شامل امنیت Host، Daemon، فایلهای تنظیمات، ایمیجها، Runtime و عملیات مدیریتی هستند.
بااینحال، همه توصیهها برای تمام محیطها مناسب نیستند.
برخی کنترلها ممکن است با نیاز برنامه یا طراحی زیرساخت تداخل داشته باشند و لازم باشد طبق ارزیابی ریسک، استثنای مستند تعریف شود.
همچنین ابزارهای بررسی خودکار فقط بخشی از وضعیت امنیتی را ارزیابی میکنند و جایگزین تحلیل معماری، کنترل دسترسی برنامه و تست امنیتی تخصصی نیستند.
سؤالات متداول درباره امنیت Docker
آیا Docker بهصورت پیشفرض امن است؟
Docker بهطور پیشفرض از چند سازوکار جداسازی و کنترل امنیتی استفاده میکند؛ اما امنیت نهایی به تنظیمات کانتینر، نسخه نرمافزار، کرنل میزبان، ایمیجها و نحوه مدیریت دسترسیها وابسته است. استفاده از تنظیمات پیشفرض بدون بررسی نیاز سرویس برای تمام محیطهای Production کافی نیست.
آیا امکان هک شدن کانتینر Docker وجود دارد؟
بله. برنامه داخل کانتینر ممکن است دارای آسیبپذیری باشد یا با تنظیمات ناامن اجرا شود. مهاجم در صورت سوءاستفاده موفق میتواند به منابع مجاز همان کانتینر دسترسی پیدا کند و در شرایط خاص، ضعفهای دیگر زیرساخت را نیز هدف قرار دهد.
آیا هک یک کانتینر به معنای هک سرور است؟
خیر، این دو اتفاق یکسان نیستند. بااینحال، اگر مجوزهای کانتینر گسترده باشد، منابع حساس میزبان Mount شده باشند یا آسیبپذیری جدی در مرز ایزولهسازی وجود داشته باشد، خطر گسترش نفوذ افزایش مییابد.
آیا Rootless Docker امنیت بیشتری دارد؟
Rootless میتواند خطرات مرتبط با اجرای Daemon و کانتینرها با اختیارات Root میزبان را کاهش دهد. اما محدودیتهای عملیاتی دارد و همچنان به امنیت کرنل و تنظیمات صحیح وابسته است. انتخاب آن باید پس از بررسی سازگاری زیرساخت انجام شود.
آیا استفاده از Docker Compose امن است؟
Docker Compose بهخودیخود یک آسیبپذیری محسوب نمیشود. امنیت استقرار به محتوای فایل پیکربندی، سطح اعتماد به آن، ایمیجها، شبکه، مجوزها، Secrets و تنظیمات اجرایی بستگی دارد. فایلهای Compose نامطمئن میتوانند عملیات پرخطر تعریف کنند و نباید بدون بررسی اجرا شوند.
آیا باید تمام کانتینرها را با Read-Only اجرا کنیم؟
در صورت سازگاری برنامه، Read-Only بودن فایلسیستم اصلی میتواند سطح حمله را کاهش دهد. اما برخی برنامهها برای Session، Cache، فایل موقت یا آپلود به فضای قابلنوشتن نیاز دارند. باید مسیرهای ضروری بهصورت محدود و کنترلشده فراهم شوند.
آیا نصب فایروال روی سرور Docker کافی است؟
خیر. علاوه بر فعالبودن فایروال باید قواعد منتشرسازی پورت، شبکههای Docker، تعامل با iptables یا nftables و دسترسی واقعی از بیرون بررسی شود. تنظیمات نادرست ممکن است باعث شود سرویس برخلاف انتظار عمومی باشد.
تفاوت Docker Security و Container Security چیست؟
Container Security مفهوم گستردهتری است که امنیت فناوریها و محیطهای کانتینری مختلف را شامل میشود. Docker Security بر حفاظت از اجزای مرتبط با Docker، از جمله Engine، ایمیجها، شبکهها، Volumeها و Runtime تمرکز دارد.
آیا Docker جایگزین ماشین مجازی است؟
Docker و ماشین مجازی کاربردهای مشترکی دارند، اما مدل ایزولهسازی آنها متفاوت است. کانتینرهای لینوکسی معمولاً کرنل میزبان را به اشتراک میگذارند، درحالیکه ماشینهای مجازی سنتی سیستمعامل مهمان و کرنل مستقل خود را اجرا میکنند. انتخاب هرکدام باید بر اساس نیاز عملکردی، عملیاتی و مدل تهدید انجام شود.
آیا Docker میتواند از حملات DDoS جلوگیری کند؟
Docker با محدودسازی منابع میتواند به کنترل اثر بعضی رفتارهای غیرعادی در سطح کانتینر کمک کند؛ اما برای مقابله با حملات حجیم شبکه کافی نیست. محافظت مؤثر ممکن است به CDN، سرویس ضد DDoS، Rate Limiting و دفاع لایه شبکه نیاز داشته باشد.
هر چند وقت یکبار باید ایمیجهای Docker را بررسی کنیم؟
زمانبندی باید بر اساس حساسیت سرویس و سرعت انتشار آسیبپذیریها مشخص شود. اسکن هنگام Build و استقرار، بررسی دورهای ایمیجهای فعال و واکنش سریع به هشدارهای بحرانی، رویکرد مناسبتری نسبت به بررسی صرفاً سالانه است.
بهترین ابزار برای بررسی امنیت Docker چیست؟
ابزار واحدی تمام جنبههای امنیت را پوشش نمیدهد. برای اسکن ایمیج میتوان از Trivy یا Docker Scout، برای بررسی رفتار زمان اجرا از Falco و برای ارزیابی پیکربندی از ابزارهای سازگار با معیارهای Hardening استفاده کرد. انتخاب ابزار باید متناسب با زیرساخت، بودجه و نیاز امنیتی انجام شود.
آیا Docker برای میزبانی وردپرس و ووکامرس مناسب است؟
بله. Docker میتواند برای استقرار وردپرس و ووکامرس استفاده شود، مشروط بر اینکه امنیت پایگاه داده، مسیرهای ذخیرهسازی، نسخه پشتیبان، مجوزها، بهروزرسانیها و دسترسی شبکه بهدرستی طراحی شوند. کانتینرسازی بهتنهایی ضعفهای امنیتی افزونهها، قالبها یا تنظیمات وردپرس را برطرف نمیکند.
آیا محدودکردن دسترسی Root میتواند تمام خطرات را حذف کند؟
خیر. اجرای برنامه با کاربر غیرروت یک کنترل مهم است، اما همچنان احتمال وجود آسیبپذیری برنامه، افشای داده، ضعف شبکه یا نقص در کرنل وجود دارد. امنیت مؤثر به چندین لایه دفاعی مستقل نیازمند است.
جمعبندی: چگونه امنیت Docker را در سرورهای وب افزایش دهیم؟
امنیت Docker تنها به نصب نسخه جدید یا اجرای کانتینرها در شبکههای جداگانه محدود نمیشود. حفاظت واقعی زمانی شکل میگیرد که سیستمعامل میزبان، Docker Daemon، ایمیجها، مجوزهای اجرایی، ارتباطات شبکه و دادههای حساس بهصورت یکپارچه مدیریت شوند.
برای بیشتر سرورهای وب، جلوگیری از دسترسی غیرمجاز به Docker Socket، حذف کانتینرهای پرمجوز، محدودکردن پورتهای عمومی، اجرای برنامهها با کمترین سطح دسترسی و استفاده از ایمیجهای بررسیشده از مهمترین اقدامات اولیه هستند.
پس از آن باید مدیریت Secrets، محدودسازی منابع، تنظیم Logging، اسکن آسیبپذیری و پایش امنیتی مستمر در چرخه نگهداری سرویس قرار گیرند.
نکته اساسی این است که هیچ تنظیمی بهتنهایی امنیت کامل ایجاد نمیکند. برای مثال، استفاده از Rootless بدون مدیریت مناسب Secrets، یا فعالسازی Seccomp در کنار انتشار عمومی یک پایگاه داده حساس، همچنان میتواند زیرساخت را در معرض خطر قرار دهد.
بهترین رویکرد، پیادهسازی دفاع چندلایه (Defense in Depth)، اصل حداقل سطح دسترسی و ارزیابی منظم تنظیمات براساس خطرات واقعی هر سرویس است.
در نهایت، امنسازی Docker باید بخشی از چرخه دائمی توسعه، استقرار و نگهداری برنامه باشد؛ نه اقدامی که فقط یکبار هنگام راهاندازی سرور انجام شود.
با اجرای چکلیست امنیت Docker، آزمایش تنظیمات در محیط مناسب و بازبینی مداوم زیرساخت، میتوان احتمال نفوذ، افشای اطلاعات و اختلال در سرویسهای وب را بهشکل معناداری کاهش داد.