前回の記事「Docker コンテナの UID と GID を理解する」では、Docker コンテナ内のユーザーとホスト マシン上のユーザーの関係を紹介し、Docker はデフォルトではホスト ユーザーとコンテナ内のユーザーを分離しないと結論付けました。 Linux のユーザー名前空間テクノロジー (「Linux 名前空間: ユーザー」を参照) を既に知っている場合は、当然次のような疑問が湧くでしょう。Docker はなぜユーザーの分離を実現するために Linux ユーザー名前空間を使用しないのでしょうか。実際、Docker にはすでに関連機能が実装されていますが、デフォルトでは有効になっていません。この記事では、コンテナ内でユーザーを分離するように Docker を構成する方法について説明します。 Linux ユーザー名前空間の理解 Linux ユーザー名前空間は、実行中のプロセスに対してセキュリティ関連の分離 (uid と gid を含む) を提供し、プロセスがこれらの制限を認識することなくシステム リソースへのアクセスを制限します。 Linux ユーザー名前空間の紹介については、私の記事「Linux 名前空間: ユーザー」を参照してください。 コンテナの場合、権限昇格攻撃を防ぐ最善の方法は、コンテナ アプリケーションを通常のユーザー権限で実行することです。 ユーザー名前空間のユーザーマッピング ユーザー名前空間を有効にするように Docker デーモンを構成する前に、従属ユーザー/グループと再マッピングに関するいくつかの概念を理解する必要があります。従属ユーザーとグループのマッピングは、2 つの構成ファイル /etc/subuid と /etc/subgid によって制御されます。デフォルトの内容を見てみましょう: ユーザー名前空間を有効にするように docker デーモンを構成する前に、従属ユーザー/グループとマッピング (再マッピング) に関するいくつかの概念を理解する必要があります。 subuid の場合、この行の意味は次のとおりです。 ユーザー nick には、現在のユーザー名前空間内に 100000 から 165535 までのユーザー ID を持つ 65536 人の従属ユーザーがいます。子ユーザー名前空間では、これらの従属ユーザーは 0 から 65535 までの ID を持つユーザーにマップされます。 subgid は subuid と同じ意味を持ちます。 たとえば、ユーザー nick は、ホスト マシン上で通常の権限を持つユーザーです。コンテナが属するユーザー名前空間にその従属 ID の 1 つ (100000 など) を割り当て、そのユーザー名前空間の uid 0 に ID 100000 をマップすることができます。この時点では、コンテナ内のプロセスにルート権限があっても、その権限はコンテナが配置されているユーザー名前空間内に限られます。ホスト マシン内に入ると、せいぜいニック ユーザーの権限しか得られません。 Docker のユーザー名前空間のサポートが有効になっている場合 (Docker の userns-remap 機能)、コンテナーにマップする異なるユーザーを指定できます。たとえば、dockeruser というユーザーを作成し、その subuid と subgid を手動で設定します。 ニックネーム:100000:65536 dockeruser:165536:65536 これを docker デーモンに割り当てます。 { "userns-remap": "dockeruser" } subuid 設定情報に注意してください。dockeruser と nick ユーザーに設定した従属 ID は重複しません。実際、どのユーザーの従属 ID 設定も重複することはできません。 あるいは、シンプルにして、Docker にすべての面倒な作業を任せることもできます。そのためには、Docker デーモンの userns-rempa パラメータを「default」として指定します。 { "userns-remap": "デフォルト" } この時点で、Docker は他の構成を自動的に完了します。 ユーザー分離を有効にするためにDockerデーモンを構成する ここでは単純なアプローチを採用し、Docker にユーザー名前空間のデフォルト ユーザーを作成させます。まず /etc/docker/daemon.json ファイルを作成する必要があります。 $ sudo touch /etc/docker/daemon.json 次に、その内容を次のように編集し (ファイルがすでに存在する場合は、次の構成項目を追加するだけです)、Docker サービスを再起動します。 { "userns-remap": "デフォルト" } $ sudo systemctl docker.serviceを再起動します ユーザーの分離についていくつかの点を確認しましょう。 まず、docker が dockremap という名前のユーザーを作成したことを確認します。 次に、新しいユーザーの dockremap 関連項目が /etc/subuid ファイルと /etc/subgid ファイルに追加されているかどうかを確認します。 次に、/var/lib/docker ディレクトリの下に新しいディレクトリ 165536.165536 が作成されていることがわかりました。ディレクトリの権限を確認します。 165536 は、ユーザー dockremap によってマップされた uid です。 165536.165536 ディレクトリの内容を表示します。 これは基本的に /var/lib/docker ディレクトリの内容と一致しており、ユーザー分離が有効になると、ファイル関連のコンテンツが新しく作成された 165536.165536 ディレクトリに配置されることを示しています。 上記のチェックにより、docker デーモンがユーザー分離機能を有効にしていることを確認できます。 ホストのUIDとコンテナのUID Docker デーモンでユーザー分離を有効にした後、ホストの uid とコンテナの uid の変更を確認してみましょう。 $ docker run -d --name sleepme ubuntu スリープ無限 uid 165536 はユーザー dockremap の従属 ID であり、ホスト マシン上で特別な権限はありません。ただし、コンテナ内のユーザーは root なので、結果は完璧に見えます。 新しく作成されたコンテナはユーザー名前空間を作成します Docker デーモンがユーザー分離を有効にする前は、新しく作成されたコンテナ プロセスとホスト上のプロセスは同じユーザー名前空間にあります。つまり、Docker はコンテナに新しいユーザー名前空間を作成しません。 上図では、コンテナプロセスのスリープとホスト上のプロセスは同じユーザー名前空間にあります(ユーザー分離機能は有効になっていません)。 docker デーモンでユーザー分離を有効にした後、コンテナ内のプロセスのユーザー名前空間を表示してみましょう。 上の図の 4404 は、先ほど起動したコンテナ内のスリープ プロセスの PID です。ご覧のとおり、Docker はコンテナの新しいユーザー名前空間を作成します。このユーザー名前空間では、コンテナ内のユーザー ルートは神であり、最高権力を持ちます。 データボリューム内のファイルにアクセスする データ ボリューム内のファイルにアクセスして、コンテナ内のルート ユーザーがどのような権限を持っているかを証明できます。それぞれユーザー root、165536、nick に属する 4 つのファイルを作成します。 root ユーザーのみが rootfile の読み取りと書き込みができます。ユーザー nick は nickfile の読み取りと書き込み権限を持っています。UID 165536 はファイル 165536file の読み取りと書き込み権限を持っています。すべてのユーザーが testfile の読み取りと書き込みができます。 次に、これらのファイルをデータ ボリュームとしてコンテナーにマウントし、コンテナーからアクセスするための権限を確認します。 $ docker run -it --name test -w=/testv -v $(pwd)/testv:/testv ubuntu コンテナ内の root ユーザーは 165536file と testfile にのみアクセスできます。つまり、このユーザーはホスト マシン内で非常に制限された権限を持っています。 コンテナ内のユーザー名前空間を無効にする docker デーモンに「userns-remap」パラメータが設定されると、すべてのコンテナでユーザー分離がデフォルトで有効になります (新しいユーザー名前空間がデフォルトで作成されます)。場合によっては、ユーザー分離が有効になっていないシナリオに戻る必要があるかもしれません。この場合、--userns=host パラメータを使用して、単一のコンテナのユーザー分離を無効にすることができます。 --userns=host パラメータは主に次の 3 つのコマンドで使用されます。 docker コンテナ作成 dockerコンテナの実行 docker コンテナ実行 たとえば、次のコマンドを実行します。 $ docker run -d --userns=host --name sleepme ubuntu スリープ無限 プロセス情報を表示します: プロセスの実効ユーザーは再び root になり、プロセスに対して新しいユーザー名前空間は作成されません。 既知の問題 ユーザー名前空間は比較的高度な機能です。現在、Docker によるサポートは完全ではありません。既存の機能との非互換性がいくつか知られています。
要約する Dockerはユーザー名前空間をサポートしており、設定方法も非常にシンプルです。ユーザー名前空間を有効にすると、セキュリティが向上しますが、同時に、さまざまな制限により他の個々の機能に問題が発生する可能性があります。現時点では、選択を行い、画一的な決定に別れを告げ、適切な機能が適切なシナリオに表示されるようにする必要があります。 参照: Docker コンテナでの uid と gid の動作を理解する 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: Ubuntu でディスク容量不足により MySQL が起動しない場合の解決策
サーバーにはNginx、データベースサポートにはMongo、Python言語のWebフレームワークに...
1. 公式サイト http://dev.mysql.com/downloads/mysql/ から ...
1. Pythonは起動時に自動的に実行されますPython の自己起動スクリプトがauto.pyで...
序文MySQL データのインポートとエクスポートは mysqldump コマンドで解決できることは誰...
目次導入公開コード(バックエンドインターフェース)例 1: 最もシンプル (純粋な HTML)コード...
目次1. データ型1.1 なぜデータ型が必要なのか? 1.2 変数のデータ型1.3 データ型の分類2...
最初の方法: docker インストール1. オープンソース版のイメージを取得する2. 対応するデー...
具体的なコードは次のとおりです。 <!DOCTYPE html> <html>...
各テーブルの行数をカウントするために使用される MySQL count() 関数は、誰もがよく知って...
1. 中国語入力方法を設定する 2. ダブルスペルモードを設定する 3. 注意事項20.04 で S...
MySQL8.0.22のインストールと設定(超詳細)参考までに、具体的な内容は次のとおりです。みなさ...
jvm.options ファイルを elasticsearch 構成に追加し、スタック サイズを変更...
目次概要サブクエリサブクエリの分類クエリの結果によるとサブクエリの位置で区別する選択後のサブクエリサ...
この記事では、スローモーションアニメーション効果を実現するためのJavaScriptの具体的なコード...
1. Fcitx入力フレームワークをインストールする関連する依存ライブラリとフレームワークは自動的に...