UNSHARE
Section: User Commands (1)
Updated: February 2016
Index
Return to Main Contents
名前
unshare - プログラムを新しい名前空間で実行する。
書式
unshare
[options]
[program
[arguments]]
説明
unshare
コマンドは (以下に説明するコマンドラインオプションで指定された) 新しい名前空間を作成し、
指定した program を実行する。
program が指定されない場合、``${SHELL}'' (デフォルトは: /bin/sh) が実行される。
デフォルトでは、新しい名前空間は、その名前空間にメンバーがある限り、
永続化される。
/proc/pid/ns/type ファイルを
ファイルシステムに bind マウントすることで、
メンバープロセスがない場合でも、新しい名前空間を永続化できる。
この方法で永続化された名前空間は、program が終了した後でも、その後で
nsenter(1)
で名前空間に入れることができる。
(PID 名前空間は例外であり、init プロセスをずっと動作させる必要がある)。
一度永続化した名前空間が必要なくなった場合、
umount(8)
で bind マウントを削除することで、永続化を解除できる。
より詳細は、「例」のセクションを参照すること。
util-linux バージョン 2.36 以降の
unshare
は、永続化 PID 名前空間と永続化時間 (TIME) 名前空間に、
/proc/[pid]/ns/pid_for_children と
proc/[pid]/ns/time_for_children ファイルを使う。
この変更は、Linux カーネル 4.17 以降が必要である。
以下のタイプの名前空間が、
unshare
で作成できる:
- マウント名前空間
-
ファイルシステムのマウントとアンマウントが、他のファイルシステムに
影響しない。
ただし、明示的に共有 (shared) とマークされているファイルシステムは除く
(共有は mount --make-shared で行われる。
/proc/self/mountinfo または
findmnt -o+PROPAGATION で shared フラグを参照すること)。
より詳細は、
mount_namespaces(7)
を参照すること。
-
unshare
は util-linux バージョン 2.27 以降で、新たなマウント名前空間で伝搬 (propagation) を
自動的に private にして、新しい名前空間を共有しないようにする。
この機能はオプション --propagation unchanged で無効化できる。
private はカーネルのデフォルトである点に注意すること。
- UTS 名前空間
-
ホスト名またはドメイン名の設定が、システムの他の部分に影響しない。
より詳細は、
uts_namespaces(7)
を参照すること。
- IPC 名前空間
-
POSIX メッセージキューと、System V メッセージキュー、
セマフォセット、共有メモリセグメントについて、プロセスは独立した
名前空間を持つ。
より詳細は、
ipc_namespaces(7)
を参照すること。
- ネットワーク名前空間
-
プロセスが独立した IPv4 と IPv6 スタック、IP ルーティングテーブル、
ファイアウォールルール、
/proc:/net
と
/sys:/class:/net
のディレクトリツリー、ソケットなどを持つ。
より詳細は、
network_namespaces(7)
を参照すること。
- PID 名前空間
-
親プロセスとは別に、子プロセスがプロセスマッピングをするための PID セットを持つ。
より詳細は、
pid_namespaces(7)
を参照すること。
- コントロールグループ (cgroup) 名前空間
-
プロセスが /proc:/self:/cgroup の仮想化されたビューを持ち、
新しい cgroup マウントで名前空間の cgroup ルートがルートにされる。
より詳細は、
cgroup_namespaces(7)
を参照すること。
- ユーザー名前空間
-
プロセスが個別の UID、GID、ケーパビリティ (capabilities) のセットを持つ。
より詳細は、
user_namespaces(7)
を参照すること。
- 時間 (time) 名前空間
-
プロセスが
CLOCK_MONOTONIC
かつ/または
CLOCK_BOOTTIME
の異なるビューを持ち、/proc/self/timens_offsets で変更できる。
より詳細は、
time_namespaces(7)
を参照すること。
オプション
- -i, --ipc[=file]
-
IPC 名前空間を共有しない。
file が指定された場合、永続化された名前空間が bind マウントにより作成される。
- -m, --mount[=file]
-
マウント名前空間を共有しない。
file が指定された場合、永続化された名前空間が bind マウントにより作成される。
file は伝搬フラグを shared 以外に設定したファイルシステムに
置かれる必要がある点に注意すること (さもないと、エラーになる)。
現在の設定が分からない場合は、コマンド findmnt -o+PROPAGATION を使うこと。
以下の例も参照すること。
- -n, --net[=file]
-
ネットワーク名前空間を共有しない。
file が指定された場合、永続化された名前空間が bind マウントにより作成される。
- -p, --pid[=file]
-
PID 名前空間を共有しない。
file が指定された場合、永続化された名前空間が bind マウントにより作成される。
(--fork
オプションも一緒に指定しないと、永続化 PID 名前空間の作成は失敗する。)
-
--fork と --mount-proc オプションも参照すること。
- -u, --uts[=file]
-
UTS 名前空間を共有しない。
file が指定された場合、永続化された名前空間が bind マウントにより作成される。
- -U, --user[=file]
-
ユーザー名前空間を共有しない。
file が指定された場合、永続化された名前空間が bind マウントにより作成される。
- -C, --cgroup[=file]
-
cgroup 名前空間を共有しない。
file が指定された場合、永続化された名前空間が bind マウントにより作成される。
- -T, --time[=file]
-
時間名前空間を共有しない。
file を指定すると、bind マウントにより永続化名前空間が作成される。
--monotonic と --boottime を使って、
時間名前空間での対応するオフセットを指定できる。
- -f, --fork
-
指定された program を、直接実行するのではなく、
unshare の子プロセスとして fork する。
これは新しい PID 名前空間を作成する際に役立つ。
unshare が子プロセスを待っている時、SIGINT と SIGTERM を無視して、
子プロセスにシグナルを送らない点に注意すること。
これは、子プロセスにシグナルを送るために必要である。
- --keep-caps
-
--user オプションが指定された場合、
名前空間に許可されたケーパビリティは、子プロセスにも保持される。
- --kill-child[=signame]
-
unshare が終了する時に、fork した子プロセスに signame を送る。
--pid と組み合わせることにより、unshare 以下のプロセスツリー全体を、
簡単に確実に kill することができる。
signame が指定されない場合、デフォルトは SIGKILL である。
このオプションは --fork を暗黙のうちに指定する。
- --mount-proc[=mountpoint]
-
プログラムを実行する直前に、proc ファイルシステムを mountpoint
(デフォルトは /proc) にマウントする。
これは新しい PID 名前空間を作成するのに役立つ。
これは暗黙のうちに新しいマウント名前空間を作成する。
そうしなければ、/proc マウントはシステム上の既存のプログラムの実行に失敗する。
新しい proc システムは、(MS_PRIVATE|MS_REC で) 明示的に private としてマウントされる。
- --map-user=uid|name
-
現在の実効 (effective) ユーザー ID を uid にマッピングした後で、
プログラムを実行する。
このオプションは複数回指定可能で、最後の指定が優先される。
このオプションは --user を暗黙のうちに指定する。
- --map-group=gid|name
-
現在の実効 (effective) グループ ID を gid にマッピングした後で、
プログラムを実行する。
このオプションは複数回指定可能で、最後の指定が優先される。
このオプションは --setgroups=deny と
--user を暗黙のうちに指定する。
- -r, --map-root-user
-
現在の実効 (effective) ユーザー ID と実効グループ ID を、
新しく作られた名前空間のスーパーユーザーの UID と GID にマッピングした後で、
プログラムを実行する。
これにより、非特権で実行されている場合でも、
新しく作られた名前空間のいろいろな側面を管理するのに必要な
ケーパビリティ (capabilities) を簡単に取得できる
(これには、ネットワーク名前空間でのインタフェースの設定や、
マウント名前空間でのファイルシステムのマウントなどがある)。
これは単なる便利機能に過ぎず、複数の範囲の UID と GID をマッピングするといった、
より洗練された使い方はサポートしていない。
このオプションは、--setgroups=deny と
--user を暗黙のうちに指定する。
このオプションは、--map-user=0 --map-group=0 と同じである。
- -c, --map-current-user
-
現在の実効ユーザー ID と実効グループ ID を、新しく作られた名前空間で
同じ UID と GID にマッピングした後で、プログラムを実行する。
このオプションは、--setgroups=deny と
--user を暗黙のうちに指定する。
このオプションは --map-user=$(id -ru) --map-group=$(id -rg) と同じである。
- --propagation private|shared|slave|unchanged
-
新しいマウント名前空間のマウント伝搬フラグを再帰的に設定する。
デフォルトでは伝搬を private に設定する。
この機能は引き数 unchanged で無効化できる。
このオプションは、マウント名前空間 (--mount) が指定されない場合、
黙って無視される。
- --setgroups allow|deny
-
ユーザー名前空間で
setgroups(2)
システムコールを許可または拒否する。
setgroups(2)
を呼び出すには、呼び出しプロセスは少なくとも CAP_SETGID 権限を持たなければならない。
しかし、Linux 3.19 以降ではさらに厳しい制限が適用される:
GID マップ (/proc/pid/gid_map) が設定された後でのみ、
カーネルは、
setgroups(2)
の呼び出しを許可する。
(allow, デフォルトで)
setgroups(2)
が有効化されると、GID マップは root による書き込みが可能なる。
(deny で)
setgroups(2)
が永続的に無効化されると、GID マップは非特権プロセスによる書き込みが可能になる。
- -R, --root=dir
-
ルートディレクトリを dir に設定し、コマンドを実行する。
- -w, --wd=dir
-
ワーキングディレクトリを dir に変更する。
- -S, --setuid uid
-
名前空間全体で使われるユーザー ID を設定する。
- -G, --setgid gid
-
名前空間全体で使われるグループ ID を設定し、補助 (supplementary) グループを削除する。
- --monotonic offset
-
時間名前空間に入った際に使われる
CLOCK_MONOTONIC
のオフセットを指定する。
このオプションは、
--time で時間名前空間を共有しないことが必要である。
- --boottime offset
-
時間名前空間に入った際に使われる
CLOCK_BOOTTIME
のオフセットを指定する。
このオプションは、
--time で時間名前空間を共有しないことが必要である。
- -V, --version
-
バージョン情報を表示して、終了する。
- -h, --help
-
ヘルプを表示して、終了する。
注意
ユーザー名前空間で root として proc と sysfs ファイルシステムをマウントすることは
制限されなければならない。
これにより、特権のあるユーザーが見えなくした機微なファイルを、
特権の少ないユーザーがアクセスできないようにできる。
端的にいうと、proc と sysfs は可能な限り閉じて bind マウントしなければならない。
例
以下のコマンドは
--fork
で PID 名前空間を作成し、実行されたコマンドが PID 1 の
子プロセス (名前空間の最初のプロセス) で実行されることを保証する。
--mount-proc
オプションを指定すると、新しいマウント名前空間も同時に作成され、
新しい
proc(5)
ファイルシステムがマウントされ、新しい PID 名前空間に対応する情報が格納される。
readlink
コマンドが終了すると、新しい名前空間は自動的に解放される。
# unshare --fork --pid --mount-proc readlink /proc/self
1
非特権ユーザーで、新しいユーザー名前空間を作成し、
ユーザーのクレデンシャル (credentials) を
名前空間内の root ID にマップする。
$ 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
以下の最初のコマンドは、新しい永続化 UTS 名前空間を作成し、
名前空間で見えるホスト名を変更している。
次に、
nsenter(1)
で名前空間に入って、変更したホスト名を表示している。
このステップでは、
unshare
コマンドが終了した後で、名前空間にメンバープロセスがない状態にも
関わらず、
UTS 名前空間が継続していることを示している。
その後、名前空間は bind マウントを削除することで破壊される。
# touch /root/uts-ns
# unshare --uts=/root/uts-ns hostname FOO
# nsenter --uts=/root/uts-ns hostname
FOO
# umount /root/uts-ns
以下のコマンドは、bind マウント
/root/namespaces/mnt
で参照される、永続化マウント名前空間を作成する。
bind マウントの作成を成功させるため、
親ディレクトリ
(/root/namespaces)
は伝搬 (propagation) タイプを
shared
以外にして、bind マウントを作成されている。
# mount --bind /root/namespaces /root/namespaces
# mount --make-private /root/namespaces
# touch /root/namespaces/mnt
# unshare --mount=/root/namespaces/mnt
以下のコマンドは、PID 名前空間を作成する際の、
--kill-child
オプションの使い方を示している。
unshare
が kill された場合、PID 名前空間内のすべてのプロセスが kill されることを確かめている。
# set +m # ジョブのステータスメッセージを表示しない
# 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' $! # バックグラウンドジョブが unshare(1) であることを表示する
unshare
# kill $! # unshare(1) を kill する
# pidof sleep
sleep
は kill されているので、
pidof
コマンドは何も出力しない。
より正確には、名前空間で PID 1 の
sleep
プロセス (つまり、名前空間の init プロセス) が kill されるとき、
名前空間の他のすべてのプロセスが kill される。
反対に、
--kill-child
オプションが使われない場合、同様のコマンドで
unshare
が終了した場合に、PID 名前空間のプロセスは kill されない:
# 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
以下の例では、時間名前空間を作成し、ブート時刻のクロックを数年前の
過去に設定している。
# uptime -p # 最初の時間名前空間の uptime を表示する
up 21 hours, 30 minutes
# unshare --time --fork --boottime 300000000 uptime -p
up 9 years, 28 weeks, 1 day, 2 hours, 50 minutes
著者
Mikhail Gusarov
Karel Zak
関連項目
clone(2),
unshare(2),
namespaces(7),
mount(8)
入手方法
unshare コマンドは util-linux パッケージの一部であり、
https://www.kernel.org/pub/linux/utils/util-linux/
から入手できる。
Index
- 名前
-
- 書式
-
- 説明
-
- オプション
-
- 注意
-
- 例
-
- 著者
-
- 関連項目
-
- 入手方法
-
This document was created by
man2html,
using the manual pages.
Time: 15:30:54 GMT, January 23, 2021