From 34d9db7a8b5b6314ea1d9176aae05265a9189ca5 Mon Sep 17 00:00:00 2001 From: bunkerity Date: Thu, 18 Mar 2021 12:34:46 +0100 Subject: [PATCH] web ui - bug fixes --- autoconf/Dockerfile-amd64 | 13 ++++- autoconf/Dockerfile-arm32v7 | 13 ++++- autoconf/Dockerfile-arm64v8 | 13 ++++- autoconf/Dockerfile-i386 | 13 ++++- entrypoint/site-config.sh | 28 ++++----- ui/Dockerfile | 10 +++- ui/config.py | 85 ---------------------------- ui/entrypoint-autoconf.py | 109 ------------------------------------ ui/utils.py | 2 + ui/wrappers.py | 4 +- 10 files changed, 62 insertions(+), 228 deletions(-) delete mode 100644 ui/config.py delete mode 100644 ui/entrypoint-autoconf.py diff --git a/autoconf/Dockerfile-amd64 b/autoconf/Dockerfile-amd64 index b515047..d765b82 100644 --- a/autoconf/Dockerfile-amd64 +++ b/autoconf/Dockerfile-amd64 @@ -16,8 +16,17 @@ RUN apk add py3-pip apache2-utils bash certbot curl logrotate openssl && \ chmod 770 /var/log/letsencrypt && \ mkdir /var/lib/letsencrypt && \ chown root:nginx /var/lib/letsencrypt && \ - chmod 770 /var/lib/letsencrypt + chmod 770 /var/lib/letsencrypt && \ + mkdir /cache && \ + chown root:nginx /cache && \ + chmod 770 /cache && \ + touch /var/log/jobs.log && \ + chown root:nginx /var/log/jobs.log && \ + chmod 770 /var/log/jobs.log && \ + chown -R root:nginx /opt/confs/nginx && \ + chmod -R 770 /opt/confs/nginx +COPY autoconf/misc/logrotate.conf /etc/logrotate.conf COPY scripts/* /opt/scripts/ COPY confs/global/ /opt/confs/global COPY confs/site/ /opt/confs/site @@ -25,6 +34,4 @@ COPY entrypoint/* /opt/entrypoint/ COPY autoconf/* /opt/entrypoint/ RUN chmod +x /opt/entrypoint/*.py /opt/entrypoint/*.sh /opt/scripts/*.sh -VOLUME /etc/nginx - ENTRYPOINT ["/opt/entrypoint/entrypoint.sh"] diff --git a/autoconf/Dockerfile-arm32v7 b/autoconf/Dockerfile-arm32v7 index b6ab404..8424a7d 100644 --- a/autoconf/Dockerfile-arm32v7 +++ b/autoconf/Dockerfile-arm32v7 @@ -22,8 +22,17 @@ RUN apk add py3-pip apache2-utils bash certbot curl logrotate openssl && \ chmod 770 /var/log/letsencrypt && \ mkdir /var/lib/letsencrypt && \ chown root:nginx /var/lib/letsencrypt && \ - chmod 770 /var/lib/letsencrypt + chmod 770 /var/lib/letsencrypt && \ + mkdir /cache && \ + chown root:nginx /cache && \ + chmod 770 /cache && \ + touch /var/log/jobs.log && \ + chown root:nginx /var/log/jobs.log && \ + chmod 770 /var/log/jobs.log && \ + chown -R root:nginx /opt/confs/nginx && \ + chmod -R 770 /opt/confs/nginx +COPY autoconf/misc/logrotate.conf /etc/logrotate.conf COPY scripts/* /opt/scripts/ COPY confs/global/ /opt/confs/global COPY confs/site/ /opt/confs/site @@ -31,6 +40,4 @@ COPY entrypoint/* /opt/entrypoint/ COPY autoconf/* /opt/entrypoint/ RUN chmod +x /opt/entrypoint/*.py /opt/entrypoint/*.sh /opt/scripts/*.sh -VOLUME /etc/nginx - ENTRYPOINT ["/opt/entrypoint/entrypoint.sh"] diff --git a/autoconf/Dockerfile-arm64v8 b/autoconf/Dockerfile-arm64v8 index db5f77b..4e1f6e7 100644 --- a/autoconf/Dockerfile-arm64v8 +++ b/autoconf/Dockerfile-arm64v8 @@ -22,8 +22,17 @@ RUN apk add py3-pip apache2-utils bash certbot curl logrotate openssl && \ chmod 770 /var/log/letsencrypt && \ mkdir /var/lib/letsencrypt && \ chown root:nginx /var/lib/letsencrypt && \ - chmod 770 /var/lib/letsencrypt + chmod 770 /var/lib/letsencrypt && \ + mkdir /cache && \ + chown root:nginx /cache && \ + chmod 770 /cache && \ + touch /var/log/jobs.log && \ + chown root:nginx /var/log/jobs.log && \ + chmod 770 /var/log/jobs.log && \ + chown -R root:nginx /opt/confs/nginx && \ + chmod -R 770 /opt/confs/nginx +COPY autoconf/misc/logrotate.conf /etc/logrotate.conf COPY scripts/* /opt/scripts/ COPY confs/global/ /opt/confs/global COPY confs/site/ /opt/confs/site @@ -31,6 +40,4 @@ COPY entrypoint/* /opt/entrypoint/ COPY autoconf/* /opt/entrypoint/ RUN chmod +x /opt/entrypoint/*.py /opt/entrypoint/*.sh /opt/scripts/*.sh -VOLUME /etc/nginx - ENTRYPOINT ["/opt/entrypoint/entrypoint.sh"] diff --git a/autoconf/Dockerfile-i386 b/autoconf/Dockerfile-i386 index b0eaff6..a5fafe3 100644 --- a/autoconf/Dockerfile-i386 +++ b/autoconf/Dockerfile-i386 @@ -16,8 +16,17 @@ RUN apk add py3-pip apache2-utils bash certbot curl logrotate openssl && \ chmod 770 /var/log/letsencrypt && \ mkdir /var/lib/letsencrypt && \ chown root:nginx /var/lib/letsencrypt && \ - chmod 770 /var/lib/letsencrypt + chmod 770 /var/lib/letsencrypt && \ + mkdir /cache && \ + chown root:nginx /cache && \ + chmod 770 /cache && \ + touch /var/log/jobs.log && \ + chown root:nginx /var/log/jobs.log && \ + chmod 770 /var/log/jobs.log && \ + chown -R root:nginx /opt/confs/nginx && \ + chmod -R 770 /opt/confs/nginx +COPY autoconf/misc/logrotate.conf /etc/logrotate.conf COPY scripts/* /opt/scripts/ COPY confs/global/ /opt/confs/global COPY confs/site/ /opt/confs/site @@ -25,6 +34,4 @@ COPY entrypoint/* /opt/entrypoint/ COPY autoconf/* /opt/entrypoint/ RUN chmod +x /opt/entrypoint/*.py /opt/entrypoint/*.sh /opt/scripts/*.sh -VOLUME /etc/nginx - ENTRYPOINT ["/opt/entrypoint/entrypoint.sh"] diff --git a/entrypoint/site-config.sh b/entrypoint/site-config.sh index bdcaa63..65e07ca 100644 --- a/entrypoint/site-config.sh +++ b/entrypoint/site-config.sh @@ -15,27 +15,21 @@ if [ "$MULTISITE" = "yes" ] ; then fi ROOT_FOLDER="${ROOT_FOLDER}/$1" fi -env | grep -E -v "^(HOSTNAME|PWD|PKG_RELEASE|NJS_VERSION|SHLVL|PATH|_|NGINX_VERSION)=" > "${NGINX_PREFIX}nginx.env" if [ "$MULTISITE" = "yes" ] ; then - sed -i "s~^SERVER_NAME=.*~SERVER_NAME=$1~" "${NGINX_PREFIX}nginx.env" + for var in $(env | cut -d '=' -f 1 | grep -E "^${1}_") ; do + repl_name=$(echo "$var" | sed "s~${1}_~~") + repl_value=$(env | grep -E "^${var}=" | sed "s~^${var}=~~") + read -r "$repl_name" <<< $repl_value + done +fi + +set | grep -E -v "^(HOSTNAME|PWD|PKG_RELEASE|NJS_VERSION|SHLVL|PATH|_|NGINX_VERSION|HOME)=" > "${NGINX_PREFIX}nginx.env" +if [ "$MULTISITE" = "yes" ] ; then for server in $SERVER_NAME ; do - if [ "$server" != "$1" ] ; then - sed -i "/^${server}_.*=.*/d" "${NGINX_PREFIX}nginx.env" - fi - done - for var in $(cut -d '=' -f 1 "${NGINX_PREFIX}nginx.env") ; do - name=$(echo "$var") - check=$(echo "$name" | grep "^${1}_") - if [ "$check" != "" ] ; then - repl_name=$(echo "$name" | sed "s~${1}_~~") - repl_value=$(env | grep -E "^${name}=" | sed "s~^${name}=~~") - read -r "$repl_name" <<< $repl_value - sed -i "/^${repl_name}=.*/d" "${NGINX_PREFIX}nginx.env" - sed -i "/^${name}=.*/d" "${NGINX_PREFIX}nginx.env" - echo "${repl_name}=${repl_value}" >> "${NGINX_PREFIX}nginx.env" - fi + sed -i "~^${server}_.*=.*~d" "${NGINX_PREFIX}nginx.env" done + sed -i "~^SERVER_NAME=.*~SERVER_NAME=${1}~" "${NGINX_PREFIX}nginx.env" fi # copy stub confs diff --git a/ui/Dockerfile b/ui/Dockerfile index 8ad0c06..ec5964f 100644 --- a/ui/Dockerfile +++ b/ui/Dockerfile @@ -3,15 +3,19 @@ FROM alpine RUN apk add py3-pip apache2-utils bash && \ pip3 install docker flask && \ mkdir /opt/entrypoint && \ - mkdir -p /opt/confs/site + mkdir -p /opt/confs/site && \ + addgroup -g 101 nginx && \ + adduser -h /var/cache/nginx -g nginx -s /sbin/nologin -G nginx -D -H -u 101 nginx && \ + mkdir /etc/nginx && \ + chown root:nginx /etc/nginx && \ + chmod 770 /etc/nginx + COPY confs/site/ /opt/confs/site COPY entrypoint/* /opt/entrypoint/ COPY ui/ /opt/entrypoint/ RUN chmod +x /opt/entrypoint/*.py /opt/entrypoint/*.sh -VOLUME /etc/nginx - EXPOSE 5000 WORKDIR /opt/entrypoint diff --git a/ui/config.py b/ui/config.py deleted file mode 100644 index 68b73c3..0000000 --- a/ui/config.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/python3 - -import utils -import subprocess, shutil, os, traceback - -def generate(instances, vars) : - try : - # Get env vars from bunkerized-nginx instances - vars_instances = {} - for instance_id, instance in instances.items() : - for var_value in instance.attrs["Config"]["Env"] : - var = var_value.split("=")[0] - value = var_value.replace(var + "=", "", 1) - vars_instances[var] = value - vars_defaults = vars.copy() - vars_defaults.update(vars_instances) - vars_defaults.update(vars) - # Call site-config.sh to generate the config - proc = subprocess.run(["/opt/entrypoint/site-config.sh", vars["SERVER_NAME"]], env=vars_defaults, capture_output=True) - if proc.returncode == 0 : - return True - except Exception as e : - traceback.print_exc() - utils.log("[!] Error while generating config : " + str(e)) - return False - -def activate(instances, vars) : - try : - # Check if file exists - if not os.path.isfile("/etc/nginx/" + vars["SERVER_NAME"] + "/server.conf") : - utils.log("[!] /etc/nginx/" + vars["SERVER_NAME"] + "/server.conf doesn't exist") - return False - - # Include the server conf - utils.replace_in_file("/etc/nginx/nginx.conf", "}", "include /etc/nginx/" + vars["SERVER_NAME"] + "/server.conf;\n}") - - # Send SIGHUP to all running instances - for instance_id, instance in instances.items() : - if instance.status == "running" : - try : - instance.kill("SIGHUP") - utils.log("[*] Sent SIGHUP signal to bunkerized-nginx instance " + instance.name + " / " + instance.id) - except docker.errors.APIError as e : - utils.log("[!] Docker error while sending SIGHUP signal : " + str(e)) - return True - except Exception as e : - utils.log("[!] Error while activating config : " + str(e)) - return False - -def deactivate(instances, vars) : - try : - # Check if file exists - if not os.path.isfile("/etc/nginx/" + vars["SERVER_NAME"] + "/server.conf") : - utils.log("[!] /etc/nginx/" + vars["SERVER_NAME"] + "/server.conf doesn't exist") - return False - - # Remove the include - utils.replace_in_file("/etc/nginx/nginx.conf", "include /etc/nginx/" + vars["SERVER_NAME"] + "/server.conf;\n", "") - - # Send SIGHUP to all running instances - for instance_id, instance in instances.items() : - if instance.status == "running" : - try : - instance.kill("SIGHUP") - utils.log("[*] Sent SIGHUP signal to bunkerized-nginx instance " + instance.name + " / " + instance.id) - except docker.errors.APIError as e : - utils.log("[!] Docker error while sending SIGHUP signal : " + str(e)) - return True - except Exception as e : - utils.log("[!] Error while deactivating config : " + str(e)) - return False - -def remove(instances, vars) : - try : - # Check if file exists - if not os.path.isfile("/etc/nginx/" + vars["SERVER_NAME"] + "/server.conf") : - utils.log("[!] /etc/nginx/" + vars["SERVER_NAME"] + "/server.conf doesn't exist") - return False - - # Remove the folder - shutil.rmtree("/etc/nginx/" + vars["SERVER_NAME"]) - return True - except Exception as e : - utils.log("[!] Error while deactivating config : " + str(e)) - return False diff --git a/ui/entrypoint-autoconf.py b/ui/entrypoint-autoconf.py deleted file mode 100644 index d314966..0000000 --- a/ui/entrypoint-autoconf.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/python3 - -import utils, config -import docker, os, stat, sys - -def process(container, event) : - global instances, containers - - # Process instance event - if "bunkerized-nginx.AUTOCONF" in container.labels : - if event == "create" : - instances[container.id] = container - utils.log("[*] bunkerized-nginx instance created : " + container.name + " / " + container.id) - elif event == "start" : - instances[container.id].reload() - utils.log("[*] bunkerized-nginx instance started : " + container.name + " / " + container.id) - elif event == "die" : - instances[container.id].reload() - utils.log("[*] bunkerized-nginx instance stopped : " + container.name + " / " + container.id) - elif event == "destroy" : - del instances[container.id] - utils.log("[*] bunkerized-nginx instance removed : " + container.name + " / " + container.id) - - # Process container event - elif "bunkerized-nginx.SERVER_NAME" in container.labels : - # Convert labels to env vars - vars = { k.replace("bunkerized-nginx.", "", 1) : v for k, v in container.labels.items() if k.startswith("bunkerized-nginx.")} - if event == "create" : - if config.generate(instances, vars) : - utils.log("[*] Generated config for " + vars["SERVER_NAME"]) - containers[container.id] = container - else : - utils.log("[!] Can't generate config for " + vars["SERVER_NAME"]) - elif event == "start" : - if container.id in containers : - containers[container.id].reload() - if config.activate(instances, vars) : - utils.log("[*] Activated config for " + vars["SERVER_NAME"]) - else : - utils.log("[!] Can't activate config for " + vars["SERVER_NAME"]) - elif event == "die" : - if container.id in containers : - containers[container.id].reload() - if config.deactivate(instances, vars) : - utils.log("[*] Deactivated config for " + vars["SERVER_NAME"]) - else : - utils.log("[!] Can't deactivate config for " + vars["SERVER_NAME"]) - elif event == "destroy" : - if container.id in containers : - del containers[container.id] - if config.remove(vars) : - utils.log("[*] Removed config for " + vars["SERVER_NAME"]) - else : - utils.log("[!] Can't remove config for " + vars["SERVER_NAME"]) - -# Connect to the endpoint -endpoint = "/var/run/docker.sock" -if not os.path.exists(endpoint) or not stat.S_ISSOCK(os.stat(endpoint).st_mode) : - utils.log("[!] /var/run/docker.sock not found (is it mounted ?)") - sys.exit(1) -try : - client = docker.DockerClient(base_url='unix:///var/run/docker.sock') -except Exception as e : - utils.log("[!] Can't instantiate DockerClient : " + str(e)) - sys.exit(2) - -# Get all bunkerized-nginx instances and web services created before -instances = {} -containers = {} -try : - before = client.containers.list(all=True, filters={"label" : "bunkerized-nginx.AUTOCONF"}) + client.containers.list(all=True, filters={"label" : "bunkerized-nginx.SERVER_NAME"}) -except docker.errors.APIError as e : - utils.log("[!] Docker API error " + str(e)) - sys.exit(3) -for container in before : - if container.status in ("restarting", "running", "created", "exited") : - process(container, "create") - if container.status == "running" : - process(container, "start") - -# Process events received from Docker -try : - for event in client.events(decode=True) : - - # Process only container events - if event["Type"] != "container" : - continue - - # Get Container object - try : - container = client.containers.get(event["id"]) - except docker.errors.NotFound as e : - continue - - # Check if there is an interesting label - interesting = False - for label in container.labels : - if label in ("bunkerized-nginx.SERVER_NAME", "bunkerized-nginx.AUTOCONF") : - interesting = True - break - if not interesting : - continue - - # Process the event - process(container, event["Action"]) - -except docker.errors.APIError as e : - utils.log("[!] Docker API error " + str(e)) - sys.exit(4) diff --git a/ui/utils.py b/ui/utils.py index d20761e..8910f41 100644 --- a/ui/utils.py +++ b/ui/utils.py @@ -15,6 +15,8 @@ def replace_in_file(file, old_str, new_str) : def env_to_summary_class(var, value) : if type(var) is list and type(value) is list : for i in range(0, len(var)) : + if not isinstance(var[i], str) : + continue if re.search(value[i], var[i]) : return "check text-success" return "times text-danger" diff --git a/ui/wrappers.py b/ui/wrappers.py index e27f0a6..ed2eb3f 100644 --- a/ui/wrappers.py +++ b/ui/wrappers.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 -import utils, config +import utils import docker, os, stat, sys, subprocess, shutil def get_client() : @@ -55,7 +55,7 @@ def reload_instances(client) : return True, i def new_service(client, env) : - proc = subprocess.run(["/opt/entrypoint/site-config.sh", env["SERVER_NAME"]], env=env, capture_output=True) + proc = subprocess.run(["/bin/su", "-s", "/bin/sh", "-c", "/opt/entrypoint/site-config.sh" + " " + env["SERVER_NAME"], "nginx"], env=env, capture_output=True) if proc.returncode != 0 : return False, "Error code " + str(proc.returncode) + " while generating config." utils.replace_in_file("/etc/nginx/nginx.conf", "}", "include /etc/nginx/" + env["SERVER_NAME"] + "/server.conf;\n}")