一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

云服務器|WEB服務器|FTP服務器|郵件服務器|虛擬主機|服務器安全|DNS服務器|服務器知識|Nginx|IIS|Tomcat|

服務器之家 - 服務器技術 - 服務器知識 - 一次 Docker 鏡像的逆向工程

一次 Docker 鏡像的逆向工程

2021-04-03 01:44Linux中國Simon Arneaud 服務器知識

Docker 鏡像的格式比想象的透明多了。雖然還需要做一些偵查工作,但只要解剖一個鏡像文件,就能發現很多東西。

一次 Docker 鏡像的逆向工程

這要從一次咨詢的失誤說起:政府組織 A 讓政府組織 B 開發一個 Web 應用程序。政府機構 B 把部分工作外包給某個人。后來,項目的托管和維護被外包給一家私人公司 C。C 公司發現,之前外包的人(已經離開很久了)構建了一個自定義的 Docker 鏡像,并將其成為系統構建的依賴項,但這個人沒有提交原始的 Dockerfile。C 公司有合同義務管理這個 Docker 鏡像,可是他們他們沒有源代碼。C 公司偶爾叫我進去做各種工作,所以處理一些關于這個神秘 Docker 鏡像的事情就成了我的工作。

幸運的是,Docker 鏡像的格式比想象的透明多了。雖然還需要做一些偵查工作,但只要解剖一個鏡像文件,就能發現很多東西。例如,這里有一個 Prettier 代碼格式化 的鏡像可供快速瀏覽。

首先,讓 Docker 守護進程daemon拉取鏡像,然后將鏡像提取到文件中:

  1. docker pull tmknom/prettier:2.0.5
  2. docker save tmknom/prettier:2.0.5 > prettier.tar

是的,該文件只是一個典型 tarball 格式的歸檔文件:

  1. $ tar xvf prettier.tar
  2. 6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/
  3. 6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/VERSION
  4. 6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/json
  5. 6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/layer.tar
  6. 88f38be28f05f38dba94ce0c1328ebe2b963b65848ab96594f8172a9c3b0f25b.json
  7. a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/
  8. a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/VERSION
  9. a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/json
  10. a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/layer.tar
  11. d4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/
  12. d4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/VERSION
  13. d4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/json
  14. d4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/layer.tar
  15. manifest.json
  16. repositories

如你所見,Docker 在命名時經常使用哈希hash。我們看看 manifest.json。它是以難以閱讀的壓縮 JSON 寫的,不過 JSON 瑞士軍刀 jq 可以很好地打印 JSON:

  1. $ jq . manifest.json
  2. [
  3. {
  4. "Config": "88f38be28f05f38dba94ce0c1328ebe2b963b65848ab96594f8172a9c3b0f25b.json",
  5. "RepoTags": [
  6. "tmknom/prettier:2.0.5"
  7. ],
  8. "Layers": [
  9. "a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/layer.tar",
  10. "d4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/layer.tar",
  11. "6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/layer.tar"
  12. ]
  13. }
  14. ]

