Merge pull request #516 from bunkerity/dev

Merge branch "dev" into branch "staging"
This commit is contained in:
Théophile Diot 2023-06-05 22:36:25 -04:00 committed by GitHub
commit a23d189d3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 112 additions and 81 deletions

View File

@ -8,9 +8,6 @@ RUN mkdir -p /usr/share/bunkerweb/deps && \
cat /tmp/req/requirements.txt /tmp/req/requirements.txt.1 > /usr/share/bunkerweb/deps/requirements.txt && \
rm -rf /tmp/req
# Update apk
RUN apk update
# Install python dependencies
RUN apk add --no-cache --virtual .build-deps g++ gcc musl-dev jpeg-dev zlib-dev libffi-dev cairo-dev pango-dev gdk-pixbuf-dev openssl-dev cargo postgresql-dev

View File

@ -3,9 +3,6 @@ FROM nginx:1.24.0-alpine AS builder
# Copy dependencies sources folder
COPY src/deps /tmp/bunkerweb/deps
# Update apk
RUN apk update
# Compile and install dependencies
RUN apk add --no-cache --virtual .build-deps bash autoconf libtool automake geoip-dev g++ gcc curl-dev libxml2-dev pcre-dev make linux-headers musl-dev gd-dev gnupg brotli-dev openssl-dev patch readline-dev && \
mkdir -p /usr/share/bunkerweb/deps && \

View File

@ -0,0 +1,9 @@
{% for k, v in all.items() %}
{% if k.startswith("COOKIE_FLAGS") and v != "" +%}
{% if COOKIE_AUTO_SECURE_FLAG == "yes" and (AUTO_LETS_ENCRYPT == "yes" or USE_CUSTOM_SSL == "yes" or GENERATE_SELF_SIGNED_SSL == "yes") +%}
set_cookie_flag {{ v }} secure;
{% else +%}
set_cookie_flag {{ v }};
{% endif +%}
{% endif +%}
{% endfor %}

View File

@ -1,5 +0,0 @@
{% for k, v in all.items() +%}
{% if k.startswith("CUSTOM_HEADER") and v != "" +%}
more_set_headers "{{ v }}";
{% endif %}
{% endfor %}

View File

@ -1,5 +0,0 @@
{% if REMOVE_HEADERS != "" %}
{% for header in REMOVE_HEADERS.split(" ") +%}
more_clear_headers '{{ header }}';
{% endfor %}
{% endif %}

View File

@ -1,41 +0,0 @@
{% if STRICT_TRANSPORT_SECURITY != "" and (AUTO_LETS_ENCRYPT == "yes" or USE_CUSTOM_SSL == "yes" or GENERATE_SELF_SIGNED_SSL == "yes") +%}
more_set_headers "Strict-Transport-Security: {{ STRICT_TRANSPORT_SECURITY }}";
{% endif +%}
{% for k, v in all.items() %}
{% if k.startswith("COOKIE_FLAGS") and v != "" +%}
{% if COOKIE_AUTO_SECURE_FLAG == "yes" and (AUTO_LETS_ENCRYPT == "yes" or USE_CUSTOM_SSL == "yes" or GENERATE_SELF_SIGNED_SSL == "yes") +%}
set_cookie_flag {{ v }} secure;
{% else +%}
set_cookie_flag {{ v }};
{% endif +%}
{% endif +%}
{% endfor %}
{% if CONTENT_SECURITY_POLICY != "" +%}
more_set_headers "Content-Security-Policy: {{ CONTENT_SECURITY_POLICY }}";
{% endif +%}
{% if REFERRER_POLICY != "" +%}
more_set_headers "Referrer-Policy: {{ REFERRER_POLICY }}";
{% endif +%}
{% if PERMISSIONS_POLICY != "" +%}
more_set_headers "Permissions-Policy: {{ PERMISSIONS_POLICY }}";
{% endif +%}
{% if FEATURE_POLICY != "" +%}
more_set_headers "Feature-Policy: {{ FEATURE_POLICY }}";
{% endif +%}
{% if X_FRAME_OPTIONS != "" +%}
more_set_headers "X-Frame-Options: {{ X_FRAME_OPTIONS }}";
{% endif +%}
{% if X_CONTENT_TYPE_OPTIONS != "" +%}
more_set_headers "X-Content-Type-Options: {{ X_CONTENT_TYPE_OPTIONS }}";
{% endif +%}
{% if X_XSS_PROTECTION != "" +%}
more_set_headers "X-XSS-Protection: {{ X_XSS_PROTECTION }}";
{% endif +%}

