基于Docker搭建漏洞驗證環(huán)境操作指導(dǎo) 冀膝,以下介紹了本地鏡像創(chuàng)建充活,基于Dockerfile文件創(chuàng)建蝌矛,基于Docker-compose創(chuàng)建并管理工程贰逾。
1. 創(chuàng)建本地Docker鏡像
本次的示例是通過ubuntu基礎(chǔ)鏡像,安裝配置Java環(huán)境师溅,并重新打包為本地docker鏡像茅信,實現(xiàn)鏡像的保存、導(dǎo)入墓臭、刪除蘸鲸、運行。
1. 安裝基礎(chǔ)鏡像ubuntu
在創(chuàng)建docker基礎(chǔ)鏡像時窿锉,通常會選擇一個基礎(chǔ)鏡像酌摇,在基礎(chǔ)鏡像上進(jìn)行修改和配置,增加自己需要的運行環(huán)境嗡载,重新打包為docker鏡像窑多,以后直接使用自行打包的docker鏡像。
docker run -it ubuntu
命令執(zhí)行完成后洼滚,我們會直接進(jìn)入docker的bash終端埂息,干凈的ubuntu中是不存在jdk的,運行以下命令檢查:
java -version
bash: java: Command not found
2. 進(jìn)入ubuntu鏡像shell安裝JDK
apt-get install default-jdk //安裝jdk
java -version //檢查安裝的版本
whereis java //獲取安裝的路徑
JAVA_HOME=/usr/bin/java;export JAVA_HOME //配置java_home環(huán)境變量
echo $JAVA_HOME //檢查環(huán)境變量結(jié)果
exit //退出docker ubuntu shell 容器
3. docker commit 創(chuàng)建本地鏡像
通過docker ps -a 找到ubuntu鏡像的唯一ID,在以下命令中替換ID值千康。
使用commit命令將容器里的所有修改提交到本地庫中享幽,形成以一個全新的鏡像,會返回新鏡像的完整ID:
docker commit -m "ubuntu jdk" ID vulenv/locubuntu:jdk
- 完整ID可以通過docker ps -l -q(用于獲取最近創(chuàng)建的容器ID)命令得到
- -m:描述我們此次創(chuàng)建image的信息
- --author:用來指定作者
- ID:被修改的基礎(chǔ)鏡像ID
- vulenv/locubuntu:jdk :倉庫名/鏡像名:TAG名
通過docker pimages查看創(chuàng)建的本地鏡像:
docker images
4. docker save 導(dǎo)出保存本地鏡像
docker save -o vulenv-locubuntu-jdk.tar vulenv/locubuntu:jdk
- -o:指定保存的鏡像的名字拾弃,vulenv-locubuntu-jdk.tar
- vulenv/locubuntu:jdk : 要保存的鏡像名稱
- 導(dǎo)出鏡像默認(rèn)在當(dāng)前目錄下
4. docker load導(dǎo)入本地鏡像
在該環(huán)境下需要先刪除已有的鏡像:
docker rmi -f ID //刪除已有的鏡像
docker images //檢查鏡像是否刪除
導(dǎo)入本地鏡像:
docker load --input vulenv-locubuntu-jdk.tar
5. docker start 運行鏡像
docker start ID
docker exec -it ID
java -version //檢查java
docker run -it vulenv/locubuntu:jdk //直接進(jìn)入bash
2. Dockerfile創(chuàng)建鏡像
本示例基于本地鏡像vulenv/locubuntu:jdk值桩,創(chuàng)建tomcat-examples漏洞鏡像。
1. Dockfile詳解
從docker commit
創(chuàng)建本地鏡像可以了解到豪椿,鏡像的定制實際上就是定制每一層所添加的配置奔坟、文件。我們將每一層的修改搭盾、安裝咳秉、構(gòu)建、操作命令寫入一個腳本鸯隅,使用這個腳本來構(gòu)建滴某、定制鏡像,那么我們就可以解決無法重復(fù)使用滋迈、鏡像透明性、體積等問題户誓,這個腳本就是Dockfile.
Dockerfile 是一個文本文件饼灿,其內(nèi)包含了一條條的 指令(Instruction),每一條指令構(gòu)建一層帝美,因此每一條指令的內(nèi)容碍彭,就是描述該層應(yīng)當(dāng)如何構(gòu)建。
指令格式:
- 注釋和指令注釋以井號開頭悼潭,后面跟上信息
- 指令以大寫的指令名開頭庇忌,后面跟上參數(shù)
FROM:指定基礎(chǔ)鏡像,必須為第一個命令
FROM <IMAGE>
FROM <IMAGE>:<TAG>
MAINTAINER: 維護(hù)者信息舰褪,所有者和聯(lián)系人信息
MAINTAINER <NAME> <email>
RUN:構(gòu)建鏡像時執(zhí)行的命令
RUN <command> (shell模式)
RUN [ "executable", "param1", "param2" ] (exec模式)
RUN yum install httpd && yum install ftp //這樣構(gòu)建減少產(chǎn)生中間層鏡像
ADD:將本地文件添加到容器中皆疹,tar類型文件會自動解壓(網(wǎng)絡(luò)壓縮資源不會被解壓),可以訪問網(wǎng)絡(luò)資源占拍,類似wget
COPY:功能類似ADD略就,但是是不會自動解壓文件,也不能訪問網(wǎng)絡(luò)資源
CMD:構(gòu)建容器后調(diào)用晃酒,也就是在容器啟動時才進(jìn)行調(diào)用表牢,提供容器運行的默認(rèn)指令
ENTRYPOINT:格式和RUN指令格式一樣,目的和CMD一樣贝次,都是指定容器啟動程序及參數(shù)崔兴,ENTRYPOINT在運行時也可以替代,通過 docker run --entrypoing指定,當(dāng)指定了ENTRYPOINT后敲茄,CMD的含義就發(fā)生了變化位谋,不再是直接的運行其命令,而是將CMD的內(nèi)容作為參數(shù)傳給ENTRYPOINT折汞,實際執(zhí)行為:
<ENTRYPOINT> "<CMD>" //適合動態(tài)給命令添加參數(shù)
VOLUME:用于向容器添加卷倔幼,可以提供共享存儲等功能
VOLUME /data
ENV:設(shè)置環(huán)境變量,以便其它地方引用爽待,規(guī)則和shell一致
ENV DEBIAN_FRONTEND=noninteractive //設(shè)置非交互式
EXPOSE:指定于外界交互的端口损同,運行該鏡像的容器使用的端口,可以是多個鸟款,EXPOSE只是聲明端口膏燃,并不會自動打開,運行時需要-p指令完成端口映射
EXPOSR <PORT>
WORKDIR:工作目錄何什,類似于cd命令组哩,在該目錄下執(zhí)行
ONBUILD:是一個特殊的指令,它后面跟的是其它指令处渣,比如 RUN, COPY 等伶贰,而這些指令,在當(dāng)前鏡像構(gòu)建時并不會被執(zhí)行罐栈。只有當(dāng)以當(dāng)前鏡像為基礎(chǔ)鏡像黍衙,去構(gòu)建下一級鏡像的時候才會被執(zhí)行
2. 下載原生tomcat
創(chuàng)建tomcat-examples目錄,下載原生Tomcat(linux版本),解壓荠诬,重命名為apache-tomcat琅翻,放置在tomcat-examples目錄下
3. 創(chuàng)建Dockerfile文件
在tomcat-examples目錄下,創(chuàng)建Dockerfile文件柑贞,其在內(nèi)容如下:
# 選定基礎(chǔ)鏡像方椎,此處為本地環(huán)境中的vulenv/locubuntu:jdk
FROM vulenv/locubuntu:jdk
# 設(shè)置auther信息
MAINTAINER yuanjunhu/11087568
# 切換root用戶
USER root
# 將tomcat容器復(fù)制到容器中
ADD ./apache-tomcat /opt/apache-tomcat
WORKDIR /opt/apache-tomcat
# 運行命令,增加sh執(zhí)行權(quán)限
RUN cd /opt/apache-tomcat/ && \
chmod +x ./bin/*.sh
# 默認(rèn)命令钧嘶,啟動容器即啟動tomcat
# 此處為了保證持續(xù)運行棠众,要求以前臺形式運行,不能使用startup.sh
# 對于容器而言康辑,其啟動程序就是容器應(yīng)用進(jìn)程摄欲,容器就是為了主進(jìn)程而存在的,主進(jìn)程退出疮薇,容器就失去了存在的意義胸墙,從而退出
CMD ["/opt/apache-tomcat/bin/catalina.sh","run"]
4. 構(gòu)建鏡像
構(gòu)建鏡像最好在Dockerfile當(dāng)前目錄,否則需要指定Dockerfile具體目錄
docker build -t tomcat:examples .
[root@orphan-192-168-1-101 tomcat-examples]# docker build -t tomcat:examples .
Sending build context to Docker daemon 15.01MB
Step 1/7 : FROM vulenv/locubuntu:jdk
---> 4ad73720fb65
Step 2/7 : MAINTAINER yuanjunhu/11087568
---> Running in 7714e911fc3a
Removing intermediate container 7714e911fc3a
---> b48150f09fa3
Step 3/7 : USER root
---> Running in f85b8827e3a2
Removing intermediate container f85b8827e3a2
---> a81aaa47aa95
Step 4/7 : ADD ./apache-tomcat /opt/apache-tomcat
---> f85ca46c4b4c
Step 5/7 : WORKDIR /opt/apache-tomcat
---> Running in 6a161190cda2
Removing intermediate container 6a161190cda2
---> 9f0af6d6a406
Step 6/7 : RUN cd /opt/apache-tomcat/ && chmod +x ./bin/*.sh
---> Running in eac17ff2cfd5
Removing intermediate container eac17ff2cfd5
---> 5e94bd6d118b
Step 7/7 : CMD ["/opt/apache-tomcat/bin/catalina.sh","run"]
---> Running in 06d8a7f14f29
Removing intermediate container 06d8a7f14f29
---> bcbda97e64f5
Successfully built bcbda97e64f5
Successfully tagged tomcat:examples
5. 啟動鏡像
通過后臺啟動鏡像按咒,docker run -d
[root@orphan-192-168-1-101 tomcat-examples]# docker run -d -p 8088:8080 tomcat:examples
194c99120c941fefb5bc9d442bf40439d39f2839eae2242ae1c6d8ece2bd8091
[root@orphan-192-168-1-101 tomcat-examples]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
194c99120c94 tomcat:examples "/opt/apache-tomcat/…" 6 seconds ago Up 5 seconds 0.0.0.0:8088->8080/tcp clever_mirzakhani
//進(jìn)入docker檢查tomcat是否啟動
[root@orphan-192-168-1-101 tomcat-examples]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
194c99120c94 tomcat:examples "/opt/apache-tomcat/…" 6 seconds ago Up 5 seconds 0.0.0.0:8088->8080/tcp clever_mirzakhani
[root@orphan-192-168-1-101 tomcat-examples]# docker exec -it 194c99120c94 /bin/bash
root@194c99120c94:/opt/apache-tomcat# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 1 21:11 ? 00:00:07 /usr/bin/java -Djava.util.logging.config.file=/opt/apache-tomcat/conf/logging.p
root 52 0 0 21:18 pts/0 00:00:00 /bin/bash
root 59 52 0 21:18 pts/0 00:00:00 ps -ef
6. 外網(wǎng)訪問
http://127.0.0.1:8088/ //在docker啟動后迟隅,訪問存在延遲
3. Docker-Compose管理鏡像
1. Docker-compose簡介
我們知道通過Dockerfile模板文件可以快速的構(gòu)建一個單獨的容器但骨,但是在實際應(yīng)用中經(jīng)常需要多個容器配合完成某項任務(wù)智袭,例如Web項目,除了web服務(wù)容器本身外吼野,往往還需要再加上數(shù)據(jù)庫服務(wù)容器,甚至還包括負(fù)載均衡器等瞳步。
Compose恰好滿足了這樣的需求闷哆,它允許用戶通過一個單獨的docker-compose.yml模板文件來定義一組相關(guān)聯(lián)的應(yīng)用容器為一個項目。
Compose中有2個重要的概念:
1. 服務(wù)(services):一個應(yīng)用的容器抱怔,實際上可以包含若干個運行相同鏡像的容器示例
2. 項目(project):由一組關(guān)聯(lián)的應(yīng)用容器組成一個完成的業(yè)務(wù)單元嘀倒, compose默認(rèn)管理對象是項目屈留,通過子命令對項目中的一組容器進(jìn)行便捷的生命管理
2. docker-compose常用命令
docker-compose [-f=<arg>...] [options] [COMMAND] [ARGS...]
docker-compose help [COMMAND]
對compose而言,大部分命令的對象既可以是項目本身测蘑,也可以指定為項目中的服務(wù)或容器灌危,如果沒有特別說明碳胳,命令的對象將是項目,意味著項目中的所有服務(wù)都會受到影響固逗。
命令選項:
- -f, --file FILE指定使用的compose模板文件藕帜,默認(rèn)docker-compose.yml
- -p, --project-name NAME指定項目名稱,默認(rèn)將所在目錄作為項目名
- --x-networking 使用Docker的可插拔網(wǎng)絡(luò)后端特性
- --x-network-driver DRIVER指定網(wǎng)絡(luò)后端的驅(qū)動贝攒,默認(rèn)bridge
- --version 輸出更多調(diào)試信息
- -v, --version打印版本退出
-
build
docker-compose build //重新構(gòu)建服務(wù)
-
config
docker-compose config //驗證文件格式是否正確
-
down
docker-compose down //此命令將停止up命令所啟動的容器时甚,并移除網(wǎng)絡(luò)
-
exec
docker-compose exec //進(jìn)入指定容器
-
images
docker-compose images //列出compose文件中的鏡像
-
ps
docker-compose ps //列出項目中目前的所有容器
-
pull
docker-compose pull //拉去服務(wù)依賴的鏡像
-
restart | start | stop
docker-compose restart //重啟項目中的服務(wù) docker-compose start //啟動已經(jīng)存在的服務(wù) docker-compose stop //停止已經(jīng)運行的服務(wù)
-
rm
docker-compose rm -f //刪除停止?fàn)顟B(tài)的服務(wù)容器,優(yōu)先通過docker-compose stop命令停止容器
-
run
docker-compose run ubuntu ping docker.com //在指定服務(wù)上執(zhí)行一個命令
-
up
docker-compose up //該命令強大梨熙,自動完成構(gòu)建鏡像刀诬,創(chuàng)建服務(wù),啟動服務(wù),并關(guān)聯(lián)相關(guān)容器一系列內(nèi)容树埠,默認(rèn)啟動都在前臺嘶伟,需要使用-d指定后臺運行
3. Compose模板文件
模板文件是使用Compose的核心,涉及的指令關(guān)鍵字比較多九昧,大部分指令根docker run相關(guān)參數(shù)的含義類似。
version: '2'
services:
#定義的服務(wù)
#單個服務(wù)的名稱
db:
#使用的鏡像
image: mariadb:10.1
#設(shè)置鏡像的環(huán)境變量愤炸,可通過dockerhub查詢鏡像的環(huán)境變量
environment:
MYSQL_ROOT_PASSWORD: "root"
MYSQL_DATABASE: "app"
MYSQL_USER: "app"
MYSQL_PASSWORD: "123123"
#數(shù)據(jù)卷掛在的路徑設(shè)置掉奄,支持設(shè)置宿主機路徑或者數(shù)據(jù)卷名稱,一級訪問模式诞仓,以下為數(shù)據(jù)卷名稱示例
volumes:
- db:/var/lib/mysql
php:
#指定構(gòu)建Docker鏡像
build:
context: ./services/php
dockerfile: Dockerfile
volumes:
- ./app:/mnt/app
web:
image: nginx:1.11.1
ports:
- "8080:80"
depends_on:
- php
volumes_from:
- php
volumes:
- ./services/web/config:/etc/nginx/conf.d
phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- "8081:80"
environment:
PMA_HOST: "db"
PMA_USER: "root"
PMA_PASSWORD: "root"
volumes:
db:
driver: local
volumes詳解:
Docker默認(rèn)的數(shù)據(jù)讀寫發(fā)生在容器的存儲層速兔,當(dāng)容器被刪除時其上的數(shù)據(jù)將會丟失,應(yīng)當(dāng)盡量保證容器存儲層不發(fā)生寫操作谍婉。Volumes(數(shù)據(jù)卷)是可供一個或多個容器使用的位于宿主機上的特殊目錄镀钓,擁有以下特性:
數(shù)據(jù)卷可以在容器間共享和重用
對數(shù)據(jù)卷的寫操作不會有任何影響
-
數(shù)據(jù)卷會默認(rèn)存在
- docker volume ps //查看數(shù)據(jù)卷
- docker volume inspect VOLUMENAME //查看具體信息
4. 運行環(huán)境搭建
基礎(chǔ)環(huán)境采用公共服務(wù),如果配置在各個項目中丁溅,則會單獨啟動各個服務(wù),浪費資源妓柜。
-
搭建公共MySQL數(shù)據(jù)庫:docker-compose.yml
version: '2' services: #公共開放mysql數(shù)據(jù)庫涯穷,供所有項目使用 mysql: image: mariadb:10.1 environment: MYSQL_ROOT_PASSWORD: "root!@# MYSQL_DATABASE: "mysql" MYSQL_USER: "mysql" MYSQL_PASSWORD: "mysqlpwd" ports: - "3306:3306" volumes: - db:/var/lib/mysql volumes: db: driver: local
-
搭建公共Apache+php環(huán)境:docker-compose.yml
-
搭建DVWA漏洞環(huán)境: