init IPv6 support, add missing healthcheck script in UI and purge local cache on init

This commit is contained in:
florian 2023-05-13 18:37:13 +02:00
parent 5c415afa18
commit 75f3d6490a
No known key found for this signature in database
GPG Key ID: 3D80806F12602A7C
21 changed files with 145 additions and 44 deletions

View File

@ -164,4 +164,8 @@ function cachestore:del_redis(key)
return true
end
function cachestore:purge()
return self.cache:purge(true)
end
return cachestore

View File

@ -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)

View File

@ -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 %}

View File

@ -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;

View File

@ -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_"}

View File

@ -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_"}

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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 }};

View File

@ -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 }};

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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"
}
}

View File

@ -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