DockerコンテナにおけるUIDとGIDの仕組みを理解する

DockerコンテナにおけるUIDとGIDの仕組みを理解する

コンテナ内で実行されているプロセスとホスト システム間のユーザー名、グループ名、ユーザー ID (UID)、グループ ID (GID) のマッピングを理解することは、安全なシステムを構築する上で重要な部分です。他のオプションが指定されていない場合、コンテナ内のプロセスはルート ユーザーとして実行されます (Dockerfile で別の UID が指定されていない限り)。この記事では、これがどのように機能するか、権限を正しく付与する方法、および例を示して説明します。

uid/gid セキュリティのステップバイステップの分析

まず、uid と gid がどのように実装されているかを確認しましょう。 Linux カーネルは、カーネルレベルのシステム コールを使用して、要求された特権を付与するかどうかを判断し、uid および gid スペースを管理する責任があります。たとえば、プロセスがファイルに書き込もうとすると、カーネルはプロセスを作成した uid と gid をチェックして、ファイルを変更するのに十分な権限があるかどうかを判断します。ユーザー名の代わりに uid が使用されます。

サーバー上で Docker コンテナを実行する場合、カーネルは 1 つだけです。コンテナ化がもたらす大きな価値の 1 つは、これらすべての独立したプロセスが単一のカーネルを引き続き共有できることです。つまり、Docker コンテナを実行しているサーバー上でも、uid と gid の世界全体が単一のカーネルによって制御されます。

したがって、同じ uid を異なるコンテナーで使用したり、異なるユーザーに割り当てることはできません。これは、一般的な Linux ツールに表示されるユーザー名 (およびグループ名) がカーネルの一部ではなく、外部ツール (/etc/passwd、LDAP、Kerberos など) によって管理されるためです。したがって、異なるユーザー名が表示される場合がありますが、異なるコンテナーであっても、同じ uid/gid に対して異なる権限を持つことはできません。最初はかなり混乱するかもしれませんので、いくつかの例を見てみましょう。

シンプルなDocker実行

まず、docker グループのメンバーであるサーバーに通常のユーザー (marc) としてログインします。この方法では、sudo コマンドを使用せずに Docker コンテナを起動できます。次に、コンテナの外側から、このプロセスがどのように見えるかを見てみましょう。

 marc@server:~$ docker run -d ubuntu:latest sleep infinity 92c57a8a4eda60678f049b906f99053cbe3bf68a7261f118e411dee173484d10 marc@server:~$ ps aux | grep sleep root 15638 0.1 0.0 4380 808 ? Ss 19:49 0:00 sleep infinity

私は sudo を入力したことがなく、root ではありませんでしたが、実行した sleep コマンドは root として開始され、root 権限がありました。ルート権限があるかどうかはどうすればわかりますか?コンテナ内のルートはコンテナ外のルートと同じですか?はい、前述したように、単一のカーネルと、uid および gid の共有プールが存在するためです。コンテナ外に表示されるユーザー名は「root」なので、コンテナ内のプロセスは uid=0 のユーザーとして開始されていることが分かります。

定義されたユーザーを含むDockerfile

Dockerfile で別のユーザーを作成し、そのユーザーとしてコマンドを起動するとどうなりますか?例を簡略化するために、ここでは gid を指定していませんが、同じ概念がグループ ID にも適用されます。

まず、ユーザー ID が 1001 の「marc」というユーザーとしてこれらのコマンドを実行します。

 marc@server:~$ echo $UID 1001

Dockerファイル:

 FROM ubuntu:latest RUN useradd -r -u 1001 -g appuser appuser USER appuser ENTRYPOINT [“sleep”, “infinity”]

