آنچه در این مقاله میخوانید
امنیت در Docker
۱۴ اسفند ۱۳۹۹
امروزه بسیاری از شرکتها حداقل در یکی از پروژههای خود از Docker استفاده میکنند. این پلتفرم بهدلیل توانایی در ایزولهسازی محیط اجرا و سادهسازی فرآیند توسعه، مورد استقبال گسترده قرار گرفته است. با اینحال، موضوع امنیت در Docker همچنان یکی از چالشهای مهم و نیازمند توجه بسیاری به حساب میآید.
همین حالا به سادگی پروژههای داکر خود را در هاست ابری لیارا دیپلوی کنید!
✅ دامنه رایگان ✅ ترافیک نامحدود ✅ هزینه ساعتی
خرید هاست ابری Docker
آنچه در ادامه خواهید خواند:
- امنیت Docker Host
- امنیت Docker image
- سخت سازی ایمیج (Image) ها
- سخت سازی Container ها
- سوالات متداول
- جمع بندی
امنیت Docker Host
کانتینرهای Docker روی یک سرور یا سیستم میزبان اجرا میشوند. بنابراین، تأمین امنیت فقط در سطح کانتینر کافی نیست و لازم است Docker Host نیز بهدرستی ایمنسازی شود. برای این منظور، ابزارهای مختلفی در شناسایی آسیبپذیریها و بهبود امنیت سیستمعامل لینوکس وجود دارند. تعدادی از آنها را در ادامه بررسی کردهایم:
1. Lynis
Lynis یک ابزار امنیتی برای بررسی وضعیت سیستمعاملهای لینوکسی است. برای این عمل از دستور زیر استفاده کنید.
apt-get install lynis && sudo lynis audit system
نکته: “میتوانید گزارشی از وضعیت امنیتی سیستمتان دریافت کرده و براساس آن اقدام به رفع مشکلات احتمالی کنید.”
2. SELinux
SELinux یک ماژول هستهای در لینوکس است که از مدل کنترل دسترسی اجباری (MAC) پشتیبانی میکند. برخلاف مدل پیشفرض لینوکس که بر کنترل دسترسی اختیاری (DAC) استفاده میکند، SELinux امکان تعریف سیاستهای دقیق امنیتی را فراهم میکند و به کمک آن میتوان دسترسیها را محدودتر و امنتر کرد.
3. AppArmor
AppArmor نیز مانند SELinux ابزاری برای پیادهسازی کنترل دسترسی اجباری با تعریف سیاستهای مشخص برای هر برنامه است. این ابزار تعیین میکند که هر فرایند یا سرویس چه دسترسیهایی دارد. این کار باعث میشود برنامهها فقط در محدودهای از پیش تعیینشده فعالیت کنند و دسترسی غیرمجاز نداشته باشند.
4. Docker Daemon
بهتر است فرایند اصلی Docker یعنی dockerd
را با کاربری غیر روت (non-root user) اجرا کنید. این اقدام باعث کاهش خطرات امنیتی در صورت نفوذ احتمالی میشود، زیرا سطح دسترسی مهاجم محدود خواهد بود.
5. بررسی منظم آسیب پذیری ها
نرمافزارها و کانتینرهای خود را بهطور منظم از نظر وجود آسیبپذیریهای شناختهشده بررسی کنید. این کار کمک میکند قبل از اینکه آسیبپذیریها مورد سوءاستفاده قرار گیرند، نسبت به رفع آنها اقدام کنید.
6. استفاده از سیستم عامل های امن برای کانتینر ها
توصیه میشود از سیستمعاملهایی استفاده کنید که برای اجرای کانتینرها بهینهسازی شدهاند. یکی از نمونههای شناختهشده در این زمینه، سیستمعامل Container-Optimized OS است که توسط گوگل توسعه داده شده و بهصورت پیشفرض با تنظیمات امنیتی مناسب ارائه میشود.

امنیت Docker image
پس از تأمین امنیت Docker Host، باید مطمئن شوید که Docker Image استفادهشده در فایل Dockerfile نیز مطمئن است. چراکه بسیاری از Docker Image ها توسط افراد یا تیمهای مختلف ساخته شدهاند و ممکن است شامل آسیبپذیریهای امنیتی باشند.
بنابراین، مهم است که Docker Image ها را بهصورت منظم از نظر وجود مشکلات امنیتی بررسی کنید. حتی برخی از Docker Image های رسمی نیز ممکن است حاوی آسیبپذیریهایی باشند؛ اما معمولا با اجرای دستورات بهروزرسانی مانند دستور زیر میتوان این مشکلات را برطرف کرد.
RUN apt-get update && apt-get upgrade
همچنین لازم است بدانید نسخههای Alpine Linux تنها ضعفهای امنیتی قبلاً شناسایی شده و رفعشده را منتشر میکنند. به همین دلیل، اسکن این نسخهها برای شناسایی آسیبپذیریها میتواند مفید باشد و به بهبود امنیت کمک کند.
سخت سازی ایمیج (Image) ها
به فرایند کاهش سطح حمله یا افزایش دشواری برای یافتن و استفاده از آسیبپذیری موجود، Hardening میگویند. برای این عمل مراحل زیر را به درستی و دقیق انجام دهید.
تنها فایل های ضروری را کپی کنید
با استفاده از فایل .dockerignore
میتوانید اطمینان حاصل کنید که برخی فایلها کپی نمیشوند.
محدود کردن دسترسی با استفاده از non-privileged user
بهصورت پیشفرض هر دستوری که در Docker container اجرا شود با شناسه کاربر صفر یعنی کاربر روت اجرا خواهد شد. حال برای افزایش امنیت توصیه میشود که دسترسیها را با روشهای مختلفی محدود کنید.
در Dockerfile
میتوانید بهصورت زیر عمل کنید.
RUN groupadd -r noroot && useradd -r -g noroot noroot
USER noroot
یا میتوانید Docker container خود را بهصورت زیر اجرا کنید.
docker run -u 1000 -it python:3.9.1-buster bash
I have no name!@a70ba4f24042:/$ echo $UID
1000
آموزش نصب و استفاده از Docker بر روی Ubuntu 18.04
آموزش نصب و استفاده از Docker
Multi-stage Build
اگر مهاجمی به Docker container شما دسترسی پیدا کند، منطقی است که بخواهید تا حد امکان ابزارها و منابع در اختیار او را محدود کنید. یکی از روشهای مهم برای کاهش سطح دسترسی و کوچکتر کردن حجم نهایی کانتینر، استفاده از multi-stage build است.
در این روش، عملیات کامپایل و ساخت برنامه در یک مرحله جداگانه انجام میشود و تنها فایل اجرایی نهایی، بدون ابزارهای توسعه و وابستگیهای اضافی، به مرحله دوم منتقل میشود. این کار باعث میشود کانتینر نهایی سادهتر، سبکتر و از نظر امنیتی مطمئنتر باشد.
بهعنوان مثال، در کد زیر یک برنامه Go ابتدا در یک کانتینر مبتنی بر تصویر golang
کامپایل شده و سپس فقط فایل اجرایی آن به یک کانتینر مبتنی بر alpine
منتقل میشود. مشاهده کنید:
FROM golang:1.7.3 AS builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
سخت سازی Container ها
سختسازی Containerها مجموعهای از روشها و تنظیمات امنیتی است که برای کاهش سطح حمله و افزایش ایزولهسازی کانتینر در برابر تهدیدات از آن استفاده میشود.
Read-Only کردن فایل های سیستمی
اگر از دستور docker run
استفاده میکنید میتوانید --read-only
را به دستور خود اضافه کنید. این سوئیچ باعث میشود تا فایلهای سیستمی read-only باشند بنابراین اگر یک مهاجم وارد سیستم شد نمیتواند چیزی را روی دیسک ذخیره کند یا فایلهای اجرایی را تغییر دهد. البته توجه داشته باشید که مهاجمین میتوانند memory را تغییر دهند.
همچنین باید به مجوز انجام برخی فعالیتها مانند ایجاد فایلهای temp دقت داشته باشید.
sudo docker run -it --read-only python:3.9.1-buster
Python 3.9.1 (default, Jan 12 2021, 16:45:25)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tempfile
>>> a = tempfile.mkdtemp()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.9/tempfile.py", line 348, in mkdtemp
prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)
File "/usr/local/lib/python3.9/tempfile.py", line 118, in _sanitize_params
dir = gettempdir()
File "/usr/local/lib/python3.9/tempfile.py", line 287, in gettempdir
tempdir = _get_default_tempdir()
File "/usr/local/lib/python3.9/tempfile.py", line 219, in _get_default_tempdir
raise FileNotFoundError(_errno.ENOENT,
FileNotFoundError: [Errno 2] No usable temporary directory found in ['/tmp', '/var/tmp', '/usr/tmp', '/']
برای برطرف کردن این اشکال میتوانید مسیر /tmp
را بهعنوان یک volume به container خود mount کنید.
$ sudo docker run -it --mount source=myvol2,target=/tmp --read-only python:3.9.1-buster
Python 3.9.1 (default, Jan 12 2021, 16:45:25)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tempfile; a = tempfile.mkdtemp()
$ sudo docker run --rm -i -v=myvol2:/tmp/v busybox find /tmp/v
/tmp/v
/tmp/v/tmpbhw8djco
حتی میتوانید از مسیر temp file های Docker host استفاده کنید.
sudo docker run -it --tmpfs /tmp --read-only python:3.9.1-buster
آموزش استفاده از Docker در توسعهی نرمافزار
آموزش استفاده از Docker
محدود کردن قابلیت ها
یکی دیگر از روشهای امنیت در داکر محدود کردن قابلیتهای Linux kernel است.
docker run --cap-drop all -it python:3.9.1-buster bash
root@3c568219116e:/# groupadd -r noroot
groupadd: failure while writing changes to /etc/gshadow
همچنین میتوانید مجوزها را بهصورت دستی را انجام دهید.
docker run --cap-drop all --cap-add CHOWN -it python:3.9.1-buster bash
root@3c568219116e:/# groupadd -r noroot
groupadd: failure while writing changes to /etc/gshadow
no-new-privileges
ممکن است بخواهید --security-opt=no-new-privileges
را تنظیم کنید. این سوئیچ باعث میشود تا فرایندهای موجود در container به privilegeهای جدید دسترسی پیدا نکنند.
اسکن آسیب پذیری ها
برای شناسایی آسیبپذیریهای امنیتی در Docker container ها میتوانید از ابزار Clair استفاده کنید. این ابزار متنباز یکی از راهکارهای معتبر برای تحلیل و اسکن لایههای مختلف Docker Image ها بهحساب میآید.
Clair با بررسی بستههای نرمافزاری موجود در هر لایه از Image، آنها را با پایگاه دادهای از آسیبپذیریهای شناختهشده (مانند CVE ها) مقایسه میکند و گزارشی دقیق از مشکلات امنیتی احتمالی ارائه میدهد. این گزارش به تیمهای توسعه و عملیات کمک میکند تا پیش از استقرار Image در محیط تولید، نقاط ضعف آن را شناسایی و برطرف کنند.
ارتباط بین Container ها
یکی از روشهای کلیدی در ارتقاء امنیت، مفهوم دفاع در عمق (Defense in Depth) است که به معنای ایجاد چندین لایه حفاظتی برای سختتر کردن دسترسی به آسیبپذیریها میباشد. در این رویکرد، اگر یک قابلیت برای اجرای برنامه ضروری نباشد، دسترسی کانتینر به آن قابلیت باید محدود شود.
علاوه بر این، محدودسازی ارتباط میان کانتینرها نقش مهمی در افزایش امنیت ایفا میکند. در بسیاری از سازمانها، برنامهها به صورت میکروسرویس و در قالب چندین کانتینر اجرا میشوند. در چنین شرایطی، تنها کانتینرهایی که نیاز واقعی به تبادل اطلاعات دارند، اجازه برقراری ارتباط با یکدیگر را خواهند داشت و سایر کانتینرها باید از این ارتباط جدا نگه داشته شوند. این اقدامات به کاهش سطح حملات و افزایش امنیت کلی سامانه کمک شایانی مینماید.
سوالات متداول
در ادامه به سوالاتی که امکان دارد در این زمینه برای شما بدون پاسخ بماند، جوابهای کوتاه اما مفیدی دادهایم که با استفاده از آن میتوانید به سوال خود پاسخ صحیحی را بدهید.
آیا استفاده از Docker به تنهایی امنیت برنامه ها را تضمین می کند؟
خیر. Docker به ایزولهسازی فرآیندها کمک میکند، اما بهتنهایی برای داشتن امنیت کافی نیست. امنیت در Docker نیازمند رعایت اصول و تنظیمات در سطوح مختلف از جمله میزبان (Host)، کانتینرها، Imageها و شبکه است.
آیا استفاده از Image های رسمی Docker مطمئن است؟
Imageهای رسمی نسبت به سایر منابع معمولا مطمئنتر هستند، اما همچنان باید بررسی و اسکن امنیتی شوند. برخی آسیبپذیریها ممکن است حتی در ایمیجهای رسمی نیز وجود داشته باشند. بنابراین توصیه ما به شما این است که پیش از استفاده، از ابزارهایی مانند Trivy یا Docker Scout برای تحلیل امنیتی استفاده شود.
چگونه می توان از وضعیت امنیتی کانتینر ها اطمینان حاصل کرد؟
برای ارزیابی امنیت کانتینرها میتوان از ابزارهای اسکن آسیبپذیری مانند Trivy , Clair یا Docker Scout استفاده کرد. همچنین اجرای کانتینر با حداقل سطح دسترسی (بهصورت غیر روت)، محدودسازی منابع و استفاده از تنظیمات شبکهای ایمن از جمله اقدامات ضروری در این زمینه است.
بهترین روش برای ایمن سازی ارتباط بین کانتینر ها چیست؟
استفاده از شبکههای سفارشی (Custom Networks) به جای شبکه پیشفرض Docker و اعمال محدودیتهای ارتباطی بین کانتینرها، یکی از روشهای موثر برای افزایش امنیت شبکهای است. در محیطهایی مانند کوبرنتیز نیز میتوان از Policy های شبکه برای کنترل دقیقتر استفاده کرد.
جمع بندی
برای اطمینان از امنیت در Docker، باید بهجای تکیه بر ایزولهسازی، رویکردی چندلایه را در پیش گرفت. استفاده از Image های معتبر، اجرای کانتینرها با حداقل سطح دسترسی و ایمنسازی شبکه بین آنها از اقدامات ضروری است. همچنین پایش مستمر و اسکن آسیبپذیریها نقش کلیدی در جلوگیری از تهدیدات امنیتی دارد.
منبع: https://levelup.gitconnected.com/docker-security-5f4df118948c