From 75f3d6490a9c425226a76fc22c6f01540320821d Mon Sep 17 00:00:00 2001 From: florian Date: Sat, 13 May 2023 18:37:13 +0200 Subject: [PATCH] init IPv6 support, add missing healthcheck script in UI and purge local cache on init --- src/bw/lua/bunkerweb/cachestore.lua | 4 ++ src/bw/lua/bunkerweb/utils.lua | 63 ++++++++++++++----- src/common/confs/default-server-http.conf | 6 ++ src/common/confs/http.conf | 2 +- src/common/confs/init-lua.conf | 7 +++ src/common/confs/init-stream-lua.conf | 7 +++ src/common/confs/server-http/server.conf | 3 + .../confs/server-stream/server-stream.conf | 3 + src/common/confs/stream.conf | 2 +- src/common/core/blacklist/blacklist.lua | 26 +++++--- .../confs/server-http/custom-cert.conf | 3 + .../confs/server-stream/custom-cert.conf | 3 + src/common/core/dnsbl/dnsbl.lua | 2 +- src/common/core/greylist/greylist.lua | 16 +++-- .../confs/server-http/lets-encrypt.conf | 3 + .../confs/server-stream/lets-encrypt.conf | 3 + .../confs/server-http/self-signed.conf | 3 + .../confs/server-stream/self-signed.conf | 3 + src/common/core/whitelist/whitelist.lua | 18 +++--- src/common/settings.json | 9 +++ src/ui/Dockerfile | 3 +- 21 files changed, 145 insertions(+), 44 deletions(-) diff --git a/src/bw/lua/bunkerweb/cachestore.lua b/src/bw/lua/bunkerweb/cachestore.lua index 2d94bc57..0c239c44 100644 --- a/src/bw/lua/bunkerweb/cachestore.lua +++ b/src/bw/lua/bunkerweb/cachestore.lua @@ -164,4 +164,8 @@ function cachestore:del_redis(key) return true end +function cachestore:purge() + return self.cache:purge(true) +end + return cachestore diff --git a/src/bw/lua/bunkerweb/utils.lua b/src/bw/lua/bunkerweb/utils.lua index ffaaa1ae..851f1b95 100644 --- a/src/bw/lua/bunkerweb/utils.lua +++ b/src/bw/lua/bunkerweb/utils.lua @@ -345,48 +345,77 @@ utils.get_rdns = function(ip) return false, err end if answers.errcode then - return false, answers.errstr + return {}, answers.errstr end - -- Return first element + -- Return all PTR + local ptrs = {} for i, answer in ipairs(answers) do if answer.ptrdname then - return answer.ptrdname, "success" + table.insert(ptrs, answer.ptrdname) end end - return false, nil + return ptrs, "success" end -utils.get_ips = function(fqdn) +utils.get_ips = function(fqdn, ipv6) + -- By default perform ipv6 lookups (only if USE_IPV6=yes) + if ipv6 == nil then + ipv6 = true + end -- Get resolvers local resolvers, err = utils.get_resolvers() if not resolvers then return false, err end -- Instantiante resolver - local rdns, err = resolver:new { + local res, err = resolver:new { nameservers = resolvers, retrans = 1, timeout = 1000 } - if not rdns then + if not res then return false, err end - -- Query FQDN - local answers, err = rdns:query(fqdn, nil, {}) - if not answers then - return false, err + -- Get query types : AAAA and A if using IPv6 / only A if not using IPv6 + local qtypes = {} + if ipv6 then + local use_ipv6, err = utils.get_variable("USE_IPV6", false) + if not use_ipv6 then + logger:log(ngx.ERR, "can't get USE_IPV6 variable " .. err) + elseif use_ipv6 == "yes" then + table.insert(qtypes, res.TYPE_AAAA) + end end - if answers.errcode then - return {}, answers.errstr + table.insert(qtypes, res.TYPE_A) + -- Loop on qtypes + local res_answers = {} + local res_errors = {} + local ans_errors = {} + for i, qtype in ipairs(qtypes) do + -- Query FQDN + local answers, err = res:query(fqdn, { qtype = qtype }, {}) + local qtype_str = qtype == res.TYPE_AAAA and "AAAA" or "A" + if not answers then + res_errors[qtype_str] = err + elseif answers.errcode then + ans_errors[qtype_str] = answers.errstr + else + table.insert(res_answers, answers) + end + end + if #res_errors == #qtypes then + return false, cjson.encode(res_errors) end -- Return all IPs local ips = {} - for i, answer in ipairs(answers) do - if answer.address then - table.insert(ips, answer.address) + for i, answers in ipairs(res_answers) do + for j, answer in ipairs(answers) do + if answer.address then + table.insert(ips, answer.address) + end end end - return ips, "success" + return ips, cjson.encode(res_errors) .. " " .. cjson.encode(ans_errors) end utils.get_country = function(ip) diff --git a/src/common/confs/default-server-http.conf b/src/common/confs/default-server-http.conf index 0f2301b6..75694224 100644 --- a/src/common/confs/default-server-http.conf +++ b/src/common/confs/default-server-http.conf @@ -9,12 +9,18 @@ server { {% if LISTEN_HTTP == "yes" +%} listen 0.0.0.0:{{ HTTP_PORT }} default_server {% if USE_PROXY_PROTOCOL == "yes" %}proxy_protocol{% endif %}; {% endif %} +{% if USE_IPV6 == "yes" +%} + listen [::]:{{ HTTP_PORT }} default_server {% if USE_PROXY_PROTOCOL == "yes" %}proxy_protocol{% endif %}; +{% endif %} # HTTPS listen {% set os = import("os") %} {% if os.path.isfile("/var/cache/bunkerweb/default-server-cert/cert.pem") +%} {% if has_variable(all, "USE_CUSTOM_SSL", "yes") or has_variable(all, "AUTO_LETS_ENCRYPT", "yes") or has_variable(all, "GENERATE_SELF_SIGNED_SSL", "yes") +%} listen 0.0.0.0:{{ HTTPS_PORT }} ssl {% if HTTP2 == "yes" %}http2{% endif %} default_server {% if USE_PROXY_PROTOCOL == "yes" %}proxy_protocol{% endif %}; + {% if USE_IPV6 == "yes" +%} + listen [::]:{{ HTTPS_PORT }} ssl {% if HTTP2 == "yes" %}http2{% endif %} default_server {% if USE_PROXY_PROTOCOL == "yes" %}proxy_protocol{% endif %}; + {% endif %} ssl_certificate /var/cache/bunkerweb/default-server-cert/cert.pem; ssl_certificate_key /var/cache/bunkerweb/default-server-cert/cert.key; {% endif %} diff --git a/src/common/confs/http.conf b/src/common/confs/http.conf index 8c31efbb..51bc9df0 100644 --- a/src/common/confs/http.conf +++ b/src/common/confs/http.conf @@ -34,7 +34,7 @@ keepalive_timeout 15; send_timeout 10; # resolvers to use -resolver {{ DNS_RESOLVERS }} ipv6=off; +resolver {{ DNS_RESOLVERS }} {% if USE_IPV6 == "no" %}ipv6=off{% endif %}; # remove ports when sending redirects port_in_redirect off; diff --git a/src/common/confs/init-lua.conf b/src/common/confs/init-lua.conf index dbd7bb38..d5f9f5c6 100644 --- a/src/common/confs/init-lua.conf +++ b/src/common/confs/init-lua.conf @@ -11,6 +11,13 @@ local logger = clogger:new("INIT") local datastore = cdatastore:new() logger:log(ngx.NOTICE, "init phase started") +-- Purge cache +local cachestore = require "bunkerweb.cachestore":new() +local ok, err = cachestore:purge() +if not ok then + logger:log(ngx.ERR, "can't purge cachestore : " .. err) +end + -- Remove previous data from the datastore logger:log(ngx.NOTICE, "deleting old keys from datastore ...") local data_keys = {"^plugin_", "^variable_", "^plugins$", "^api_", "^misc_"} diff --git a/src/common/confs/init-stream-lua.conf b/src/common/confs/init-stream-lua.conf index 07f2fb86..edb04b18 100644 --- a/src/common/confs/init-stream-lua.conf +++ b/src/common/confs/init-stream-lua.conf @@ -11,6 +11,13 @@ local logger = clogger:new("INIT-STREAM") local datastore = cdatastore:new() logger:log(ngx.NOTICE, "init-stream phase started") +-- Purge cache +local cachestore = require "bunkerweb.cachestore":new() +local ok, err = cachestore:purge() +if not ok then + logger:log(ngx.ERR, "can't purge cachestore : " .. err) +end + -- Remove previous data from the datastore logger:log(ngx.NOTICE, "deleting old keys from datastore ...") local data_keys = {"^plugin_", "^variable_", "^plugins$", "^api_", "^misc_"} diff --git a/src/common/confs/server-http/server.conf b/src/common/confs/server-http/server.conf index 138f527a..31a729fa 100644 --- a/src/common/confs/server-http/server.conf +++ b/src/common/confs/server-http/server.conf @@ -6,6 +6,9 @@ server { {% if LISTEN_HTTP == "yes" +%} listen 0.0.0.0:{{ HTTP_PORT }}{% if MULTISITE == "no" and DISABLE_DEFAULT_SERVER == "no" %} default_server{% endif %}{% if USE_PROXY_PROTOCOL == "yes" %} proxy_protocol{% endif %}; {% endif %} +{% if USE_IPV6 == "yes" +%} + listen [::]:{{ HTTP_PORT }}{% if MULTISITE == "no" and DISABLE_DEFAULT_SERVER == "no" %} default_server{% endif %}{% if USE_PROXY_PROTOCOL == "yes" %} proxy_protocol{% endif %}; +{% endif %} index index.php index.html index.htm; diff --git a/src/common/confs/server-stream/server-stream.conf b/src/common/confs/server-stream/server-stream.conf index cae07afe..6b7981a1 100644 --- a/src/common/confs/server-stream/server-stream.conf +++ b/src/common/confs/server-stream/server-stream.conf @@ -4,6 +4,9 @@ server { {% if LISTEN_STREAM == "yes" +%} listen 0.0.0.0:{{ LISTEN_STREAM_PORT }}{% if USE_UDP == "yes" %} udp {% endif %}{% if USE_PROXY_PROTOCOL == "yes" %} proxy_protocol {% endif %}; {% endif %} +{% if USE_IPV6 == "yes" +%} + listen [::]:{{ LISTEN_STREAM_PORT }}{% if USE_UDP == "yes" %} udp {% endif %}{% if USE_PROXY_PROTOCOL == "yes" %} proxy_protocol {% endif %}; +{% endif %} # custom config include /etc/bunkerweb/configs/server-stream/*.conf; diff --git a/src/common/confs/stream.conf b/src/common/confs/stream.conf index 1f51ffb0..bc330392 100644 --- a/src/common/confs/stream.conf +++ b/src/common/confs/stream.conf @@ -13,7 +13,7 @@ preread_timeout 30s; proxy_protocol_timeout 30s; # resolvers to use -resolver {{ DNS_RESOLVERS }} ipv6=off; +resolver {{ DNS_RESOLVERS }} {% if USE_IPV6 == "no" %}ipv6=off{% endif %}; # resolver timeout # TODO : global setting STREAM_RESOLVER_TIMEOUT diff --git a/src/common/core/blacklist/blacklist.lua b/src/common/core/blacklist/blacklist.lua index ddb8c97a..2a80cffd 100644 --- a/src/common/core/blacklist/blacklist.lua +++ b/src/common/core/blacklist/blacklist.lua @@ -224,24 +224,30 @@ function blacklist:is_blacklisted_ip() end if check_rdns then -- Get rDNS - local rdns, err = utils.get_rdns(ngx.ctx.bw.remote_addr) - if rdns then + local rdns_list, err = utils.get_rdns(ngx.ctx.bw.remote_addr) + if rdns_list then -- Check if rDNS is in ignore list local ignore = false - for i, ignore_suffix in ipairs(self.lists["IGNORE_RDNS"]) do - if rdns:sub(-#ignore_suffix) == ignore_suffix then - ignore = true - break + for i, rdns in ipairs(rdns_list) do + for j, suffix in ipairs(self.lists["IGNORE_RDNS"]) do + if rdns:sub(-#suffix) == suffix then + ignore = true + break + end end end -- Check if rDNS is in blacklist if not ignore then - for i, suffix in ipairs(self.lists["RDNS"]) do - if rdns:sub(-#suffix) == suffix then - return true, "rDNS " .. suffix + for i, rdns in ipairs(rdns_list) do + for j, suffix in ipairs(self.lists["RDNS"]) do + if rdns:sub(-#suffix) == suffix then + return true, "rDNS " .. suffix + end end end end + else + self.logger:log(ngx.ERR, "error while getting rdns : " .. err) end end @@ -249,7 +255,7 @@ function blacklist:is_blacklisted_ip() if ngx.ctx.bw.ip_is_global then local asn, err = utils.get_asn(ngx.ctx.bw.remote_addr) if not asn then - return nil, err + return nil, "ASN " .. err end local ignore = false for i, ignore_asn in ipairs(self.lists["IGNORE_ASN"]) do diff --git a/src/common/core/customcert/confs/server-http/custom-cert.conf b/src/common/core/customcert/confs/server-http/custom-cert.conf index 467ad931..421a334f 100644 --- a/src/common/core/customcert/confs/server-http/custom-cert.conf +++ b/src/common/core/customcert/confs/server-http/custom-cert.conf @@ -6,6 +6,9 @@ # listen on HTTPS PORT listen 0.0.0.0:{{ HTTPS_PORT }} ssl {% if HTTP2 == "yes" %}http2{% endif %} {% if USE_PROXY_PROTOCOL == "yes" %}proxy_protocol{% endif %}; +{% if USE_IPV6 == "yes" +%} +listen [::]:{{ HTTPS_PORT }} ssl {% if HTTP2 == "yes" %}http2{% endif %} {% if USE_PROXY_PROTOCOL == "yes" %}proxy_protocol{% endif %}; +{% endif %} # TLS config ssl_certificate {{ cert_file_path }}; diff --git a/src/common/core/customcert/confs/server-stream/custom-cert.conf b/src/common/core/customcert/confs/server-stream/custom-cert.conf index d24fa5ba..db5405de 100644 --- a/src/common/core/customcert/confs/server-stream/custom-cert.conf +++ b/src/common/core/customcert/confs/server-stream/custom-cert.conf @@ -6,6 +6,9 @@ # listen listen 0.0.0.0:{{ LISTEN_STREAM_PORT_SSL }} ssl {% if USE_UDP == "yes" %} udp {% endif %}{% if USE_PROXY_PROTOCOL == "yes" %} proxy_protocol {% endif %}; +{% if USE_IPV6 == "yes" +%} +listen [::]:{{ LISTEN_STREAM_PORT_SSL }} ssl {% if USE_UDP == "yes" %} udp {% endif %}{% if USE_PROXY_PROTOCOL == "yes" %} proxy_protocol {% endif %}; +{% endif %} # TLS config ssl_certificate {{ cert_file_path }}; diff --git a/src/common/core/dnsbl/dnsbl.lua b/src/common/core/dnsbl/dnsbl.lua index 7198547e..8fd28435 100644 --- a/src/common/core/dnsbl/dnsbl.lua +++ b/src/common/core/dnsbl/dnsbl.lua @@ -85,7 +85,7 @@ end function dnsbl:is_in_dnsbl(ip, server) local request = resolver.arpa_str(ip):gsub("%.in%-addr%.arpa", ""):gsub("%.ip6%.arpa", "") .. "." .. server - local ips, err = utils.get_ips(request) + local ips, err = utils.get_ips(request, false) if not ips then return nil, err end diff --git a/src/common/core/greylist/greylist.lua b/src/common/core/greylist/greylist.lua index 65bafc5e..162ffc6b 100644 --- a/src/common/core/greylist/greylist.lua +++ b/src/common/core/greylist/greylist.lua @@ -184,14 +184,18 @@ function greylist:is_greylisted_ip() end if check_rdns then -- Get rDNS - local rdns, err = utils.get_rdns(ngx.ctx.bw.remote_addr) + local rdns_list, err = utils.get_rdns(ngx.ctx.bw.remote_addr) -- Check if rDNS is in greylist - if rdns then - for i, suffix in ipairs(self.lists["RDNS"]) do - if rdns:sub(-#suffix) == suffix then - return true, "rDNS " .. suffix + if rdns_list then + for i, rdns in ipairs(rdns_list) do + for j, suffix in ipairs(self.lists["RDNS"]) do + if rdns:sub(-#suffix) == suffix then + return true, "rDNS " .. suffix + end end end + else + self.logger:log(ngx.ERR, "error while getting rdns : " .. err) end end @@ -199,7 +203,7 @@ function greylist:is_greylisted_ip() if ngx.ctx.bw.ip_is_global then local asn, err = utils.get_asn(ngx.ctx.bw.remote_addr) if not asn then - return nil, err + return nil, "ASN " .. err end for i, bl_asn in ipairs(self.lists["ASN"]) do if bl_asn == tostring(asn) then diff --git a/src/common/core/letsencrypt/confs/server-http/lets-encrypt.conf b/src/common/core/letsencrypt/confs/server-http/lets-encrypt.conf index 7472a9c5..6cf6f2bf 100644 --- a/src/common/core/letsencrypt/confs/server-http/lets-encrypt.conf +++ b/src/common/core/letsencrypt/confs/server-http/lets-encrypt.conf @@ -8,6 +8,9 @@ location ~ ^/.well-known/acme-challenge/ { # listen on HTTPS PORT listen 0.0.0.0:{{ HTTPS_PORT }} ssl {% if HTTP2 == "yes" %}http2{% endif %} {% if USE_PROXY_PROTOCOL == "yes" %}proxy_protocol{% endif %}; +{% if USE_IPV6 == "yes" +%} +listen [::]:{{ HTTPS_PORT }} ssl {% if HTTP2 == "yes" %}http2{% endif %} {% if USE_PROXY_PROTOCOL == "yes" %}proxy_protocol{% endif %}; +{% endif %} # TLS config ssl_certificate /var/cache/bunkerweb/letsencrypt/etc/live/{{ SERVER_NAME.split(" ")[0] }}/fullchain.pem; diff --git a/src/common/core/letsencrypt/confs/server-stream/lets-encrypt.conf b/src/common/core/letsencrypt/confs/server-stream/lets-encrypt.conf index ca76fdc7..6e07fd6e 100644 --- a/src/common/core/letsencrypt/confs/server-stream/lets-encrypt.conf +++ b/src/common/core/letsencrypt/confs/server-stream/lets-encrypt.conf @@ -2,6 +2,9 @@ # listen listen 0.0.0.0:{{ LISTEN_STREAM_PORT_SSL }} ssl {% if USE_UDP == "yes" %} udp {% endif %}{% if USE_PROXY_PROTOCOL == "yes" %} proxy_protocol {% endif %}; +{% if USE_IPV6 == "yes" +%} +listen [::]:{{ LISTEN_STREAM_PORT_SSL }} ssl {% if USE_UDP == "yes" %} udp {% endif %}{% if USE_PROXY_PROTOCOL == "yes" %} proxy_protocol {% endif %}; +{% endif %} # TLS config ssl_certificate /var/cache/bunkerweb/letsencrypt/etc/live/{{ SERVER_NAME.split(" ")[0] }}/fullchain.pem; diff --git a/src/common/core/selfsigned/confs/server-http/self-signed.conf b/src/common/core/selfsigned/confs/server-http/self-signed.conf index b4851584..da5242d7 100644 --- a/src/common/core/selfsigned/confs/server-http/self-signed.conf +++ b/src/common/core/selfsigned/confs/server-http/self-signed.conf @@ -2,6 +2,9 @@ # listen on HTTPS PORT listen 0.0.0.0:{{ HTTPS_PORT }} ssl {% if HTTP2 == "yes" %}http2{% endif %} {% if USE_PROXY_PROTOCOL == "yes" %}proxy_protocol{% endif %}; +{% if USE_IPV6 == "yes" +%} +listen [::]:{{ HTTPS_PORT }} ssl {% if HTTP2 == "yes" %}http2{% endif %} {% if USE_PROXY_PROTOCOL == "yes" %}proxy_protocol{% endif %}; +{% endif %} # TLS config ssl_certificate /var/cache/bunkerweb/selfsigned/{{ SERVER_NAME.split(" ")[0] }}.pem; diff --git a/src/common/core/selfsigned/confs/server-stream/self-signed.conf b/src/common/core/selfsigned/confs/server-stream/self-signed.conf index bdd1ded1..672649eb 100644 --- a/src/common/core/selfsigned/confs/server-stream/self-signed.conf +++ b/src/common/core/selfsigned/confs/server-stream/self-signed.conf @@ -2,6 +2,9 @@ # listen listen 0.0.0.0:{{ LISTEN_STREAM_PORT_SSL }} ssl {% if USE_UDP == "yes" %} udp {% endif %}{% if USE_PROXY_PROTOCOL == "yes" %} proxy_protocol {% endif %}; +{% if USE_IPV6 == "yes" +%} +listen [::]:{{ LISTEN_STREAM_PORT_SSL }} ssl {% if USE_UDP == "yes" %} udp {% endif %}{% if USE_PROXY_PROTOCOL == "yes" %} proxy_protocol {% endif %}; +{% endif %} # TLS config ssl_certificate /var/cache/bunkerweb/selfsigned/{{ SERVER_NAME.split(" ")[0] }}.pem; diff --git a/src/common/core/whitelist/whitelist.lua b/src/common/core/whitelist/whitelist.lua index 70742af8..8bcb6a77 100644 --- a/src/common/core/whitelist/whitelist.lua +++ b/src/common/core/whitelist/whitelist.lua @@ -125,7 +125,7 @@ function whitelist:access() if not already_cached[k] then local ok, whitelisted = self:is_whitelisted(k) if ok == nil then - self.logger:log(ngx.ERR, "error while checking if " .. k .. " is whitelisted : " .. err) + self.logger:log(ngx.ERR, "error while checking if " .. k .. " is whitelisted : " .. whitelisted) else local ok, err = self:add_to_cache(self:kind_to_ele(k), whitelisted) if not ok then @@ -240,14 +240,18 @@ function whitelist:is_whitelisted_ip() end if check_rdns then -- Get rDNS - local rdns, err = utils.get_rdns(ngx.ctx.bw.remote_addr) + local rdns_list, err = utils.get_rdns(ngx.ctx.bw.remote_addr) -- Check if rDNS is in whitelist - if rdns then - for i, suffix in ipairs(self.lists["RDNS"]) do - if rdns:sub(-#suffix) == suffix then - return true, "rDNS " .. suffix + if rdns_list then + for i, rdns in ipairs(rdns_list) do + for j, suffix in ipairs(self.lists["RDNS"]) do + if rdns:sub(-#suffix) == suffix then + return true, "rDNS " .. suffix + end end end + else + self.logger:log(ngx.ERR, "error while getting rdns : " .. err) end end @@ -255,7 +259,7 @@ function whitelist:is_whitelisted_ip() if ngx.ctx.bw.ip_is_global then local asn, err = utils.get_asn(ngx.ctx.bw.remote_addr) if not asn then - return nil, err + return nil, "ASN " .. err end for i, bl_asn in ipairs(self.lists["ASN"]) do if bl_asn == tostring(asn) then diff --git a/src/common/settings.json b/src/common/settings.json index 60b5d0ed..12f759c6 100644 --- a/src/common/settings.json +++ b/src/common/settings.json @@ -279,5 +279,14 @@ "label": "Listen UDP", "regex": "^(yes|no)$", "type": "check" + }, + "USE_IPV6": { + "context": "global", + "default": "no", + "help": "Enable IPv6 connectivity.", + "id": "use-ipv6", + "label": "Use IPv6", + "regex": "^(yes|no)$", + "type": "check" } } diff --git a/src/ui/Dockerfile b/src/ui/Dockerfile index da9a592d..c7d62145 100755 --- a/src/ui/Dockerfile +++ b/src/ui/Dockerfile @@ -26,6 +26,7 @@ COPY src/common/core /usr/share/bunkerweb/core COPY src/common/gen /usr/share/bunkerweb/gen COPY src/common/settings.json /usr/share/bunkerweb/settings.json COPY src/common/utils /usr/share/bunkerweb/utils +COPY src/common/helpers /usr/share/bunkerweb/helpers COPY src/ui /usr/share/bunkerweb/ui COPY src/VERSION /usr/share/bunkerweb/VERSION @@ -47,7 +48,7 @@ RUN apk add --no-cache bash && \ for dir in $(echo "/usr/share/bunkerweb /etc/bunkerweb") ; do find ${dir} -type f -exec chmod 0740 {} \; ; done && \ for dir in $(echo "/usr/share/bunkerweb /etc/bunkerweb") ; do find ${dir} -type d -exec chmod 0750 {} \; ; done && \ chmod 770 /var/cache/bunkerweb /var/lib/bunkerweb /var/tmp/bunkerweb /var/log/nginx/ui.log && \ - chmod 750 /usr/share/bunkerweb/gen/*.py /usr/share/bunkerweb/ui/*.py /usr/share/bunkerweb/ui/src/*.py /usr/share/bunkerweb/deps/python/bin/* && \ + chmod 750 /usr/share/bunkerweb/gen/*.py /usr/share/bunkerweb/ui/*.py /usr/share/bunkerweb/ui/src/*.py /usr/share/bunkerweb/deps/python/bin/* /usr/share/bunkerweb/helpers/*.sh && \ chmod 660 /usr/share/bunkerweb/INTEGRATION # Fix CVEs