داکر نصب کردن را آسان کرده، ولی چند رفتار پیشفرض دارد که اگر ندانید، سرور را بیسروصدا باز میگذارد. این هفت مورد را روی هر سرور داکری چک کنید.
۱. داکر فایروال را دور میزند
این مهمترین و غافلگیرکنندهترین مورد است. روی سرور UFW روشن کردهاید و فقط پورت ۲۲، ۸۰ و ۴۴۳ را باز گذاشتهاید. بعد یک دیتابیس با -p 3306:3306 اجرا میکنید و فکر میکنید فایروال جلویش را میگیرد. نمیگیرد. داکر برای پورتهای منتشرشده مستقیم قانون iptables مینویسد، و این قانونها قبل از قانونهای UFW بررسی میشوند. دیتابیس روی اینترنت باز است.
راهحلها، به ترتیب سادگی:
- پورت را منتشر نکنید: سرویسهایی که فقط کانتینرهای دیگر به آنها وصل میشوند (مثل دیتابیس) اصلاً
portsلازم ندارند؛ در شبکهٔ داخلی compose هم را پیدا میکنند. - فقط روی localhost منتشر کنید:
"127.0.0.1:8080:80"به جای"8080:80"، و یک reverse proxy جلویش بگذارید. - قانون در زنجیرهٔ DOCKER-USER: برای وقتی که باید پورتی را فقط برای IPهای مشخص باز کنید.
# ببینید کدام پورتها روی همهٔ آدرسها باز است (0.0.0.0 یا [::])
sudo ss -tlnp | grep -E '0.0.0.0|\[::\]'
docker ps --format 'table {{.Names}}\t{{.Ports}}'از بیرون سرور هم با یک پورتاسکنر چک کنید؛ این تنها تستی است که دروغ نمیگوید.
۲. گروه docker یعنی root
کسی که میتواند docker run بزند، میتواند docker run -v /:/host ... هم بزند و به کل دیسک سرور دسترسی root داشته باشد. پس عضویت در گروه docker را مثل دادن رمز root ببینید. اگر کاربرهای مختلفی روی سرور دارید، به rootless mode داکر نگاه کنید که داکر را بدون دسترسی root اجرا میکند.
۳. mount کردن docker.sock
بعضی ابزارها (پنلهای مدیریت داکر، Traefik، Watchtower) میخواهند /var/run/docker.sock را به کانتینرشان mount کنید. این یعنی آن کانتینر کنترل کامل داکر و در نتیجه کل سرور را دارد. اگر آن ابزار حفره داشته باشد یا پنلش با رمز ضعیف روی اینترنت باشد، سرور از دست رفته است. فقط برای ابزارهای معتبر، با :ro اگر کافی است، و هرگز پنلش را بدون محافظت روی اینترنت نگذارید.
۴. کانتینر privileged و root داخل کانتینر
--privilegedتقریباً همهٔ دیوارهای بین کانتینر و سرور را برمیدارد. اگر آموزشی گفت «اگر کار نکرد privileged بزنید»، دنبال راه دیگری باشید.- بیشتر imageها بهطور پیشفرض با root داخل کانتینر اجرا میشوند. اگر image اجازه میدهد، با
user: "1000:1000"در compose کاربر معمولی بدهید وread_only: trueرا امتحان کنید.
۵. رمز داخل image یا گیت
رمزی که در Dockerfile با ENV یا COPY .env وارد image شود، داخل لایههای image میماند و هر کسی که image را داشته باشد با docker history یا باز کردن لایهها پیدایش میکند، حتی اگر بعداً پاکش کرده باشید. رمزها را موقع اجرا بدهید: فایل .env کنار compose (و در .gitignore) یا secrets خود compose.
۶. لاگی که دیسک را پر میکند
درایور لاگ پیشفرض داکر (json-file) هیچ سقفی ندارد. یک کانتینر پرحرف بعد از چند ماه میتواند دهها گیگابایت لاگ بسازد و دیسک سرور را پر کند؛ آن موقع دیتابیس هم میخوابد. سقف بگذارید:
{
"registry-mirrors": ["https://docker.arvancloud.ir"],
"log-driver": "json-file",
"log-opts": { "max-size": "10m", "max-file": "3" }
}sudo systemctl restart docker
docker system df # چقدر فضا مصرف شده
docker system prune # پاک کردن کانتینرها، شبکهها و imageهای بلااستفادهتنظیم لاگ فقط روی کانتینرهایی اعمال میشود که بعد از آن ساخته شوند؛ کانتینرهای قبلی را با docker compose up -d --force-recreate دوباره بسازید.
۷. imageی که هرگز آپدیت نمیشود
کانتینر یک بار ساخته شده و دو سال است کار میکند؛ یعنی دو سال وصلهٔ امنیتی نگرفته. imageها را مرتب با docker compose pull && docker compose up -d آپدیت کنید (اول بکاپ). یک اسکنر مثل Trivy هم آسیبپذیریهای شناختهشدهٔ هر image را لیست میکند. و خود سرور را فراموش نکنید: داکر جایگزین apt upgrade نیست.
چکلیست سریع
ss -tlnp: هیچ پورت داکری جز ۸۰ و ۴۴۳ (و موارد عمدی) روی 0.0.0.0 نیست.- دیتابیسها
portsندارند. - اعضای گروه docker را میشناسید.
- هیچ کانتینر privileged یا docker.sock بیدلیلی ندارید.
- رمزها در
.envهستند، نه در image یا گیت. - سقف لاگ تنظیم شده.
- imageها در یک ماه اخیر آپدیت شدهاند و بکاپ volumeها بیرون از سرور هست.
منابع
- Docker Docs — Packet filtering and firewalls docs.docker.com/engine/network/packet-filtering-firewalls
- Docker Docs — Docker Engine security docs.docker.com/engine/security
- Docker Docs — Rootless mode docs.docker.com/engine/security/rootless
- Docker Docs — JSON File logging driver docs.docker.com/engine/logging/drivers/json-file
- Trivy trivy.dev