Docker imageからDockerfileを抽出する

## 目的
Pullしてきたイメージが中で何をしているのかを確認したい場合があるので、今回はその方法を備忘録として残しておく

## 方法1 (docker history)
```bash
docker history --no-trunc <image name>  | tac | tr -s ' ' | cut -d " " -f 5- | sed 's,^/bin/sh -c #(nop) ,,g' | sed 's,^/bin/sh -c,RUN,g' | sed 's, && ,\n  & ,g' | sed 's,\s*[0-9]*[\.]*[0-9]*[kMG]*B\s*$,,g' | head -n -1
```

例
```bash
root@shoma:/home/shoma/wireguard# docker history --no-trunc ghcr.io/linuxserver/wireguard  | tac | tr -s ' ' | cut -d " " -f 5- | sed 's,^/bin/sh -c #(nop) ,,g' | sed 's,^/bin/sh -c,RUN,g' | sed 's, && ,\n  & ,g' | sed 's,\s*[0-9]*[\.]*[0-9]*[kMG]*B\s*$,,g' | head -n -1
COPY /root-out/ / # buildkit 12.7MB buildkit.dockerfile.v0
ARG BUILD_DATE 0B buildkit.dockerfile.v0
ARG VERSION 0B buildkit.dockerfile.v0
ARG MODS_VERSION=v3 0B buildkit.dockerfile.v0
ARG PKG_INST_VERSION=v1 0B buildkit.dockerfile.v0
LABEL build_version=Linuxserver.io version:- c84a529a-ls18 Build-date:- 2023-09-02T13:27:56+00:00 0B buildkit.dockerfile.v0
LABEL maintainer=TheLamer 0B buildkit.dockerfile.v0
ADD https://raw.githubusercontent.com/linuxserver/docker-mods/mod-scripts/docker-mods.v3 /docker-mods # buildkit 18.3kB buildkit.dockerfile.v0
ADD https://raw.githubusercontent.com/linuxserver/docker-mods/mod-scripts/package-install.v1 /etc/s6-overlay/s6-rc.d/init-mods-package-install/run # buildkit 2.83kB buildkit.dockerfile.v0
ENV PS1=$(whoami)@$(hostname):$(pwd)\$ HOME=/root TERM=xterm S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 S6_VERBOSITY=1 S6_STAGE2_HOOK=/docker-mods VIRTUAL_ENV=/lsiopy PATH=/lsiopy/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 0B buildkit.dockerfile.v0
RUN |4 BUILD_DATE=2023-09-02T13:27:56+00:00 VERSION=c84a529a-ls18 MODS_VERSION=v3 PKG_INST_VERSION=v1 /bin/sh -c echo "**** install runtime packages ****"
   &&  apk add --no-cache alpine-release bash ca-certificates coreutils curl jq netcat-openbsd procps-ng shadow tzdata
   &&  echo "**** create abc user and make our folders ****"
   &&  groupmod -g 1000 users
   &&  useradd -u 911 -U -d /config -s /bin/false abc
   &&  usermod -G users abc
   &&  mkdir -p /app /config /defaults /lsiopy
   &&  echo "**** cleanup ****"
   &&  rm -rf /tmp/* # buildkit 12.7MB buildkit.dockerfile.v0
COPY root/ / # buildkit 5.48kB buildkit.dockerfile.v0
ENTRYPOINT ["/init"] 0B buildkit.dockerfile.v0
ENV LSIO_FIRST_PARTY=true 0B buildkit.dockerfile.v0
ARG BUILD_DATE 0B buildkit.dockerfile.v0
ARG VERSION 0B buildkit.dockerfile.v0
ARG WIREGUARD_RELEASE 0B buildkit.dockerfile.v0
LABEL build_version=Linuxserver.io version:- v1.0.20210914-ls4 Build-date:- 2023-09-07T11:18:48+00:00 0B buildkit.dockerfile.v0
LABEL maintainer=thespad 0B buildkit.dockerfile.v0
RUN |3 BUILD_DATE=2023-09-07T11:18:48+00:00 VERSION=v1.0.20210914-ls4 WIREGUARD_RELEASE= /bin/sh -c echo "**** install dependencies ****"
   &&  apk add --no-cache --virtual=build-dependencies build-base elfutils-dev gcc git linux-headers
   &&  apk add --no-cache bc coredns gnupg grep iproute2 iptables ip6tables iputils libcap-utils libqrencode net-tools openresolv perl
   &&  echo "wireguard" >> /etc/modules
   &&  echo "**** install wireguard-tools ****"
   &&  if [ -z ${WIREGUARD_RELEASE+x} ]; then WIREGUARD_RELEASE=$(curl -sX GET "https://api.github.com/repos/WireGuard/wireguard-tools/tags" | jq -r .[0].name); fi
   &&  cd /app
   &&  git clone https://git.zx2c4.com/wireguard-tools
   &&  cd wireguard-tools
   &&  git checkout "${WIREGUARD_RELEASE}"
   &&  sed -i 's|\[\[ $proto == -4 \]\]
   &&  cmd sysctl -q net\.ipv4\.conf\.all\.src_valid_mark=1|[[ $proto == -4 ]] \&\& [[ $(sysctl -n net.ipv4.conf.all.src_valid_mark) != 1 ]] \&\& cmd sysctl -q net.ipv4.conf.all.src_valid_mark=1|' src/wg-quick/linux.bash
   &&  make -C src -j$(nproc)
   &&  make -C src install
   &&  echo "**** clean up ****"
   &&  apk del --no-network build-dependencies
   &&  rm -rf /tmp/* # buildkit 116MB buildkit.dockerfile.v0
COPY /root / # buildkit 11.4kB buildkit.dockerfile.v0
EXPOSE map[51820/udp:{}] 0B buildkit.dockerfile.v0
```

