イメージレイヤへの機密情報の保持

Docker イメージは OverlayFS のようにレイヤが存在し、ベースとなる OS レイヤに対してアプリケーションやライブラリを追加されたものになっています。

例えば次のような Dockerfile を用意しビルドします。

$ cat Dockerfile
FROM alpine:latest
RUN echo "secret" > /secret.txt
RUN rm /secret.txt

$ docker build -t test .
Sending build context to Docker daemon  10.61MB
Step 1/3 : FROM alpine:latest
 ---> d6e46aa2470d
Step 2/3 : RUN echo "secret" > /secret.txt
 ---> Running in 32f150d1804c
Removing intermediate container 32f150d1804c
 ---> 2cac5efedab4
Step 3/3 : RUN rm /secret.txt
 ---> Running in be0569fd1744
Removing intermediate container be0569fd1744
 ---> b29dd8898773
Successfully built b29dd8898773
Successfully tagged test:latest

この Dockerfile は3つのレイヤで構成されています。

  • Layer 1 ... FROM alpine:latest
  • Layer 2 ... RUN echo "secret" > /secret.txt
  • Layer 3 ... RUN rm /secret.txt

より視覚的に確認するために dive を使ってみると、確かに3つのレイヤであることを確認できます。1

$ dive test
┃ ● Layers ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │ Current Layer Contents ├────────────────────
Cmp   Size  Command                            ├── bin
    5.6 MB  FROM b1c62b187dcd114               │   ├── arch → /bin/busybox
       7 B  echo "secret" > /secret.txt        │   ├── ash → /bin/busybox
       0 B  rm /secret.txt                     │   ├── base64 → /bin/busybox
                                               │   ├── bbconfig → /bin/busybox
│ Layer Details ├───────────────────────────── │   ├── busybox
                                               │   ├── cat → /bin/busybox
Tags:   (unavailable)                          │   ├── chgrp → /bin/busybox
Id:     b1c62b187dcd114a7252e45a4f03577549d822 │   ├── chmod → /bin/busybox
77149b5467c73eefaa956260bd                     │   ├── chown → /bin/busybox
Digest: sha256:ace0eda3e3be35a979cec764a3321b4 │   ├── conspy → /bin/busybox
c7d0b9e4bb3094d20d3ff6782961a8d54              │   ├── cp → /bin/busybox
Command:                                       │   ├── date → /bin/busybox
#(nop) ADD file:f17f65714f703db9012f00e5ec98d0 │   ├── dd → /bin/busybox
b2541ff6147c2633f7ab9ba659d0c507f4 in /        │   ├── df → /bin/busybox
                                               │   ├── dmesg → /bin/busybox
│ Image Details ├───────────────────────────── │   ├── dnsdomainname → /bin/busybox
                                               │   ├── dumpkmap → /bin/busybox
                                               │   ├── echo → /bin/busybox
Total Image size: 5.6 MB                       │   ├── ed → /bin/busybox
Potential wasted space: 7 B                    │   ├── egrep → /bin/busybox
Image efficiency score: 99 %                   │   ├── false → /bin/busybox
                                               │   ├── fatattr → /bin/busybox

イメージは各レイヤを保持しているため、特定のレイヤを抽出することができます。
つまり、rm /secret.txt のように Dockerfile 内で機密情報を削除している場合でも、その機密情報を取り出すことが可能です。

$ docker save test > test.tar
$ mkdir test
$ cd test
~/test$ tar -xf ../test.tar
~/test$ ls
b1c62b187dcd114a7252e45a4f03577549d82277149b5467c73eefaa956260bd       b6433cc45f11a118c68ef34b9b3192f7c3514ee1a36c85d26df80122d058af4a  manifest.json
b29dd88987735c67e31b37de3c0c44abf656b42e6ce396defbfd967ba772e027.json  c8e83ef6a497050f640412539ecd335c4f7cf72808a75aea4ef1d0e04bb28156  repositories

$ cat b29*.json | jq
"history": [
    {
      "created": "2020-10-22T02:19:24.33416307Z",
      "created_by": "/bin/sh -c #(nop) ADD file:f17f65714f703db9012f00e5ec98d0b2541ff6147c2633f7ab9ba659d0c507f4 in / "
    },
    {
      "created": "2020-10-22T02:19:24.499382102Z",
      "created_by": "/bin/sh -c #(nop)  CMD [\"/bin/sh\"]",
      "empty_layer": true
    },
    {
      "created": "2020-11-02T09:05:38.780508124Z",
      "created_by": "/bin/sh -c echo \"secret\" > /secret.txt"
    },
    {
      "created": "2020-11-02T09:05:39.890868911Z",
      "created_by": "/bin/sh -c rm /secret.txt"
    }

$ cat manifest.json | jq
...
    "Layers": [
      "b1c62b187dcd114a7252e45a4f03577549d82277149b5467c73eefaa956260bd/layer.tar",
      "c8e83ef6a497050f640412539ecd335c4f7cf72808a75aea4ef1d0e04bb28156/layer.tar",
      "b6433cc45f11a118c68ef34b9b3192f7c3514ee1a36c85d26df80122d058af4a/layer.tar"
...

$ tar xf c8e83ef6a497050f640412539ecd335c4f7cf72808a75aea4ef1d0e04bb28156/layer.tar
$ cat secret.txt
secret

上記のようなケースを防ぐために、機密情報は環境変数で渡したりするようにしましょう。23


1. https://github.com/wagoodman/dive
2. https://docs.docker.com/engine/swarm/secrets/
3. https://docs.docker.com/develop/develop-images/build_enhancements/

results matching ""

    No results matching ""