templating - added missing features in site templates

This commit is contained in:
bunkerity 2021-05-25 17:07:06 +02:00
parent 23aa053003
commit ec19f93081
No known key found for this signature in database
GPG Key ID: 3D80806F12602A7C
8 changed files with 119 additions and 30 deletions

View File

@ -1,7 +1,13 @@
error_page {{ CODE }} {{ PAGE }};
{% if ERRORS != "" %}
{% for element in ERRORS.split(" ") %}
{% set code = element.split("=")[0] %}
{% set page = element.split("=")[1] %}
error_page {{ code }} {{ page }};
location = {{ PAGE }} {
location = {{ page }} {
root {{ ROOT_FOLDER }};
modsecurity off;
internal;
}
{% endfor %}
{% endif %}

View File

@ -1,4 +1,8 @@
{% if ANTIBOT_SESSION_SECRET == "random" %}
set $session_secret {{ random(32) }} ;
{% else %}
set $session_secret {{ ANTIBOT_SESSION_SECRET }};
{% endif %}
set $session_check_addr on;
access_by_lua_block {

View File

@ -58,13 +58,26 @@ SecAuditLog /var/log/nginx/modsec_audit.log
include {{ NGINX_PREFIX }}modsecurity-clamav.conf
{% endif %}
# include OWASP CRS rules
# include OWASP CRS configuration
{% if USE_MODSECURITY_CRS == "yes" %}
include /opt/owasp/crs.conf
# TODO : include without errors ?
#{{ MODSECURITY_INCLUDE_CUSTOM_CRS }}
# custom CRS configurations before loading rules (exclusions)
{% if is_custom_conf("/modsec-crs-confs") %}
include /modsec-crs-confs/*.conf
{% endif %}
{% if MULTISITE == "yes" and is_custom_conf("/modsec-crs-confs/" + FIRST_SERVER) %}
include /modsec-crs-confs/{{ FIRST_SERVER }}/*.conf
{% endif %}
# include OWASP CRS rules
include /opt/owasp/crs/*.conf
{% endif %}
# TODO : include custom rules
# {{ MODSECURITY_INCLUDE_CUSTOM_RULES }}
# custom rules after loading the CRS
{% if is_custom_conf("/modsec-confs") %}
include /modsec-confs/*.conf
{% endif %}
{% if MULTISITE == "yes" and is_custom_conf("/modsec-confs/" + FIRST_SERVER) %}
include /modsec-confs/{{ FIRST_SERVER }}/*.conf
{% endif %}

View File

@ -1,7 +1,25 @@
location {{ REVERSE_PROXY_URL }} {
{% if USE_REVERSE_PROXY == "yes" %}
{% for k, v in all.items() %}
{% if k.startswith("REVERSE_PROXY_URL") %}
{% set url = v %}
{% set host = all[k.replace("URL", "HOST")] if k.replace("URL", "HOST") in all else "" %}
{% set ws = all[k.replace("URL", "WS")] if k.replace("URL", "WS") in all else "" %}
{% set headers = all[k.replace("URL", "HEADERS")] if k.replace("URL", "HEADERS") in all else "" %}
location {{ url }} {% raw %}{{% endraw %}
etag off;
proxy_pass {{ REVERSE_PROXY_HOST }};
{{ REVERSE_PROXY_HEADERS }}
{{ REVERSE_PROXY_WS }}
{{ REVERSE_PROXY_CUSTOM_HEADERS }}
}
proxy_pass {{ host }};
include {{ NGINX_PREFIX }}reverse-proxy-headers.conf;
{% if ws == "yes" %}
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
{% endif %}
{% if headers != "" %}
{% for header in headers.split(";") %}
proxy_set_header {{ header }};
{% endfor %}
{% endif %}
{% raw %}}{% endraw %}
{% endif %}
{% endfor %}
{% endif %}

View File

@ -130,7 +130,8 @@ server {
include {{ NGINX_PREFIX }}cookie-flags.conf;
{% endif %}
# TODO : ERRORS
# custom errors
include {{ NGINX_PREFIX }}error.conf;
# client caching
{% if USE_CLIENT_CACHE == "yes" %}
@ -165,7 +166,7 @@ server {
# reverse proxy
{% if USE_REVERSE_PROXY == "yes" %}
include {{ NGINX_PREFIX }}reverse-proxy-*.conf;
include {{ NGINX_PREFIX }}reverse-proxy.conf;
{% endif %}
# remote PHP

View File

@ -40,4 +40,9 @@ class Configurator :
real_var = var
elif var[len(var.split("_")[0])+1:] in self.__settings :
real_var = var[len(var.split("_")[0])+1:]
elif re.search("\\_\d+$", var) and ("_".join(var.split("_")[:-1]) in self.__settings or "_".join(var.split("_")[:-1][1:]) in self.__settings) :
if "_".join(var.split("_")[:-1]) in self.__settings :
real_var = "_".join(var.split("_")[:-1])
else :
real_var = "_".join(var.split("_")[:-1][1:])
return real_var != "" and re.search(self.__settings[real_var]["regex"], value) and (not multisite_only or self.__settings[real_var]["context"] == "multisite")

View File

@ -1,4 +1,4 @@
import jinja2, glob, os, pathlib, copy, crypt
import jinja2, glob, os, pathlib, copy, crypt, random, string
class Templator :
@ -21,7 +21,7 @@ class Templator :
first_server = self.__config["SERVER_NAME"].split(" ")[0]
return self.__render("site", server_name, first_server)
def __render(self, type, server_name=None, first_server=None) :
def __prepare_config(self, type, server_name=None, first_server=None) :
real_config = copy.deepcopy(self.__config)
if not server_name is None :
real_config["SERVER_NAME"] = server_name
@ -30,23 +30,48 @@ class Templator :
real_config["NGINX_PREFIX"] = self.__target_path
if real_config["MULTISITE"] == "yes" and type == "site" :
real_config["NGINX_PREFIX"] += first_server + "/"
real_config["ROOT_FOLDER"] += "/" + first_server
for variable, value in self.__config.items() :
if variable.startswith(first_server + "_") :
real_config[variable.replace(first_server + "_", "", 1)] = value
if real_config["ROOT_SITE_SUBFOLDER"] != "" :
real_config["ROOT_FOLDER"] += "/" + real_config["ROOT_SITE_SUBFOLDER"]
return real_config
def __save_config(self, type, config) :
data = ""
for variable, value in config.items() :
data += variable + "=" + value + "\n"
file = self.__output_path
if type == "global" :
file += "/global.env"
elif config["MULTISITE"] == "yes" :
file += "/" + config["FIRST_SERVER"] + "/site.env"
else :
file += "/site.env"
with open(file, "w") as f :
f.write(data)
def __render(self, type, server_name=None, first_server=None) :
real_config = self.__prepare_config(type, server_name, first_server)
for filename in glob.iglob(self.__input_path + "/" + type + "**/**", recursive=True) :
if os.path.isfile(filename) :
relative_filename = filename.replace(self.__input_path, "").replace(type + "/", "")
template = self.__template_env.get_template(type + "/" + relative_filename)
template.globals["has_value"] = Templator.has_value
template.globals["sha512_crypt"] = Templator.sha512_crypt
output = template.render(real_config, all=real_config)
if real_config["MULTISITE"] == "yes" and type == "site" :
relative_filename = first_server + "/" + relative_filename
if "/" in relative_filename :
directory = relative_filename.replace(relative_filename.split("/")[-1], "")
pathlib.Path(self.__output_path + "/" + directory).mkdir(parents=True, exist_ok=True)
with open(self.__output_path + "/" + relative_filename, "w") as f :
f.write(output)
if not os.path.isfile(filename) :
continue
relative_filename = filename.replace(self.__input_path, "").replace(type + "/", "")
template = self.__template_env.get_template(type + "/" + relative_filename)
template.globals["has_value"] = Templator.has_value
template.globals["sha512_crypt"] = Templator.sha512_crypt
template.globals["is_custom_conf"] = Templator.is_custom_conf
template.globals["random"] = Templator.random
output = template.render(real_config, all=real_config)
if real_config["MULTISITE"] == "yes" and type == "site" :
relative_filename = real_config["FIRST_SERVER"] + "/" + relative_filename
if "/" in relative_filename :
directory = relative_filename.replace(relative_filename.split("/")[-1], "")
pathlib.Path(self.__output_path + "/" + directory).mkdir(parents=True, exist_ok=True)
with open(self.__output_path + "/" + relative_filename, "w") as f :
f.write(output)
self.__save_config(type, real_config)
@jinja2.contextfunction
def has_value(context, name, value) :
@ -57,3 +82,11 @@ class Templator :
def sha512_crypt(password) :
return crypt.crypt(password, crypt.mksalt(crypt.METHOD_SHA512))
def is_custom_conf(folder) :
for filename in glob.iglob(folder + "/*.conf") :
return True
return False
def random(number) :
return "".join(random.choices(string.ascii_uppercase + string.ascii_lowercase + string.digits, k=number))

View File

@ -749,6 +749,15 @@
"label": "Disable default server",
"regex": "^(yes|no)$",
"type": "checkbox"
},
{
"context": "multisite",
"default": "",
"env": "ERRORS",
"id": "errors",
"label": "Custom error pages (code1=/page1 code2=/page2 ...)",
"regex": ".*",
"type": "text"
}
]
},