非特権LXCコンテナーとは何ですか?


20

Linuxコンテナ(LXCコンテナ)が「非特権」と呼ばれる場合、どういう意味ですか?

回答:


20

非特権LXCコンテナーは、ユーザーの名前空間)を使用するです。名前空間にホスト上でのUIDの範囲をマッピングすることを可能にするカーネル機能のすなわち内側 UID 0のユーザが再び存在することができるの。

しばらくの間、特権のないLXCコンテナに対する私の最初の認識とは反対に、これは、コンテナを特権のないホストユーザーが所有する必要があるという意味ではありません。それが唯一の可能性です。

関連するのは:

  1. 下位UIDとGIDの範囲がホストユーザーに対して定義されていること(usermod [-v|-w|--add-sub-uids|--add-sub-gids]
  2. ...そして、この範囲はコンテナ構成にマッピングされます(lxc.id_map = ...

rootホスト上のコンテナプロセスの有効なUIDは、マッピングで定義された範囲内に収まるため、特権のないコンテナを所有することもできます。

ただし、root最初に従属IDを定義する必要があります。経て作成されたユーザーとは異なりadduserrootデフォルトで定義された下位IDの範囲を持っていません。

また、指定するすべての範囲を自由に使用できるため、次の構成行を持つ3つのコンテナーを作成できます(UIDマッピングのみを表示)。

  1. lxc.id_map = u 0 100000 100000
  2. lxc.id_map = u 0 200000 100000
  3. lxc.id_map = u 0 300000 100000

それは仮定root100000と400000の間の従属UIDを所有している私が見つけたすべての文書は、それがより人間readbable、しかし作るためにいくつかの使用100000コンテナあたり65536の従属IDを使用することを示唆しています。

つまり、各コンテナに同じ範囲を割り当てる必要はありません。

40億(〜2^32)を超える下位IDがあるため、ホストユーザーに下位範囲を処理するときに寛大になります。

ルートが所有および実行する非特権コンテナー

それをもう一度こすります。特権のないLXCゲストは、ホスト上の特権のないユーザーが実行する必要はありません。

次のような下位UID / GIDマッピングを使用してコンテナを構成します。

lxc.id_map = u 0 100000 100000
lxc.id_map = g 0 100000 100000

rootホスト上のユーザーが特定の従属ID範囲を所有している場合、ゲストをさらに制限できます。

ただし、このようなシナリオには1つの重要な追加の利点があります(そして、はい、動作することを確認しました):システムの起動時にコンテナーを自動起動できます。

通常、LXCに関する情報をWebで探し回ると、特権のないLXCゲストを自動起動することはできないと言われます。ただし、これはデフォルトではコンテナのシステム全体のストレージにないコンテナ(通常はのようなもの/var/lib/lxc)にのみ当てはまります。それらが(通常はルートによって作成され、ルートによって開始されることを意味します)場合は、まったく別の話です。

lxc.start.auto = 1

コンテナ設定に入れると、非常にうまく機能します。

権限と設定権を取得する

私はこれに少し苦労したので、ここにセクションを追加します。

lxc.include通常含まれている設定スニペット/usr/share/lxc/config/$distro.common.conf$distro名前はディストリビューションの名前)に加え/usr/share/lxc/config/$distro.userns.confて、システム上にもあるかどうかを確認し、それも含めてください。例えば:

lxc.include = /usr/share/lxc/config/ubuntu.common.conf
lxc.include = /usr/share/lxc/config/ubuntu.userns.conf

さらに、従属IDマッピングを追加します。

lxc.id_map = u 0 100000 65535
lxc.id_map = g 0 100000 65535

つまり、ホストUID 100000はLXCゲストのユーザー名前空間root 内にあります。

ここで、権限が正しいことを確認してください。ゲストの名前が環境変数に保存される$lxcguest場合、次を実行します。

# Directory for the container
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest
chmod ug=rwX,o=rX $(lxc-config lxc.lxcpath)/$lxcguest
# Container config
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest/config
chmod u=rw,go=r $(lxc-config lxc.lxcpath)/$lxcguest/config
# Container rootfs
chown 100000:100000 $(lxc-config lxc.lxcpath)/$lxcguest/rootfs
chmod u=rwX,go=rX $(lxc-config lxc.lxcpath)/$lxcguest/rootfs

これにより、最初の試行で許可関連のエラーが発生した場合に、コンテナーを実行できるようになります。


4
良い答え-しかしlxc、この種のものの必要はありません。util-linuxツールを使用して、あらゆる種類の名前空間コンテナを作成できますunshareutil-linuxツールを使用して、上記のコンテナに入ることができますnsenter。後者のツールを使用すると、実行中のプロセスを、それなしで既に作成されたコンテナに追加することもできます。名前空間のサポートはカーネル内で実装されます。
mikeserv

4
@mikeserv:つまり、usernsを利用するのにLXCは必要ないということですか?私はそれを知っていました。また、Dockerにはこれらの機能を利用する独自のライブラリがあることも知っています。しかし、LXCが提供する機能の助けを借りずに、システム全体をどのようにコンテナー化できますか?そして、なぜあなたはそれをしますか?私は単一のアプリケーションを含むことを意味し、chrootこれと組み合わせると役立ちますが、LXCはさまざまな名前空間(UTS、マウントなど)を組み合わせてシステム全体をコンテナ化します。
0xC0000022L

2
さて...私が言ったように、unshareこれはすでにさまざまな名前空間のいずれか/すべてに対して見事に行われています-そして/proc、単一のCLIスイッチで別のプライベートマウントを取得します。あなたの場合は、単一のアプリケーションがあるinitとあなたchrootであるinitramfs、あなたは秒フラットで容器全体を取得します。
mikeserv

0

ソリューションがうまく機能した0xC0000022Lをフォローアップするために、LXCコンテナー内のファイルが適切にマッピングされるように必要な所有権の変更を自動化するための increment-uid-gid.pl perlスクリプトを作成しました。

これがないと、この提案されたセットアップでは、メインホストの0 / rootに属するLXCコンテナーrootfs内のファイルは、LXCコンテナー自体内で65534 / nobodyにマッピングされます。LXCコンテナ内の0 / rootにマッピングするには、ホスト上の100000に属している必要があります。

これはhttps://yeupou.wordpress.com/2017/06/23/setting-up-lxc-containers-with-mapped-giduid/で説明されており、スクリプトはgitlab https://gitlab.comから直接取得できます。 /yeupou/stalag13/blob/master/usr/local/bin/increase-uid-gid.pl

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.