ユーザー名前空間は 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 エラー) の解決方法
目次utf8mb4 の紹介UTF8 バイト数超過エラーutf8mb4 サポートデフォルトの文字エンコ...
Vue でタブ切り替えを実装する 3 つの方法1. v-showはコンテンツの切り替えを制御します1...
序文国家とは何か私たちは皆、React はステート マシンであると言います。それはどのように反映され...
概要この記事は、centos7.3 上で mysql5.3.6 を自動的にコンパイルしてインストール...
私は最近 Linux を学び始めました。Ma Ge の umask に関する Linux コースを読...
Dockerの概要Docker はオープンソースのソフトウェア展開ソリューションです。 Docker...
CSSスタイルの分類1. 内部スタイル ---- インラインスタイルスタイルタグの使用 <ス...
SQLはテーブル内の重複レコードをすべて見つけます1. テーブルには id と name の 2 つ...
背景日本語を学び始めた当初は、日本語の50音を覚えるのは簡単ではなく、特にカタカナを覚えるのは困難で...
1. 原因公式の cerbot は面倒すぎます。野生の成長よりもさらに悪い acme.sh の使用は...
1. まず、自分のdockerhubアカウントを登録します。登録アドレス: https://hub....
シナリオ 1: サーバーの制限により、外部に開かれているポートは 1 つだけですが、別の外部ネットワ...
mysql5.7.18のインストール時に次の問題が発生しました: プログラム入力ポイントfesetr...
目次序文1. Nginx+Tomcat 2. Nginxサーバーを構成する3. Tomcatアプリケ...
CSS変数の知識を使って、追加したコードとコメントを直接投稿します <!DOCTYPE htm...