web-dev-qa-db-ja.com

特権コンテナーを非特権に移行することにより、非特権(ユーザー)LXCコンテナーをゼロから構築する

特権LXC(1.0.3)コンテナー(私が知っているその部分)をビルドして、正常に移行して非特権で実行するにはどうすればよいですか?つまり、これを自分でdebootstrapするか、または_lxc-ubuntu_テンプレート(通常は_/usr/share/lxc/templates_の下)を調整して、これが機能するようにします。

これが私がこの質問をしている理由です。 _lxc-ubuntu_テンプレートを見ると、次のことがわかります。

_# Detect use under userns (unsupported)
for arg in "$@"; do
    [ "$arg" = "--" ] && break
    if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
        echo "This template can't be used for unprivileged containers." 1>&2
        echo "You may want to try the \"download\" template instead." 1>&2
        exit 1
    fi
done
_

ただし、参照されている_LXC_MAPPED_GID_テンプレートで_LXC_MAPPED_UID_および_lxc-download_を使用した後は、特に特別なことは何もないようです。実際には、ファイルの所有権を調整するだけです(chgrp + chown)。ただし、downloadテンプレートの拡張属性は、必要な「魔法」を実現するためにすでに微調整されている可能性があります。

StéphaneGraberによるこのブログ投稿 Stéphaneはコメント投稿者に次のように伝えています。

残念ながら、これを行う簡単な方法はありません。非特権コンテナーからのコンテナー構成と一致するようにコンテナー構成を更新し、コンテナーのディレクトリーを実行先の非特権ユーザーに移動してから、Sergeのuidshiftプログラムを使用して変更する必要があります。すべてのファイルの所有権。

...そして:

  • downloadテンプレート用にビルドされたパッケージについては https://jenkins.linuxcontainers.org/ をご覧ください
  • ここ [.____からuidmapshiftをチェックしてください。]
    • このプログラムは、 lxc-usernsexec(1) で説明されているように、おおよそ_lxc-usernsexec -m b:0:1000:1 -m b:1:190000:1 -- /bin/chown 1:1 $file_を実行しているように見えます。

しかし、それ以上の指針はありません。

だから私の質問は、私が自分で構築した(rootとすべてを持っている)通常の(特権)LXCコンテナーを取得して、それを非特権コンテナーに移行するにはどうすればよいですか? スクリプトなどを提供できない場合でも、考慮すべきポイントと、それらが非特権LXCコンテナを実行する機能にどのように影響するかを理解しておくと便利です。自分でスクリプトを作成し、解決策が見つかれば、この質問への回答として投稿することを誓約します。

注:Ubuntu 14.04を使用していますが、これは一般的な質問です。

5
0xC0000022L

KVM VMを特権のないLXCに移動しました。

私はこれにシステムコンテナを使用していましたが(起動時に自動的に起動できるように)、マップされたUID/GID(ユーザー名前空間)を使用していました。

  1. / etc/subuid、subgidを編集します(uid/gids 10M-100Mをルートにマップし、コンテナーごとに100Kを使用します)
  2. 最初のコンテナーには、/ var/lib/lxc/CTNAME/configのu/gids10000000-10099999を使用します
  3. / var/lib/lxc/CTNAME/rootfsにコンテナーストレージをマウントします(またはコンテナーごとに個別のボリューム/データセット/何も使用しない場合は何もしません)
  4. chown 10000000:10000000/var/lib/lxc/CTNAME/rootfs
  5. setfacl -m u:10000000:x/var/lib/lxc(または単にchmod o + x/var/lib/lxc)
  6. lxc-usernsexec -m b:0:10000000:100000-/bin/bash

これで、最初のコンテナーユーザー名前空間に移動しました。すべては同じですが、プロセスはuidが0であるとプロセスが判断しますが、実際にはホスト名前空間ではuid 10000000です。/proc/self/uid_mapをチェックして、uidがマップされているかどうかを確認してください。/rootから読み取ることができなくなり、nobody/nogroupが所有しているように見えます。

ユーザー名前空間にいる間、元のホストからrsyncします。

ユーザー名前空間の外では、/ var/lib/lxc/CTNAME/rootfs内のファイルが、Originのインストールと予想される(同じ)uidではなく、10000000 + remote_uidによって所有されていることがわかります。これはあなたが望むものです。

それでおしまい。データを同期したら、コンテナーの/ etc/fstabからすべてを削除して、マウントを試みないようにします。他にも変更が必要な場合があります。コンテナ化されたディストリビューションのLXCテンプレートの機能を確認してください。コンテナ内のカーネル、grub、ntp、およびハードウェアプローブパッケージを確実に削除できます(実行する必要はなく、ユーザー名前空間からコンテナにchrootできます)

実行中のリモートVMがない場合は、元のVMストレージをホスト名前空間にマウントし、rsync/SSHをローカルホストに戻すこともできます。効果は同じです。

(見たところ)特権コンテナを非特権コンテナに変更したいだけの場合は、uid/gidマッピングを追加し、上記のようにコンテナ設定にマッピングを追加してから、次の行に沿って何かを実行することもできます。

for i in `seq 0 65535`; do
  find /var/lib/lxc/CTNAME/rootfs -uid $i -exec chown $((10000000+i)) \{\} \;
  find /var/lib/lxc/CTNAME/rootfs -gid $i -exec chgrp $((10000000+i)) \{\} \;
done

これで必要な作業はこれですべてです。これで、コンテナを非特権で実行できるようになります。上記のこの例は非常に非効率的であり、uidshiftはおそらくこれでより良い仕事をするでしょう(しかし私はまだそれを使用していません)。

HTH。

6
Borut Mrak

シンボリックリンクがコンテナー内のファイルを指している場合、Borut Mrakのサンプルコードがホストシステム上のファイルの所有権も変更することを警告したいと思いました。あなたが望んでいるものではありません!

専用のファイルシステムがある場合は、chown/chgrpに-hフラグを使用するか、findに-mountを使用する必要があります。

ここに私のより速いスマートバージョンがあります:

find "/var/lib/lxc/$name/rootfs" -mount -uid '-65536' -printf '%U\n'|sort -n|uniq|while read i; do
        find "/var/lib/lxc/$name/rootfs" -mount -uid "$i" -exec chown -h "$((200000+i))" \{\} \;
done

find "/var/lib/lxc/$name/rootfs" -mount -gid '-65536' -printf '%G\n'|sort -n|uniq|while read i; do
        find "/var/lib/lxc/$name/rootfs" -mount -gid "$i" -exec chgrp -h "$((200000+i))" \{\} \;
done
3
thejhh

Alpine Linuxuidmapshiftluaに変換 から 特権コンテナを非特権に変換 を使用するようになりました。 initd script を見て、設定/作成されている他のフォルダのアクセス許可と要件を確認してください。 (/etc/subuid/etc/subgid

1
Stuart Cardall

ピエロコンテナ用

SUBUID_OFFSET=-65536
SUBGID_OFFSET=-65536
cd rootfs || exit 1
find .|while read i; do SUBUID=$(stat --format=%u $i); SUBGID=$(stat --format=%g $i); NEW_SUBUID=$((SUBUID+SUBUID_OFFSET)); NEW_SUBGID=$((SUBGID+SUBGID_OFFSET)); echo "chown -h $NEW_SUBUID.$NEW_SUBGID $i"; done

linuxシステムを移行するため

SUBUID=100000
SUBGID=100000
cd rootfs || exit 1
find .|while read i; do CURRENT_UID=$(stat --format=%u $i); CURRENT_GID=$(stat --format=%g $i); NEW_SUBUID=$((CURRENT_UID+SUBUID)); NEW_SUBGID=$((CURRENT_GID+SUBGID)); echo "chown -h $NEW_SUBUID.$NEW_SUBGID $i"; done
1
Sam