請注意,這三個Layer對應三個以哈希命名的目錄。我們以后再看。現在,讓我們看看 Config 鍵指向的 JSON 文件。它有點長,所以我只在這里轉儲第一部分:

  1. $ jq . 88f38be28f05f38dba94ce0c1328ebe2b963b65848ab96594f8172a9c3b0f25b.json | head -n 20
  2. {
  3. "architecture": "amd64",
  4. "config": {
  5. "Hostname": "",
  6. "Domainname": "",
  7. "User": "",
  8. "AttachStdin": false,
  9. "AttachStdout": false,
  10. "AttachStderr": false,
  11. "Tty": false,
  12. "OpenStdin": false,
  13. "StdinOnce": false,
  14. "Env": [
  15. "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  16. ],
  17. "Cmd": [
  18. "--help"
  19. ],
  20. "ArgsEscaped": true,
  21. "Image": "sha256:93e72874b338c1e0734025e1d8ebe259d4f16265dc2840f88c4c754e1c01ba0a",

最重要的是 history 列表,它列出了鏡像中的每一層。Docker 鏡像由這些層堆疊而成。Dockerfile 中幾乎每條命令都會變成一個層,描述該命令對鏡像所做的更改。如果你執行 RUN script.sh 命令創建了 really_big_file,然后用 RUN rm really_big_file 命令刪除文件,Docker 鏡像實際生成兩層:一個包含 really_big_file,一個包含 .wh.really_big_file 記錄來刪除它。整個鏡像文件大小不變。這就是為什么你會經常看到像 RUN script.sh && rm really_big_file 這樣的 Dockerfile 命令鏈接在一起——它保障所有更改都合并到一層中。

以下是該 Docker 鏡像中記錄的所有層。注意,大多數層不改變文件系統鏡像,并且 empty_layer 標記為 true。以下只有三個層是非空的,與我們之前描述的相符。

  1. $ jq .history 88f38be28f05f38dba94ce0c1328ebe2b963b65848ab96594f8172a9c3b0f25b.json
  2. [
  3. {
  4. "created": "2020-04-24T01:05:03.608058404Z",
  5. "created_by": "/bin/sh -c #(nop) ADD file:b91adb67b670d3a6ff9463e48b7def903ed516be66fc4282d22c53e41512be49 in / "
  6. },
  7. {
  8. "created": "2020-04-24T01:05:03.92860976Z",
  9. "created_by": "/bin/sh -c #(nop) CMD [\"/bin/sh\"]",
  10. "empty_layer": true
  11. },
  12. {
  13. "created": "2020-04-29T06:34:06.617130538Z",
  14. "created_by": "/bin/sh -c #(nop) ARG BUILD_DATE",
  15. "empty_layer": true
  16. },
  17. {
  18. "created": "2020-04-29T06:34:07.020521808Z",
  19. "created_by": "/bin/sh -c #(nop) ARG VCS_REF",
  20. "empty_layer": true
  21. },
  22. {
  23. "created": "2020-04-29T06:34:07.36915054Z",
  24. "created_by": "/bin/sh -c #(nop) ARG VERSION",
  25. "empty_layer": true
  26. },
  27. {
  28. "created": "2020-04-29T06:34:07.708820086Z",
  29. "created_by": "/bin/sh -c #(nop) ARG REPO_NAME",
  30. "empty_layer": true
  31. },
  32. {
  33. "created": "2020-04-29T06:34:08.06429638Z",
  34. "created_by": "/bin/sh -c #(nop) LABEL org.label-schema.vendor=tmknom org.label-schema.name=tmknom/prettier org.label-schema.description=Prettier is an opinionated code formatter. org.label-schema.build-date=2020-04-29T06:34:01Z org
  35. .label-schema.version=2.0.5 org.label-schema.vcs-ref=35d2587 org.label-schema.vcs-url=https://github.com/tmknom/prettier org.label-schema.usage=https://github.com/tmknom/prettier/blob/master/README.md#usage org.label-schema.docker.cmd=do
  36. cker run --rm -v $PWD:/work tmknom/prettier --parser=markdown --write '**/*.md' org.label-schema.schema-version=1.0",
  37. "empty_layer": true
  38. },
  39. {
  40. "created": "2020-04-29T06:34:08.511269907Z",
  41. "created_by": "/bin/sh -c #(nop) ARG NODEJS_VERSION=12.15.0-r1",
  42. "empty_layer": true
  43. },
  44. {
  45. "created": "2020-04-29T06:34:08.775876657Z",
  46. "created_by": "/bin/sh -c #(nop) ARG PRETTIER_VERSION",
  47. "empty_layer": true
  48. },
  49. {
  50. "created": "2020-04-29T06:34:26.399622951Z",
  51. "created_by": "|6 BUILD_DATE=2020-04-29T06:34:01Z NODEJS_VERSION=12.15.0-r1 PRETTIER_VERSION=2.0.5 REPO_NAME=tmknom/prettier VCS_REF=35d2587 VERSION=2.0.5 /bin/sh -c set -x && apk add --no-cache nodejs=${NODEJS_VERSION} nodejs-np
  52. m=${NODEJS_VERSION} && npm install -g prettier@${PRETTIER_VERSION} && npm cache clean --force && apk del nodejs-npm"
  53. },
  54. {
  55. "created": "2020-04-29T06:34:26.764034848Z",
  56. "created_by": "/bin/sh -c #(nop) WORKDIR /work"
  57. },
  58. {
  59. "created": "2020-04-29T06:34:27.092671047Z",
  60. "created_by": "/bin/sh -c #(nop) ENTRYPOINT [\"/usr/bin/prettier\"]",
  61. "empty_layer": true
  62. },
  63. {
  64. "created": "2020-04-29T06:34:27.406606712Z",
  65. "created_by": "/bin/sh -c #(nop) CMD [\"--help\"]",
  66. "empty_layer": true
  67. }
  68. ]

太棒了!所有的命令都在 created_by 字段中,我們幾乎可以用這些命令重建 Dockerfile。但不是完全可以。最上面的 ADD 命令實際上沒有給我們需要添加的文件。COPY 命令也沒有全部信息。我們還失去了 FROM 語句,因為它們擴展成了從基礎 Docker 鏡像繼承的所有層。

我們可以通過查看時間戳timestamp,按 Dockerfile 對層進行分組。大多數層的時間戳相差不到一分鐘,代表每一層構建所需的時間。但是前兩層是 2020-04-24,其余的是 2020-04-29。這是因為前兩層來自一個基礎 Docker 鏡像。理想情況下,我們可以找出一個 FROM 命令來獲得這個鏡像,這樣我們就有了一個可維護的 Dockerfile。

manifest.json 展示第一個非空層是 a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/layer.tar。讓我們看看它:

  1. $ cd a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/
  2. $ tar tf layer.tf | head
  3. bin/
  4. bin/arch
  5. bin/ash
  6. bin/base64
  7. bin/bbconfig
  8. bin/busybox
  9. bin/cat
  10. bin/chgrp
  11. bin/chmod
  12. bin/chown

看起來它可能是一個操作系統operating system基礎鏡像,這也是你期望從典型 Dockerfile 中看到的。Tarball 中有 488 個條目,如果你瀏覽一下,就會發現一些有趣的條目:

  1. ...
  2. dev/
  3. etc/
  4. etc/alpine-release
  5. etc/apk/
  6. etc/apk/arch
  7. etc/apk/keys/
  8. etc/apk/keys/alpine-devel@lists.alpinelinux.org-4a6a0840.rsa.pub
  9. etc/apk/keys/alpine-devel@lists.alpinelinux.org-5243ef4b.rsa.pub
  10. etc/apk/keys/alpine-devel@lists.alpinelinux.org-5261cecb.rsa.pub
  11. etc/apk/protected_paths.d/
  12. etc/apk/repositories
  13. etc/apk/world
  14. etc/conf.d/
  15. ...

果不其然,這是一個 Alpine 鏡像,如果你注意到其他層使用 apk 命令安裝軟件包,你可能已經猜到了。讓我們解壓 tarball 看看:

  1. $ mkdir files
  2. $ cd files
  3. $ tar xf ../layer.tar
  4. $ ls
  5. bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
  6. $ cat etc/alpine-release
  7. 3.11.6

如果你拉取、解壓 alpine:3.11.6,你會發現里面有一個非空層,layer.tar 與 Prettier 鏡像基礎層中的 layer.tar 是一樣的。

出于興趣,另外兩個非空層是什么?第二層是包含 Prettier 安裝包的主層。它有 528 個條目,包含 Prettier、一堆依賴項和證書更新:

  1. ...
  2. usr/lib/libuv.so.1
  3. usr/lib/libuv.so.1.0.0
  4. usr/lib/node_modules/
  5. usr/lib/node_modules/prettier/
  6. usr/lib/node_modules/prettier/LICENSE
  7. usr/lib/node_modules/prettier/README.md
  8. usr/lib/node_modules/prettier/bin-prettier.js
  9. usr/lib/node_modules/prettier/doc.js
  10. usr/lib/node_modules/prettier/index.js
  11. usr/lib/node_modules/prettier/package.json
  12. usr/lib/node_modules/prettier/parser-angular.js
  13. usr/lib/node_modules/prettier/parser-babel.js
  14. usr/lib/node_modules/prettier/parser-flow.js
  15. usr/lib/node_modules/prettier/parser-glimmer.js
  16. usr/lib/node_modules/prettier/parser-graphql.js
  17. usr/lib/node_modules/prettier/parser-html.js
  18. usr/lib/node_modules/prettier/parser-markdown.js
  19. usr/lib/node_modules/prettier/parser-postcss.js
  20. usr/lib/node_modules/prettier/parser-typescript.js
  21. usr/lib/node_modules/prettier/parser-yaml.js
  22. usr/lib/node_modules/prettier/standalone.js
  23. usr/lib/node_modules/prettier/third-party.js
  24. usr/local/
  25. usr/local/share/
  26. usr/local/share/ca-certificates/
  27. usr/sbin/
  28. usr/sbin/update-ca-certificates
  29. usr/share/
  30. usr/share/ca-certificates/
  31. usr/share/ca-certificates/mozilla/
  32. usr/share/ca-certificates/mozilla/ACCVRAIZ1.crt
  33. usr/share/ca-certificates/mozilla/AC_RAIZ_FNMT-RCM.crt
  34. usr/share/ca-certificates/mozilla/Actalis_Authentication_Root_CA.crt
  35. ...

第三層由 WORKDIR /work 命令創建,它只包含一個條目:

  1. $ tar tf 6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/layer.tar
  2. work/

原始 Dockerfile 在 Prettier 的 git 倉庫中。

原文地址:https://linux.cn/article-13258-1.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产农村一级特黄α真人毛片 | 蜜桃成熟3在线观看 | 日韩视频一 | 欧美日韩综合一区 | 日韩一区在线观看 | 亚洲成av人片在线观看天堂无码 | 国产1区精品 | 色多多视频网站 | 国产精品永久免费10000 | 免费成年网站 | 亚洲29p| 成人国产在线播放 | 美国美女hd18 | 天天欲色成人综合网站 | 国产图片综合区 | 成年无限观看onlyfans | 四虎2021地址入口 | 日韩美一区二区三区 | 成人精品第一区二区三区 | 亚洲人成网站在线观看90影院 | 满溢游泳池免费土豪全集下拉版 | 亚洲精品资源在线 | 亚洲国产一区二区三区青草影视 | 国产成人精品s8sp视频 | 丁香六月婷婷激情 | 青丝视频免费版在线看 | 精品视频在线免费 | 欧美亚洲另类在线观看 | 亚洲国产精品91 | 边摸边吃奶又黄激烈视频韩国 | 国产福利微拍精品一区二区 | 国产极品美女在线 | 九九国产在线 | 色悠久久久| 久久久精品免费免费直播 | 欧洲另类一二三四区 | 九草在线视频 | 好吊色网站 | 欧美人畜 | 车上小婕子系列辣文小说 | 欧美日韩1区2区 |