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
[コンテナを使い始めますか?この無料コースをチェックしてください。コンテナ化されたアプリケーションのデプロイ:技術的な概要。 ]
まとめ
残念ながら、主にセキュリティ上の懸念から、カーネル内のすべてを修正して、ユーザーが期待するルートレスエクスペリエンスを提供することはできません。しかし、私たちはかなり近づくことができます。もちろん、追加機能が必要な場合は、いつでもルートフルモードで作業できます。