## 方法２（Whaler）
Go言語が動くことが前提

https://github.com/P3GLEG/Whaler

インストール
```bash
go get -u github.com/P3GLEG/Whaler
cd ~/go/pkg/mod/github.com/!p3!g!l!e!g/!whaler@v0.0.0-20220625091030-bf1e0ec922d3#
go build .
install whaler /usr/local/bin
```

解析
```bash
docker pull ghcr.io/linuxserver/wireguard 
whaler ghcr.io/linuxserver/wireguard
```

結果
```bash
Analyzing ghcr.io/linuxserver/wireguard
Docker Version:
GraphDriver: overlay2
Environment Variables
|PATH=/lsiopy/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|PS1=$(whoami)@$(hostname):$(pwd)\$
|HOME=/root
|TERM=xterm
|S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0
|S6_VERBOSITY=1
|S6_STAGE2_HOOK=/docker-mods
|VIRTUAL_ENV=/lsiopy
|LSIO_FIRST_PARTY=true

Open Ports
|51820

Image user
|User is root

Potential secrets:
|Found match etc/apk/keys/alpine-devel@lists.alpinelinux.org-524d27bb.rsa.pub Possible public key \.pub$ 295fe25415450357b7c99bc267445e1f2b6685c97c8acb63c7f6ef623cca7dc9/layer.tar
|Found match etc/apk/keys/alpine-devel@lists.alpinelinux.org-58199dcc.rsa.pub Possible public key \.pub$ 295fe25415450357b7c99bc267445e1f2b6685c97c8acb63c7f6ef623cca7dc9/layer.tar
|Found match etc/apk/keys/alpine-devel@lists.alpinelinux.org-616a9724.rsa.pub Possible public key \.pub$ 295fe25415450357b7c99bc267445e1f2b6685c97c8acb63c7f6ef623cca7dc9/layer.tar
|Found match etc/apk/keys/alpine-devel@lists.alpinelinux.org-616adfeb.rsa.pub Possible public key \.pub$ 295fe25415450357b7c99bc267445e1f2b6685c97c8acb63c7f6ef623cca7dc9/layer.tar
|Found match etc/apk/keys/alpine-devel@lists.alpinelinux.org-616ae350.rsa.pub Possible public key \.pub$ 295fe25415450357b7c99bc267445e1f2b6685c97c8acb63c7f6ef623cca7dc9/layer.tar
|Found match etc/udhcpd.conf DHCP server configs dhcpd[^ ]*.conf 295fe25415450357b7c99bc267445e1f2b6685c97c8acb63c7f6ef623cca7dc9/layer.tar
Dockerfile:
ARG BUILD_DATE
ARG VERSION
ARG MODS_VERSION=v3
ARG PKG_INST_VERSION=v1
LABEL build_version=Linuxserver.io version:- c84a529a-ls18 Build-date:- 2023-09-02T13:27:56+00:00
LABEL maintainer=TheLamer
ADD https://raw.githubusercontent.com/linuxserver/docker-mods/mod-scripts/docker-mods.v3 /docker-mods # buildkit
        docker-mods

ADD https://raw.githubusercontent.com/linuxserver/docker-mods/mod-scripts/package-install.v1 /etc/s6-overlay/s6-rc.d/init-mods-package-install/run # buildkit
        etc/
        etc/s6-overlay/
        etc/s6-overlay/s6-rc.d/
        etc/s6-overlay/s6-rc.d/init-mods-package-install/
        etc/s6-overlay/s6-rc.d/init-mods-package-install/run

ENV PS1=$(whoami)@$(hostname):$(pwd)\$ HOME=/root TERM=xterm S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 S6_VERBOSITY=1 S6_STAGE2_HOOK=/docker-mods VIRTUAL_ENV=/lsiopy PATH=/lsiopy/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
RUN |4 BUILD_DATE=2023-09-02T13:27:56+00:00 VERSION=c84a529a-ls18 MODS_VERSION=v3 PKG_INST_VERSION=v1 RUN echo "**** install runtime packages ****"  \
        && apk add --no-cache alpine-release bash ca-certificates coreutils curl jq netcat-openbsd procps-ng shadow tzdata  \
        && echo "**** create abc user and make our folders ****"  \
        && groupmod -g 1000 users  \
        && useradd -u 911 -U -d /config -s /bin/false abc  \
        && usermod -G users abc  \
        && mkdir -p /app /config /defaults /lsiopy  \
        && echo "**** cleanup ****"  \
        && rm -rf /tmp/* # buildkit
COPY root/ / # buildkit
        etc/
        etc/s6-overlay/
        etc/s6-overlay/s6-rc.d/
        etc/s6-overlay/s6-rc.d/ci-service-check/
        etc/s6-overlay/s6-rc.d/ci-service-check/dependencies.d/
        etc/s6-overlay/s6-rc.d/ci-service-check/dependencies.d/legacy-services
        etc/s6-overlay/s6-rc.d/ci-service-check/type
        etc/s6-overlay/s6-rc.d/ci-service-check/up
        etc/s6-overlay/s6-rc.d/init-adduser/
        etc/s6-overlay/s6-rc.d/init-adduser/branding
        etc/s6-overlay/s6-rc.d/init-adduser/dependencies.d/
        etc/s6-overlay/s6-rc.d/init-adduser/dependencies.d/init-migrations
        etc/s6-overlay/s6-rc.d/init-adduser/run
        etc/s6-overlay/s6-rc.d/init-adduser/type
        etc/s6-overlay/s6-rc.d/init-adduser/up
        etc/s6-overlay/s6-rc.d/init-config/
        etc/s6-overlay/s6-rc.d/init-config/dependencies.d/
        etc/s6-overlay/s6-rc.d/init-config/dependencies.d/init-os-end
        etc/s6-overlay/s6-rc.d/init-config/type
        etc/s6-overlay/s6-rc.d/init-config/up
        etc/s6-overlay/s6-rc.d/init-config-end/
        etc/s6-overlay/s6-rc.d/init-config-end/dependencies.d/
        etc/s6-overlay/s6-rc.d/init-config-end/dependencies.d/init-config
        etc/s6-overlay/s6-rc.d/init-config-end/type
        etc/s6-overlay/s6-rc.d/init-config-end/up
        etc/s6-overlay/s6-rc.d/init-custom-files/
        etc/s6-overlay/s6-rc.d/init-custom-files/dependencies.d/
        etc/s6-overlay/s6-rc.d/init-custom-files/dependencies.d/init-mods-end
        etc/s6-overlay/s6-rc.d/init-custom-files/run
        etc/s6-overlay/s6-rc.d/init-custom-files/type
        etc/s6-overlay/s6-rc.d/init-custom-files/up
        etc/s6-overlay/s6-rc.d/init-envfile/
        etc/s6-overlay/s6-rc.d/init-envfile/run
        etc/s6-overlay/s6-rc.d/init-envfile/type
        etc/s6-overlay/s6-rc.d/init-envfile/up
        etc/s6-overlay/s6-rc.d/init-migrations/
        etc/s6-overlay/s6-rc.d/init-migrations/run
        etc/s6-overlay/s6-rc.d/init-migrations/type
        etc/s6-overlay/s6-rc.d/init-migrations/up
        etc/s6-overlay/s6-rc.d/init-mods/
        etc/s6-overlay/s6-rc.d/init-mods/dependencies.d/
        etc/s6-overlay/s6-rc.d/init-mods/dependencies.d/base
        etc/s6-overlay/s6-rc.d/init-mods/dependencies.d/init-config-end
        etc/s6-overlay/s6-rc.d/init-mods/type
        etc/s6-overlay/s6-rc.d/init-mods/up
        etc/s6-overlay/s6-rc.d/init-mods-end/
        etc/s6-overlay/s6-rc.d/init-mods-end/dependencies.d/
        etc/s6-overlay/s6-rc.d/init-mods-end/dependencies.d/init-mods
        etc/s6-overlay/s6-rc.d/init-mods-end/dependencies.d/init-mods-package-install
        etc/s6-overlay/s6-rc.d/init-mods-end/type
        etc/s6-overlay/s6-rc.d/init-mods-end/up
        etc/s6-overlay/s6-rc.d/init-mods-package-install/
        etc/s6-overlay/s6-rc.d/init-mods-package-install/dependencies.d/
        etc/s6-overlay/s6-rc.d/init-mods-package-install/dependencies.d/init-mods
        etc/s6-overlay/s6-rc.d/init-mods-package-install/type
        etc/s6-overlay/s6-rc.d/init-mods-package-install/up
        etc/s6-overlay/s6-rc.d/init-os-end/
        etc/s6-overlay/s6-rc.d/init-os-end/dependencies.d/
        etc/s6-overlay/s6-rc.d/init-os-end/dependencies.d/base
        etc/s6-overlay/s6-rc.d/init-os-end/dependencies.d/init-adduser
        etc/s6-overlay/s6-rc.d/init-os-end/dependencies.d/init-envfile
        etc/s6-overlay/s6-rc.d/init-os-end/dependencies.d/init-migrations
        etc/s6-overlay/s6-rc.d/init-os-end/type
        etc/s6-overlay/s6-rc.d/init-os-end/up
        etc/s6-overlay/s6-rc.d/init-services/
        etc/s6-overlay/s6-rc.d/init-services/dependencies.d/
        etc/s6-overlay/s6-rc.d/init-services/dependencies.d/init-custom-files
        etc/s6-overlay/s6-rc.d/init-services/dependencies.d/init-mods-end
        etc/s6-overlay/s6-rc.d/init-services/type
        etc/s6-overlay/s6-rc.d/init-services/up
        etc/s6-overlay/s6-rc.d/user/
        etc/s6-overlay/s6-rc.d/user/contents.d/
        etc/s6-overlay/s6-rc.d/user/contents.d/init-adduser
        etc/s6-overlay/s6-rc.d/user/contents.d/init-config
        etc/s6-overlay/s6-rc.d/user/contents.d/init-config-end
        etc/s6-overlay/s6-rc.d/user/contents.d/init-custom-files
        etc/s6-overlay/s6-rc.d/user/contents.d/init-envfile
        etc/s6-overlay/s6-rc.d/user/contents.d/init-migrations
        etc/s6-overlay/s6-rc.d/user/contents.d/init-mods
        etc/s6-overlay/s6-rc.d/user/contents.d/init-mods-end
        etc/s6-overlay/s6-rc.d/user/contents.d/init-mods-package-install
        etc/s6-overlay/s6-rc.d/user/contents.d/init-os-end
        etc/s6-overlay/s6-rc.d/user/contents.d/init-services
        etc/s6-overlay/s6-rc.d/user2/
        etc/s6-overlay/s6-rc.d/user2/contents.d/
        etc/s6-overlay/s6-rc.d/user2/contents.d/ci-service-check

ENTRYPOINT ["/init"]
ENV LSIO_FIRST_PARTY=true
ARG BUILD_DATE
ARG VERSION
ARG WIREGUARD_RELEASE
LABEL build_version=Linuxserver.io version:- v1.0.20210914-ls4 Build-date:- 2023-09-07T11:18:48+00:00
LABEL maintainer=thespad
RUN |3 BUILD_DATE=2023-09-07T11:18:48+00:00 VERSION=v1.0.20210914-ls4 WIREGUARD_RELEASE= RUN echo "**** install dependencies ****"  \
        && apk add --no-cache --virtual=build-dependencies build-base elfutils-dev gcc git linux-headers  \
        && apk add --no-cache bc coredns gnupg grep iproute2 iptables ip6tables iputils libcap-utils libqrencode net-tools openresolv perl  \
        && echo "wireguard" >> /etc/modules  \
        && echo "**** install wireguard-tools ****"  \
        && if [ -z ${WIREGUARD_RELEASE+x} ]; then WIREGUARD_RELEASE=$(curl -sX GET "https://api.github.com/repos/WireGuard/wireguard-tools/tags" | jq -r .[0].name); fi  \
        && cd /app  \
        && git clone https://git.zx2c4.com/wireguard-tools  \
        && cd wireguard-tools  \
        && git checkout "${WIREGUARD_RELEASE}"  \
        && sed -i 's|\[\[ $proto == -4 \]\]  \
        && cmd sysctl -q net\.ipv4\.conf\.all\.src_valid_mark=1|[[ $proto == -4 ]] \&\& [[ $(sysctl -n net.ipv4.conf.all.src_valid_mark) != 1 ]] \&\& cmd sysctl -q net.ipv4.conf.all.src_valid_mark=1|' src/wg-quick/linux.bash  \
        && make -C src -j$(nproc)  \
        && make -C src install  \
        && echo "**** clean up ****"  \
        && apk del --no-network build-dependencies  \
        && rm -rf /tmp/* # buildkit
COPY /root / # buildkit
        app/
        app/show-peer
        defaults/
        defaults/Corefile
        defaults/peer.conf
        defaults/server.conf
        donate.txt
        etc/
        etc/s6-overlay/
        etc/s6-overlay/s6-rc.d/
        etc/s6-overlay/s6-rc.d/init-config-end/
        etc/s6-overlay/s6-rc.d/init-config-end/dependencies.d/
        etc/s6-overlay/s6-rc.d/init-config-end/dependencies.d/init-wireguard-confs
        etc/s6-overlay/s6-rc.d/init-wireguard-confs/
        etc/s6-overlay/s6-rc.d/init-wireguard-confs/dependencies.d/
        etc/s6-overlay/s6-rc.d/init-wireguard-confs/dependencies.d/init-wireguard-module
        etc/s6-overlay/s6-rc.d/init-wireguard-confs/run
        etc/s6-overlay/s6-rc.d/init-wireguard-confs/type
        etc/s6-overlay/s6-rc.d/init-wireguard-confs/up
        etc/s6-overlay/s6-rc.d/init-wireguard-module/
        etc/s6-overlay/s6-rc.d/init-wireguard-module/dependencies.d/
        etc/s6-overlay/s6-rc.d/init-wireguard-module/dependencies.d/init-config
        etc/s6-overlay/s6-rc.d/init-wireguard-module/run
        etc/s6-overlay/s6-rc.d/init-wireguard-module/type
        etc/s6-overlay/s6-rc.d/init-wireguard-module/up
        etc/s6-overlay/s6-rc.d/svc-coredns/
        etc/s6-overlay/s6-rc.d/svc-coredns/dependencies.d/
        etc/s6-overlay/s6-rc.d/svc-coredns/dependencies.d/init-services
        etc/s6-overlay/s6-rc.d/svc-coredns/notification-fd
        etc/s6-overlay/s6-rc.d/svc-coredns/run
        etc/s6-overlay/s6-rc.d/svc-coredns/type
        etc/s6-overlay/s6-rc.d/svc-wireguard/
        etc/s6-overlay/s6-rc.d/svc-wireguard/dependencies.d/
        etc/s6-overlay/s6-rc.d/svc-wireguard/dependencies.d/svc-coredns
        etc/s6-overlay/s6-rc.d/svc-wireguard/down
        etc/s6-overlay/s6-rc.d/svc-wireguard/finish
        etc/s6-overlay/s6-rc.d/svc-wireguard/run
        etc/s6-overlay/s6-rc.d/svc-wireguard/type
        etc/s6-overlay/s6-rc.d/svc-wireguard/up
        etc/s6-overlay/s6-rc.d/user/
        etc/s6-overlay/s6-rc.d/user/contents.d/
        etc/s6-overlay/s6-rc.d/user/contents.d/init-wireguard-confs
        etc/s6-overlay/s6-rc.d/user/contents.d/init-wireguard-module
        etc/s6-overlay/s6-rc.d/user/contents.d/svc-coredns
        etc/s6-overlay/s6-rc.d/user/contents.d/svc-wireguard

EXPOSE map[51820/udp:{}]
```