建てる:

 marc@server:~$ docker build -t test . Sending build context to Docker daemon 14.34 kB Step 1/4 : FROM ubuntu:latest — -> f49eec89601e Step 2/4 : RUN useradd -r -u 1001 appuser — -> Running in 8c4c0a442ace — -> 6a81547f335e Removing intermediate container 8c4c0a442ace Step 3/4 : USER appuser — -> Running in acd9e30b4aba — -> fc1b765e227f Removing intermediate container acd9e30b4aba Step 4/4 : ENTRYPOINT sleep infinity — -> Running in a5710a32a8ed — -> fd1e2ab0fb75 Removing intermediate container a5710a32a8ed Successfully built fd1e2ab0fb75 marc@server:~$ docker run -d test 8ad0cd43592e6c4314775392fb3149015adc25deb22e5e5ea07203ff53038073 marc@server:~$ ps aux | grep sleep marc 16507 0.3 0.0 4380 668 ? Ss 20:02 0:00 sleep infinity marc@server:~$ docker exec -it 8ad0 /bin/bash appuser@8ad0cd43592e:/$ ps aux | grep sleep appuser 1 0.0 0.0 4380 668 ? Ss 20:02 0:00 sleep infinity

ここでは一体何が起こっているのでしょうか、そしてそれは何を意味するのでしょうか?私は、uid 1001 の「appuser」というユーザーを持つ Docker イメージを構築しました。テスト サーバーでは、uid 1001 の「marc」というアカウントも使用しています。コンテナを起動すると、Dockerfile に「USER appuser」という行が含まれていたため、sleep コマンドが appuser として実行されました。ただし、これは実際には appuser として実行されているわけではなく、Docker イメージで appuser として識別されるユーザーの uid として実行されています。

コンテナ外で実行されているプロセスを調べると、ユーザー「marc」にマップされていることがわかりますが、コンテナ内ではユーザー「appuser」にマップされています。これら 2 つのユーザー名は、実行コンテキストが認識しているユーザー名を 1001 にマップしているだけを示しています。

これはあまり重要ではありません。しかし、コンテナ内では、ユーザー「appuser」がコンテナ外のユーザー「marc」から権限と特権を取得したことを認識することが重要です。 Linux ホスト上のユーザー marc または uid 1001 に付与された権限は、コンテナー内の appuser にも付与されます。

コンテナのアクセス権限を制御する方法

もう 1 つのオプションは、Docker コンテナを実行するときにユーザー名またはユーザー ID とグループ名またはグループ ID を指定することです。

最初の例をもう一度使ってみましょう。

 marc@server:~$ docker run -d --user 1001 ubuntu:latest sleep infinity 84f436065c90ac5f59a2256e8a27237cf8d7849d18e39e5370c36f9554254e2b marc@server$ ps aux | grep sleep marc 17058 0.1 0.0 4380 664 ? Ss 21:23 0:00 sleep infinity

ここで何をしたのでしょうか?ユーザー 1001 として起動するコンテナーを作成しました。そのため、ps や top (またはほとんどの監視ツール) などのコマンドを実行すると、プロセスは「marc」ユーザーにマップされます。

興味深いことに、そのコンテナに ssh すると、1001 ユーザーのエントリが /etc/passwd ファイルに存在せず、「名前がありません」と表示されることがわかります。コンテナの bash プロンプトで。

 marc@server:~$ docker exec -it 84f43 /bin/bash I have no name!@84f436065c90:/$

コンテナを作成するときにユーザー フラグを指定すると、Dockerfile 内の値も上書きされることに注意することが重要です。 2番目の例を覚えていますか?当時、私は、uid がローカル ホスト上の異なるユーザー名にマップされている Dockerfile を使用していました。コマンドラインでユーザーフラグを使用して、「sleep infinity」プロセスを実行するコンテナを起動すると何が起こりますか?

 marc@server:$ docker run -d test 489a236261a0620e287e434ed1b15503c844648544694e538264e69d534d0d65 marc@server:~$ ps aux | grep sleep marc 17689 0.2 0.0 4380 680 ? Ss 21:28 0:00 sleep infinity marc@server:~$ docker run --user 0 -d test ac27849fcbce066bad37190b5bf6a46cf526f56d889af61e7a02c3726438fa7a marc@server:~$ ps aux | grep sleep marc 17689 0.0 0.0 4380 680 ? Ss 21:28 0:00 sleep infinity root 17783 0.3 0.0 4380 668 ? Ss 21:28 0:00 sleep infinity