View File

@ -0,0 +1,71 @@
local class = require "middleclass"
local plugin = require "bunkerweb.plugin"
local utils = require "bunkerweb.utils"
local headers = class("headers", plugin)
function headers:initialize()
-- Call parent initialize
plugin.initialize(self, "headers")
self.all_headers = {
["STRICT_TRANSPORT_SECURITY"] = "Strict-Transport-Security",
["CONTENT_SECURITY_POLICY"] = "Content-Security-Policy",
["REFERRER_POLICY"] = "Referrer-Policy",
["PERMISSIONS_POLICY"] = "Permissions-Policy",
["FEATURE_POLICY"] = "Feature-Policy",
["X_FRAME_OPTIONS"] = "X-Frame-Options",
["X_CONTENT_TYPE_OPTIONS"] = "X-Content-Type-Options",
["X_XSS_PROTECTION"] = "X-XSS-Protection"
}
end
function headers:header()
-- Override upstream headers if needed
local ssl = utils.get_variable("AUTO_LETS_ENCRYPT") == "yes" or utils.get_variable("USE_CUSTOM_SSL") == "yes" or utils.get_variable("GENERATE_SELF_SIGNED_SSL") == "yes"
for variable, header in pairs(self.all_headers) do
if ngx.header[header] == nil or self.variables[variable] and self.variables["KEEP_UPSTREAM_HEADERS"] ~= "*" and utils.regex_match(self.variables["KEEP_UPSTREAM_HEADERS"], "(^| )" .. header .. "($| )") == nil then
if header ~= "Strict-Transport-Security" or ssl then
ngx.header[header] = self.variables[variable]
end
end
end
-- Get variables
local variables, err = utils.get_multiple_variables({ "CUSTOM_HEADER" })
if variables == nil then
return self:ret(false, err)
end
-- Add custom headers
for srv, vars in pairs(variables) do
if srv == ngx.ctx.bw.server_name then
for var, value in pairs(vars) do
if utils.regex_match(var, "CUSTOM_HEADER") and value then
local m = utils.regex_match(value, "([\\w-]+): ([^,]+)")
if m then
ngx.header[m[1]] = m[2]
end
end
end
end
end
-- Remove headers
if self.variables["REMOVE_HEADERS"] ~= "" then
local iterator, err = ngx.re.gmatch(self.variables["REMOVE_HEADERS"], "([\\w-]+)")
if not iterator then
return self:ret(false, "Error while matching remove headers: " .. err)
end
while true do
local m, err = iterator()
if err then
return self:ret(false, "Error while matching remove headers: " .. err)
end
if not m then
-- No more remove headers
break
end
ngx.header[m[1]] = nil
end
end
return self:ret(true, "Edited headers for request")
end
return headers

View File

