状況
非公開リポジトリを取得するため、Dockerfile に SSH の鍵を入れている。作成者は「最後に消しているので問題ない」と言う。
このレビューで最初に指摘すべき点は?
FROM alpine:3.20COPY id_ed25519 /root/.ssh/id_ed25519RUN apk add git openssh && git clone git@github.com:example/lib.git /srcRUN rm /root/.ssh/id_ed25519正答
- known_hosts が無いので、
git cloneがホスト鍵の確認で失敗する - 鍵のパーミッションを 600 にしないと、ssh が鍵の使用を拒否する
- COPY ではなく ADD を使えば、ビルド後に鍵が自動で削除される
- 鍵は COPY した層に残り、後の RUN rm では消えない。シークレットで渡す
解説
イメージは命令ごとの層を重ねたもので、RUN rm は「消した」という変更を新しい層に足すだけで、COPY した層の中の鍵はそのまま残る。イメージを pull できる人は、docker save などで層を取り出して鍵を読める。非公開リポジトリの取得には RUN --mount=type=ssh で SSH エージェントを渡すか --mount=type=secret を使えば、鍵はその RUN の間だけ見え、層に残らない。known_hosts やパーミッションの問題はビルドが失敗して気づけるが、鍵の漏えいは気づかないまま広がる。ADD にも鍵を自動で消す機能は無い。
参考: docs.docker.com
この問題を含む Docker のテストを制限時間つきで解く
Dockerクイズへ