上記の最後の例では、スリープ プロセスを実行するコンテナーが 2 つあることがわかります。1 つは「marc」、もう 1 つは「root」です。これは、2 番目のコマンドがコマンド ラインで --user フラグを渡すことによってユーザー ID を変更したためです。

要約する

これを調べてみると、制限された権限でコンテナを実行するすべての方法がホストのユーザー システムを利用していることがわかります。

  • コンテナ内のプロセスが既知の uid を使用して実行されている場合は、コンテナ内の uid のアクセスが制限されるようにホスト システムへのアクセスを制限するだけで済みます。
  • より良い解決策としては、--user を使用して既知の uid でコンテナを起動し (ユーザー名を使用することもできますが、これはホストのユーザー名システムで uid を提供するよりわかりやすい方法にすぎないことに注意してください)、コンテナを実行する uid にホストへのアクセスを制限することです。
  • コンテナはホストの uid とユーザー名 (および gid とグループ名) にマッピングされるため、コンテナ化されたプロセスを実行するユーザーを指定すると、プロセスがコンテナの内外で異なるユーザーによって所有されているように見えることがあります。

<<:  SaaS とオンプレミスの IT 管理プラットフォームの導入: 長所と短所

>>:  テスラがハッキングされた? Kubernetes クラスターを保護し、ハッカーの侵入を防ぐにはどうすればよいでしょうか?

推薦する

IoTがエッジコンピューティングへの入り口となる

ここ数年、IoT プラットフォームについては多くの議論が行われてきました。アナリストは、今後発展して...

タオバオオンラインストアの運営方法: 製品の位置付け

電子商取引税は多くのネットショップ経営者の頭上にぶら下がっているダモクレスの剣のようなもので、いつで...

Weiboマーケティングの3つの戦略についてお話しします

ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービスWeibo はネットユー...

ステーショングループを合理的に見てみましょう。無条件の成功はありません

独立したウェブマスターとしての私のキャリアは、ウェブサイト グループから始まり、ウェブサイト グルー...

Baidu では、サイト内検索の許可数を 1 日あたり 10,000 件に制限しています。これはあらゆる規模のサイトに適していますか?

最近、Baiduはサイト内検索権限を開始しましたが、大規模サイトと小規模サイトではまだ多くの違いがあ...

SEOERのオプションに関する簡単な説明

過去数日、グループに参加した友人の何人かが私に個人的に尋ねました。「王世凡、私の惨めなSEO生活はい...

サーバー側における高並列分散アーキテクチャの進化

1. 概要この記事では、Taobao を例に、同時ユーザー数が 1 億人から数千万に及ぶサーバー側ア...

チャネル運用の分析: 3つの主要要素 + 1つの主要コアポイント

インターネット環境においては、トラフィックこそが王様と言われており、トラフィックの入り口を奪取するこ...

ウェブサイトのプロモーションと最適化の本質「持続性」について簡単に説明します。

はじめに: メイクアップ写真ウェブサイトのプロモーションと最適化に2年近く携わってきて、私が得た最も...

ビューコンピューティングの背後にある技術アーキテクチャについて考える

データキャリアとコンピューティングパワーの配分は根本的な変化を遂げている動画や写真は強力な情報伝達能...

5省庁:ビットコインは通貨と同じ法的地位を持たないため、マネーロンダリングに注意

[要約] 中国人民銀行と他の 5 つの省庁は最近、「ビットコインのリスク防止に関する通知」を発行し、...

hostus-2g メモリ KVM/G ポート/アトランタ/月額 9 ドル (4g メモリ 15 ドル)

Hostusは2009年に設立されました。ホストキャットを見ると、ワンマンではないことがわかります。...

謝文:ビッグデータの時代には、少しの砂で塔が建てられ、少しの毛皮でコートが作られる

地球上のどこで石を拾っても鉄を見つけることができます。しかし、鉄鉱石が世界中どこにでもあると言うのは...

クラウド データベースの正しい選び方

近年、企業がローカルに展開されたデータをクラウドに移行する傾向が高まっています。しかし、企業はクラウ...

Yu Yongfu: 2013 年のモバイル インターネットはどこに向かうのでしょうか?

数日前、Geek Park Innovation Conference で、2013 年の起業家に向...