ユーザー名前空間は Linux 3.8 で追加された新しい名前空間で、ユーザー ID やグループ ID、キー、機能などのセキュリティ関連のリソースを分離するために使用されます。同じユーザーのユーザー ID とグループ ID は、異なるユーザー名前空間では異なる場合があります (PID 名前空間と同様)。つまり、ユーザーは、あるユーザー名前空間では通常のユーザーである一方、別のユーザー名前空間ではスーパーユーザーである可能性があります。 ユーザー名前空間はネストできます (現在、カーネルは最大 32 層を制御します)。システムのデフォルトのユーザー名前空間を除き、すべてのユーザー名前空間には親ユーザー名前空間があり、各ユーザー名前空間には 0 個以上の子ユーザー名前空間を含めることができます。 プロセス内で unshare または clone が呼び出されて新しいユーザー名前空間が作成されると、現在のプロセスの元のユーザー名前空間が親ユーザー名前空間になり、新しいユーザー名前空間が子ユーザー名前空間になります。 注: この記事のデモ環境は Ubuntu 16.04 です。 ユーザー名前空間を作成する unshare コマンドの --user オプションを使用して、新しいユーザー名前空間を作成できます。 $ unshare -user -r /bin/bash -r パラメータを使用して、新しいユーザー名前空間のルート ユーザーを外部ニックネーム ユーザーにマッピングします (マッピングに関連する概念については次に説明します)。新しいユーザー名前空間では、ルート ユーザーに、uts 名前空間などの他の名前空間を作成する権限が与えられます。これは、現在の bash プロセスにすべての機能があるためです。 新しい uts 名前空間を作成して試してみましょう。 $ unshare --uts /bin/bash 新しい uts 名前空間が正常に作成されたことがわかります。これは、ユーザー名前空間を除き、他のタイプの名前空間を作成するには CAP_SYS_ADMIN 機能が必要になるためです。新しいユーザー名前空間が作成され、uid と gid がマップされると、このユーザー名前空間の最初のプロセスは完全な機能をすべて持つようになり、他のタイプの新しい名前空間を作成できるようになります。 実際、上記の操作 (2 つの名前空間の作成) を 2 つのステップに分割する必要はありません。unshare を使用すると、一度に複数の名前空間を作成できます。 unshare の実装では、実際には CLONE_NEWUSER | CLONE_NEWUTS が渡されます。これはおおよそ次のようになります。 共有を解除します(CLONE_NEWUSER | CLONE_NEWUTS); 上記の場合、カーネルは CLONE_NEWUSER が最初に実行されることを確認し、次に残りの CLONE_NEW* を実行します。これにより、ルート ユーザーを使用せずに新しいコンテナを作成できます。このルールはクローン機能にも適用されます。 UIDとGIDのマッピングを理解する 前回のデモでは、ユーザー名前空間間のユーザーのマッピングについて説明しました。今度は同じデモを使用して、マッピングが何であるかを理解しましょう。まず、現在のユーザーの ID とユーザー名前空間を確認しましょう。 次に、unshare --user /bin/bash コマンドを実行して、新しいユーザー名前空間を作成します。今回は -r パラメータがないことに注意してください。 $ unshare --user /bin/bash 新しいユーザー名前空間では、現在のユーザーは nobody になり、ID は 65534 になります。 これは、親ユーザー名前空間のユーザー ID とグループ ID を子ユーザー名前空間にまだマッピングしていないためです。この手順は、システムが 1 つのユーザー名前空間のユーザーの権限を他のユーザー名前空間で制御できるようにするために必要です (他のユーザー名前空間のプロセスにシグナルを送信したり、他のユーザー名前空間にマウントされたファイルにアクセスしたりするなど)。 マッピングがない場合、getuid() および getgid() を使用して新しいユーザー名前空間のユーザー ID とグループ ID を取得すると、システムはファイル /proc/sys/kernel/overflowuid で定義されたユーザー ID と proc/sys/kernel/overflowgid で定義されたグループ ID を返します。どちらのデフォルト値も 65534 です。つまり、マッピングが指定されていない場合、ID はデフォルトで 65534 にマッピングされます。 次に、新しいユーザー名前空間でのニックネーム ユーザーのマッピングを完了します。 ID をマッピングする方法は、/proc/PID/uid_map ファイルと /proc/PID/gid_map ファイルにマッピング情報を追加することです (ここで、PID は新しいユーザー名前空間のプロセス ID であり、両方のファイルは最初は空です)。これら 2 つのファイル内の構成情報の形式は次のとおりです (各ファイルには複数の構成情報を含めることができます)。 ID-inside-ns ID-outside-ns 長さ たとえば、構成 0 1000 500 は、親ユーザー名前空間の 1000 ~ 1500 が新しいユーザー名前空間の 0 ~ 500 にマップされることを意味します。 uid_map ファイルと gid_map ファイルの書き込み操作には、厳密な権限制御があります。簡単に言うと、これら 2 つのファイルの所有者は、新しいユーザー名前空間を作成したユーザーであるため、このユーザーと同じユーザー名前空間内の root アカウントは、これらのファイルに書き込むことができます。このユーザーがマップ ファイルに書き込む権限を持っているかどうかは、CAP_SETUID および CAP_SETGID 機能を持っているかどうかによって決まります。注: マップ ファイルにデータを書き込むことができるのは 1 回だけですが、一度に複数のエントリを書き込むことができ、エントリの最大数は 5 です。 開いたばかりのシェル ウィンドウを最初のシェル ウィンドウとして呼び出し、ユーザー マッピング操作 (新しいユーザー名前空間でユーザー ニックネームをルートにマップする) の実行を開始します。 最初のステップは、最初のシェル ウィンドウで現在のプロセスの ID を確認することです。 2 番目のステップは、新しいシェル ウィンドウ (2 番目のシェル ウィンドウと呼ぶ) を開くことです。プロセス 3049 のマッピング ファイルのプロパティを表示します。 ユーザー nick はこれら 2 つのファイルの所有者です。これら 2 つのファイルにマッピング情報を書き込んでみましょう。 自分がファイルの所有者なのに、ファイルに書き込む権限がないのは奇妙に思えます。実際、根本的な理由は、現在の bash プロセスに CAP_SETUID および CAP_SETGID 権限がないことです。 次に、/bin/bash プログラムの関連する機能を設定します。 次のようにコードをコピーします。 $ sudo setcap cap_setgid、cap_setuid+ep /bin/bash $ sudo setcap cap_setgid、cap_setuid+ep /bin/bash 次に bash をリロードすると、対応する機能が表示されます。 次に、マッピング情報をマップ ファイルに書き換えます。 $ エコー '0 1000 500' > /proc/3049/uid_map $ エコー '0 1000 500' > /proc/3049/gid_map 今回は書き込みが成功しました。後でマッピング情報を手動で書き込む必要はないので、次のコマンドを使用して /bin/bash の機能を元の設定に戻します。 $ sudo setcap cap_setgid,cap_setuid-ep /bin/bash ステップ3: 最初のシェルウィンドウに戻る bash をリロードし、id コマンドを実行します。 現在のユーザーは root (新しいユーザー名前空間の root ユーザー) になりました。現在の bash プロセスの機能を見てみましょう。 0000003fffffffff は、現在実行中の bash がすべての機能を持っていることを意味します。 ステップ4. 最初のシェルウィンドウで /root ディレクトリのアクセス権限を確認します。 許可なし!ホスト名を変更してみてください: まだ許可が出ません!この新しいユーザー名前空間のルート ユーザーは、親ユーザー名前空間では機能しないようです。これはまさに、ユーザー名前空間が期待する効果です。他のユーザー名前空間のリソースにアクセスする場合、アクセスを実行するために権限が使用されます。たとえば、root の親ユーザー名前空間に対応するユーザーは nick であるため、システムのホスト名を変更することはできません。 通常ユーザー nick にはホスト名を変更する権限がありません。では、デフォルトユーザー名前空間の root ユーザーをサブユーザー名前空間の root ユーザーにマッピングした後、ホスト名を変更することはできますか?答えはノーです!これは、マッピングがどのように実行されたとしても、子ユーザー名前空間のユーザーが親ユーザー名前空間のリソースにアクセスする場合、そのユーザーが開始するプロセスの機能は空であるため、子ユーザー名前空間のルート ユーザーは親ユーザー名前空間の通常のユーザーと同等になるためです。 ユーザー名前空間と他の名前空間の関係 Linux の各名前空間は、ユーザー名前空間に関連付けられています。このユーザー名前空間は、対応する名前空間が作成されたときにプロセスが属するユーザー名前空間です。これは、各名前空間に所有者 (ユーザー名前空間) があることと同じです。これにより、任意の名前空間での操作がユーザー名前空間の権限によって制御されることが保証されます。これは、変更する uts 名前空間が親ユーザー名前空間に属しており、新しいユーザー名前空間のプロセスには古いユーザー名前空間の機能がないため、子ユーザー名前空間でホスト名を設定すると失敗する理由でもあります。 uts 名前空間を例にとると、uts_namespace 構造体にはユーザー名前空間へのポインターがあり、それが属するユーザー名前空間を指します (私が確認した v4.13 カーネルでは、uts_namespace 構造体の定義は /include/linux/utsname.h ファイルにあります)。 他の名前空間の定義も同様です。 要約する 他の名前空間と比較すると、ユーザー名前空間は少し複雑です。これは機能性によるもので、権限管理に関しては直感的ではない傾向があります。この記事では、ユーザー名前空間の基本的な概念についてのみ紹介しました。他にも興味深い内容が数多くありますので、ぜひご覧ください。 参照: ユーザー名前空間のマニュアルページ 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
>>: MySQL がテーブルを読み取れないエラー (MySQL 1018 エラー) の解決方法
データは企業の中核資産であり、企業にとって最も重要なタスクの 1 つです。注意しないと、データが意図...
ウェブサイトのデザインを編集または変更する必要がある場合、CSS が重要な役割を果たします。 CSS...
1. Vueとは何かVue は、ユーザー ページを構築するためのプログレッシブ フレームワークです。...
公式ドキュメント http://dev.mysql.com/doc/refman/5.7/en/se...
Linux でファイルを編集した後、保存して終了するにはどうすればよいですか?保存して終了するコマン...
この記事では、スクロールウィンドウを実装するためのJavaScriptの具体的なコードを参考までに紹...
1. フォントを実行し、フォント フォルダーを開いて、使用するフォント ファイルを見つけます。 2....
序文: MySQL では、ビューはおそらく最も一般的に使用されるデータベース オブジェクトの 1 つ...
次の Web デザイン プロジェクトはレスポンシブにする必要があると上司をようやく納得させることがで...
序文Js は現在最も一般的に使用されているコード操作言語であり、その中でも new 演算子は特によく...
ダウンロードしたバージョンは、Zip 解凍版、Windows システムです。長い間 Windows ...
よくある質問easyswoole を初めて使用する場合は、次のような問題に遭遇することがよくあります...
【序文】最近、ITOO の試験システムのストレステストを行いたいので、自分のコンピュータに Lin...
レンダリング ネットで関連情報を調べたところ、現在のダイナミックグラデーションボーダーの実装方法のほ...
CentOS の紹介CentOS は、Red Hat Linux が提供する無料で利用できるソースコ...