دسترسی به دیوایس‌های مورد نظر در Docker

۱۸ دی ۱۳۹۶

مدت‌ها بود در فکر نوشتن مطلبی در مورد مجازی سازی و مشتقاتش بودم. مدتی قبل به موردی بر خوردم که مربوط به باگ جالبی از داکر Docker می‌شد. این باگ جرقه‌ای برای نوشتن و شاید بهتر است بگویم ترجمه‌ای از متن و بازنگری بر صفحه‌ی Manual لینوکس و داکیومنت داکر شد.

اگر با Docker و کانتینرها کار کرده‌اید حتما با موضوع دسترسی و اجازه‌های کانتینرها برخورد داشته‌اید. به عنوان مثال شاید بخواهید داخل کانتینر، داکر را نصب کنید. به دلیل نیازمندی به دسترسی‌های متفاوت سیستمی، طبیعی است که با مخالفت روبه‌رو شوید. چون به‌صورت پیش‌فرض کانتینر اجازه دسترسی به هیچ دیوایسی را ندارد مگر اینکه با –privileged آن را راه‌اندازی کنید. زمانی که شما با این آرگومان کانتینر را بالا بیارید، داکر اجازه دسترسی به تمامی دیوایس‌های روی هاست و پروسس‌هایی که بیرون از کانتینر بر روی هاست راه‌اندازی شده را می‌دهد و فکر نمی‌کنم دسترسی جالب و پیش‌پا افتاده‌ای باشد.

راه بهتر از آرگومان privileged، استفاده از آرگومان –device است که با این فلگ فقط به دیوایس(های) مد نظر دسترسی می‌دهد:

docker run --device=/dev/sda:/dev/sda

به صورت پیش‌فرض کانتینر اجازه نوشتن، خواندن و mknod برای دیوایس(های) مد نظر را دارد. البته با استفاده از “:rwm” که در ادامه دیوایس اضافه می‌شود، شما می‌توانید این موارد را تغییر دهید. به عنوان مثالی ساده:

 

$ docker run --device=/dev/sdc:/dev/xvdc --rm -it debian fdisk  /dev/xvdc

Command (m for help): q

$ docker run --device=/dev/sdc:/dev/xvdc:r --rm -it debian fdisk  /dev/xvdc

You will not be able to write the partition table.

Command (m for help): q

 

$ docker run --device=/dev/sdc:/dev/xvdc:w --rm -it debian fdisk  /dev/xvdc

    Crash...



$ docker run --device=/dev/sdc:/dev/xvdc:m --rm -it debian fdisk  /dev/xvdc

fdisk: unable to open /dev/xvdc: Operation not permitted

 

علاوه بر فلگ privileged، با استفاده از دستورات مربوط به capability می‌توانید دسترسی خاص مورد نظر را به کانتینر مورد نظر بدهید. با استفاده از –cap-add مجوز را داده و با استفاده از –cap-drop مجوز مورد نظر را پس می‌گیرید.

 

به صورت پیش‌فرض یک سری ازcapability ها برای کانتینرها فعال است:

توضیحات

کلید

امکان تغییر بر روی capability

SETPCAP

ساخت nodfile (به عنوان مثال ساخت device file)

MKNOD

نوشتن رکورد روی لاگ‌های Audit کرنل

AUDIT_WRITE

امکان تغییر صاحب و گروه

CHOWN

استفاده از دیتای خام شبکه

NET_RAW

امکان ندید گرفتن چک کردن دسترسی خواندن، نوشتن و اجرا

DAC_OVERRIDE

امکان ندید گرفتن صاحب و گروه فایل

FOWNER

عدم امکان برداشتن صاحب و گروه اصلی فایل‌ها

FSETID

امکان ارسال سیگنال KILL

KILL

امکان تنظیم gid

SETGID

امکان تنظیم uid

SETUID

امکان باز کردن سوکت برای پورت‌های زیر ۱۰۲۴

NET_BIND_SERVICE

امکان chroot

SYS_CHROOT

تنظیم cap برای فایل

SETFCAP

و امکاناتی که به صورت پیش‌فرض وجود ندارد:

توضیح

کلید

فراخوانی و یا عدم فراخوانی ماژول

SYS_MODULE

دسترسی خام به IO

SYS_RAWIO

فعال و غیر فعال کردن اجازه استفاده پروسس‌ها

SYS_PACCT

امکان اجرای دستوراتی که نیازمند دسترسی ادمین باشد

SYS_ADMIN

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

SYS_NICE

تغییر در محدودیت منابع

SYS_RESOURCE

تنظیم زمان سیستم

