Linux名前空間について読んだ後、私はそれらが他の多くの機能の中でも、chrootの代替であるという印象を受けました。たとえば、この記事では:
[名前空間の]他の用途には、[…]単一ディレクトリ階層の一部へのプロセスのchroot()スタイルの分離が含まれます。
ただし、たとえば次のコマンドを使用してマウント名前空間のクローンを作成すると、元のルートツリー全体が表示されます。
unshare --mount -- /bin/bash
元の名前空間と共有されていない新しい名前空間で追加のマウントを実行できるようになったことを理解しました。これにより、分離が提供されますが、ルートは同じです。 /etc
両方の名前空間で同じです。まだchroot
が必要ですか? ルートを変更しますか、それとも別の方法がありますか?
この質問が答えを提供することを期待していましたが、答えはchroot
のみを使用しています 、もう一度。
編集#1
pivot_root
について言及したコメントが削除されました 。これは実際にはlinux/fs/namespace.c
の一部であるため 、それは実際には名前空間の実装の一部です。これは、unshare
でのみルートディレクトリを変更することを示唆しています。 およびmount
不可能ですが、namespacesは独自の-より賢い-バージョンのchroot
を提供します 。それでも、chroot
とは根本的に異なるこのアプローチの主なアイデアはわかりません。 、ソースコードを読んだ後でも(セキュリティやより良い分離などの意味で)
編集#2
これはこの質問の複製ではありません。回答からすべてのコマンドを実行した後、別の/tmp/tmp.vyM9IwnKuY(または同様のもの)がありますが、ルートディレクトリは同じです!
承認された回答:
chroot
を設定する前にマウント名前空間を入力する 、追加のマウントでホスト名前空間が乱雑になるのを回避できます。 /proc
の場合 。 chroot
を使用できます 素晴らしくシンプルなハックとしてのマウント名前空間内。
pivot_root
を理解することには利点があると思います 、しかしそれは少し学習曲線があります。ドキュメントはすべてを完全に説明しているわけではありません...man 8 pivot_root
に使用例がありますが (シェルコマンドの場合)。 man 2 pivot_root
(システムコールの場合)同じことを行い、Cプログラムの例が含まれていると、より明確になる可能性があります。
pivot_rootの使用方法
マウント名前空間を入力した直後に、mount --make-rslave /
も必要です。 または同等のもの。それ以外の場合、マウントの変更はすべて、pivot_root
を含む元の名前空間のマウントに反映されます。 。あなたはそれを望まない:)
unshare --mount
を使用した場合 コマンド、mount --make-rprivate
を適用することが文書化されていることに注意してください デフォルトでは。 AFAICSこれは悪いデフォルトであり、本番コードではこれを望まないでしょう。例えば。この時点で、eject
は停止します。 ホスト名前空間にマウントされたDVDまたはUSBでの作業から。 DVDまたはUSBはプライベートマウントツリー内にマウントされたままになり、カーネルはDVDを取り出せません。
それが済んだら、たとえば/proc
使用するディレクトリ。 chroot
の場合と同じ方法 。
chroot
を使用する場合とは異なり 、pivot_root
新しいルートファイルシステムがマウントポイントである必要があります。まだ1つでない場合は、バインドマウントを適用するだけでこれを満たすことができます。mount --rbind new_root new_root
。
pivot_root
を使用します –次にumount
-l
を含む古いルートファイルシステム / MNT_DETACH
オプション。 (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
の位置 このシーケンスには、さらに別の微妙な詳細があります。 pivot_root
のポイントですが マウント名前空間を再配置することである場合、カーネルコードは、プロセスごとのルートを調べることによって、移動するルートファイルシステムを見つけているようです。これは、chroot
です。 セット。
pivot_rootを使用する理由
原則として、pivot_root
を使用することは理にかなっています セキュリティと分離のために。私は、機能ベースのセキュリティの理論について考えるのが好きです。必要な特定のリソースのリストを渡すと、プロセスは他のリソースにアクセスできなくなります。この場合、マウント名前空間に渡されるファイルシステムについて話します。このアイデアは、Linuxの「名前空間」機能に一般的に当てはまりますが、私はおそらくそれをうまく表現していません。
chroot
プロセスルートを設定するだけですが、プロセスは引き続きフルマウント名前空間を参照します。プロセスがchroot
を実行する権限を保持している場合 、その後、ファイルシステムの名前空間をバックアップできます。 man 2 chroot
で詳しく説明されています 、「スーパーユーザーは…によって「chroot刑務所」から脱出することができます。」
chroot
を元に戻すもう1つの示唆に富む方法 nsenter --mount=/proc/self/ns/mnt
です 。これはおそらく、原則に対するより強力な議論です。 nsenter
/ setns()
必然的に、マウント名前空間のルートからプロセスルートを再ロードします…2つが異なる物理ディレクトリを参照している場合にこれが機能するという事実は、カーネルのバグと見なされる可能性があります。 (テクニカルノート:ルートに複数のファイルシステムがマウントされている可能性があります; setns()
一番上に取り付けられたものを使用します。
これは、マウント名前空間を「PID名前空間」と組み合わせる利点の1つを示しています。 PID名前空間内にあると、制限のないプロセスのマウント名前空間に入ることができなくなります。また、制限されていないプロセスのルート(/proc/$PID/root
)に入るのを防ぎます。 )。そしてもちろん、PID名前空間は、その外部にあるプロセスを強制終了することも防ぎます:-)