diff --git a/.github/workflows/container-build.yml b/.github/workflows/container-build.yml index 5747a11bf..ab0f5aa5d 100644 --- a/.github/workflows/container-build.yml +++ b/.github/workflows/container-build.yml @@ -86,7 +86,7 @@ jobs: # Compute metadata - name: Extract metadata id: meta - uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c # v5.5.0 + uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 with: images: bunkerity/${{ inputs.IMAGE }} # Build cached image diff --git a/.github/workflows/linux-build.yml b/.github/workflows/linux-build.yml index 416cfc102..da038282e 100644 --- a/.github/workflows/linux-build.yml +++ b/.github/workflows/linux-build.yml @@ -137,7 +137,7 @@ jobs: - name: Extract metadata if: inputs.TEST == true id: meta - uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c # v5.5.0 + uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 with: images: ghcr.io/bunkerity/${{ inputs.LINUX }}-tests:${{ inputs.RELEASE }} - name: Build test image diff --git a/.github/workflows/push-docker.yml b/.github/workflows/push-docker.yml index ee576a2b7..6ef4ed8f7 100644 --- a/.github/workflows/push-docker.yml +++ b/.github/workflows/push-docker.yml @@ -65,7 +65,7 @@ jobs: # Compute metadata - name: Extract metadata id: meta - uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c # v5.5.0 + uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 with: images: bunkerity/${{ inputs.IMAGE }} # Build and push diff --git a/.github/workflows/push-packagecloud.yml b/.github/workflows/push-packagecloud.yml index d5959f0df..10592a44f 100644 --- a/.github/workflows/push-packagecloud.yml +++ b/.github/workflows/push-packagecloud.yml @@ -42,7 +42,7 @@ jobs: - name: Check out repository code uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Install ruby - uses: ruby/setup-ruby@bd03e04863f52d169e18a2b190e8fa6b84938215 # v1.170.0 + uses: ruby/setup-ruby@22fdc77bf4148f810455b226c90fb81b5cbc00a7 # v1.171.0 with: ruby-version: "3.0" - name: Install packagecloud diff --git a/.github/workflows/test-core-linux.yml b/.github/workflows/test-core-linux.yml index 2a619c7f5..8f42a28a6 100644 --- a/.github/workflows/test-core-linux.yml +++ b/.github/workflows/test-core-linux.yml @@ -36,7 +36,7 @@ jobs: ' | sudo tee /etc/apt/preferences.d/mozilla-firefox sudo apt install --no-install-recommends -y openssl git nodejs tar bzip2 wget curl grep libx11-xcb1 libappindicator3-1 libasound2 libdbus-glib-1-2 libxtst6 libxt6 php-fpm unzip firefox - name: Download geckodriver - uses: nick-fields/retry@14672906e672a08bd6eeb15720e9ed3ce869cdd4 # v2.9.0 + uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e # v3.0.0 with: max_attempts: 3 timeout_minutes: 20 diff --git a/.github/workflows/tests-ui-linux.yml b/.github/workflows/tests-ui-linux.yml index 7ee82670c..8b6f42903 100644 --- a/.github/workflows/tests-ui-linux.yml +++ b/.github/workflows/tests-ui-linux.yml @@ -33,7 +33,7 @@ jobs: ' | sudo tee /etc/apt/preferences.d/mozilla-firefox sudo apt install --no-install-recommends -y openssl git nodejs tar bzip2 wget curl grep libx11-xcb1 libappindicator3-1 libasound2 libdbus-glib-1-2 libxtst6 libxt6 php-fpm unzip firefox - name: Download geckodriver - uses: nick-fields/retry@14672906e672a08bd6eeb15720e9ed3ce869cdd4 # v2.9.0 + uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e # v3.0.0 with: max_attempts: 3 timeout_minutes: 20 diff --git a/CHANGELOG.md b/CHANGELOG.md index f3729cea1..1f7d6c44b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,27 @@ ## v1.5.6 - YYYY/MM/DD +- [BUGFIX] Fix issues with the antibot feature ([#866](https://github.com/bunkerity/bunkerweb/issues/866), [#870](https://github.com/bunkerity/bunkerweb/issues/870)) +- [UI] Add bans management page in the web UI +- [UI] Add blocked requests page in the web UI +- [UI] Add the possibility to clone a service in the web UI +- [UI] Add the possibility to set a service as draft in the web UI +- [FEATURE] Add setting REDIS_SSL_VERIFY to activate/disable the SSL certificate verification when using Redis +- [FEATURE] Add Redis Sentinel fallback to master automatically if no slaves are available +- [FEATURE] Add Redis Sentinel support for bwcli +- [FEATURE] Add new Metrics core plugin that will allow metrics collection and retrieval of internal metrics +- [FEATURE] Add setting DATABASE_LOG_LEVEL to control SQLAlchemy loggers separately from the main one +- [MISC] Add a better custom certificate cache handling - [MISC] Updated Linux base images in Dockerfiles +- [MISC] Add recommended dialects to databases string +- [DOCUMENTATION] Update web UI's setup wizard instructions in the documentation - [DEPS] Updated stream-lua-nginx-module to v0.0.14 - [DEPS] Updated lua-nginx-module version to v0.10.26 - [DEPS] Updated libmaxminddb version to v1.9.1 - [DEPS] Updated lua-resty-core to v0.1.28 - [DEPS] Updated zlib version to v1.3.1 +- [DEPS] Updated ModSecurity version to v3.0.12 +- [DEPS] Updated lua-resty-mlcache version to v2.6.1 ## v1.5.5 - 2024/01/12 diff --git a/docs/plugins.md b/docs/plugins.md index 3a3dee47f..c99184e4d 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -260,10 +260,39 @@ The first step is to install the plugin by putting the plugin files inside the c ## Writing a plugin +### Structure + !!! tip "Existing plugins" If the documentation is not enough, you can have a look at the existing source code of [official plugins](https://github.com/bunkerity/bunkerweb-plugins) and the [core plugins](https://github.com/bunkerity/bunkerweb/tree/v1.5.6/src/common/core) (already included in BunkerWeb but they are plugins, technically speaking). +What a plugin structure looks like : +``` +plugin / + confs / conf_type.conf + ui / actions.py + template.html + plugin.lua + plugin.json +``` + +- **conf_type.conf** : add a [custom NGINX configurations.](/quickstart-guide/#custom-configurations) + +- **actions.py** : script to execute on flask server. +This script is running on flask context, you have access to lib and utils like `jinja2`, `requests`, etc... + +- **template.html** : custom plugin page you can access from ui. + +- **plugin.lua** : code to execute on NGINX using [NGING LUA modile.](https://github.com/openresty/lua-nginx-module) + +- **plugin.json** : metadata, settings and jobs for your settings. + +!!! info "Optional files" + + Files like `confs` and `ui` ones are optional. Add them only to fit your needs. + +### Getting started + The first step is to create a folder that will contain the plugin : ```shell @@ -515,9 +544,9 @@ BunkerWeb uses an internal job scheduler for periodic tasks like renewing certif ### Plugin page -Plugin pages are used to display information about your plugin and interact with the user inside the plugins section of the [web UI](web-ui.md). +Everything related to the web UI is located inside the subfolder **ui** as we seen in the [previous structure section.](#structure) -Everything related to the web UI is located inside a subfolder named **ui** at the root directory of your plugin. A template file named **template.html** and located inside the **ui** subfolder contains the client code and logic to display your page. Another file named **actions.py** and also located inside the **ui** subfolder contains code that will be executed when the user is interacting with your page (filling a form for example). +#### Basic example !!! info "Jinja 2 template" The **template.html** file is a Jinja2 template, please refer to the [Jinja2 documentation](https://jinja.palletsprojects.com) if needed. @@ -555,3 +584,40 @@ def myplugin() : !!! info "Python libraries" You can use Python libraries that are already available like : `Flask`, `Flask-Login`, `Flask-WTF`, `beautifulsoup4`, `docker`, `Jinja2`, `python-magic` and `requests`. To see the full list, you can have a look at the Web UI [requirements.txt](https://github.com/bunkerity/bunkerweb/blobsrc/ui/requirements.txt). If you need external libraries, you can install them inside the **ui** folder of your plugin and then use the classical **import** directive. + +#### Utils + +To easily update the content of a template inside the UI with JSON, a **SetupPlugin class** is available in `src/ui/static/js/plugins/setup.js` and will be executed when the plugin template is load. + +For example, in case **actions.py** return this JSON : +```python +def plugin(): + return {"message": "ok", "data": {"name": "test"}} +``` + +I need to add this on my **template.html** : +```html + +``` + +!!! info "Check core plugins" + + Core plugins are using this utils. Feel free to look at them in order to see in details how each `key` is working. + + +| key | Type | Description | +| :--------: | :----: | :------------------------------------------------------------------------------------------- | +| `name ` | string | Replace `name` by the JSON key to extract the related value. | +| `el` | element| Select element you want the value to be updated. | +| `value` | any | Default value on template load or in case retrieving JSON failed. | +| `type` | string | Define the script behavior with the incoming value. Available : `text`, `list` and `status`. | +| `textEl` | element| Optional additionnal text content when type is `status`. | +| `listNames`| string | List of data keys when type is `list`. | diff --git a/docs/requirements.in b/docs/requirements.in index b8b8f6f54..e597685a9 100644 --- a/docs/requirements.in +++ b/docs/requirements.in @@ -1,5 +1,5 @@ mike==2.0.0 mkdocs==1.5.3 -mkdocs-material[imaging]==9.5.5 +mkdocs-material[imaging]==9.5.6 mkdocs-print-site-plugin==2.3.6 pytablewriter==1.2.0 diff --git a/docs/requirements.txt b/docs/requirements.txt index e90dbfb4d..d49a2ba8a 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -311,9 +311,9 @@ mkdocs==1.5.3 \ # -r requirements.in # mike # mkdocs-material -mkdocs-material==9.5.5 \ - --hash=sha256:4480d9580faf42fed0123d0465502bfc1c0c239ecc9c4d66159cf0459ea1b4ae \ - --hash=sha256:ac50b2431a79a3b160fdefbba37c9132485f1a69166aba115ad49fafdbbbc5df +mkdocs-material==9.5.6 \ + --hash=sha256:5b24df36d8ac6cecd611241ce6f6423ccde3e1ad89f8360c3f76d5565fc2d82a \ + --hash=sha256:e115b90fccf5cd7f5d15b0c2f8e6246b21041628b8f590630e7fca66ed7fcf6c # via # -r requirements.in # mkdocs-material @@ -415,9 +415,9 @@ pillow==10.2.0 \ # via # cairosvg # mkdocs-material -platformdirs==4.1.0 \ - --hash=sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380 \ - --hash=sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420 +platformdirs==4.2.0 \ + --hash=sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068 \ + --hash=sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768 # via mkdocs pycparser==2.21 \ --hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \ @@ -445,9 +445,9 @@ python-dateutil==2.8.2 \ # via # ghp-import # typepy -pytz==2023.3.post1 \ - --hash=sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b \ - --hash=sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7 +pytz==2023.4 \ + --hash=sha256:31d4583c4ed539cd037956140d695e42c033a19e984bfce9964a3f7d59bc2b40 \ + --hash=sha256:f90ef520d95e7c46951105338d918664ebfd6f1d995bd7d153127ce90efafa6a # via typepy pyyaml==6.0.1 \ --hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \ @@ -643,9 +643,9 @@ typepy==1.3.2 \ # pytablewriter # tabledata # typepy -urllib3==2.1.0 \ - --hash=sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3 \ - --hash=sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54 +urllib3==2.2.0 \ + --hash=sha256:051d961ad0c62a94e50ecf1af379c3aba230c66c710493493560c0c223c49f20 \ + --hash=sha256:ce3711610ddce217e6d113a2732fafad960a03fd0318c91faa79481e35c11224 # via requests verspec==0.1.0 \ --hash=sha256:741877d5633cc9464c45a469ae2a31e801e6dbbaa85b9675d481cda100f11c31 \ diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index ed966699a..9f1ee4e16 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -119,6 +119,10 @@ Here is how you can access the logs, depending on your integration : Don't forget that BunkerWeb runs as an unprivileged user for obvious security reasons. Double-check the permissions of files and folders used by BunkerWeb, especially if you use custom configurations (more info [here](quickstart-guide.md#custom-configurations)). You will need to set at least **RW** rights on files and **_RWX_** on folders. +## Disable security checks + +For debugging purposes, you may need to temporarily disable the security checks made by BunkerWeb. One quick way of doing it is by adding everyone in the whitelist (e.g. `WHITELIST_IP=0.0.0.0/0`). + ## ModSecurity The default BunkerWeb configuration of ModSecurity is to load the Core Rule Set in anomaly scoring mode with a paranoia level (PL) of 1 : diff --git a/misc/update-version.sh b/misc/update-version.sh index 720684c76..3da699e97 100755 --- a/misc/update-version.sh +++ b/misc/update-version.sh @@ -37,6 +37,7 @@ shopt -u globstar # linux sed -i "s@${OLD_VERSION}@${NEW_VERSION}@g" src/linux/scripts/*.sh # db +sed -i "s@${OLD_VERSION}@${NEW_VERSION}@g" src/common/db/Database.py sed -i "s@${OLD_VERSION}@${NEW_VERSION}@g" src/common/db/model.py # github sed -i "s@${OLD_VERSION}@${NEW_VERSION}@g" .github/ISSUE_TEMPLATE/bug_report.yml diff --git a/src/autoconf/IngressController.py b/src/autoconf/IngressController.py index c49f5039c..137107d26 100644 --- a/src/autoconf/IngressController.py +++ b/src/autoconf/IngressController.py @@ -232,6 +232,7 @@ class IngressController(Controller): obj = event["object"] metadata = obj.metadata if obj else None annotations = metadata.annotations if metadata else None + data = obj.data if obj else None if not obj: return False if obj.kind == "Pod": @@ -242,6 +243,8 @@ class IngressController(Controller): return annotations and "bunkerweb.io/CONFIG_TYPE" in annotations if obj.kind == "Service": return True + if obj.kind == "Secret": + return data and "tls.crt" in data and "tls.key" in data return False def __watch(self, watch_type): @@ -255,6 +258,8 @@ class IngressController(Controller): what = self.__corev1.list_config_map_for_all_namespaces elif watch_type == "service": what = self.__corev1.list_service_for_all_namespaces + elif watch_type == "secret": + what = self.__corev1.list_secret_for_all_namespaces else: raise Exception(f"Unsupported watch_type {watch_type}") @@ -328,7 +333,7 @@ class IngressController(Controller): def process_events(self): self._set_autoconf_load_db() - watch_types = ("pod", "ingress", "configmap", "service") + watch_types = ("pod", "ingress", "configmap", "service", "secret") threads = [Thread(target=self.__watch, args=(watch_type,)) for watch_type in watch_types] for thread in threads: thread.start() diff --git a/src/bw/lua/bunkerweb/helpers.lua b/src/bw/lua/bunkerweb/helpers.lua index 3c41fa82f..09b1d6dc3 100644 --- a/src/bw/lua/bunkerweb/helpers.lua +++ b/src/bw/lua/bunkerweb/helpers.lua @@ -185,7 +185,7 @@ helpers.fill_ctx = function(no_ref) end data.remote_addr = var.remote_addr data.server_name = var.server_name - data.local_time = var.local_time + data.time_local = var.time_local if data.kind == "http" then data.uri = var.uri data.request_uri = var.request_uri @@ -196,6 +196,7 @@ helpers.fill_ctx = function(no_ref) data.http_content_length = var.http_content_length data.http_origin = var.http_origin data.http_version = req.http_version() + data.start_time = req.start_time() data.scheme = var.scheme end -- IP data : global diff --git a/src/bw/lua/bunkerweb/plugin.lua b/src/bw/lua/bunkerweb/plugin.lua index 3db038311..7230a9b62 100644 --- a/src/bw/lua/bunkerweb/plugin.lua +++ b/src/bw/lua/bunkerweb/plugin.lua @@ -93,4 +93,19 @@ function plugin:ret(ret, msg, status, redirect, data) return { ret = ret, msg = msg, status = status, redirect = redirect, data = data } end +function plugin:set_metric(kind, key, value) + if self.ctx and self.ctx.bw then + if not self.ctx.bw.metrics then + self.ctx.bw.metrics = {} + end + if not self.ctx.bw.metrics[self.id] then + self.ctx.bw.metrics[self.id] = {} + end + if not self.ctx.bw.metrics[self.id][kind] then + self.ctx.bw.metrics[self.id][kind] = {} + end + self.ctx.bw.metrics[self.id][kind][key] = value + end +end + return plugin diff --git a/src/bw/lua/bunkerweb/utils.lua b/src/bw/lua/bunkerweb/utils.lua index e4e528666..89e7d94e0 100644 --- a/src/bw/lua/bunkerweb/utils.lua +++ b/src/bw/lua/bunkerweb/utils.lua @@ -786,6 +786,7 @@ utils.get_phases = function() "preread", "log_stream", "log_default", + "timer" } end diff --git a/src/common/confs/init-worker-lua.conf b/src/common/confs/init-worker-lua.conf index 01d3f29cc..8105ba073 100644 --- a/src/common/confs/init-worker-lua.conf +++ b/src/common/confs/init-worker-lua.conf @@ -13,10 +13,15 @@ init_worker_by_lua_block { local ngx = ngx local INFO = ngx.INFO local ERR = ngx.ERR + local WARN = ngx.WARN local NOTICE = ngx.NOTICE + local worker = ngx.worker + local worker_id = worker.id + local timer_at = ngx.timer.at local require_plugin = helpers.require_plugin local new_plugin = helpers.new_plugin local call_plugin = helpers.call_plugin + local tostring = tostring -- Don't go further we are in loading state local is_loading, err = require "bunkerweb.utils".get_variable("IS_LOADING", false) @@ -27,6 +32,71 @@ init_worker_by_lua_block { return end + -- Recurrent timer + local recurrent_timer + recurrent_timer = function(premature) + + local worker_id = tostring(worker.id()) + local logger = require "bunkerweb.logger":new("TIMER-" .. worker_id) + + -- Worker exiting + if premature then + logger:log(WARN, "worker is exiting, disabling timer") + return + end + logger:log(INFO, "timer started") + + -- Get plugins order + local order, err = datastore:get("plugins_order", true) + if not order then + logger:log(ERR, "can't get plugins order from datastore : " .. err) + return + end + + -- Call timer() methods + logger:log(INFO, "calling timer() methods of plugins ...") + for i, plugin_id in ipairs(order.timer) do + -- Require call + local plugin_lua, err = require_plugin(plugin_id) + if plugin_lua == false then + logger:log(ERR, err) + elseif plugin_lua == nil then + logger:log(INFO, err) + else + -- Check if plugin has timer method + if plugin_lua.timer ~= nil then + -- New call + local ok, plugin_obj = new_plugin(plugin_lua) + if not ok then + logger:log(ERR, plugin_obj) + else + local ok, ret = call_plugin(plugin_obj, "timer") + if not ok then + logger:log(ERR, ret) + elseif not ret.ret then + logger:log(ERR, plugin_id .. ":timer() call failed : " .. ret.msg) + else + logger:log(INFO, plugin_id .. ":timer() call successful : " .. ret.msg) + end + end + else + logger:log(INFO, "skipped execution of " .. plugin_id .. " because method timer() is not defined") + end + end + end + logger:log(INFO, "called timer() methods of plugins") + local hdl + hdl, err = timer_at(5, recurrent_timer) + if not hdl then + logger:log(ERR, "can't create timer : " .. err) + end + end + local hdl + hdl, err = timer_at(0, recurrent_timer) + if not hdl then + logger:log(ERR, "can't create timer : " .. err) + end + -- Instantiate lock local lock = require "resty.lock":new("worker_lock", { timeout = 10 }) if not lock then diff --git a/src/common/core/antibot/antibot.lua b/src/common/core/antibot/antibot.lua index d7ef474f2..10ddce3db 100644 --- a/src/common/core/antibot/antibot.lua +++ b/src/common/core/antibot/antibot.lua @@ -152,6 +152,7 @@ function antibot:access() if ok == nil then return self:ret(false, "check challenge error : " .. err, HTTP_INTERNAL_SERVER_ERROR) elseif not ok then + self:set_metric("counters", "failed_challenges", 1) self.logger:log(ngx.WARN, "client failed challenge : " .. err) end if redirect then diff --git a/src/common/core/antibot/ui/actions.py b/src/common/core/antibot/ui/actions.py index c34b8c821..52b4f80f6 100644 --- a/src/common/core/antibot/ui/actions.py +++ b/src/common/core/antibot/ui/actions.py @@ -1 +1,11 @@ -# Spoofing an action file +def antibot(**kwargs): + try: + data = kwargs["app"].config["INSTANCES"].get_metrics("antibot") + + if data.get("counter_failed_challenges") is None: + data["counter_failed_challenges"] = 0 + + return data + + except: + return {"counter_failed_challenges": 0} diff --git a/src/common/core/antibot/ui/template.html b/src/common/core/antibot/ui/template.html index 46a45e762..338068f13 100644 --- a/src/common/core/antibot/ui/template.html +++ b/src/common/core/antibot/ui/template.html @@ -1,4 +1,11 @@ {% extends "base.html" %} {% block content %} +
- {{ antibot_info or "Anti-bot technology is designed to detect and - mitigate suspicious or malicious bots, preventing them from reaching an - organization's websites or IT ecosystem." }} -
+ >- total number + total failed +
@@ -66,4 +68,20 @@ + + {% endblock %} diff --git a/src/common/core/authbasic/ui/actions.py b/src/common/core/authbasic/ui/actions.py deleted file mode 100644 index c34b8c821..000000000 --- a/src/common/core/authbasic/ui/actions.py +++ /dev/null @@ -1 +0,0 @@ -# Spoofing an action file diff --git a/src/common/core/authbasic/ui/template.html b/src/common/core/authbasic/ui/template.html deleted file mode 100644 index 112e6d4b1..000000000 --- a/src/common/core/authbasic/ui/template.html +++ /dev/null @@ -1,65 +0,0 @@ -{% extends "base.html" %} {% block content %} - -- {{ authbasic_info or "Basic Auth is a method for an HTTP user agent - (e.g. a web browser) to provide a user name and password when making a - request." }} -
-- AUTH BASIC -
-- passed credentials -
-- {{ bad_behavior_info or "Ban IP generating too much 'bad' HTTP status - code in a period of time." }} -
-- BAD BEHAVIOR -
-- total ip bans -
-- {{item['code']}} -
+ >- {{item['count']}} -
+ >- {{ blacklist_info or "Deny access based on internal and external - IP/network/rDNS/ASN blacklists." }} -
+ >@@ -72,9 +75,7 @@ > IP
-@@ -112,9 +113,7 @@ > RDNS
-@@ -160,9 +159,7 @@ > ASN
-@@ -200,9 +197,7 @@ > User Agent
-@@ -231,6 +226,41 @@
- Active -
+ >- Inactive -
-- {{ bunkernet_info or "BunkerNet is a crowdsourced database of malicious - requests shared between all BunkerWeb instances over the world. " }} -
+ >- {{ country_info or "The country security feature allows you to apply - policy based on the country of the IP address of clients (blacklist / - whitelist)." }} -
-blacklist request blockedrequest blocked
- Country -
-- whitelist request passed -
-- {{ custom_certificate_info or "Custom certificates allow you to get - HTTPS / SSL / TLS on your requests." }} -
-- Server name -
-- CN -
-- Expiry date -
- - - -- {{item['server_name']}} -
-- {{item['cn']}} -
-- {{item['expire']}} -
-- {{ db_info or "BunkerWeb securely stores its current configuration in - a backend database, which contains essential data for smooth - operation." }} + DRIVER + + +
++ VERSION + +
- DRIVER - - {{ db_driver or "unknown" }} - -
-- VERSION - - {{ db_version or "unknown" }} - -
-@@ -102,6 +104,31 @@
- {{ dnsbl_info or "Deny access based on external DNSBL servers." }} -
+ >+
+ DNSBL +
+ + ++ request blocked - Server name -
-- Status -
- - -- {{item['server_name']}} -
- {% if item['status'] == "ko"%} -- {{ dnsbl_info or "Deny access based on external DNSBL servers." }} -
+ >- {{item['code']}} -
+ >- {{item['count']}} -
+ >+
++ GREYLIST +
+ + ++ request blocked - {{ greylist_info or "Allow access while keeping security features - based on internal and external IP/network/rDNS/ASN greylists. " }} -
-- URL -
-- - denied -
- IP -
-- - denied - -
-- RDNS -
-- - denied - -
-- ASN -
-- - denied - -
-- User Agent -
-- - denied - -
-- {{ lets_encrypt_info or "Let's Encrypt certificates for secure HTTP - requests." }} -
-- Server name -
-- CN -
-- Expiry date -
- - - -- {{item['server_name']}} -
-- {{item['cn']}} -
-- {{item['expire']}} -
-- {{ limit_info or "Limit maximum number of requests and connections." }} -
+ >- {{item['url']}} -
+ >- {{item['count']}} -
+ >- {{ misc_info or "Miscellaneous settings (methods, servers...)." }} -
+ >@@ -74,9 +81,10 @@ > DISALLOWED METHODS
-@@ -103,6 +111,26 @@
- {{ modsec_info or "ModSecurity is an open source, cross platform web application firewall (WAF) engine for Apache, IIS and Nginx that is developed by Trustwave's SpiderLabs." }} -
-- MODSECURITY -
-- request blocked - -
-- Active -
+ >- Inactive -
-- {{ redis_info or "Redis server configuration when using BunkerWeb in - cluster mode. " }} -
+ >- {{ lets_encrypt_info or "Selfsigned certificates for secure HTTP - requests." }} -
-- Server name -
-- CN -
-- Expiry date -
- - - -- {{item['server_name']}} -
-- {{item['cn']}} -
-- {{item['expire']}} -
-+
++ WHITELIST +
+ + ++ request passed - {{ whitelist_info or "Allow access based on internal and external - IP/network/rDNS/ASN whitelists." }} -
-- URL -
-- - passed -
- IP -
-- - passed - -
-- RDNS -
-- - passed - -
-- ASN -
-- - passed - -
-- User Agent -
-- - passed - -
-