diff --git a/src/common/confs/default-server-http.conf b/src/common/confs/default-server-http.conf index 5e7b01012..7a36c54be 100644 --- a/src/common/confs/default-server-http.conf +++ b/src/common/confs/default-server-http.conf @@ -13,7 +13,7 @@ server { # HTTPS listen {% set os = import("os") %} {% if os.path.isfile("/var/cache/bunkerweb/default-server-cert/cert.pem") +%} - {% if has_variable(all, "USE_CUSTOM_HTTPS", "yes") or has_variable(all, "AUTO_LETS_ENCRYPT", "yes") or has_variable(all, "GENERATE_SELF_SIGNED_SSL", "yes") +%} + {% 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 %}; ssl_certificate /var/cache/bunkerweb/selfsigned/{{ SERVER_NAME.split(" ")[0] }}.pem; ssl_certificate_key /var/cache/bunkerweb/selfsigned/{{ SERVER_NAME.split(" ")[0] }}.key; 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 21cfb6e7f..b90a72c38 100644 --- a/src/common/core/customcert/confs/server-http/custom-cert.conf +++ b/src/common/core/customcert/confs/server-http/custom-cert.conf @@ -1,18 +1,18 @@ {% set os_path = import("os.path") %} -{% if USE_CUSTOM_HTTPS == "yes" and os_path.isfile("/data/cache/customcert/{}".format(CUSTOM_HTTPS_CERT.replace("/", "_"))) and os_path.isfile("/data/cache/customcert/{}".format(CUSTOM_HTTPS_KEY.replace("/", "_"))) +%} +{% if USE_CUSTOM_SSL == "yes" and os_path.isfile("/data/cache/customcert/{}".format(CUSTOM_SSL_CERT.replace("/", "_"))) and os_path.isfile("/data/cache/customcert/{}".format(CUSTOM_SSL_KEY.replace("/", "_"))) +%} # 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 %}; # TLS config -ssl_certificate /data/cache/customcert/{{ CUSTOM_HTTPS_CERT.replace("/", "_") }}; -ssl_certificate_key /data/cache/customcert/{{ CUSTOM_HTTPS_KEY.replace("/", "_") }}; -ssl_protocols {{ HTTPS_PROTOCOLS }}; +ssl_certificate /data/cache/customcert/{{ CUSTOM_SSL_CERT.replace("/", "_") }}; +ssl_certificate_key /data/cache/customcert/{{ CUSTOM_SSL_KEY.replace("/", "_") }}; +ssl_protocols {{ SSL_PROTOCOLS }}; ssl_prefer_server_ciphers on; ssl_session_tickets off; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; -{% if "TLSv1.2" in HTTPS_PROTOCOLS +%} +{% if "TLSv1.2" in SSL_PROTOCOLS +%} ssl_dhparam /etc/nginx/dhparam; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; {% endif %} 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 0b71534d6..931e02036 100644 --- a/src/common/core/customcert/confs/server-stream/custom-cert.conf +++ b/src/common/core/customcert/confs/server-stream/custom-cert.conf @@ -1,18 +1,18 @@ {% set os_path = import("os.path") %} -{% if USE_CUSTOM_HTTPS == "yes" and os_path.isfile("/data/cache/customcert/{}".format(CUSTOM_HTTPS_CERT.replace("/", "_"))) and os_path.isfile("/data/cache/customcert/{}".format(CUSTOM_HTTPS_KEY.replace("/", "_"))) +%} +{% if USE_CUSTOM_SSL == "yes" and os_path.isfile("/data/cache/customcert/{}".format(CUSTOM_SSL_CERT.replace("/", "_"))) and os_path.isfile("/data/cache/customcert/{}".format(CUSTOM_SSL_KEY.replace("/", "_"))) +%} # 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 %}; # TLS config -ssl_certificate /data/cache/customcert/{{ CUSTOM_HTTPS_CERT.replace("/", "_") }}; -ssl_certificate_key /data/cache/customcert/{{ CUSTOM_HTTPS_KEY.replace("/", "_") }}; -ssl_protocols {{ HTTPS_PROTOCOLS }}; +ssl_certificate /data/cache/customcert/{{ CUSTOM_SSL_CERT.replace("/", "_") }}; +ssl_certificate_key /data/cache/customcert/{{ CUSTOM_SSL_KEY.replace("/", "_") }}; +ssl_protocols {{ SSL_PROTOCOLS }}; ssl_prefer_server_ciphers on; ssl_session_tickets off; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; -{% if "TLSv1.2" in HTTPS_PROTOCOLS +%} +{% if "TLSv1.2" in SSL_PROTOCOLS +%} ssl_dhparam /etc/nginx/dhparam; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; {% endif %} diff --git a/src/common/core/customcert/jobs/custom-cert.py b/src/common/core/customcert/jobs/custom-cert.py index 8b0239c42..e8b57c823 100644 --- a/src/common/core/customcert/jobs/custom-cert.py +++ b/src/common/core/customcert/jobs/custom-cert.py @@ -30,7 +30,7 @@ def check_cert(cert_path, key_path, first_server: str = None) -> bool: try: if not cert_path or not key_path: logger.warning( - "Both variables CUSTOM_HTTPS_CERT and CUSTOM_HTTPS_KEY have to be set to use custom certificates" + "Both variables CUSTOM_SSL_CERT and CUSTOM_SSL_KEY have to be set to use custom certificates" ) return False elif not isfile(cert_path): @@ -125,17 +125,17 @@ try: for first_server in getenv("SERVER_NAME").split(" "): if not first_server or ( getenv( - f"{first_server}_USE_CUSTOM_HTTPS", getenv("USE_CUSTOM_HTTPS", "no") + f"{first_server}_USE_CUSTOM_SSL", getenv("USE_CUSTOM_SSL", "no") ) != "yes" ): continue cert_path = getenv( - f"{first_server}_CUSTOM_HTTPS_CERT", getenv("CUSTOM_HTTPS_CERT", "") + f"{first_server}_CUSTOM_SSL_CERT", getenv("CUSTOM_SSL_CERT", "") ) key_path = getenv( - f"{first_server}_CUSTOM_HTTPS_KEY", getenv("CUSTOM_HTTPS_KEY", "") + f"{first_server}_CUSTOM_SSL_KEY", getenv("CUSTOM_SSL_KEY", "") ) logger.info( @@ -152,9 +152,9 @@ try: f"No change for certificate {cert_path}", ) # Singlesite case - elif getenv("USE_CUSTOM_HTTPS") == "yes" and getenv("SERVER_NAME") != "": - cert_path = getenv("CUSTOM_HTTPS_CERT", "") - key_path = getenv("CUSTOM_HTTPS_KEY", "") + elif getenv("USE_CUSTOM_SSL") == "yes" and getenv("SERVER_NAME") != "": + cert_path = getenv("CUSTOM_SSL_CERT", "") + key_path = getenv("CUSTOM_SSL_KEY", "") logger.info(f"Checking certificate {cert_path} ...") need_reload = check_cert(cert_path, key_path) diff --git a/src/common/core/customcert/plugin.json b/src/common/core/customcert/plugin.json index 260bac09a..c2510a919 100644 --- a/src/common/core/customcert/plugin.json +++ b/src/common/core/customcert/plugin.json @@ -5,7 +5,7 @@ "description": "Choose custom certificate for HTTPS.", "version": "0.1", "settings": { - "USE_CUSTOM_HTTPS": { + "USE_CUSTOM_SSL": { "context": "multisite", "default": "no", "help": "Use custom HTTPS certificate.", @@ -14,7 +14,7 @@ "regex": "^(yes|no)$", "type": "check" }, - "CUSTOM_HTTPS_CERT": { + "CUSTOM_SSL_CERT": { "context": "multisite", "default": "", "help": "Full path of the certificate or bundle file.", @@ -23,7 +23,7 @@ "regex": "^(/[\\w. -]+)*/?$", "type": "text" }, - "CUSTOM_HTTPS_KEY": { + "CUSTOM_SSL_KEY": { "context": "multisite", "default": "", "help": "Full path of the key file.", diff --git a/src/common/core/greylist/greylist.lua b/src/common/core/greylist/greylist.lua index c32b7e46d..74b991541 100644 --- a/src/common/core/greylist/greylist.lua +++ b/src/common/core/greylist/greylist.lua @@ -224,6 +224,124 @@ function _M:access() return ret, "IP is not in list (error = " .. ret_err .. ")", true, utils.get_deny_status() end +function _M:preread() + -- Check if preread is needed + local preread_needed, err = utils.get_variable("USE_GREYLIST") + if preread_needed == nil then + return false, err, false, nil + end + if preread_needed ~= "yes" then + return true, "Greylist not activated", false, nil + end + + -- Check the cache + local cached_ip, err = self:is_in_cache("ip" .. ngx.var.remote_addr) + if cached_ip and cached_ip ~= "ok" then + return true, "IP is in greylist cache (info = " .. cached_ip .. ")", false, ngx.OK + end + if cached_ip then + return true, "full request is in greylist cache (not greylisted)", false, nil + end + + -- Get list + local data, err = datastore:get("plugin_greylist_list") + if not data then + return false, "can't get Greylist list : " .. err, false, nil + end + local ok, greylists = pcall(cjson.decode, data) + if not ok then + return false, "error while decoding greylists : " .. greylists, false, nil + end + + -- Return value + local ret, ret_err = true, "success" + + -- Check if IP is in IP/net greylist + local ip_net, err = utils.get_variable("GREYLIST_IP") + if ip_net and ip_net ~= "" then + for element in ip_net:gmatch("%S+") do + table.insert(greylists["IP"], element) + end + end + if not cached_ip then + local ipm, err = ipmatcher.new(greylists["IP"]) + if not ipm then + ret = false + ret_err = "can't instantiate ipmatcher " .. err + else + if ipm:match(ngx.var.remote_addr) then + self:add_to_cache("ip" .. ngx.var.remote_addr, "ip/net") + return ret, "client IP " .. ngx.var.remote_addr .. " is in greylist", false, ngx.OK + end + end + end + + -- Check if rDNS is in greylist + local rdns_global, err = utils.get_variable("GREYLIST_RDNS_GLOBAL") + local check = true + if not rdns_global then + logger.log(ngx.ERR, "GREYLIST", "Error while getting GREYLIST_RDNS_GLOBAL variable : " .. err) + elseif rdns_global == "yes" then + check, err = utils.ip_is_global(ngx.var.remote_addr) + if check == nil then + logger.log(ngx.ERR, "GREYLIST", "Error while getting checking if IP is global : " .. err) + end + end + if not cached_ip and check then + local rdns, err = utils.get_rdns(ngx.var.remote_addr) + if not rdns then + ret = false + ret_err = "error while trying to get reverse dns : " .. err + else + local rdns_list, err = utils.get_variable("GREYLIST_RDNS") + if rdns_list and rdns_list ~= "" then + for element in rdns_list:gmatch("%S+") do + table.insert(greylists["RDNS"], element) + end + end + for i, suffix in ipairs(greylists["RDNS"]) do + if rdns:sub(- #suffix) == suffix then + self:add_to_cache("ip" .. ngx.var.remote_addr, "rDNS " .. suffix) + return ret, "client IP " .. ngx.var.remote_addr .. " is in greylist (info = rDNS " .. suffix .. ")", false, ngx.OK + end + end + end + end + + -- Check if ASN is in greylist + if not cached_ip then + if utils.ip_is_global(ngx.var.remote_addr) then + local asn, err = utils.get_asn(ngx.var.remote_addr) + if not asn then + ret = false + ret_err = "error while trying to get asn number : " .. err + else + local asn_list, err = utils.get_variable("GREYLIST_ASN") + if asn_list and asn_list ~= "" then + for element in asn_list:gmatch("%S+") do + table.insert(greylists["ASN"], element) + end + end + for i, asn_bl in ipairs(greylists["ASN"]) do + if tostring(asn) == asn_bl then + self:add_to_cache("ip" .. ngx.var.remote_addr, "ASN " .. tostring(asn)) + return ret, "client IP " .. ngx.var.remote_addr .. " is in greylist (kind = ASN " .. tostring(asn) .. ")", false, + ngx.OK + end + end + end + end + end + + -- IP is not greylisted + local ok, err = self:add_to_cache("ip" .. ngx.var.remote_addr, "ok") + if not ok then + ret = false + ret_err = err + end + return ret, "IP is not in list (error = " .. ret_err .. ")", true, utils.get_deny_status() +end + function _M:is_in_cache(ele) local kind, err = datastore:get("plugin_greylist_cache_" .. ngx.var.server_name .. ele) if not kind then diff --git a/src/common/core/headers/confs/server-http/security-headers.conf b/src/common/core/headers/confs/server-http/security-headers.conf index 2dd2c58a6..2e4c4a285 100644 --- a/src/common/core/headers/confs/server-http/security-headers.conf +++ b/src/common/core/headers/confs/server-http/security-headers.conf @@ -1,10 +1,10 @@ -{% if STRICT_TRANSPORT_SECURITY != "" and (AUTO_LETS_ENCRYPT == "yes" or USE_CUSTOM_HTTPS == "yes" or GENERATE_SELF_SIGNED_SSL == "yes") +%} +{% 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_HTTPS == "yes" or GENERATE_SELF_SIGNED_SSL == "yes") +%} + {% 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 }}; 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 59612b359..b15472e0a 100644 --- a/src/common/core/letsencrypt/confs/server-http/lets-encrypt.conf +++ b/src/common/core/letsencrypt/confs/server-http/lets-encrypt.conf @@ -11,12 +11,12 @@ listen 0.0.0.0:{{ HTTPS_PORT }} ssl {% if HTTP2 == "yes" %}http2{% endif %} {% i # TLS config ssl_certificate /etc/letsencrypt/live/{{ SERVER_NAME.split(" ")[0] }}/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/{{ SERVER_NAME.split(" ")[0] }}/privkey.pem; -ssl_protocols {{ HTTPS_PROTOCOLS }}; +ssl_protocols {{ SSL_PROTOCOLS }}; ssl_prefer_server_ciphers on; ssl_session_tickets off; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; -{% if "TLSv1.2" in HTTPS_PROTOCOLS +%} +{% if "TLSv1.2" in SSL_PROTOCOLS +%} ssl_dhparam /etc/nginx/dhparam; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; {% endif %} diff --git a/src/common/core/letsencrypt/confs/server-stream/lets-encrypt.conf b/src/common/core/letsencrypt/confs/server-stream/lets-encrypt.conf new file mode 100644 index 000000000..85fdc27dc --- /dev/null +++ b/src/common/core/letsencrypt/confs/server-stream/lets-encrypt.conf @@ -0,0 +1,19 @@ +{% if AUTO_LETS_ENCRYPT == "yes" %} + +# 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 %}; + +# TLS config +ssl_certificate /etc/letsencrypt/live/{{ SERVER_NAME.split(" ")[0] }}/fullchain.pem; +ssl_certificate_key /etc/letsencrypt/live/{{ SERVER_NAME.split(" ")[0] }}/privkey.pem; +ssl_protocols {{ SSL_PROTOCOLS }}; +ssl_prefer_server_ciphers on; +ssl_session_tickets off; +ssl_session_timeout 1d; +ssl_session_cache shared:MozSSL:10m; +{% if "TLSv1.2" in SSL_PROTOCOLS +%} +ssl_dhparam /etc/nginx/dhparam; +ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; +{% endif %} + +{% endif %} \ No newline at end of file diff --git a/src/common/core/misc/confs/server-http/redirect-http-to-https.conf b/src/common/core/misc/confs/server-http/redirect-http-to-https.conf index dcea2f5c5..39937b920 100644 --- a/src/common/core/misc/confs/server-http/redirect-http-to-https.conf +++ b/src/common/core/misc/confs/server-http/redirect-http-to-https.conf @@ -3,7 +3,7 @@ if ($scheme = http) { return 301 https://$host$request_uri; } {% elif AUTO_REDIRECT_HTTP_TO_HTTPS == "yes" +%} - {% if AUTO_LETS_ENCRYPT == "yes" or USE_CUSTOM_HTTPS == "yes" or GENERATE_SELF_SIGNED_SSL == "yes" +%} + {% if AUTO_LETS_ENCRYPT == "yes" or USE_CUSTOM_SSL == "yes" or GENERATE_SELF_SIGNED_SSL == "yes" +%} if ($scheme = http) { return 301 https://$host$request_uri; } diff --git a/src/common/core/misc/jobs/default-server-cert.py b/src/common/core/misc/jobs/default-server-cert.py index abc4c51ce..0b9b73510 100644 --- a/src/common/core/misc/jobs/default-server-cert.py +++ b/src/common/core/misc/jobs/default-server-cert.py @@ -25,7 +25,7 @@ try: if getenv("MULTISITE", "no") == "yes": for first_server in getenv("SERVER_NAME", "").split(" "): for check_var in [ - "USE_CUSTOM_HTTPS", + "USE_CUSTOM_SSL", "AUTO_LETS_ENCRYPT", "GENERATE_SELF_SIGNED_SSL", ]: @@ -38,7 +38,7 @@ try: if need_default_cert: break elif getenv("DISABLE_DEFAULT_SERVER", "no") == "yes" and ( - getenv("USE_CUSTOM_HTTPS", "no") == "yes" + getenv("USE_CUSTOM_SSL", "no") == "yes" or getenv("AUTO_LETS_ENCRYPT", "no") == "yes" or getenv("GENERATE_SELF_SIGNED_SSL", "no") == "yes" ): diff --git a/src/common/core/misc/plugin.json b/src/common/core/misc/plugin.json index 84d7854c6..6bf0b4731 100644 --- a/src/common/core/misc/plugin.json +++ b/src/common/core/misc/plugin.json @@ -68,7 +68,7 @@ "regex": "^(/[\\w. -]+)*/?$", "type": "text" }, - "HTTPS_PROTOCOLS": { + "SSL_PROTOCOLS": { "context": "multisite", "default": "TLSv1.2 TLSv1.3", "help": "The supported version of TLS. We recommend the default value TLSv1.2 TLSv1.3 for compatibility reasons.", 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 87a74861b..b48515841 100644 --- a/src/common/core/selfsigned/confs/server-http/self-signed.conf +++ b/src/common/core/selfsigned/confs/server-http/self-signed.conf @@ -6,12 +6,12 @@ listen 0.0.0.0:{{ HTTPS_PORT }} ssl {% if HTTP2 == "yes" %}http2{% endif %} {% i # TLS config ssl_certificate /var/cache/bunkerweb/selfsigned/{{ SERVER_NAME.split(" ")[0] }}.pem; ssl_certificate_key /var/cache/bunkerweb/selfsigned/{{ SERVER_NAME.split(" ")[0] }}.key; -ssl_protocols {{ HTTPS_PROTOCOLS }}; +ssl_protocols {{ SSL_PROTOCOLS }}; ssl_prefer_server_ciphers on; ssl_session_tickets off; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; -{% if "TLSv1.2" in HTTPS_PROTOCOLS +%} +{% if "TLSv1.2" in SSL_PROTOCOLS +%} ssl_dhparam /etc/nginx/dhparam; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; {% endif %} diff --git a/src/common/core/selfsigned/confs/server-stream/self-signed.conf b/src/common/core/selfsigned/confs/server-stream/self-signed.conf new file mode 100644 index 000000000..ee5ef5dd6 --- /dev/null +++ b/src/common/core/selfsigned/confs/server-stream/self-signed.conf @@ -0,0 +1,19 @@ +{% if GENERATE_SELF_SIGNED_SSL == "yes" %} + +# 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 %}; + +# TLS config +ssl_certificate /var/cache/bunkerweb/selfsigned/{{ SERVER_NAME.split(" ")[0] }}.pem; +ssl_certificate_key /var/cache/bunkerweb/selfsigned/{{ SERVER_NAME.split(" ")[0] }}.key; +ssl_protocols {{ SSL_PROTOCOLS }}; +ssl_prefer_server_ciphers on; +ssl_session_tickets off; +ssl_session_timeout 1d; +ssl_session_cache shared:MozSSL:10m; +{% if "TLSv1.2" in SSL_PROTOCOLS +%} +ssl_dhparam /etc/nginx/dhparam; +ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; +{% endif %} + +{% endif %} \ No newline at end of file diff --git a/src/common/core/whitelist/confs/modsec/whitelist.conf b/src/common/core/whitelist/confs/modsec/whitelist.conf deleted file mode 100644 index fd3d6fef7..000000000 --- a/src/common/core/whitelist/confs/modsec/whitelist.conf +++ /dev/null @@ -1,5 +0,0 @@ -{% if USE_WHITELIST == "yes" +%} - {% if WHITELIST_IP != "" +%} -SecRule REMOTE_ADDR "@ipMatch {{ WHITELIST_IP.replace(" ", ",") }}" "id:1000,phase:1,t:none,nolog,pass,ctl:ruleEngine=Off" - {% endif +%} -{% endif +%} \ No newline at end of file diff --git a/src/common/core/whitelist/confs/server-stream/whitelist.conf b/src/common/core/whitelist/confs/server-stream/whitelist.conf new file mode 100644 index 000000000..20e9304a1 --- /dev/null +++ b/src/common/core/whitelist/confs/server-stream/whitelist.conf @@ -0,0 +1 @@ +set $is_whitelisted 'no'; \ No newline at end of file diff --git a/src/common/core/whitelist/whitelist.lua b/src/common/core/whitelist/whitelist.lua index e96e72a66..78c535c14 100644 --- a/src/common/core/whitelist/whitelist.lua +++ b/src/common/core/whitelist/whitelist.lua @@ -275,6 +275,128 @@ function _M:access() return ret, "IP is not in list (error = " .. ret_err .. ")", false, nil end +function _M:preread() + -- Check if preread is needed + local preread_needed, err = utils.get_variable("USE_WHITELIST") + if preread_needed == nil then + return false, err, nil, nil + end + if preread_needed ~= "yes" then + return true, "Whitelist not activated", nil, nil + end + + -- Check the cache + local cached_ip, err = self:is_in_cache("ip" .. ngx.var.remote_addr) + if cached_ip and cached_ip ~= "ok" then + ngx.var.is_whitelisted = "yes" + return true, "IP is in whitelist cache (info = " .. cached_ip .. ")", true, ngx.OK + end + if cached_ip then + return true, "full request is in whitelist cache (not whitelisted)", nil, nil + end + + -- Get list + local data, err = datastore:get("plugin_whitelist_list") + if not data then + return false, "can't get Whitelist list : " .. err, false, nil + end + local ok, whitelists = pcall(cjson.decode, data) + if not ok then + return false, "error while decoding whitelists : " .. whitelists, false, nil + end + + -- Return value + local ret, ret_err = true, "success" + + -- Check if IP is in IP/net whitelist + local ip_net, err = utils.get_variable("WHITELIST_IP") + if ip_net and ip_net ~= "" then + for element in ip_net:gmatch("%S+") do + table.insert(whitelists["IP"], element) + end + end + if not cached_ip then + local ipm, err = ipmatcher.new(whitelists["IP"]) + if not ipm then + ret = false + ret_err = "can't instantiate ipmatcher " .. err + else + if ipm:match(ngx.var.remote_addr) then + self:add_to_cache("ip" .. ngx.var.remote_addr, "ip/net") + ngx.var.is_whitelisted = "yes" + return ret, "client IP " .. ngx.var.remote_addr .. " is in whitelist", true, ngx.OK + end + end + end + + -- Check if rDNS is in whitelist + local rdns_global, err = utils.get_variable("WHITELIST_RDNS_GLOBAL") + local check = true + if not rdns_global then + logger.log(ngx.ERR, "WHITELIST", "Error while getting WHITELIST_RDNS_GLOBAL variable : " .. err) + elseif rdns_global == "yes" then + check, err = utils.ip_is_global(ngx.var.remote_addr) + if check == nil then + logger.log(ngx.ERR, "WHITELIST", "Error while getting checking if IP is global : " .. err) + end + end + if not cached_ip and check then + local rdns, err = utils.get_rdns(ngx.var.remote_addr) + if not rdns then + ret = false + ret_err = "error while trying to get reverse dns : " .. err + else + local rdns_list, err = utils.get_variable("WHITELIST_RDNS") + if rdns_list and rdns_list ~= "" then + for element in rdns_list:gmatch("%S+") do + table.insert(whitelists["RDNS"], element) + end + end + for i, suffix in ipairs(whitelists["RDNS"]) do + if rdns:sub(- #suffix) == suffix then + self:add_to_cache("ip" .. ngx.var.remote_addr, "rDNS " .. suffix) + ngx.var.is_whitelisted = "yes" + return ret, "client IP " .. ngx.var.remote_addr .. " is in whitelist (info = rDNS " .. suffix .. ")", true, ngx.OK + end + end + end + end + + -- Check if ASN is in whitelist + if not cached_ip then + if utils.ip_is_global(ngx.var.remote_addr) then + local asn, err = utils.get_asn(ngx.var.remote_addr) + if not asn then + ret = false + ret_err = "error while trying to get asn number : " .. err + else + local asn_list, err = utils.get_variable("WHITELIST_ASN") + if asn_list and asn_list ~= "" then + for element in asn_list:gmatch("%S+") do + table.insert(whitelists["ASN"], element) + end + end + for i, asn_bl in ipairs(whitelists["ASN"]) do + if tostring(asn) == asn_bl then + self:add_to_cache("ip" .. ngx.var.remote_addr, "ASN " .. tostring(asn)) + ngx.var.is_whitelisted = "yes" + return ret, "client IP " .. ngx.var.remote_addr .. " is in whitelist (kind = ASN " .. tostring(asn) .. ")", true, + ngx.OK + end + end + end + end + end + + -- IP is not whitelisted + local ok, err = self:add_to_cache("ip" .. ngx.var.remote_addr, "ok") + if not ok then + ret = false + ret_err = err + end + return ret, "IP is not in list (error = " .. ret_err .. ")", false, nil +end + function _M:is_in_cache(ele) local kind, err = datastore:get("plugin_whitelist_cache_" .. ngx.var.server_name .. ele) if not kind then diff --git a/src/common/gen/Templator.py b/src/common/gen/Templator.py index 1ebd78386..2f01010ad 100644 --- a/src/common/gen/Templator.py +++ b/src/common/gen/Templator.py @@ -103,7 +103,10 @@ class Templator: "access-lua.conf", "init-lua.conf", "log-lua.conf", - "set-lua.conf" + "set-lua.conf", + "log-stream-lua.conf", + "preread-stream-lua.conf", + "server-stream.conf" ] for root_conf in root_confs: if template.endswith(f"/{root_conf}"): diff --git a/src/common/settings.json b/src/common/settings.json index fcfe4732f..84933667d 100644 --- a/src/common/settings.json +++ b/src/common/settings.json @@ -188,5 +188,54 @@ "label": "Kubernetes mode", "regex": "^(yes|no)$", "type": "check" + }, + "SERVER_TYPE": { + "context": "multisite", + "default": "http", + "help": "Server type : http or stream.", + "id": "server-type", + "label": "Server type", + "regex": "^(http|stream)$", + "type": "select", + "select": [ + "http", + "stream" + ] + }, + "LISTEN_STREAM": { + "context": "multisite", + "default": "yes", + "help": "Enable listening for non-ssl (passthrough).", + "id": "listen-stream", + "label": "Listen stream", + "regex": "^(yes|no)$", + "type": "check" + }, + "LISTEN_STREAM_PORT": { + "context": "multisite", + "default": "1337", + "help": "Listening port for non-ssl (passthrough).", + "id": "listen-stream-port", + "label": "Listen stream port", + "regex": "^[0-9]+$", + "type": "text" + }, + "LISTEN_STREAM_PORT_SSL": { + "context": "multisite", + "default": "4242", + "help": "Listening port for ssl (passthrough).", + "id": "listen-stream-port-ssl", + "label": "Listen stream port ssl", + "regex": "^[0-9]+$", + "type": "text" + }, + "USE_UDP": { + "context": "multisite", + "default": "no", + "help": "UDP listen instead of TCP (stream).", + "id": "use-udp", + "label": "Listen UDP", + "regex": "^(yes|no)$", + "type": "check" } } diff --git a/src/ui/templates/services.html b/src/ui/templates/services.html index d8b38b02f..f30cb6a48 100644 --- a/src/ui/templates/services.html +++ b/src/ui/templates/services.html @@ -156,7 +156,7 @@

- {% if service['REMOTE_PHP']['value'] == 'yes' or service['USE_CUSTOM_HTTPS'] and service['USE_CUSTOM_HTTPS']['value'] == + {% if service['REMOTE_PHP']['value'] == 'yes' or service['USE_CUSTOM_SSL'] and service['USE_CUSTOM_SSL']['value'] == 'yes' or service['GENERATE_SELF_SIGNED_SSL'] and service['GENERATE_SELF_SIGNED_SSL']['value'] == 'yes' %}