| UNSHARE(1) | دستورات کاربر | UNSHARE(1) |
نام (NAME)
unshare - اجرای برنامه با فضاهای نام جداشده از والد
خلاصه دستور (SYNOPSIS)
unshare [options] [program [arguments]]
توضیحات (DESCRIPTION)
دستور unshare فضاهای نام جدیدی (بر اساس گزینههای خط فرمان توصیفشده در ادامه) ایجاد کرده و سپس program مشخصشده را اجرا میکند. اگر program داده نشده باشد، "${SHELL}" اجرا میشود (پیشفرض: /bin/sh).
به طور پیشفرض، یک فضای نام جدید تنها تا زمانی که فرآیندهای عضو داشته باشد باقی میماند. میتوان یک فضای نام جدید را حتی در زمانی که هیچ فرآیند عضوی ندارد، با اتصال سوارکردن (bind mount) فایلهای /proc/pid/ns/type به یک مسیر در سیستمفایل ماندگار کرد. فضای نامی که به این شیوه ماندگار شده است میتواند متعاقباً با nsenter(1) حتی پس از پایان یافتن program وارد شود (به جز فضاهای نام PID که در آنها به یک فرآیند init همواره در حال اجرا نیاز است). زمانی که یک فضای نام ماندگار دیگر مورد نیاز نباشد، میتوان با استفاده از umount(8) برای حذف اتصال سوارکردن آن را از حالت ماندگار خارج کرد. برای جزئیات بیشتر به بخش مثالها (EXAMPLES) مراجعه کنید.
ابزار unshare از نسخه ۲.۳۶ util-linux از فایلهای /proc/[pid]/ns/pid_for_children و /proc/[pid]/ns/time_for_children برای فضاهای نام ماندگار PID و TIME استفاده میکند. این تغییر نیازمند هسته لینوکس ۴.۱۷ یا جدیدتر است.
انواع زیر از فضاهای نام را میتوان با unshare ایجاد کرد:
فضای نام سوارکردن (mount namespace)
ابزار unshare از نسخه ۲.۲۷ util-linux انتشار (propagation) را به طور خودکار در فضای نام سوارکردن جدید روی private تنظیم میکند تا اطمینان حاصل شود که فضای نام جدید واقعاً جدا شده است. غیرفعال کردن این ویژگی با گزینه --propagation unchanged امکانپذیر است. توجه داشته باشید که private پیشفرض هسته است.
فضای نام UTS (UTS namespace)
فضای نام IPC (IPC namespace)
فضای نام شبکه (network namespace)
فضای نام PID (PID namespace)
فضای نام cgroup (cgroup namespace)
فضای نام کاربر (user namespace)
فضای نام زمان (time namespace)
گزینهها (OPTIONS)
-i, --ipc[=file]
-m, --mount[=file]
-n, --net[=file]
-p, --pid[=file]
همچنین گزینههای --fork و --mount-proc را ببینید.
-u, --uts[=file]
-U, --user[=file]
-C, --cgroup[=file]
-T, --time[=file]
-f, --fork
--keep-caps
--kill-child[=signame]
--mount-proc[=mountpoint]
--mount-binfmt[=mountpoint]
--map-user uid|name
--map-users inneruid:outeruid:count|auto|subids|all
قبل از نسخه ۲.۳۹ util-linux، این گزینه یک آرگومان جداشده با ویرگول به صورت outeruid,inneruid,count دریافت میکرد اما آن قالب اکنون جهت هماهنگی با ترتیبی که در /proc/[pid]/uid_map و گزینه سوارکردن X-mount.idmap استفاده میشود، منسوخ شده است.
--map-group gid|name
--map-groups innergid:outergid:count|auto|subids|all
قبل از نسخه ۲.۳۹ util-linux، این گزینه یک آرگومان جداشده با ویرگول به صورت outergid,innergid,count دریافت میکرد اما آن قالب اکنون جهت هماهنگی با ترتیبی که در /proc/[pid]/gid_map و گزینه سوارکردن X-mount.idmap استفاده میشود، منسوخ شده است.
--map-auto
--map-subids
-r, --map-root-user
-c, --map-current-user
--propagation private|shared|slave|unchanged
--setgroups allow|deny
برای فراخوانی setgroups(2)، فرآیند فراخواننده باید حداقل قابلیت CAP_SETGID را داشته باشد. اما از لینوکس ۳.۱۹ محدودیت دیگری نیز اعمال میشود: هسته تنها پس از تنظیم نگاشت GID (/proc/pid*/gid_map*) اجازه فراخوانی setgroups(2) را میدهد. زمانی که setgroups(2) فعال است (یعنی allow، مقدار پیشفرض)، نگاشت GID توسط root قابل نوشتن است و زمانی که setgroups(2) به طور دائم غیرفعال میشود (با deny)، نگاشت GID توسط فرآیندهای بدون امتیاز قابل نوشتن میشود.
-R, --root dir
-w, --wd dir
-S, --setuid uid
-G, --setgid gid
-l, --load-interp string
--monotonic offset
--boottime offset
-h, --help
-V, --version
نکات (NOTES)
سوارکردن سیستمهای فایل proc و sysfs به عنوان root در یک فضای نام کاربر باید محدود شود تا یک کاربر با دسترسی کمتر نتواند به فایلهای حساسی که یک کاربر با دسترسی بالاتر غیرقابل دسترس کرده است، دسترسی بیشتری پیدا کند. به طور خلاصه قاعده برای proc و sysfs این است که تا حد امکان مشابه یک اتصال سوارکردن (bind mount) باشد.
مثالها (EXAMPLES)
دستور زیر یک فضای نام PID با استفاده از --fork ایجاد میکند تا اطمینان حاصل شود دستور اجراشده در فرآیند فرزندی اجرا میشود که (به عنوان اولین فرآیند در فضای نام) دارای PID 1 است. گزینه --mount-proc تضمین میکند که یک فضای نام سوارکردن جدید نیز همزمان ایجاد شده و یک سیستمفایل جدید proc(5) سوار میشود که حاوی اطلاعات متناظر با فضای نام PID جدید است. با پایان یافتن دستور readlink(1)، فضاهای نام جدید به طور خودکار برچیده میشوند.
# unshare --fork --pid --mount-proc readlink /proc/self 1
به عنوان یک کاربر بدون دسترسی ویژه، یک فضای نام کاربر جدید ایجاد کنید که در آن اعتبارنامههای کاربر به شناسههای root درون فضای نام نگاشت میشوند:
$ id -u; id -g
1000
1000
$ unshare --user --map-root-user \
sh -c 'whoami; cat /proc/self/uid_map /proc/self/gid_map'
root
0 1000 1
0 1000 1
به عنوان یک کاربر بدون دسترسی ویژه، یک فضای نام کاربر ایجاد کنید که در آن ۶۵۵۳۶ شناسه اول همگی نگاشت شدهاند و اعتبارنامههای کاربر به شناسههای root درون فضای نام نگاشت میشوند. این نگاشت با شناسههای زیرمجموعه تعیینشده در subuid(5) و subgid(5) مشخص میشود. این نگاشت را با ایجاد فایلی با شناسه کاربر 1 و شناسه گروه 1 نشان دهید. برای اختصار، تنها نگاشتهای شناسه کاربر نشان داده شدهاند:
$ id -u
1000
$ cat /etc/subuid
1000:100000:65536
$ unshare --user --map-auto --map-root-user
# id -u
0
# cat /proc/self/uid_map
0 1000 1
1 100000 65535
# touch file; chown 1:1 file
# ls -ln --time-style=+ file
-rw-r--r-- 1 1 1 0 file
# exit
$ ls -ln --time-style=+ file
-rw-r--r-- 1 100000 100000 0 file
اولین دستور از دستورهای زیر یک فضای نام UTS ماندگار جدید ایجاد میکند و نام میزبان را آنگونه که در آن فضای نام دیده میشود تغییر میدهد. سپس برای نمایش نام میزبان تغییریافته، با nsenter(1) وارد فضای نام میشود؛ این مرحله نشان میدهد که فضای نام UTS حتی با وجود اینکه پس از پایان دستور unshare هیچ فرآیند عضوی نداشت، همچنان به وجود خود ادامه میدهد. سپس فضای نام با حذف اتصال سوارکردن نابود میشود.
# touch /root/uts-ns # unshare --uts=/root/uts-ns hostname FOO # nsenter --uts=/root/uts-ns hostname FOO # umount /root/uts-ns
دستورهای زیر یک فضای نام سوارکردن ماندگار را ایجاد میکنند که توسط اتصال سوارکردن /root/namespaces/mnt مورد ارجاع قرار میگیرد. به منظور اطمینان از موفقیتآمیز بودن ایجاد آن اتصال سوارکردن، دایرکتوری والد (/root/namespaces) به یک اتصال سوارکردن تبدیل میشود که نوع انتشار آن shared نیست.
# mount --bind /root/namespaces /root/namespaces # mount --make-private /root/namespaces # touch /root/namespaces/mnt # unshare --mount=/root/namespaces/mnt
دستورهای زیر نحوه استفاده از گزینه --kill-child را هنگام ایجاد یک فضای نام PID نشان میدهند، تا اطمینان حاصل شود که هنگام پایان یافتن یا کشته شدن unshare، تمام فرآیندهای درون فضای نام PID کشته میشوند.
# set +m # Don't print job status messages
# unshare --pid --fork --mount-proc --kill-child -- \
bash --norc -c '(sleep 555 &) && (ps a &) && sleep 999' &
[1] 53456
# PID TTY STAT TIME COMMAND
1 pts/3 S+ 0:00 sleep 999
3 pts/3 S+ 0:00 sleep 555
5 pts/3 R+ 0:00 ps a
# ps h -o 'comm' $! # Show that background job is unshare(1)
unshare
# kill $! # Kill unshare(1)
# pidof sleep
دستور pidof(1) هیچ خروجی چاپ نمیکند، زیرا فرآیندهای sleep کشته شدهاند. به طور دقیقتر، هنگامی که فرآیند sleep دارای PID 1 در فضای نام (یعنی فرآیند init فضای نام) کشته شد، این امر باعث کشته شدن تمام فرآیندهای دیگر در آن فضای نام گردید. در مقابل، سری مشابهی از دستورها که در آنها از گزینه --kill-child استفاده نشده است نشان میدهد که با خاتمه یافتن unshare، فرآیندهای درون فضای نام PID کشته نمیشوند:
# unshare --pid --fork --mount-proc -- \
bash --norc -c '(sleep 555 &) && (ps a &) && sleep 999' &
[1] 53479
# PID TTY STAT TIME COMMAND
1 pts/3 S+ 0:00 sleep 999
3 pts/3 S+ 0:00 sleep 555
5 pts/3 R+ 0:00 ps a
# kill $!
# pidof sleep
53482 53480
مثال زیر ایجاد یک فضای نام زمان را نشان میدهد که در آن ساعت boottime روی نقطهای چند سال در گذشته تنظیم شده است:
# uptime -p # Show uptime in initial time namespace up 21 hours, 30 minutes # unshare --time --fork --boottime 300000000 uptime -p up 9 years, 28 weeks, 1 day, 2 hours, 50 minutes
مثال زیر یک chroot را به دایرکتوری /chroot/powerpc/jessie اجرا میکند و مفسر /bin/qemu-ppc-static را برای اجرای باینریهای powerpc نصب میکند.
$ unshare --map-root-user --fork --pid --load-interp=":qemu-ppc:M::\\x7fELF\x01\\x02\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x14:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff:/bin/qemu-ppc-static:OCF" --root=/chroot/powerpc/jessie /bin/bash -l
پارامتر load-interp را میتوان به صورت زیر خواند
qemu-ppc
M
\\x7fELF\x01\\x02\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x1
\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff
/bin/qemu-ppc-static
OCF
نویسندگان (AUTHORS)
Mikhail Gusarov <dottedmag@dottedmag.net>, Karel Zak <kzak@redhat.com>
همچنین ببینید (SEE ALSO)
newuidmap(1), newgidmap(1), clone(2), unshare(2), namespaces(7), mount(8)
گزارش باگها (REPORTING BUGS)
برای گزارش باگها از ردیاب مشکلات https://github.com/util-linux/util-linux/issues. استفاده کنید.
دسترسپذیری (AVAILABILITY)
دستور unshare بخشی از بسته util-linux است که میتوان آن را از آرشیو هسته لینوکس https://www.kernel.org/pub/linux/utils/util-linux. دریافت کرد.
| 2026-06-16 | util-linux 2.41.5 |