docker-compose的写法(实现pwn的动态flag)

1.Compose介绍

Docker Compose是一个用来定义和运行复杂应用的Docker工具。一个使用Docker容器的应用,通常由多个容器组成。使用Docker Compose 不再需要使用shell脚本来启动容器。

Compose 通过一个配置文件来管理多个Docker容器,在配置文件中,所有的容器通过Service来定义,然后使用docker-compose 脚本来启动,停止和重启应用,和应用中的服务以及所有的依赖服务的容器,非常适合组合使用多个容器进行开发的场景。

2.compose常用服务配置参考

Compose文件是一个定义服务,网络和卷的YAML文件。Compose文件默认文件名为docker-compose.yml。

提示:您可以对此文件使用.yml或者.yaml扩展名。

与docker运行一样,默认情况下,Dockerfile中指定的选项(CMD,EXPOSE,VOLUME,ENV)都会继续使用,你不需要在docker-compose.yml中再次指定它们。

build

build可以指定包含构建上下文的路径:

1
2
3
4
version: '2'
services:
webapp:
build: ./dir

或者作为一个对象,该对象具有上下文路径和指定的Dockerfile文件以及args参数值:

1
2
3
4
5
6
7
8
version: '2'
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1

webapp服务将会通过./dir目录下的dockerfile-alternate文件构建容器镜像

如果你同时指定image和build,则compose会通过build指定的目录构建容器镜像,而构建的镜像名为image中指定的镜像名和标签

1
2
build: ./dir
image: webapp:tag

image

指定启动容器的镜像,可以是镜像仓库/标签或者是镜像id(或者id的前一部分)

1
2
3
4
5
image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd

如果镜像不存在,Compose将尝试从官方镜像仓库将其Pull下来,如果你还指定了build,这种情况下吗,它将使用指定的build选项构建它,并使用image指定的名字和标记对其进行标记。

container_name

指定一个自定义容器名称,而不是生成默认名称。

1
container_name: my-web-container

由于Docker 容器名称必须是唯一的,因此如果指定了自定义名称,则无法将服务扩展到多个容器。

volumes

卷挂载路径设置。可以设置宿主机路径(HOST:CONTAINER)或加上访问模式(HOST:CONTAINER:ro),挂载数据卷的默认权限是读写(RW),可以通过ro指定为只读。你可以在主机上挂载相对路径,该路径将相对于当前正在使用的Compose配置文件的目录进行扩展。相对路径应始终以. 或者.. 开始。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
volumes:
# 只需指定一个路径,让引擎创建一个卷
- /var/lib/mysql

# 指定绝对路径映射
- /opt/data:/var/lib/mysql

# 相对于当前compose文件的相对路径
- ./cache:/tmp/cache

# 用户家目录相对路径
- ~/configs:/etc/configs/:ro

# 命名卷
- datavolume:/var/lib/mysql

command

覆盖容器启动后默认执行的命令。

1
command: bundle exec thin -p 3000

该命令也可以是一个类似于dockerfile的列表:

1
command: ["bundle", "exec", "thin", "-p", "3000"]

expose

暴露端口,但不映射到宿主机,只被连接的服务访问。仅可以指定内部端口为参数

1
2
3
expose:
- "3000"
- "8000"

port

暴露端口信息。

常用的简单格式:使用宿主:容器(HOST:CONTAINER)格式或者仅仅指定容器的端口(宿主将会随机选择端口)都可以。

1
2
3
4
5
6
7
8
9
ports:
- "3000"
- "3000-3005"
- "8000:8000"
- "9090-9091:8080-8081"
- "49100:22"
- "127.0.0.1:8001:8001"
- "127.0.0.1:5000-5010:5000-5010"
- "6060:6060/udp"

在v3.2中的ports的长格式的语法允许配置不能用短格式表示的附加字段。

长格式:

1
2
3
4
5
ports:
- target: 80
published: 8080
protocol: tcp
mode: host

target:容器内的端口

published:物理主机的端口

protocol:端口协议(tcp或udp)

mode:host和ingress两种模式,host用于在每个节点上发布主机端口,ingress用于被负载平衡的swarm模式端口。

dns

配置DNS服务器。可以是一个值,也可以是一个列表。

1
2
3
4
dns: 8.8.8.8
dns:
- 8.8.8.8
- 9.9.9.9

更多的docker-compose的解释可以去看看https://www.runoob.com/docker/docker-compose.html

3.docker-compose搭建动态flag的pwn

1
2
3
4
5
6
7
8
9
version: '2'
services:
pwndocker3:
image: springpwndocker3
build: .
volumes:
- "$PWD/flag:/home/pwn/flag"
ports:
- 9999:44500

这里通过volumes来挂载当前运行目录上的flag到文件的对应目录上,通过CTF-whale来实现动态。