@ -11,7 +11,7 @@
"help": "Custom header to add (HeaderName: HeaderValue).",
"id": "custom-header",
"label": "Custom header (HeaderName: HeaderValue)",
"regex": "^([\\w-]+: .+)?$",
"regex": "^([\\w-]+: [^,]+)?$",
"type": "text",
"multiple": "custom-headers"
},
@ -24,6 +24,15 @@
"regex": "^(?! )( ?[\\w-]+)*$",
"type": "text"
},
"KEEP_UPSTREAM_HEADERS": {
"context": "multisite",
"default": "*",
"help": "Headers to keep from upstream (Header1 Header2 Header3 ... or * for all).",
"id": "keep-upstream-headers",
"label": "Keep upstream headers",
"regex": "^((?! )( ?[\\w-]+)+|\\*)?$",
"type": "text"
},
"STRICT_TRANSPORT_SECURITY": {
"context": "multisite",
"default": "max-age=31536000",

View File

@ -9,9 +9,6 @@ RUN mkdir -p /usr/share/bunkerweb/deps && \
cat /tmp/req/requirements.txt /tmp/req/requirements.txt.1 /tmp/req/requirements.txt.2 > /usr/share/bunkerweb/deps/requirements.txt && \
rm -rf /tmp/req
# Update apk
RUN apk update
# Install python dependencies
RUN apk add --no-cache --virtual .build-deps g++ gcc musl-dev jpeg-dev zlib-dev libffi-dev cairo-dev pango-dev gdk-pixbuf-dev openssl-dev cargo postgresql-dev

View File

@ -9,9 +9,6 @@ RUN mkdir -p /usr/share/bunkerweb/deps && \
cat /tmp/req/requirements.txt /tmp/req/requirements.txt.1 /tmp/req/requirements.txt.2 > /usr/share/bunkerweb/deps/requirements.txt && \
rm -rf /tmp/req
# Update apk
RUN apk update
# Install python dependencies
RUN apk add --no-cache --virtual .build-deps g++ gcc musl-dev jpeg-dev zlib-dev libffi-dev cairo-dev pango-dev gdk-pixbuf-dev openssl-dev cargo postgresql-dev file make

View File

@ -247,10 +247,6 @@ def update_config():
server_name = service.get("SERVER_NAME", {"value": None})["value"]
endpoint = service.get("REVERSE_PROXY_URL", {"value": "/"})["value"]
logger.warning(service.get("AUTO_LETS_ENCRYPT", {"value": "no"}))
logger.warning(service.get("GENERATE_SELF_SIGNED_SSL", {"value": "no"}))
logger.warning(service.get("USE_CUSTOM_SSL", {"value": "no"}))
if any(
[
service.get("AUTO_LETS_ENCRYPT", {"value": "no"})["value"] == "yes",
@ -282,9 +278,9 @@ def update_config():
if SCRIPT_NAME != getenv("SCRIPT_NAME"):
environ["SCRIPT_NAME"] = f"/{basename(ABSOLUTE_URI[:-1])}"
logger.info(f"The script name is now {environ['SCRIPT_NAME']}")
logger.info(f"The SCRIPT_NAME is now {environ['SCRIPT_NAME']}")
else:
logger.info(f"The script name is still {environ['SCRIPT_NAME']}")
logger.info(f"The SCRIPT_NAME is still {environ['SCRIPT_NAME']}")
def check_config_changes():
@ -387,6 +383,15 @@ def manage_bunkerweb(method: str, *args, operation: str = "reloads"):
app.config["RELOADING"] = False
@app.after_request
def set_csp_header(response):
"""Set the Content-Security-Policy header to prevent XSS attacks."""
response.headers[
"Content-Security-Policy"
] = "object-src 'none'; frame-ancestors 'self';"
return response
@login_manager.user_loader
def load_user(user_id):
return User(user_id, vars["ADMIN_PASSWORD"])

View File

@ -68,10 +68,10 @@ try:
exit(1)
elif bad_behavior_ban_time != "86400":
print(
" Sleeping for 7s to wait if Bad Behavior's ban time changed ...",
" Sleeping for 65s to wait if Bad Behavior's ban time changed ...",
flush=True,
)
sleep(7)
sleep(65)
status_code = get(
f"http://www.example.com",
@ -86,11 +86,11 @@ try:
exit(1)
elif bad_behavior_count_time != "60":
print(
" Sleeping for 7s to wait if Bad Behavior's count time changed ...",
" Sleeping for 35s to wait if Bad Behavior's count time changed ...",
flush=True,
)
current_time = datetime.now().timestamp()
sleep(7)
sleep(35)
print(
" Checking BunkerWeb's logs to see if Bad Behavior's count time changed ...",

View File

@ -21,9 +21,9 @@ cleanup_stack () {
if [[ $end -eq 1 || $exit_code = 1 ]] || [[ $end -eq 0 && $exit_code = 0 ]] && [ $manual = 0 ] ; then
find . -type f -name 'docker-compose.*' -exec sed -i 's@USE_BAD_BEHAVIOR: "no"@USE_BAD_BEHAVIOR: "yes"@' {} \;
find . -type f -name 'docker-compose.*' -exec sed -i 's@BAD_BEHAVIOR_STATUS_CODES: "400 401 404 405 429 444"@BAD_BEHAVIOR_STATUS_CODES: "400 401 403 404 405 429 444"@' {} \;
find . -type f -name 'docker-compose.*' -exec sed -i 's@BAD_BEHAVIOR_BAN_TIME: "5"@BAD_BEHAVIOR_BAN_TIME: "86400"@' {} \;
find . -type f -name 'docker-compose.*' -exec sed -i 's@BAD_BEHAVIOR_BAN_TIME: "60"@BAD_BEHAVIOR_BAN_TIME: "86400"@' {} \;
find . -type f -name 'docker-compose.*' -exec sed -i 's@BAD_BEHAVIOR_THRESHOLD: "20"@BAD_BEHAVIOR_THRESHOLD: "10"@' {} \;
find . -type f -name 'docker-compose.*' -exec sed -i 's@BAD_BEHAVIOR_COUNT_TIME: "5"@BAD_BEHAVIOR_COUNT_TIME: "60"@' {} \;
find . -type f -name 'docker-compose.*' -exec sed -i 's@BAD_BEHAVIOR_COUNT_TIME: "30"@BAD_BEHAVIOR_COUNT_TIME: "60"@' {} \;
if [[ $end -eq 1 && $exit_code = 0 ]] ; then
return
fi
@ -56,17 +56,17 @@ do
find . -type f -name 'docker-compose.*' -exec sed -i 's@USE_BAD_BEHAVIOR: "no"@USE_BAD_BEHAVIOR: "yes"@' {} \;
find . -type f -name 'docker-compose.*' -exec sed -i 's@BAD_BEHAVIOR_STATUS_CODES: "400 401 403 404 405 429 444"@BAD_BEHAVIOR_STATUS_CODES: "400 401 404 405 429 444"@' {} \;
elif [ "$test" = "ban_time" ] ; then
echo "📟 Running tests with badbehavior's ban time changed to 5 seconds ..."
echo "📟 Running tests with badbehavior's ban time changed to 60 seconds ..."
find . -type f -name 'docker-compose.*' -exec sed -i 's@BAD_BEHAVIOR_STATUS_CODES: "400 401 404 405 429 444"@BAD_BEHAVIOR_STATUS_CODES: "400 401 403 404 405 429 444"@' {} \;
find . -type f -name 'docker-compose.*' -exec sed -i 's@BAD_BEHAVIOR_BAN_TIME: "86400"@BAD_BEHAVIOR_BAN_TIME: "5"@' {} \;
find . -type f -name 'docker-compose.*' -exec sed -i 's@BAD_BEHAVIOR_BAN_TIME: "86400"@BAD_BEHAVIOR_BAN_TIME: "60"@' {} \;
elif [ "$test" = "threshold" ] ; then
echo "📟 Running tests with badbehavior's threshold set to 20 ..."
find . -type f -name 'docker-compose.*' -exec sed -i 's@BAD_BEHAVIOR_BAN_TIME: "5"@BAD_BEHAVIOR_BAN_TIME: "86400"@' {} \;
find . -type f -name 'docker-compose.*' -exec sed -i 's@BAD_BEHAVIOR_BAN_TIME: "60"@BAD_BEHAVIOR_BAN_TIME: "86400"@' {} \;
find . -type f -name 'docker-compose.*' -exec sed -i 's@BAD_BEHAVIOR_THRESHOLD: "10"@BAD_BEHAVIOR_THRESHOLD: "20"@' {} \;
elif [ "$test" = "count_time" ] ; then
echo "📟 Running tests with badbehavior's count time set to 5 seconds ..."
echo "📟 Running tests with badbehavior's count time set to 30 seconds ..."
find . -type f -name 'docker-compose.*' -exec sed -i 's@BAD_BEHAVIOR_THRESHOLD: "20"@BAD_BEHAVIOR_THRESHOLD: "10"@' {} \;
find . -type f -name 'docker-compose.*' -exec sed -i 's@BAD_BEHAVIOR_COUNT_TIME: "60"@BAD_BEHAVIOR_COUNT_TIME: "5"@' {} \;
find . -type f -name 'docker-compose.*' -exec sed -i 's@BAD_BEHAVIOR_COUNT_TIME: "60"@BAD_BEHAVIOR_COUNT_TIME: "30"@' {} \;
fi
echo "📟 Starting stack ..."