Skip to content

Instantly share code, notes, and snippets.

@stypr
Last active August 17, 2019 19:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stypr/ffe28c8262a8a362be0fd7b1558dc2b4 to your computer and use it in GitHub Desktop.
Save stypr/ffe28c8262a8a362be0fd7b1558dc2b4 to your computer and use it in GitHub Desktop.
Docker runner for CTF
#!/usr/bin/python
#-*- coding:utf-8 -*-
# Developer: Harold Kim (ho.kim@linecorp.com)
import os
import sys
import time
import urllib
import urllib2
''' Docker Runner (lol)
1. Restart all instances every hour
2. Check access to the instance half an hour
3. Start instance if something goes wrong
'''
class DockerRunner:
''' DockerRunner class '''
docker_bin = "/usr/bin/docker"
docker_opt = " run -d --restart always -m 256M -c 64 "
docker_opt += "--name unwind-container-%s -p%s:8080 unwind:latest"
maximum_instance_count = 0
# port starts with 8081, 8082, 8083, ...
starting_port = 8081
def __init__(self, maximum_instance):
self.maximum_instance_count = maximum_instance
self.kill() # reset instances
def get_port(self):
return range(self.starting_port, self.starting_port + self.maximum_instance_count)
def count(self):
''' count running (ret int) '''
# docker ps -a -q | wc -l
c = os.popen("%s ps -a -q | wc -l" % (self.docker_bin, )).read().strip()
return int(c)
def kill(self, ps=None):
''' runner.kill("8081") '''
if ps is None:
c = os.popen("%s rm -f $(%s ps -a -q) 2>&1" % (self.docker_bin, self.docker_bin,)).read()
else:
ps = str(ps)
c = os.popen("%s rm -f $(%s ps --filter 'name=unwind-container-%s' -q) 2>&1" % (self.docker_bin, self.docker_bin, ps,)).read()
return True
def run(self):
while self.count() < self.maximum_instance_count:
# starting from 8081
count = self.count()
# check non-alive ports
port = self.get_port()
_check_alive = os.popen("%s ps --format \"{{.ID}} {{.Names}}\" 2>&1" % (self.docker_bin,)).read()
_check_alive = _check_alive.strip().split("\n")
for _check in _check_alive:
try:
port.remove(int(_check.split("-")[-1]))
except:
pass
print(port)
port = port[0]
# start docker
res = os.popen(self.docker_bin + self.docker_opt % (port, port,)).read()
time.sleep(1)
print("Instance %s started.." % (port,))
return True
def run_infinite(self):
c = 1
d = 0
while True:
if c % (12 * 30) == 0:
# Half hour: check if everything is alright.
print(">> Checking if everything is alright.")
port = self.get_port()
_check1 = []
_check2 = []
for _port in port:
try:
_check1.append(urllib2.urlopen("http://localhost:%s/healthcheck/" % (str(port), )).read())
_check2.append(urllib2.urlopen("http://localhost:%s/are_you_ok/" % (str(port),)).read())
except:
pass
# check if all instances returns the same result, otherwise reset all of them
if len(set(_check1)) is not 1 or len(set(_check2)) is not 1:
self.kill()
# 1 hour: Restart all
print(">> Rebooting instances..")
d += 1
if d % 2 == 0:
self.kill()
# Instance runner
self.run()
time.sleep(5)
c += 1
if __name__ == "__main__":
# Run 3 docker instances, forever.
docker = DockerRunner(3)
docker.run_infinite()
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 1024;
multi_accept on;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_bucket_size 128;
server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
upstream unwind {
ip_hash;
server localhost:8081;
server localhost:8082;
server localhost:8083;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
root /dev/null;
server_name _;
location / {
auth_basic "Access is denied";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://unwind/;
}
location ~ /\.ht {
deny all;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment