Linux名前空間について読んだ後、他の多くの機能の中で、chrootに代わるものであるという印象を受けました。たとえば、 この記事 の場合:
[名前空間の]その他の用途には、[...] chroot()スタイルの単一ディレクトリ階層の一部へのプロセスの分離が含まれます。
ただし、たとえば次のコマンドを使用してマウント名前空間を複製すると、元のルートツリー全体が表示されます。
unshare --mount -- /bin/bash
新しい名前空間で、元の名前空間と共有されていない追加のマウントを実行できるようになったことを理解しています。これにより分離が提供されますが、それでも同じルートです。 /etc
は、両方の名前空間で同じです。ルートを変更するためにchroot
が必要ですか、それとも代替手段はありますか?
この質問 で回答が得られると期待していましたが、回答ではchroot
のみを使用しています。
pivot_root
についてのコメントが削除されました。これは実際には linux/fs/namespace.c
の一部であるため、実際には名前空間の実装の一部です。これは、ルートディレクトリをunshare
とmount
だけで変更することは不可能であることを示唆していますが、名前空間はchroot
の独自のバージョンを提供します。それでも、ソースコードを読んだ後でも(たとえば、セキュリティやより良い分離の意味で)、このアプローチの基本的な考え方がchroot
と根本的に異なることはありません。
これは この質問 の複製ではありません。回答からすべてのコマンドを実行した後、別の/tmp/tmp.vyM9IwnKuY(または類似の)がありますが、ルートディレクトリは同じです!
chroot
を設定する前にマウント名前空間を入力すると、追加のマウントでホスト名前空間が煩雑になるのを回避できます。 _/proc
_の場合。マウントネームスペース内でchroot
を使用すると、素晴らしくシンプルなハックができます。
_pivot_root
_を理解することには利点があると思いますが、学習曲線が少しあります。ドキュメントはすべてを完全に説明していません... _man 8 pivot_root
_の使用例があります(シェルコマンドの場合)。 _man 2 pivot_root
_(システムコールの場合)が同じである場合、よりわかりやすくなる可能性があり、サンプルCプログラムが含まれています。
マウント名前空間を入力した直後に、_mount --make-rslave /
_または同等のものも必要です。それ以外の場合、すべてのマウントの変更は、_pivot_root
_を含め、元の名前空間のマウントに伝達されます。あなたはそれを望まない:)。
_unshare --mount
_コマンドを使用した場合は、デフォルトで_mount --make-rprivate
_を適用することが記載されていることに注意してください。 AFAICSこれは不適切なデフォルトであり、これを本番コードで使用したくありません。例えば。この時点で、ホストネームスペースにマウントされたDVDまたはUSBでeject
が機能しなくなります。 DVDまたはUSBはプライベートマウントツリー内にマウントされたままで、カーネルはDVDを取り出せません。
それが終わったら、マウントすることができます。使用する_/proc
_ディレクトリchroot
の場合と同じです。
chroot
を使用する場合とは異なり、_pivot_root
_では、新しいルートファイルシステムがマウントポイントである必要があります。まだバインドされていない場合は、バインドマウントを適用するだけで満足できます:_mount --rbind new_root new_root
_。
_pivot_root
_を使用し、次に_-l
_/_MNT_DETACH
_オプションを使用して古いルートファイルシステムをumount
します。 ( _umount -R
_は必要ありません。時間がかかることがあります。 )。
技術的には、_pivot_root
_を使用するには、通常、chroot
も使用する必要があります。 「どちらか一方」ではありません。
_man 2 pivot_root
_によると、それはマウント名前空間のルートを交換することとしてのみ定義されています。プロセスルートが指している物理ディレクトリを変更することは定義されていません。または、現在の作業ディレクトリ(_/proc/self/cwd
_)。たまたま実行しますが、これはカーネルスレッドを処理するためのハックです。マンページには、将来変更される可能性があると記載されています。
通常、このシーケンスが必要です。
_chdir(new_root); // cd new_root
pivot_root(".", put_old); // pivot_root . put_old
chroot("."); // chroot .
_
このシーケンスでのchroot
の位置付けは、もう1つの微妙な詳細です 。 _pivot_root
_の目的はマウント名前空間を再配置することですが、カーネルコードは、プロセスごとのルートを調べて移動するルートファイルシステムを見つけているようです。これはchroot
が設定するものです。
原則として、セキュリティと分離のために_pivot_root
_を使用することは理にかなっています。 機能ベースのセキュリティ の理論について考えたいと思います。必要な特定のリソースのリストを渡し、プロセスは他のリソースにアクセスできません。この場合は、マウント名前空間に渡されるファイルシステムについて話している。この考えは、Linuxの「名前空間」機能に一般的に当てはまりますが、おそらく私はそれをうまく表現していません。
chroot
はプロセスのルートのみを設定しますが、プロセスは引き続き完全なマウント名前空間を参照します。プロセスがchroot
を実行する特権を保持している場合、ファイルシステム名前空間をさかのぼってバックアップできます。 _man 2 chroot
_で詳しく説明されているように、「スーパーユーザーは...によって「chroot刑務所」から脱出できます。」.
chroot
を元に戻す別の考えさせる方法は、_nsenter --mount=/proc/self/ns/mnt
_です。これはおそらくこの原則に対するより強力な議論です。 nsenter
/setns()
は、必ず、マウントネームスペースのルートからプロセスルートを再ロードします ...異なる物理ディレクトリ。カーネルのバグと見なされる場合があります。 (テクニカルノート:複数のファイルシステムがルート上で相互にマウントされている可能性があります。setns()
は、最も新しくマウントされたものを使用します)。
これは、マウント名前空間を「PID名前空間」と組み合わせる利点の1つを示しています。 PID名前空間内にいると、制限のないプロセスのマウント名前空間に入ることができなくなります。また、制限のないプロセスのルート(_/proc/$PID/root
_)に入るのを防ぎます。そしてもちろん、PID名前空間は、その外にあるプロセスを強制終了することも防ぎます:-)。