仮想環境(5)

Date: 2021/02/12 (initial publish), 2021/07/13 (last update)

Source: jp/note-00032.md

Previous Post Top Next Post

TOC

引き続き非特権ユーザー権限から立ち上げられたLXC仮想環境を実現するための 技術背景を学ぶために、Linux Namespaces 周辺に着目します。

User Namespaces

Linux Namespacesの中でuser_namespaces(7)で説明されている User NamespacesはユーザーIDやグループID等のセキュリティー関連の識別子 と属性(credentials(7)参照。本来は、資格、信任状の意味の単語)を 分離します。属性とは具体的に言うとルートディレクトリーや、 キー(keyrings(7)参照。本来は、鍵の意味の単語)や、 ケーパビリティ(capabilities(7)参照。本来は能力・資質の意味の単語) 等です。

このUser Namespacesにより、Namespacesの中ではあたかも特権ユーザーとして 振る舞いながら、Namespacesの外では通常の非特権ユーザー権限を保持するプロセスを 実現することができます。この際のユーザーIDの対応関係が/proc/[pid]/uid_map ファイルに記されています。(グループIDの場合は/proc/[pid]/gid_map)

たとえばコンテナ環境外のシェルプロセスのuid_map以下です。

$ cat /proc/$$/uid_map
         0          0 4294967295

これは、最初の0 が現amespacesのユーザーID、次の0 が(実在しない)親Namespaces のユーザーID に対応し、(2^32)-1の4294967295が対応関係範囲長となります。 対応関係範囲長を2^32としないのは故意で2^32番目のユーザーID 4294967295 は「ユーザーID無し」の返り値となっているからだそうです。

/proc/[pid]/uid_mapは、newuidmap(1)で設定できます。その際に 許容されるユーザーIDが/etc/subuidに羅列し規定されています。

LXC 4.0の非特権ユーザーのコンテナ起動は、/usr/share/doc/lxc/README.Debianに 詳しく書かれています。この様な現在のシステムでは、各コンテナ環境では 16ビットユーザーIDの 0 - 65536=(2^16)-2 を使っているようです。

$ id -nu
osamu
$ cat /etc/subuid
osamu:100000:65536

ここの100000は見通しが良いように大きい目になっていますが、65538以上の 適当なオフセット値ですね。このようなオフセット値を各コンテナ毎ずらせば 確かにコンテナを安全に隔離できますね。

ちなみに、chroot(2)システムコールが設定するプロセスごとの ルートディレクトリーは/proc/[pid]/rootからのシムリンクとして 記録されています。これを使えば、コンテナ毎に違うルートファイルシステム 内容のシステムを作成できます。

オーバーレイマウントやバインドマウント等のカーネル機能も効率的な仮想環境 構成に使えます。

なんとなく、コンテナ環境の仮想化が収まっている全体感というか様子が、 ちょっと見えてきました。

shadow-utils

Linux Namespaces関連のnewuidmap(1)等のコマンドは、 Shadow が提供するshadow-utilsのソース中にあり、Debianでは uidmapバイナリーパッケージの中で提供されています。

shadow-utilsのソースはpasswd(1)コマンド等も提供しています。

POSIX Access Control Lists

現在のLinuxにおけるcapabilities(7)には、Access Control Listsという 旧来のUNIXには無い要素技術があります。これは旧来のUNIXのchmod(1)で 設定する、u, g, oに対するr, w, x等の属性設定よりきめ細か い制御ができる機能です。

詳しくは、acl(5)を参照しましょう。aclバイナリーパッケージに含まれる、 getfacl(1) や setfacl(1) を使って管理操作します。

Previous Post Top Next Post