差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン 前のリビジョン 次のリビジョン | 前のリビジョン | ||
linux:kernel:namespace:user_namespace [2013/09/01 14:26] – [マッピングファイルを書くルール] tenforward | linux:kernel:namespace:user_namespace [2013/09/03 16:46] (現在) – [ユーザとグループの ID のマッピングを眺める] tenforward | ||
---|---|---|---|
行 127: | 行 127: | ||
$ ./ | $ ./ | ||
</ | </ | ||
+ | |||
+ | 今回は,マッピングファイルの更新が成功し,シェルが期待するユーザ ID,グループ ID,ケーパビリティを持っているのがわかる. | ||
+ | |||
+ | < | ||
+ | $ id -u | ||
+ | 0 | ||
+ | $ id -g | ||
+ | 0 | ||
+ | $ cat / | ||
+ | CapInh: 0000000000000000 | ||
+ | CapPrm: 0000001fffffffff | ||
+ | CapEff: 0000001fffffffff | ||
+ | </ | ||
+ | |||
+ | userns_child_exec プログラムの実装には微妙な点が少し存在する.まず,親プロセス (すなわち clone() を呼び出した側) も新しい子プロセスも,新しいユーザ名前空間の uid/gid のマッピングを更新可能であることである.しかし,先に述べたルールにより,子プロセスは自身の実効ユーザ ID だけをマップするマッピングを定義できる.もし,任意の子供内でのユーザ ID,グループ ID のマッピングを定義したい場合,定義は親プロセス側で行わなければならない.その上,親プロセスは適切なケーパビリティを持っていなければならない.具体的には CAP_SETUID, CAP_SETGID, | ||
+ | |||
+ | その上に,親は子供が execve() を呼ぶ前にマッピングファイルを確実に更新する必要がある (でなければ,子供が execve() の間にケーパビリティを失うという,まさに前述のような問題が生じる).確実に実行するために,2 つのプロセスは必要な同期を取るためパイプを採用している.プログラムのソースコードのコメントに詳細な説明がある. | ||
+ | |||
+ | ===== ユーザとグループの ID のマッピングを眺める ===== | ||
+ | |||
+ | 今までの所の例で / | ||
+ | |||
+ | シェルを実行する 2 つのユーザ名前空間を作成し,名前空間内のプロセスの uid_map ファイルを調べる事で,これを示す事ができる.シェルを実行する新しいユーザ名前空間を作成して,始めよう. | ||
+ | |||
+ | < | ||
+ | $ id -u # Display effective user ID | ||
+ | 1000 | ||
+ | $ ./ | ||
+ | $ echo $$ # Show shell' | ||
+ | 2465 | ||
+ | $ cat / | ||
+ | | ||
+ | $ id -u # Mapping gives this process an effective user ID of 0 | ||
+ | 0 | ||
+ | </ | ||
+ | |||
+ | ここで別のターミナルウィンドウに移り,異なるユーザとグループのマッピングを持つ兄弟となるユーザ名前空間を作る. | ||
+ | |||
+ | < | ||
+ | $ ./ | ||
+ | $ cat / | ||
+ | | ||
+ | $ id -u # Mapping gives this process an effective user ID of 200 | ||
+ | 200 | ||
+ | $ echo $$ # Show shell' | ||
+ | 2535 | ||
+ | </ | ||
+ | |||
+ | 2 つ目のユーザ名前空間のシェルを実行している 2 つ目のターミナルウィンドウで,他のユーザ名前空間内のプロセスのユーザ ID のマッピングを見よう. | ||
+ | |||
+ | < | ||
+ | $ cat / | ||
+ | | ||
+ | </ | ||
+ | |||
+ | このコマンドの出力は,他のユーザ名前空間内でのユーザ ID 0 が,自分の名前空間内ではユーザ ID 200 にマッピングされていることを示している.同じコマンドが他のユーザ名前空間内で実行されると,異なる出力を生成していることに注意すること.これは,ファイルから読み込みを行っているプロセスの属するユーザ名前空間に従って,カーネルが ID-outside-ns の値を生成しているからである. | ||
+ | |||
+ | もし,最初のターミナルウィンドウに戻って,2 つ目のユーザ名前空間内のプロセスに対するマッピングファイルを表示したとすると,以下のような出力が見られるだろう. | ||
+ | |||
+ | < | ||
+ | $ cat / | ||
+ | | ||
+ | </ | ||
+ | |||
+ | 再び,ここでの出力は 2 つ目のユーザ名前空間で実行した時の同じコマンドと異なる.これは ID-outside-ns の値はファイルから読み込みを行っているプロセスのユーザ名前空間に従って生成されているからである.もちろん,初期の名前空間では,最初のユーザ名前空間のユーザ ID 0 と,2 つ目の名前空間のユーザ ID 200 は,両方ともユーザ ID 1000 にマッピングされている.これを,初期の名前空間で実行する 3 つ目のシェルウィンドウで以下のコマンドを実行して調べてみよう. | ||
+ | |||
+ | < | ||
+ | $ cat / | ||
+ | | ||
+ | $ cat / | ||
+ | | ||
+ | </ | ||
+ | |||
+ | ===== 最後に ===== | ||
+ | |||
+ | この記事では,ユーザ名前空間の基礎を見てきた.ユーザ名前空間の作成,ユーザとグループ ID のマッピングファイルの使用,ユーザ名前空間とケーパビリティの関係である. | ||
+ | |||
+ | [[http:// | ||
+ | |||
+ | ユーザ名前空間は,(名前空間外では特権を持たない) プロセスが,その名前空間に特権の範囲を制限すると同時に root 特権を持てるようにする.その結果,プロセスはシステム全体の特権プログラムの実行環境の操作はできない.これらの root 特権を有意義に使うために,他のタイプの名前空間と同時にユーザ名前空間を同時に使う必要がある.このトピックはこのシリーズの次の記事の主題を形作る. | ||