From bd7b6af668324f24cd8cb5432484b716c622c9e1 Mon Sep 17 00:00:00 2001 From: bunkerity Date: Tue, 22 Dec 2020 22:35:15 +0100 Subject: [PATCH] UI - load config template from json --- ui/config.json | 512 ++++++++++++++++++++++++++++++ ui/entrypoint.py | 13 +- ui/templates/services-delete.html | 17 + ui/templates/services-edit.html | 42 +++ ui/templates/services.html | 40 +-- ui/utils.py | 16 + 6 files changed, 605 insertions(+), 35 deletions(-) create mode 100644 ui/config.json create mode 100644 ui/templates/services-delete.html create mode 100644 ui/templates/services-edit.html diff --git a/ui/config.json b/ui/config.json new file mode 100644 index 0000000..9f884ec --- /dev/null +++ b/ui/config.json @@ -0,0 +1,512 @@ +{ + "max-client-size":{ + "category":"Misc", + "type":"text", + "label":"Max client size", + "env":"MAX_CLIENT_SIZE" + }, + "allowed-methods":{ + "category":"Misc", + "type":"text", + "label":"Allowed methods", + "env":"ALLOWED_METHODS" + }, + "serve-files":{ + "category":"Misc", + "type":"checkbox", + "label":"Serve files", + "env":"SERVE_FILES" + }, + "remove-headers":{ + "category":"Info leak", + "type":"text", + "label":"Remove headers", + "env":"REMOVE_HEADERS" + }, + "use-auth-basic":{ + "category":"Basic auth", + "type":"checkbox", + "label":"Use auth basic", + "env":"USE_AUTH_BASIC" + }, + "auth-basic-location":{ + "category":"Basic auth", + "type":"text", + "label":"Auth basic location", + "env":"AUTH_BASIC_LOCATION" + }, + "auth-basic-user":{ + "category":"Basic auth", + "type":"text", + "label":"Auth basic user", + "env":"AUTH_BASIC_USER" + }, + "auth-basic-password":{ + "category":"Basic auth", + "type":"text", + "label":"Auth basic password", + "env":"AUTH_BASIC_PASSWORD" + }, + "auth-basic-text":{ + "category":"Basic auth", + "type":"text", + "label":"Auth basic text", + "env":"AUTH_BASIC_TEXT" + }, + "use-reverse-proxy":{ + "category":"Reverse proxy", + "type":"checkbox", + "label":"Use reverse proxy", + "env":"USE_REVERSE_PROXY" + }, + "reverse-proxy-url":{ + "category":"Reverse proxy", + "type":"text", + "label":"Reverse proxy url", + "env":"REVERSE_PROXY_URL" + }, + "reverse-proxy-host":{ + "category":"Reverse proxy", + "type":"text", + "label":"Reverse proxy host", + "env":"REVERSE_PROXY_HOST" + }, + "reverse-proxy-ws":{ + "category":"Reverse proxy", + "type":"checkbox", + "label":"Reverse proxy ws", + "env":"REVERSE_PROXY_WS" + }, + "proxy-real-ip":{ + "category":"Reverse proxy", + "type":"checkbox", + "label":"Proxy real ip", + "env":"PROXY_REAL_IP" + }, + "proxy-real-ip-from":{ + "category":"Reverse proxy", + "type":"text", + "label":"Proxy real ip from", + "env":"PROXY_REAL_IP_FROM" + }, + "proxy-real-ip-header":{ + "category":"Reverse proxy", + "type":"text", + "label":"Proxy real ip header", + "env":"PROXY_REAL_IP_HEADER" + }, + "proxy-real-ip-recursive":{ + "category":"Reverse proxy", + "type":"text", + "label":"Proxy real ip recursive", + "env":"PROXY_REAL_IP_RECURSIVE" + }, + "use-gzip":{ + "category":"Compression", + "type":"checkbox", + "label":"Use gzip", + "env":"USE_GZIP" + }, + "gzip-comp-level":{ + "category":"Compression", + "type":"text", + "label":"Gzip comp level", + "env":"GZIP_COMP_LEVEL" + }, + "gzip-min-length":{ + "category":"Compression", + "type":"text", + "label":"Gzip min length", + "env":"GZIP_MIN_LENGTH" + }, + "gzip-types":{ + "category":"Compression", + "type":"text", + "label":"Gzip types", + "env":"GZIP_TYPES" + }, + "use-brotli":{ + "category":"Compression", + "type":"checkbox", + "label":"Use brotli", + "env":"USE_BROTLI" + }, + "brotli-comp-level":{ + "category":"Compression", + "type":"text", + "label":"Brotli comp level", + "env":"BROTLI_COMP_LEVEL" + }, + "brotli-min-length":{ + "category":"Compression", + "type":"text", + "label":"Brotli min length", + "env":"BROTLI_MIN_LENGTH" + }, + "brotli-types":{ + "category":"Compression", + "type":"text", + "label":"Brotli types", + "env":"BROTLI_TYPES" + }, + "use-client-cache":{ + "category":"Cache", + "type":"checkbox", + "label":"Use client cache", + "env":"USE_CLIENT_CACHE" + }, + "client-cache-extensions":{ + "category":"Cache", + "type":"text", + "label":"Client cache extensions", + "env":"CLIENT_CACHE_EXTENSIONS" + }, + "client-cache-control":{ + "category":"Cache", + "type":"text", + "label":"Client cache control", + "env":"CLIENT_CACHE_CONTROL" + }, + "client-cache-etag":{ + "category":"Cache", + "type":"text", + "label":"Client cache etag", + "env":"CLIENT_CACHE_ETAG" + }, + "use-open-file-cache":{ + "category":"Cache", + "type":"checkbox", + "label":"Use open file cache", + "env":"USE_OPEN_FILE_CACHE" + }, + "open-file-cache":{ + "category":"Cache", + "type":"text", + "label":"Open file cache", + "env":"OPEN_FILE_CACHE" + }, + "open-file-cache-errors":{ + "category":"Cache", + "type":"text", + "label":"Open file cache errors", + "env":"OPEN_FILE_CACHE_ERRORS" + }, + "open-file-cache-min-uses":{ + "category":"Cache", + "type":"text", + "label":"Open file cache min uses", + "env":"OPEN_FILE_CACHE_MIN_USES" + }, + "open-file-cache-valid":{ + "category":"Cache", + "type":"text", + "label":"Open file cache valid", + "env":"OPEN_FILE_CACHE_VALID" + }, + "use-proxy-cache":{ + "category":"Cache", + "type":"checkbox", + "label":"Use proxy cache", + "env":"USE_PROXY_CACHE" + }, + "proxy-cache-path-zone-size":{ + "category":"Cache", + "type":"text", + "label":"Proxy cache path zone size", + "env":"PROXY_CACHE_PATH_ZONE_SIZE" + }, + "proxy-cache-path-params":{ + "category":"Cache", + "type":"text", + "label":"Proxy cache path params", + "env":"PROXY_CACHE_PATH_PARAMS" + }, + "proxy-cache-methods":{ + "category":"Cache", + "type":"text", + "label":"Proxy cache methods", + "env":"PROXY_CACHE_METHODS" + }, + "proxy-cache-min-uses":{ + "category":"Cache", + "type":"text", + "label":"Proxy cache min uses", + "env":"PROXY_CACHE_MIN_USES" + }, + "proxy-cache-key":{ + "category":"Cache", + "type":"text", + "label":"Proxy cache key", + "env":"PROXY_CACHE_KEY" + }, + "proxy-cache-valid":{ + "category":"Cache", + "type":"text", + "label":"Proxy cache valid", + "env":"PROXY_CACHE_VALID" + }, + "proxy-no-cache":{ + "category":"Cache", + "type":"text", + "label":"Proxy no cache", + "env":"PROXY_NO_CACHE" + }, + "proxy-cache-bypass":{ + "category":"Cache", + "type":"text", + "label":"Proxy cache bypass", + "env":"PROXY_CACHE_BYPASS" + }, + "auto-lets-encrypt":{ + "category":"HTTPS", + "type":"checkbox", + "label":"Auto lets encrypt", + "env":"AUTO_LETS_ENCRYPT" + }, + "email-lets-encrypt":{ + "category":"HTTPS", + "type":"text", + "label":"Email lets encrypt", + "env":"EMAIL_LETS_ENCRYPT" + }, + "listen-http":{ + "category":"", + "type":"checkbox", + "label":"Listen http", + "env":"LISTEN_HTTP" + }, + "redirect-http-to-https":{ + "category":"HTTPS", + "type":"checkbox", + "label":"Redirect http to https", + "env":"REDIRECT_HTTP_TO_HTTPS" + }, + "http2":{ + "category":"HTTPS", + "type":"checkbox", + "label":"HTTP2", + "env":"HTTP2" + }, + "https-protocols":{ + "category":"HTTPS", + "type":"text", + "label":"HTTPS protocols", + "env":"HTTPS_PROTOCOLS" + }, + "use-modsecurity":{ + "category":"ModSecurity", + "type":"checkbox", + "label":"Use modsecurity", + "env":"USE_MODSECURITY" + }, + "use-modsecurity-crs":{ + "category":"ModSecurity", + "type":"checkbox", + "label":"Use modsecurity crs", + "env":"USE_MODSECURITY_CRS" + }, + "x-frame-options":{ + "category":"Headers", + "type":"text", + "label":"X frame options", + "env":"X_FRAME_OPTIONS" + }, + "x-xss-protection":{ + "category":"Headers", + "type":"text", + "label":"X xss protection", + "env":"X_XSS_PROTECTION" + }, + "x-content-type-options":{ + "category":"Headers", + "type":"text", + "label":"X content type options", + "env":"X_CONTENT_TYPE_OPTIONS" + }, + "referrer-policy":{ + "category":"Headers", + "type":"text", + "label":"Referrer policy", + "env":"REFERRER_POLICY" + }, + "feature-policy":{ + "category":"Headers", + "type":"text", + "label":"Feature policy", + "env":"FEATURE_POLICY" + }, + "permissions-policy":{ + "category":"Headers", + "type":"text", + "label":"Permissions policy", + "env":"PERMISSIONS_POLICY" + }, + "cookie-flags":{ + "category":"Headers", + "type":"text", + "label":"Cookie flags", + "env":"COOKIE_FLAGS" + }, + "cookie-auto-secure-flag":{ + "category":"Headers", + "type":"checkbox", + "label":"Cookie auto secure flag", + "env":"COOKIE_AUTO_SECURE_FLAG" + }, + "strict-transport-security":{ + "category":"Headers", + "type":"text", + "label":"Strict transport security", + "env":"STRICT_TRANSPORT_SECURITY" + }, + "content-security-policy":{ + "category":"Headers", + "type":"text", + "label":"Content security policy", + "env":"CONTENT_SECURITY_POLICY" + }, + "use-antibot":{ + "category":"Antibot", + "type":"text", + "label":"Use antibot", + "env":"USE_ANTIBOT" + }, + "antibot-uri":{ + "category":"Antibot", + "type":"text", + "label":"Antibot uri", + "env":"ANTIBOT_URI" + }, + "antibot-session-secret":{ + "category":"Antibot", + "type":"text", + "label":"Antibot session secret", + "env":"ANTIBOT_SESSION_SECRET" + }, + "antibot-recaptcha-score":{ + "category":"Antibot", + "type":"text", + "label":"Antibot recaptcha score", + "env":"ANTIBOT_RECAPTCHA_SCORE" + }, + "block-user-agent":{ + "category":"Block", + "type":"checkbox", + "label":"Block user agent", + "env":"BLOCK_USER_AGENT" + }, + "block-tor-exit-node":{ + "category":"Block", + "type":"checkbox", + "label":"Block tor exit node", + "env":"BLOCK_TOR_EXIT_NODE" + }, + "block-proxies":{ + "category":"Block", + "type":"checkbox", + "label":"Block proxies", + "env":"BLOCK_PROXIES" + }, + "block-abusers":{ + "category":"Block", + "type":"checkbox", + "label":"Block abusers", + "env":"BLOCK_ABUSERS" + }, + "block-referrer":{ + "category":"Block", + "type":"checkbox", + "label":"Block referrer", + "env":"BLOCK_REFERRER" + }, + "use-dnsbl":{ + "category":"DNSBL", + "type":"checkbox", + "label":"Use dnsbl", + "env":"USE_DNSBL" + }, + "use-crowdsec":{ + "category":"CrowdSec", + "type":"checkbox", + "label":"Use crowdsec", + "env":"USE_CROWDSEC" + }, + "use-whitelist-ip":{ + "category":"Whitelist", + "type":"checkbox", + "label":"Use whitelist ip", + "env":"USE_WHITELIST_IP" + }, + "use-whitelist-reverse":{ + "category":"Whitelist", + "type":"checkbox", + "label":"Use whitelist reverse", + "env":"USE_WHITELIST_REVERSE" + }, + "use-blacklist-ip":{ + "category":"Blacklist", + "type":"checkbox", + "label":"Use blacklist ip", + "env":"USE_BLACKLIST_IP" + }, + "use-blacklist-reverse":{ + "category":"Blacklist", + "type":"checkbox", + "label":"Use blacklist reverse", + "env":"USE_BLACKLIST_REVERSE" + }, + "use-limit-req":{ + "category":"Limit req", + "type":"checkbox", + "label":"Use limit req", + "env":"USE_LIMIT_REQ" + }, + "limit-req-rate":{ + "category":"Limit req", + "type":"text", + "label":"Limit req rate", + "env":"LIMIT_REQ_RATE" + }, + "limit-req-burst":{ + "category":"Limit req", + "type":"text", + "label":"Limit req burst", + "env":"LIMIT_REQ_BURST" + }, + "blacklist-country":{ + "category":"Blacklist", + "type":"text", + "label":"Blacklist country", + "env":"BLACKLIST_COUNTRY" + }, + "whitelist-country":{ + "category":"Whitelist", + "type":"text", + "label":"Whitelist country", + "env":"WHITELIST_COUNTRY" + }, + "remote-php":{ + "category":"PHP", + "type":"text", + "label":"Remote php", + "env":"REMOTE_PHP" + }, + "remote-php-path":{ + "category":"PHP", + "type":"text", + "label":"Remote php path", + "env":"REMOTE_PHP_PATH" + }, + "use-fail2ban":{ + "category":"PHP", + "type":"checkbox", + "label":"Use fail2ban", + "env":"USE_FAIL2BAN" + }, + "use-clamav-upload":{ + "category":"ClamAV", + "type":"checkbox", + "label":"Use clamav upload", + "env":"USE_CLAMAV_UPLOAD" + } +} diff --git a/ui/entrypoint.py b/ui/entrypoint.py index 7e3f9ac..fd63e34 100644 --- a/ui/entrypoint.py +++ b/ui/entrypoint.py @@ -3,14 +3,25 @@ from flask import Flask, render_template, current_app import wrappers, utils -import os +import os, json app = Flask(__name__, static_url_path="/", static_folder="static", template_folder="templates") ABSOLUTE_URI = "" if "ABSOLUTE_URI" in os.environ : ABSOLUTE_URI = os.environ["ABSOLUTE_URI"] app.config["ABSOLUTE_URI"] = ABSOLUTE_URI +with open("/opt/entrypoint/config.json", "r") as f : + config = json.loads(f.read()) +app.config["CONFIG"] = {} +for k in config : + if not config[k]["category"] in app.config["CONFIG"] : + app.config["CONFIG"][config[k]["category"]] = [] + tmp = config[k].copy() + tmp["id"] = k + app.config["CONFIG"][config[k]["category"]].append(tmp) + app.jinja_env.globals.update(env_to_summary_class=utils.env_to_summary_class) +app.jinja_env.globals.update(form_service_gen=utils.form_service_gen) @app.route('/') @app.route('/home') diff --git a/ui/templates/services-delete.html b/ui/templates/services-delete.html new file mode 100644 index 0000000..50775f3 --- /dev/null +++ b/ui/templates/services-delete.html @@ -0,0 +1,17 @@ + diff --git a/ui/templates/services-edit.html b/ui/templates/services-edit.html new file mode 100644 index 0000000..e8a9a6a --- /dev/null +++ b/ui/templates/services-edit.html @@ -0,0 +1,42 @@ +{% set id_server_name = service["SERVER_NAME"].replace(".", "-") %} + + diff --git a/ui/templates/services.html b/ui/templates/services.html index 480031c..2d388e0 100644 --- a/ui/templates/services.html +++ b/ui/templates/services.html @@ -5,6 +5,7 @@
{% for service in services %} +
@@ -38,40 +39,11 @@
- - + + {% include "services-edit.html" %} + + {% include "services-delete.html" %} + {% endfor %}
diff --git a/ui/utils.py b/ui/utils.py index 520961e..7383d42 100644 --- a/ui/utils.py +++ b/ui/utils.py @@ -23,3 +23,19 @@ def env_to_summary_class(var, value) : if re.search(value, var) : return "check text-success" return "times text-danger" + +def form_service_gen(form, server, id, label, type, value) : + if form == "edit" : + new_id = "form-edit-" + server.replace(".", "-") + "-" + id + elif form == "new" : + new_id = "form-new-" + id + if type == "text" : + input = '' % (type, new_id, value) + pt = "" + elif type == "checkbox" : + checked = "" + if value == "yes" : + checked = "checked" + input = '
' % (type, new_id, checked) + pt = "pt-0" + return '
%s
' % (new_id, pt, label, input)