SYS_TIME

تنظیمات مربوط به TTY

SYS_TTY_CONFIG

تغییر مربوط به auditing

AUDIT_CONTROL

تغییر بر روی MAC (مربوط به LSM می‌شود)

MAC_OVERRIDE

مدیریت MAC (مربوط به LSM می‌شود)

MAC_ADMIN

مجوز انجام فرایندهای مربوط به شبکه

NET_ADMIN

دسترسی به syslog

SYSLOG

گذر از چک مجوز خواندن و اجرا

DAC_READ_SEARCH

امکان تغییر بر روی فلگ i-node (مرتبط با صفات immutable)

LINUX_IMMUTABLE

امکان باز کردن سوکت Multicast و Broadcast

NET_BROADCAST

امکان تصاحب مموری

IPC_LOCK

گذر از چک دسترسی System V IPC Objects

IPC_OWNER

امکان تریس کردن پروسس

SYS_PTRACE

امکان انجام ریبوت یا اعمالی که مربوط به بوت سیستم می‌شود

SYS_BOOT

امکان آزادسازی فایل‌ها

LEASE

امکان wakeup سیستم

WAKE_ALARM

امکان جلوگیری از suspend

BLOCK_SUSPEND

برای اطلاعات بیشتر می‌توانید به صفحه manual مراجعه کنید:

http://man7.org/linux/man-pages/man7/capabilities.7.html

 

برای هر دو فلگ می‌توانید از کلید ALL استفاده کنید:

--cap-add=ALL --cap-drop=MKNOD

 

حالا وقت تست کردن برخی از این قابلیت‌ها است.

فرض کنید می‌خواهید بر روی کارت‌های شبکه کار کنید. اگر به صورت معمولی انجام دهید:

$ docker run -it --rm  ubuntu ip link add dummy0 type dummy

بعد با این پیام مواجه می‌شوید:

RTNETLINK answers: Operation not permitted

 

حالا با اضافه کردن NET_ADMIN مجوز تغییرات شبکه‌ای به شما داده می‌شود:

$ docker run -it --rm --cap-add=NET_ADMIN ubuntu ip link add dummy0 type dummy

 

در مثال بعدی فرض کنید می‌خواهید فایل سیستمی که از FUSE استفاده می‌کند را بر روی کانتینر خود mount کنید.

با استفاده از SYS_ADMIN شما امکان mount را بدست می‌آورید:

$ docker run --rm -it --cap-add SYS_ADMIN sshfs sshfs sven@10.10.10.20:/home/sven /mnt

اما در اینجا شما دسترسی به دیوایس FUSE را ندارید و با پیغام:

fuse: failed to open /dev/fuse: Operation not permitted

در پیام مشاهده می‌کنید که به کدام دیوایس دسترسی ندارید. حال دیوایس را نیز به کانتینر می‌دهیم:

docker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse sshfs

# sshfs sven@10.10.10.20:/home/sven /mnt

The authenticity of host '10.10.10.20 (10.10.10.20)' can't be established.

ECDSA key fingerprint is 25:34:85:75:25:b0:17:46:05:19:04:93:b5:dd:5f:c6.

Are you sure you want to continue connecting (yes/no)? yes

sven@10.10.10.20's password:

root@30aa0cfaf1b5:/# ls -la /mnt/src/docker

total 1516

drwxrwxr-x 1 1000 1000   ۴۰۹۶ Dec  ۴ ۰۶:۰۸ .

drwxrwxr-x 1 1000 1000   ۴۰۹۶ Dec  ۴ ۱۱:۴۶ ..

-rw-rw-r-- 1 1000 1000     ۱۶ Oct  ۸ ۰۰:۰۹ .dockerignore

-rwxrwxr-x 1 1000 1000    ۴۶۴ Oct  ۸ ۰۰:۰۹ .drone.yml

drwxrwxr-x 1 1000 1000   ۴۰۹۶ Dec  ۴ ۰۶:۱۱ .git

-rw-rw-r-- 1 1000 1000    ۴۶۱ Dec  ۴ ۰۶:۰۸ .gitignore

....

 

در این مثال فرض کنید می‌خواهید swap سیستم را خاموش کنید:

$ docker run --rm -it --cap-add SYS_ADMIN swapoff -a

 

در این مختصر ترجمه دیدیم که چطور می‌شود بدون استفاده از –privileged به دسترسی مد نظر برسیم. امیدوارم این مطلب برای شما کاربردی باشد.

بدون دیدگاه
برچسب‌ها:
× برای اطلاع از آخرین اخبار و مقالات آروان عضو خبرنامه ما شوید