クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

安全なイメージ: 小さく、非 root、秘密なし

このレッスンのあとで: イメージを安全に出す条件を言い、危ない Dockerfile を直すことができる。

55分のレッスンコマンド6件Docker 入門ラボ:止まったサービスを直して、コンテナー、ログ、再起動を学ぶ

小さなサイトのサーバーの欠陥

だれかが、通販サイトのページを返すプログラムの欠陥を見つけました。そのプログラムに、好きなことをさせられます。

その先で何に届くかは、プログラムがだれとして動くかで決まります。イメージに何が入っているか、何が書かれているかでも決まります。

このレッスンのゴール

メモ

イメージを安全に出す条件を言い、危ない Dockerfile を直すことができる。

大事な言葉

ことばいみれい
rootシステムの何でも変えられるユーザーuid=0
非 root ユーザー権限が限られた、ふつうのユーザー
固定したタグ正確に1つの版を指すイメージのタグnginx:1.27-alpine
秘密プログラムだけが知るべきパスワードや鍵
攻撃面攻撃者が使えるかもしれない、イメージの中のすべて

学生が入力するセルは、このプレビューでは空白です。

できることの少ないユーザーで動かす

何も指定しないと、コンテナのプログラムは root で動きます。root は、コンテナが書き込めるファイルなら、マウントしたボリュームも含めて何でも変えられます。

非 root ユーザーにはできません。プログラムが攻撃されても、被害は小さくなります。ラボの2つの主なサービスを比べましょう。

web はだれとして動く?

コマンド
docker exec web id

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

cache はだれとして動く?

コマンド
docker exec cache id

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

cache に /etc へ書かせてみる

コマンド
docker exec cache touch /etc/probe

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

web に同じことをさせてみる

コマンド
docker exec web touch /etc/probe

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

Dockerfile でユーザーを作る

コード: bash
FROM python:3.12-alpine
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
RUN adduser -D -u 10001 shop
USER shop
CMD ["python", "app.py"]

よくある間違い

注意

コンテナは隔離されているから、中の root は気にしなくてよい、と考える人がいます。壁にも欠陥はあり、マウントしたボリュームは本物のデータです。ユーザーを作って USER で切り替えます。ラボの cache もそうしています。

中身が少ないほど、攻撃されにくい

イメージの中のプログラムは、欠陥がありうるものがもう1つ増えることです。道具は、攻撃者が使えるものがもう1つ増えることです。

Alpine のような軽いベースは、ずっと少ししか持ちません。どの版を受け取るかはタグが決めます。latest のようなタグは動きます。来月のビルドは別のイメージかもしれません。

例: 1つのイメージの2つのタグ

タグ試験用マシンでの大きさ意味
nginx:1.27284 MB下に完全なシステム
nginx:1.27-alpine76.8 MB下に小さなシステム
nginx:latest測っていませんビルド時にいちばん新しいもの

学生が入力するセルは、このプレビューでは空白です。

cache はどのタグに固定している?

コマンド
docker inspect --format '{{.Config.Image}}' cache

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

イメージに書いた秘密は残る

イメージは共有されます。レジストリに送られ、サーバーにコピーされ、同僚に渡されます。レイヤーの中にあるものは、一緒に行きます。

Dockerfile に書いたパスワードは、あとの手順でファイルを消しても、レイヤーに残り続けます。秘密はイメージの外に置き、コンテナの起動時に渡します。

秘密を書いた Dockerfile(まねしない)

コード: bash
FROM alpine:3.20
ENV API_KEY=abc123-not-real
RUN echo hello

例: 秘密が見えた場所

設定のしかた読み戻した場所出たもの
Dockerfile の ENVdocker history --no-truncENV API_KEY=abc123-not-real の行
コンテナ起動時の -edocker inspect の Config.Env一覧の中に DB_PASSWORD=hunter2
どちらでもないイメージにも設定にもなし実行時に渡した秘密

学生が入力するセルは、このプレビューでは空白です。

cache に渡されたものをすべて読む

コマンド
docker inspect --format '{{json .Config.Env}}' cache

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

もう一歩先へ

秘密を書いた Dockerfile を取り上げます。タグを固定し、ユーザーとして動き、秘密を持たないように書き直しましょう。

そのあと、課題の3つの関数を古い版と自分の版に実行します。新しい版は、何も指摘されないはずです。

このラボとソースについて: Docker 入門ラボ:止まったサービスを直して、コンテナー、ログ、再起動を学ぶ

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。