Skip to content
This repository has been archived by the owner on Apr 13, 2024. It is now read-only.

Commit

Permalink
Allow cpu usage limit, support multi image.
Browse files Browse the repository at this point in the history
  • Loading branch information
glzjin committed Aug 29, 2019
1 parent 9ac610a commit ecd7b9c
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 7 deletions.
10 changes: 10 additions & 0 deletions assets/create.html
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,16 @@

</div>

<div class="form-group">
<label for="value">Docker Container CPU Limit<br>
<small class="form-text text-muted">
The CPU usage limit
</small>
</label>
<input type="number" class="form-control" name="cpu_limit" placeholder="Enter the cpu limit" value="0.5" required>

</div>

<input type="hidden" name="state" value="hidden">
<input type="hidden" value="dynamic_docker" name="type" id="chaltype">

Expand Down
10 changes: 10 additions & 0 deletions assets/update.html
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,16 @@

</div>

<div class="form-group">
<label for="value">Docker Container CPU Limit<br>
<small class="form-text text-muted">
The CPU usage limit
</small>
</label>
<input type="number" class="form-control" name="cpu_limit" placeholder="Enter the cpu limit" value="{{ challenge.cpu_limit }}" required>

</div>

<div class="form-group">
<label for="value">Score Type<br>
<small class="form-text text-muted">
Expand Down
86 changes: 79 additions & 7 deletions docker_utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import json
import random
import uuid
from collections import OrderedDict

import docker
from .db_utils import DBUtils
from .models import DynamicDockerChallenge
Expand All @@ -13,23 +18,90 @@ def add_new_docker_container(user_id, challenge_id, flag, uuid_code):
.first_or_404()

client = docker.DockerClient(base_url=configs.get("docker_api_url"))
client.containers.run(image=dynamic_docker_challenge.docker_image, name=str(user_id) + '-' + uuid_code,
environment={'FLAG': flag}, detach=True, network="ctfd_frp-containers",
mem_limit=dynamic_docker_challenge.memory_limit)
if dynamic_docker_challenge.docker_image.startswith("{"):
images = json.loads(dynamic_docker_challenge.docker_image, object_pairs_hook=OrderedDict)

range_prefix = '172.64.' + str(random.randint(10, 200))
while True:
if len(client.networks.list(filters={'label': range_prefix})) == 0:
break
range_prefix = '172.64.' + str(random.randint(10, 200))

ipam_pool = docker.types.IPAMPool(
subnet=range_prefix + '.0/24',
gateway=range_prefix + '.254'
)
ipam_config = docker.types.IPAMConfig(driver='default', pool_configs=[ipam_pool])
network_name = str(user_id) + '-' + uuid_code
network = client.networks.create(network_name, internal=True, ipam=ipam_config,
labels={range_prefix: range_prefix})

containers = configs.get("docker_auto_connect_containers", "").split(",")
for c in containers:
network.connect(c)

has_processed_main = False
for name in images:
if not has_processed_main:
image = images[name]
container_name = str(user_id) + '-' + uuid_code
client.containers.run(image=image, name=container_name, network=network_name,
environment={'FLAG': flag}, detach=True,
mem_limit=dynamic_docker_challenge.memory_limit,
nano_cpus=int(dynamic_docker_challenge.cpu_limit * 1e9),
labels={str(user_id) + '-' + uuid_code: str(user_id) + '-' + uuid_code},
hostname=name, auto_remove=True)
network.disconnect(container_name)
network.connect(container_name, aliases=[name])
has_processed_main = True
continue

image = images[name]
container_name = str(user_id) + '-' + str(uuid.uuid4())
client.containers.run(image=image, name=container_name, network=network_name,
environment={'FLAG': flag}, detach=True,
mem_limit=dynamic_docker_challenge.memory_limit,
nano_cpus=int(dynamic_docker_challenge.cpu_limit * 1e9),
labels={str(user_id) + '-' + uuid_code: str(user_id) + '-' + uuid_code},
hostname=name, auto_remove=True)
network.disconnect(container_name)
network.connect(container_name, aliases=[name])

else:
client.containers.run(image=dynamic_docker_challenge.docker_image, name=str(user_id) + '-' + uuid_code,
environment={'FLAG': flag}, detach=True, network="ctfd_frp-containers",
mem_limit=dynamic_docker_challenge.memory_limit,
nano_cpus=int(dynamic_docker_challenge.cpu_limit * 1e9), auto_remove=True)

@staticmethod
def remove_current_docker_container(user_id, is_retry = False):
def remove_current_docker_container(user_id, is_retry=False):
configs = DBUtils.get_all_configs()
container = DBUtils.get_current_containers(user_id=user_id)

auto_containers = configs.get("docker_auto_connect_containers", "").split(",")

if container is None:
return

try:
client = docker.DockerClient(base_url=configs.get("docker_api_url"))
containers = client.containers.list(filters={'name': str(user_id) + '-' + container.uuid})
for c in containers:
c.remove(force=True)
networks = client.networks.list(names=[str(user_id) + '-' + container.uuid])

if len(networks) == 0:
containers = client.containers.list(filters={'name': str(user_id) + '-' + container.uuid})
for c in containers:
c.remove(force=True)
else:
containers = client.containers.list(filters={'label': str(user_id) + '-' + container.uuid})
for c in containers:
c.remove(force=True)

for n in networks:
for ac in auto_containers:
n.disconnect(ac)
n.remove()


except:
if not is_retry:
DockerUtils.remove_current_docker_container(user_id, True)
1 change: 1 addition & 0 deletions models.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ class DynamicDockerChallenge(Challenges):
minimum = db.Column(db.Integer, default=0)
decay = db.Column(db.Integer, default=0)
memory_limit = db.Column(db.Text, default="128m")
cpu_limit = db.Column(db.Float, default=0.5)
dynamic_score = db.Column(db.Integer, default=0)

docker_image = db.Column(db.Text, default=0)
Expand Down
10 changes: 10 additions & 0 deletions templates/configs/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@
<textarea class="form-control" id="frp-config-template" name="frp_config_template" rows="7">{{ configs.get("frp_config_template") }}</textarea>
</div>

<div class="form-group">
<label>
Docker Auto Connect Containers
<small class="form-text text-muted">
Decide which container will be connected to multi-container-network automatically. Separated by commas.
</small>
</label>
<input type="text" class="form-control" id="docker-auto-connect-containers" name="docker_auto_connect_containers" value="{{ configs.get("docker_auto_connect_containers") }}">
</div>

<button type="submit" class="btn btn-md btn-primary float-right">Update</button>
</form>
</div>

0 comments on commit ecd7b9c

Please sign in to comment.