GNU/Linux >> Linux の 問題 >  >> Linux

Buildahで雑草に入る:buildahunshareコマンド

BuildahおよびPodmanコンテナエンジンのルートレスモードの制約について疑問に思うことがあります。ルートレスモードでは、非特権ユーザーができることの限界を押し広げています。私の仕事の1つは、カーネルチームやファイルシステムチームと協力して、ルートレスを改善することです。この記事では、ルートレスモードでイメージをマウントするのが難しい理由を説明します。

[次のこともお勧めします:Linuxのセキュリティと使いやすさのバランスをとる]

ルートレスマウント

通常のユーザーは、ユーザー名前空間にいない限り、ファイルシステムをマウントできません。 独自のマウント名前空間とともに 。マウント名前空間を使用すると、その内部のプロセスは、ホストのマウント名前空間からは見えないファイルシステムをマウントできます。このカーネル制約は、ユーザーが/tmpを介してコンテンツをマウントする可能性のある潜在的な攻撃からホストオペレーティングシステムを保護します または、ホームディレクトリでさえ、システムまたは管理者の他のプロセスをだましてマウントポイントを使用させます。

ユーザーのプロセスがユーザー名前空間と新しいマウント名前空間に参加すると、カーネルは特定のファイルシステムのみをマウントできるようにします。この記事の執筆時点では、カーネルはsysfs、procfs、tmpfs、バインドマウント、およびヒューズファイルシステムを許可しています。最近、オーバーレイファイルシステムをサポートするパッチをアップストリームカーネルに追加しました。これは大幅な改善になりますが、現在、ほとんどのディストリビューションではこのサポートが提供されていません。 NFSサポートを利用したいのですが、これにはセキュリティ上のリスクがあります。うまくいけば、カーネルはこれらの問題を修正し、最終的にはサポートされるでしょう。

PodmanやBuildahなどのルートレスコンテナエンジンは、実行時に独自のユーザー名前空間を自動的に作成し、名前空間をマウントします。コンテナエンジンプロセスが終了すると、ユーザーとマウントの名前空間はなくなり、ユーザープロセスはホストのマウント名前空間に戻ります。この時点で、ツールの実行中に作成されたマウントは、ホスト上の他のプロセスからは見えなくなったり、使用できなくなったりします。

なぜこれが重要なのですか?

Buildahの優れた機能の1つは、ユーザーがコンテナ構築の低レベルのセマンティクスにアクセスできるようにすることです。ほとんどのコンテナイメージビルダーは、コンテナを構築する1つの方法、つまり基本的にContainerfilesまたはDockerfilesを使用する方法に固執しています。 Buildah bud これらのファイルを使用したビルドをサポートします。 Buildahを使用すると、ユーザーは低レベルのプリミティブを使用してコンテナーを作成することもできます。ユーザーはこれを使用して、ディレクトリを作成し、ディレクトリにコンテンツを入力し、画像を作成して、レジストリにプッシュすることができます。

# ctr=$(buildah from scratch)
# mnt=$buildah mount $ctr)
# dnf -y --install-root $mnt httpd 
# buildah config --entrypoint .... $ctr
# buildah commit $ctr IMAGE
# buildah push IMAGE REGISTRY

これはすべてrootとして実行するとうまく機能しますが、ユーザーがこれをrootlessモードで実行しようとすると、スクリプトが爆発します。

$ mnt=$(buildah mount $ctr)
cannot mount using driver overlay in rootless mode. You need to run it in a `buildah unshare` session

問題はmnt=$(buildah mount $ctr)です buildah unshareを実行していない場合、オーバーレイドライバーでイメージをマウントすることを拒否します 。

詳しく見る

buildahを実行するとき budなどのコマンド およびrun 、ルートレスモードでは、buildah コマンドは、ユーザーとマウントの名前空間を入力します。コンテナファイルシステムを正常にマウントし、コマンドを実行します。コマンドが完了すると、buildah 終了し、名前空間が破棄されます。 mountでこれを行う場合 コマンドを実行すると、マウントされたファイルシステムがホストのマウント名前空間に表示されませんでした。 Buildahはこの状況をチェックし、ユーザーにbuildah unshareを発行する必要があることを報告します。 最初。

buildah unshare

BuildahとPodmanには、unshareという特別なコマンドがあります。 。このコマンドは、コンテナーを作成または操作せずに、ユーザー名前空間を作成して入力します。このモードを調べて、ユーザーの名前空間が何をしているのかを完全に理解することは、実際にはかなり興味深いことです。 buildah unshareの実行 コマンドは、 rootとして実行されている名前空間でシェルコマンドを実行します ユーザー名前空間で。これで、buildahを含む任意のコマンドを実行できます。 上記のコマンド。これらのコマンドはすでに名前空間にあるため、buildah mount コマンドは、ルートフルモードの場合と同じように機能します。すべてが名前空間内で行われ、ユーザーは期待どおりの結果を得ることができます。

これで、ユーザーは上記のコマンドを実行してシェルスクリプトを作成できます。このシェルスクリプトは、buildah unshareを使用して直接実行されます。 コマンド。

$ cat > buildahimage.sh < _EOF
ctr=$(buildah from scratch)
mnt=$buildah mount $ctr)
dnf -y --install-root $mnt httpd 
buildah config --entrypoint .... $ctr
buildah commit $ctr IMAGE
buildah push IMAGE REGISTRY
 < _EOF
chmod +x /buildahimage.sh
buildah unshare ./buildimage.sh

[コンテナを使い始めますか?この無料コースをチェックしてください。コンテナ化されたアプリケーションのデプロイ:技術的な概要。 ]

まとめ

残念ながら、主にセキュリティ上の懸念から、カーネル内のすべてを修正して、ユーザーが期待するルートレスエクスペリエンスを提供することはできません。しかし、私たちはかなり近づくことができます。もちろん、追加機能が必要な場合は、いつでもルートフルモードで作業できます。


Linux
  1. Linuxcronコマンドを使用したタスクのスケジューリング

  2. Linuxtacコマンドの使用を開始する

  3. Linuxcatコマンドの使用を開始する

  1. sourceコマンドを使用して関数と変数をBashにインポートします

  2. sedを使用してコマンドラインでテキストを操作する

  3. 組み込みのsplitコマンドを使用してファイルをチャンクに分割します

  1. Linuxatコマンドでタスクをスケジュールする

  2. Duコマンドで–excludeを使用しますか?

  3. vsish コマンドで情報を取得する (esxi のみ)