BunkerWeb is a next-generation and open-source Web Application Firewall (WAF).
-Being a full-featured web server (based on [NGINX](https://nginx.org/) under the hood), it will protect your web services to make them "secure by default". BunkerWeb integrates seamlessly into your existing environments ([Linux](https://docs.bunkerweb.io/1.5.0/integrations/#linux), [Docker](https://docs.bunkerweb.io/1.5.0/integrations/#docker), [Swarm](https://docs.bunkerweb.io/1.5.0/integrations/#swarm), [Kubernetes](https://docs.bunkerweb.io/1.5.0/integrations/#kubernetes), âĻ) and is fully configurable (don't panic, there is an [awesome web UI](https://docs.bunkerweb.io/1.5.0/web-ui/) if you don't like the CLI) to meet your own use-cases . In other words, cybersecurity is no more a hassle.
+Being a full-featured web server (based on [NGINX](https://nginx.org/) under the hood), it will protect your web services to make them "secure by default". BunkerWeb integrates seamlessly into your existing environments ([Linux](https://docs.bunkerweb.io/1.5.1/integrations/#linux), [Docker](https://docs.bunkerweb.io/1.5.1/integrations/#docker), [Swarm](https://docs.bunkerweb.io/1.5.1/integrations/#swarm), [Kubernetes](https://docs.bunkerweb.io/1.5.1/integrations/#kubernetes), âĻ) and is fully configurable (don't panic, there is an [awesome web UI](https://docs.bunkerweb.io/1.5.1/web-ui/) if you don't like the CLI) to meet your own use-cases . In other words, cybersecurity is no more a hassle.
-BunkerWeb contains primary [security features](https://docs.bunkerweb.io/1.5.0/security-tuning/) as part of the core but can be easily extended with additional ones thanks to a [plugin system](https://docs.bunkerweb.io/1.5.0/plugins/)).
+BunkerWeb contains primary [security features](https://docs.bunkerweb.io/1.5.1/security-tuning/) as part of the core but can be easily extended with additional ones thanks to a [plugin system](https://docs.bunkerweb.io/1.5.1/plugins/)).
## Why BunkerWeb ?
@@ -64,12 +64,12 @@ A non-exhaustive list of security features :
- **Block known bad IPs** with external blacklists and DNSBL
- And much more ...
-Learn more about the core security features in the [security tuning](https://docs.bunkerweb.io/1.5.0/security-tuning/) section of the documentation.
+Learn more about the core security features in the [security tuning](https://docs.bunkerweb.io/1.5.1/security-tuning/) section of the documentation.
## Demo
-
+
A demo website protected with BunkerWeb is available at [demo.bunkerweb.io](https://demo.bunkerweb.io). Feel free to visit it and perform some security tests.
@@ -77,10 +77,10 @@ A demo website protected with BunkerWeb is available at [demo.bunkerweb.io](http
# Concepts
-
+
-You will find more information about the key concepts of BunkerWeb in the [documentation](https://docs.bunkerweb.io/1.5.0/concepts).
+You will find more information about the key concepts of BunkerWeb in the [documentation](https://docs.bunkerweb.io/1.5.1/concepts).
## Integrations
@@ -88,13 +88,13 @@ The first concept is the integration of BunkerWeb into the target environment. W
The following integrations are officially supported :
-- [Docker](https://docs.bunkerweb.io/1.5.0/integrations/#docker)
-- [Docker autoconf](https://docs.bunkerweb.io/1.5.0/integrations/#docker-autoconf)
-- [Swarm](https://docs.bunkerweb.io/1.5.0/integrations/#swarm)
-- [Kubernetes](https://docs.bunkerweb.io/1.5.0/integrations/#kubernetes)
-- [Linux](https://docs.bunkerweb.io/1.5.0/integrations/#linux)
-- [Ansible](https://docs.bunkerweb.io/1.5.0/integrations/#ansible)
-- [Vagrant](https://docs.bunkerweb.io/1.5.0/integrations/#vagrant)
+- [Docker](https://docs.bunkerweb.io/1.5.1/integrations/#docker)
+- [Docker autoconf](https://docs.bunkerweb.io/1.5.1/integrations/#docker-autoconf)
+- [Swarm](https://docs.bunkerweb.io/1.5.1/integrations/#swarm)
+- [Kubernetes](https://docs.bunkerweb.io/1.5.1/integrations/#kubernetes)
+- [Linux](https://docs.bunkerweb.io/1.5.1/integrations/#linux)
+- [Ansible](https://docs.bunkerweb.io/1.5.1/integrations/#ansible)
+- [Vagrant](https://docs.bunkerweb.io/1.5.1/integrations/#vagrant)
## Settings
@@ -126,7 +126,7 @@ When multisite mode is enabled, BunkerWeb will serve and protect multiple web ap
## Custom configurations
-Because meeting all the use cases only using the settings is not an option (even with [external plugins](https://docs.bunkerweb.io/1.5.0/plugins)), you can use custom configurations to solve your specific challenges.
+Because meeting all the use cases only using the settings is not an option (even with [external plugins](https://docs.bunkerweb.io/1.5.1/plugins)), you can use custom configurations to solve your specific challenges.
Under the hood, BunkerWeb uses the notorious NGINX web server, that's why you can leverage its configuration system for your specific needs. Custom NGINX configurations can be included in different [contexts](https://docs.nginx.com/nginx/admin-guide/basic-functionality/managing-configuration-files/#contexts) like HTTP or server (all servers and/or specific server block).
@@ -160,7 +160,7 @@ In other words, the scheduler is the brain of BunkerWeb.
## Docker
-
+
We provide ready to use prebuilt images for x64, x86, armv7 and arm64 platforms on [Docker Hub](https://hub.docker.com/u/bunkerity).
@@ -171,46 +171,46 @@ Docker integration key concepts are :
- **Scheduler** container to store configuration and execute jobs
- **Networks** to expose ports for clients and connect to upstream web services
-You will find more information in the [Docker integration section](https://docs.bunkerweb.io/1.5.0/integrations/#docker) of the documentation.
+You will find more information in the [Docker integration section](https://docs.bunkerweb.io/1.5.1/integrations/#docker) of the documentation.
## Docker autoconf
-
+
The downside of using environment variables is that the container needs to be recreated each time there is an update which is not very convenient. To counter that issue, you can use another image called **autoconf** which will listen for Docker events and automatically reconfigure BunkerWeb in real-time without recreating the container.
Instead of defining environment variables for the BunkerWeb container, you simply add **labels** to your web applications containers and the **autoconf** will "automagically" take care of the rest.
-You will find more information in the [Docker autoconf section](https://docs.bunkerweb.io/1.5.0/integrations/#docker-autoconf) of the documentation.
+You will find more information in the [Docker autoconf section](https://docs.bunkerweb.io/1.5.1/integrations/#docker-autoconf) of the documentation.
## Swarm
-
+
To automatically configure BunkerWeb instances, a special service, called **autoconf** will listen for Docker Swarm events like service creation or deletion and automatically configure the **BunkerWeb instances** in real-time without downtime.
-Like the [Docker autoconf integration](https://docs.bunkerweb.io/1.5.0/integrations/#docker-autoconf), configuration for web services is defined using labels starting with the special **bunkerweb.** prefix.
+Like the [Docker autoconf integration](https://docs.bunkerweb.io/1.5.1/integrations/#docker-autoconf), configuration for web services is defined using labels starting with the special **bunkerweb.** prefix.
-You will find more information in the [Swarm section](https://docs.bunkerweb.io/1.5.0/integrations/#swarm) of the documentation.
+You will find more information in the [Swarm section](https://docs.bunkerweb.io/1.5.1/integrations/#swarm) of the documentation.
## Kubernetes
-
+
The autoconf acts as an [Ingress controller](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/) and will configure the BunkerWeb instances according to the [Ingress resources](https://kubernetes.io/docs/concepts/services-networking/ingress/). It also monitors other Kubernetes objects like [ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/) for custom configurations.
-You will find more information in the [Kubernetes section](https://docs.bunkerweb.io/1.5.0/integrations/#kubernetes) of the documentation.
+You will find more information in the [Kubernetes section](https://docs.bunkerweb.io/1.5.1/integrations/#kubernetes) of the documentation.
## Linux
-
+
List of supported Linux distros :
@@ -222,12 +222,12 @@ List of supported Linux distros :
Repositories of Linux packages for BunkerWeb are available on [PackageCloud](https://packagecloud.io/bunkerity/bunkerweb), they provide a bash script to automatically add and trust the repository (but you can also follow the [manual installation](https://packagecloud.io/bunkerity/bunkerweb/install) instructions if you prefer).
-You will find more information in the [Linux section](https://docs.bunkerweb.io/1.5.0/integrations/#linux) of the documentation.
+You will find more information in the [Linux section](https://docs.bunkerweb.io/1.5.1/integrations/#linux) of the documentation.
## Ansible
-
+
List of supported Linux distros :
@@ -241,21 +241,20 @@ List of supported Linux distros :
A specific BunkerWeb Ansible role is available on [Ansible Galaxy](https://galaxy.ansible.com/bunkerity/bunkerweb) (source code is available [here](https://github.com/bunkerity/bunkerweb-ansible)).
-You will find more information in the [Ansible section](https://docs.bunkerweb.io/1.5.0/integrations/#ansible) of the documentation.
+You will find more information in the [Ansible section](https://docs.bunkerweb.io/1.5.1/integrations/#ansible) of the documentation.
## Vagrant
We maintain ready to use Vagrant boxes hosted on Vagrant cloud for the following providers :
-- vmware_desktop
-- virtualbox
+- virtualbox
- libvirt
-You will find more information in the [Vagrant section](https://docs.bunkerweb.io/1.5.0/integrations/#vagrant) of the documentation.
+You will find more information in the [Vagrant section](https://docs.bunkerweb.io/1.5.1/integrations/#vagrant) of the documentation.
# Quickstart guide
-Once you have setup BunkerWeb with the integration of your choice, you can follow the [quickstart guide](https://docs.bunkerweb.io/1.5.0/quickstart-guide/) that will cover the following common use cases :
+Once you have setup BunkerWeb with the integration of your choice, you can follow the [quickstart guide](https://docs.bunkerweb.io/1.5.1/quickstart-guide/) that will cover the following common use cases :
- Protecting a single HTTP application
- Protecting multiple HTTP application
@@ -266,9 +265,9 @@ Once you have setup BunkerWeb with the integration of your choice, you can follo
# Security tuning
-BunkerWeb offers many security features that you can configure with [settings](https://docs.bunkerweb.io/1.5.0/settings). Even if the default values of settings ensure a minimal "security by default", we strongly recommend you to tune them. By doing so you will be able to ensure a security level of your choice but also manage false positives.
+BunkerWeb offers many security features that you can configure with [settings](https://docs.bunkerweb.io/1.5.1/settings). Even if the default values of settings ensure a minimal "security by default", we strongly recommend you to tune them. By doing so you will be able to ensure a security level of your choice but also manage false positives.
-You will find more information in the [security tuning section](https://docs.bunkerweb.io/1.5.0/security-tuning) of the documentation.
+You will find more information in the [security tuning section](https://docs.bunkerweb.io/1.5.1/security-tuning) of the documentation.
# Settings
@@ -278,7 +277,7 @@ As a general rule when multisite mode is enabled, if you want to apply settings
When settings are considered as "multiple", it means that you can have multiple groups of settings for the same feature by adding numbers as suffix like `REVERSE_PROXY_URL_1=/subdir`, `REVERSE_PROXY_HOST_1=http://myhost1`, `REVERSE_PROXY_URL_2=/anotherdir`, `REVERSE_PROXY_HOST_2=http://myhost2`, ... for example.
-Check the [settings section](https://docs.bunkerweb.io/1.5.0/settings) of the documentation to get the full list.
+Check the [settings section](https://docs.bunkerweb.io/1.5.1/settings) of the documentation to get the full list.
# Web UI
@@ -296,7 +295,7 @@ The "Web UI" is a web application that helps you manage your BunkerWeb instance
- Monitor jobs execution
- View the logs and search pattern
-You will find more information in the [Web UI section](https://docs.bunkerweb.io/1.5.0/web-ui) of the documentation.
+You will find more information in the [Web UI section](https://docs.bunkerweb.io/1.5.1/web-ui) of the documentation.
# Plugins
@@ -304,15 +303,17 @@ BunkerWeb comes with a plugin system to make it possible to easily add new featu
Here is the list of "official" plugins that we maintain (see the [bunkerweb-plugins](https://github.com/bunkerity/bunkerweb-plugins) repository for more information) :
-| Name | Version | Description | Link |
-| :------------: | :-----: | :------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------: |
-| **ClamAV** | 0.1 | Automatically scans uploaded files with the ClamAV antivirus engine and denies the request when a file is detected as malicious. | [bunkerweb-plugins/clamav](https://github.com/bunkerity/bunkerweb-plugins/tree/main/clamav) |
-| **CrowdSec** | 0.1 | CrowdSec bouncer for BunkerWeb. | [bunkerweb-plugins/crowdsec](https://github.com/bunkerity/bunkerweb-plugins/tree/main/crowdsec) |
-| **Discord** | 0.1 | Send security notifications to a Discord channel using a Webhook. | [bunkerweb-plugins/discord](https://github.com/bunkerity/bunkerweb-plugins/tree/main/discord) |
-| **Slack** | 0.1 | Send security notifications to a Slack channel using a Webhook. | [bunkerweb-plugins/slack](https://github.com/bunkerity/bunkerweb-plugins/tree/main/slack) |
-| **VirusTotal** | 0.1 | Automatically scans uploaded files with the VirusTotal API and denies the request when a file is detected as malicious. | [bunkerweb-plugins/virustotal](https://github.com/bunkerity/bunkerweb-plugins/tree/main/virustotal) |
+| Name | Version | Description | Link |
+| :------------: | :-----: | :------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------: |
+| **ClamAV** | 1.1 | Automatically scans uploaded files with the ClamAV antivirus engine and denies the request when a file is detected as malicious. | [bunkerweb-plugins/clamav](https://github.com/bunkerity/bunkerweb-plugins/tree/main/clamav) |
+| **Coraza** | 1.1 | Inspect requests using a the Coraza WAF (alternative of ModSecurity). | [bunkerweb-plugins/coraza](https://github.com/bunkerity/bunkerweb-plugins/tree/main/coraza) |
+| **CrowdSec** | 1.1 | CrowdSec bouncer for BunkerWeb. | [bunkerweb-plugins/crowdsec](https://github.com/bunkerity/bunkerweb-plugins/tree/main/crowdsec) |
+| **Discord** | 1.1 | Send security notifications to a Discord channel using a Webhook. | [bunkerweb-plugins/discord](https://github.com/bunkerity/bunkerweb-plugins/tree/main/discord) |
+| **Slack** | 1.1 | Send security notifications to a Slack channel using a Webhook. | [bunkerweb-plugins/slack](https://github.com/bunkerity/bunkerweb-plugins/tree/main/slack) |
+| **VirusTotal** | 1.1 | Automatically scans uploaded files with the VirusTotal API and denies the request when a file is detected as malicious. | [bunkerweb-plugins/virustotal](https://github.com/bunkerity/bunkerweb-plugins/tree/main/virustotal) |
+| **WebHook** | 1.1 | Send security notifications to a custom HTTP endpoint using a Webhook. | [bunkerweb-plugins/slack](https://github.com/bunkerity/bunkerweb-plugins/tree/main/webhook) |
-You will find more information in the [plugins section](https://docs.bunkerweb.io/1.5.0/plugins) of the documentation.
+You will find more information in the [plugins section](https://docs.bunkerweb.io/1.5.1/plugins) of the documentation.
# Support
@@ -340,12 +341,12 @@ Please don't use [GitHub issues](https://github.com/bunkerity/bunkerweb/issues)
# License
-This project is licensed under the terms of the [GNU Affero General Public License (AGPL) version 3](https://github.com/bunkerity/bunkerweb/tree/1.5.0/LICENSE.md).
+This project is licensed under the terms of the [GNU Affero General Public License (AGPL) version 3](https://github.com/bunkerity/bunkerweb/tree/1.5.1/LICENSE.md).
# Contribute
-If you would like to contribute to the plugins you can read the [contributing guidelines](https://github.com/bunkerity/bunkerweb/tree/1.5.0/CONTRIBUTING.md) to get started.
+If you would like to contribute to the plugins you can read the [contributing guidelines](https://github.com/bunkerity/bunkerweb/tree/1.5.1/CONTRIBUTING.md) to get started.
# Security policy
-We take security bugs as serious issues and encourage responsible disclosure, see our [security policy](https://github.com/bunkerity/bunkerweb/tree/1.5.0/SECURITY.md) for more information.
\ No newline at end of file
+We take security bugs as serious issues and encourage responsible disclosure, see our [security policy](https://github.com/bunkerity/bunkerweb/tree/1.5.1/SECURITY.md) for more information.
diff --git a/SECURITY.md b/SECURITY.md
index 560b97f37..4727f3b5e 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -4,7 +4,7 @@ Even though this project is focused on security, it is still prone to possible v
## Responsible disclosure
-If you have found a security bug, please send us an email at security \[@\] bunkerity.com with technical details so we can resolve it as soon as possible.
+If you have found a security bug, please send us an email at security \[@\] bunkerity.com (using a ProtonMail if possible) with technical details so we can resolve it as soon as possible.
Here is a non-exhaustive list of issues we consider as high risk :
- Vulnerability in the code
diff --git a/docs/assets/img/bunkerweb_db.svg b/docs/assets/img/bunkerweb_db.svg
new file mode 100644
index 000000000..d7f898638
--- /dev/null
+++ b/docs/assets/img/bunkerweb_db.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/docs/concepts.md b/docs/concepts.md
index 9237d4a0f..439ff769a 100644
--- a/docs/concepts.md
+++ b/docs/concepts.md
@@ -1,7 +1,7 @@
# Concepts
- { align=center }
+ { align=center, width="600" }
## Integrations
@@ -52,17 +52,19 @@ USE_BROTLI=no
## Multisite mode
-The multisite mode is a crucial concept to understand when using BunkerWeb. Because the goal is to protect web applications, our solution is intrinsically linked to the concept of "virtual host" or "vhost" (more info [here](https://en.wikipedia.org/wiki/Virtual_hosting)) which makes it possible to serve multiple web applications from a single (or a cluster of) instance.
+Understanding the multisite mode is essential when utilizing BunkerWeb. As our primary focus is safeguarding web applications, our solution is intricately linked to the concept of "virtual hosts" or "vhosts" (more info [here](https://en.wikipedia.org/wiki/Virtual_hosting)). These virtual hosts enable the serving of multiple web applications from a single instance or cluster.
-By default, the multisite mode of BunkerWeb is disabled which means that only one web application will be served and all the settings will be applied to it. The typical use case is having a single application to protect : you don't have to worry about the multisite and the default behavior should be the right one for you.
+By default, BunkerWeb has the multisite mode disabled. This means that only one web application will be served, and all settings will be applied to it. This setup is ideal when you have a single application to protect, as you don't need to concern yourself with multisite configurations.
-When multisite mode is enabled, BunkerWeb serves and protects multiple web applications. Each web application is identified by a unique server name and have its own set of settings. The typical use case is having multiple applications to protect and you want to use a single (or a cluster depending of the integration) instance of BunkerWeb.
+However, when the multisite mode is enabled, BunkerWeb becomes capable of serving and protecting multiple web applications. Each web application is identified by a unique server name and has its own set of settings. This mode proves beneficial when you have multiple applications to secure, and you prefer to utilize a single instance (or a cluster) of BunkerWeb.
-The multisite mode is controlled by the `MULTISITE` setting which can be set to `yes` (enabled) or `no` (disabled, which is the default).
+The activation of the multisite mode is controlled by the `MULTISITE` setting, which can be set to `yes` to enable it or `no` to keep it disabled (which is the default value).
-Each setting has a context that defines "where" it can be applied. If the context is global then the setting can't be set per server (or "per site", "per app") but only to the whole configuration. Otherwise, if the context is multisite, the setting can be set globally and per server. Defining a multisite setting to a specific server is done by adding the server name as a prefix of the setting name like `app1.example.com_AUTO_LETS_ENCRYPT` or `app2.example.com_USE_ANTIBOT` for example. When a multisite setting is defined globally (without any server prefix), all the servers will inherit that setting (but can still be overridden if we set the same setting with the server name prefix).
+Each setting within BunkerWeb has a specific context that determines where it can be applied. If the context is set to "global," the setting can't be applied per server or site but is instead applied to the entire configuration as a whole. On the other hand, if the context is "multisite," the setting can be applied globally and per server. To define a multisite setting for a specific server, simply add the server name as a prefix to the setting name. For example, `app1.example.com_AUTO_LETS_ENCRYPT` or `app2.example.com_USE_ANTIBOT` are examples of setting names with server name prefixes. When a multisite setting is defined globally without a server prefix, all servers inherit that setting. However, individual servers can still override the setting if the same setting is defined with a server name prefix.
-Here is a dummy example of a multisite BunkerWeb configuration :
+Understanding the intricacies of multisite mode and its associated settings allows you to tailor BunkerWeb's behavior to suit your specific requirements, ensuring optimal protection for your web applications.
+
+Here's a dummy example of a multisite BunkerWeb configuration :
```conf
MULTISITE=yes
@@ -79,48 +81,66 @@ app3.example.com_USE_BAD_BEHAVIOR=no
!!! info "Going further"
- You will find concrete examples of multisite mode in the [quickstart guide](quickstart-guide.md) of the documentation and the [examples](https://github.com/bunkerity/bunkerweb/tree/v1.5.0/examples) directory of the repository.
+ You will find concrete examples of multisite mode in the [quickstart guide](quickstart-guide.md) of the documentation and the [examples](https://github.com/bunkerity/bunkerweb/tree/v1.5.1/examples) directory of the repository.
## Custom configurations
-Because meeting all the use cases only using the settings is not an option (even with [external plugins](plugins.md)), you can use custom configurations to solve your specific challenges.
+To address unique challenges and cater to specific use cases, BunkerWeb offers the flexibility of custom configurations. While the provided settings and [external plugins](plugins.md) cover a wide range of scenarios, there may be situations that require additional customization.
-Under the hood, BunkerWeb uses the notorious NGINX web server, that's why you can leverage its configuration system for your specific needs. Custom NGINX configurations can be included in different [contexts](https://docs.nginx.com/nginx/admin-guide/basic-functionality/managing-configuration-files/#contexts) like HTTP or server (all servers and/or specific server block).
+BunkerWeb is built on the renowned NGINX web server, which provides a powerful configuration system. This means you can leverage NGINX's configuration capabilities to meet your specific needs. Custom NGINX configurations can be included in various [contexts](https://docs.nginx.com/nginx/admin-guide/basic-functionality/managing-configuration-files/#contexts) such as HTTP or server, allowing you to fine-tune the behavior of BunkerWeb according to your requirements. Whether you need to customize global settings or apply configurations to specific server blocks, BunkerWeb empowers you to optimize its behavior to align perfectly with your use case.
-Another core component of BunkerWeb is the ModSecurity Web Application Firewall : you can also use custom configurations to fix some false positives or add custom rules for example.
+Another integral component of BunkerWeb is the ModSecurity Web Application Firewall. With custom configurations, you have the flexibility to address false positives or add custom rules to further enhance the protection provided by ModSecurity. These custom configurations allow you to fine-tune the behavior of the firewall and ensure that it aligns with the specific requirements of your web applications.
+
+By leveraging custom configurations, you unlock a world of possibilities to tailor BunkerWeb's behavior and security measures precisely to your needs. Whether it's adjusting NGINX configurations or fine-tuning ModSecurity, BunkerWeb provides the flexibility to meet your unique challenges effectively.
!!! info "Going further"
- You will find concrete examples of custom configurations in the [quickstart guide](quickstart-guide.md) of the documentation and the [examples](https://github.com/bunkerity/bunkerweb/tree/v1.5.0/examples) directory of the repository.
+ You will find concrete examples of custom configurations in the [quickstart guide](quickstart-guide.md) of the documentation and the [examples](https://github.com/bunkerity/bunkerweb/tree/v1.5.1/examples) directory of the repository.
## Database
-State of the current configuration of BunkerWeb is stored in a backend database which contains the following data :
+BunkerWeb securely stores its current configuration in a backend database, which contains essential data for smooth operation. The following information is stored in the database:
-- Settings defined for all the services
-- Custom configurations
-- BunkerWeb instances
-- Metadata about jobs execution
-- Cached files
+- **Settings for all services**: The database holds the defined settings for all the services provided by BunkerWeb. This ensures that your configurations and preferences are preserved and readily accessible.
-Under the hood, when you edit a setting or add a new configuration, everything is stored in the database. We actually support SQLite, MariaDB, MySQL and PostgreSQL as backends.
+- **Custom configurations**: Any custom configurations you create are also stored in the backend database. This includes personalized settings and modifications tailored to your specific requirements.
-Database configuration is done by using the `DATABASE_URI` setting which respects the following formats :
+- **BunkerWeb instances**: Information about BunkerWeb instances, including their setup and relevant details, is stored in the database. This allows for easy management and monitoring of multiple instances if applicable.
-- SQLite : `sqlite:///var/lib/bunkerweb/db.sqlite3`
-- MariaDB : `mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db`
-- MySQL : `mysql+pymysql://bunkerweb:changeme@bw-db:3306/db`
-- PostgreSQL : `postgresql://bunkerweb:changeme@bw-db:5432/db`
+- **Metadata about job execution**: The database stores metadata related to the execution of various jobs within BunkerWeb. This includes information about scheduled tasks, maintenance processes, and other automated activities.
+
+- **Cached files**: BunkerWeb utilizes caching mechanisms for improved performance. The database holds cached files, ensuring efficient retrieval and delivery of frequently accessed resources.
+
+Under the hood, whenever you edit a setting or add a new configuration, BunkerWeb automatically stores the changes in the database, ensuring data persistence and consistency. BunkerWeb supports multiple backend database options, including SQLite, MariaDB, MySQL, and PostgreSQL.
+
+Configuring the database is straightforward using the `DATABASE_URI` setting, which follows the specified formats for each supported database:
+
+- **SQLite**: `sqlite:///var/lib/bunkerweb/db.sqlite3`
+- **MariaDB**: `mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db`
+- **MySQL**: `mysql+pymysql://bunkerweb:changeme@bw-db:3306/db`
+- **PostgreSQL**: `postgresql://bunkerweb:changeme@bw-db:5432/db`
+
+By specifying the appropriate database URI in the configuration, you can seamlessly integrate BunkerWeb with your preferred database backend, ensuring efficient and reliable storage of your configuration data.
+
+
+ { align=center, width="800" }
+ Database Schema
+
## Scheduler
-To make things automagically work together, a dedicated service called the scheduler is in charge of :
+For seamless coordination and automation, BunkerWeb employs a specialized service known as the scheduler. The scheduler plays a vital role in ensuring smooth operation by performing the following tasks:
-- Storing the settings and custom configurations inside the database
-- Executing various tasks (called jobs)
-- Generating a configuration which is understood by BunkerWeb
-- Being the intermediary for other services (like web UI or autoconf)
+- **Storing settings and custom configurations**: The scheduler is responsible for storing all the settings and custom configurations within the backend database. This centralizes the configuration data, making it easily accessible and manageable.
-In other words, the scheduler is the brain of BunkerWeb.
+- **Executing various tasks (jobs)**: The scheduler handles the execution of various tasks, referred to as jobs. These jobs encompass a range of activities, such as periodic maintenance, scheduled updates, or any other automated tasks required by BunkerWeb.
-When using container-based integrations, the scheduler is executed in its own container. Whereas, for linux-based integrations scheduler is self-contained in the `bunkerweb` service.
\ No newline at end of file
+- **Generating BunkerWeb configuration**: The scheduler generates a configuration that is readily understood by BunkerWeb. This configuration is derived from the stored settings and custom configurations, ensuring that the entire system operates cohesively.
+
+- **Acting as an intermediary for other services**: The scheduler acts as an intermediary, facilitating communication and coordination between different components of BunkerWeb. It interfaces with services such as the web UI or autoconf, ensuring a seamless flow of information and data exchange.
+
+In essence, the scheduler serves as the brain of BunkerWeb, orchestrating various operations and ensuring the smooth functioning of the system.
+
+Depending on the integration approach, the execution environment of the scheduler may differ. In container-based integrations, the scheduler is executed within its dedicated container, providing isolation and flexibility. On the other hand, for Linux-based integrations, the scheduler is self-contained within the bunkerweb service, simplifying the deployment and management process.
+
+By employing the scheduler, BunkerWeb streamlines the automation and coordination of essential tasks, enabling efficient and reliable operation of the entire system.
\ No newline at end of file
diff --git a/docs/index.md b/docs/index.md
index 17c64011d..c5014802b 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -7,35 +7,56 @@
Make your web services secure by default !
-BunkerWeb is a next-generation and open-source Web Application Firewall (WAF).
+Introducing BunkerWeb, the **cutting-edge** and **open-source Web Application Firewall** (WAF) that will revolutionize your web security experience.
-Being a full-featured web server (based on [NGINX](https://nginx.org/) under the hood), it will protect your web services to make them "secure by default". BunkerWeb integrates seamlessly into your existing environments ([Linux](integrations.md#linux), [Docker](integrations.md#docker), [Swarm](integrations.md#swarm), [Kubernetes](integrations.md#kubernetes), âĻ) and is fully configurable (don't panic, there is an [awesome web UI](web-ui.md) if you don't like the CLI) to meet your own use-cases . In other words, cybersecurity is no more a hassle.
+With BunkerWeb, your web services are safeguarded by default, providing you with peace of mind and enhanced protection. Powered by [NGINX](https://nginx.org/), this comprehensive web server combines advanced features seamlessly, ensuring your online assets remain secure.
+
+BunkerWeb effortlessly integrates into your existing environments, whether it's [Linux](integrations.md#linux), [Docker](integrations.md#docker), [Swarm](integrations.md#swarm), [Kubernetes](integrations.md#kubernetes), or more. Its versatility allows for easy configuration to suit your specific requirements. Don't worry if you prefer a user-friendly interfaceâBunkerWeb offers an exceptional [web UI](web-ui.md) alongside the command-line interface (CLI), ensuring accessibility for all users.
+
+Experience the transformation in cybersecurity, where complexities and obstacles are a thing of the past. With BunkerWeb, fortifying your digital assets has never been more delightful and hassle-free.
+
+Furthermore, BunkerWeb boasts a comprehensive set of primary [security features](security-tuning.md) at its core. However, what sets it apart is its remarkable flexibility through an intuitive [plugin system](plugins.md). This ingenious design empowers you to effortlessly enhance BunkerWeb with additional security measures, ensuring a tailored and robust defense for your web applications.
+
+By seamlessly integrating new plugins into BunkerWeb, you can customize and expand its capabilities to address specific security requirements unique to your environment. Whether you need to strengthen authentication protocols, bolster threat detection, or implement specialized security measures, BunkerWeb's [plugin system](plugins.md) grants you the freedom to fortify your web infrastructure with ease.
+
+With BunkerWeb's dynamic [plugin system](plugins.md), security becomes an enjoyable journey of exploration and empowerment. Discover the endless possibilities and create a fortified web environment that perfectly aligns with your needs.
-BunkerWeb contains primary [security features](security-tuning.md) as part of the core but can be easily extended with additional ones thanks to a [plugin system](plugins.md)).
## Why BunkerWeb ?
-- **Easy integration into existing environments** : support for Linux, Docker, Swarm, Kubernetes, Ansible, Vagrant, ...
-- **Highly customizable** : enable, disable and configure features easily to meet your use case
-- **Secure by default** : offers out-of-the-box and hassle-free minimal security for your web services
-- **Awesome web UI** : keep control of everything more efficiently without the need of the CLI
-- **Plugin system** : extend BunkerWeb to meet your own use-cases
-- **Free as in "freedom"** : licensed under the free [AGPLv3 license](https://www.gnu.org/licenses/agpl-3.0.en.html)
+- **Easy integration into existing environments** : Seamlessly integrate BunkerWeb into various environments such as Linux, Docker, Swarm, Kubernetes, Ansible, Vagrant, and more. Enjoy a smooth transition and hassle-free implementation.
+
+- **Highly customizable** : Tailor BunkerWeb to your specific requirements with ease. Enable, disable, and configure features effortlessly, allowing you to customize the security settings according to your unique use case.
+
+- **Secure by default** : BunkerWeb provides out-of-the-box, hassle-free minimal security for your web services. Experience peace of mind and enhanced protection right from the start.
+
+- **Awesome web UI** : Take control of BunkerWeb more efficiently with the exceptional web user interface (UI). Navigate settings and configurations effortlessly through a user-friendly graphical interface, eliminating the need for the command-line interface (CLI).
+
+- **Plugin system** : Extend the capabilities of BunkerWeb to meet your own use cases. Seamlessly integrate additional security measures and customize the functionality of BunkerWeb according to your specific requirements.
+
+- **Free as in "freedom"** : BunkerWeb is licensed under the free [AGPLv3 license](https://www.gnu.org/licenses/agpl-3.0.en.html), embracing the principles of freedom and openness. Enjoy the freedom to use, modify, and distribute the software, backed by a supportive community.
## Security features
-A non-exhaustive list of security features :
+Explore the impressive array of security features offered by BunkerWeb. While not exhaustive, here are some notable highlights:
-- **HTTPS** support with transparent **Let's Encrypt** automation
-- **State-of-the-art web security** : HTTP security headers, prevent leaks, TLS hardening, ...
-- Integrated **ModSecurity WAF** with the **OWASP Core Rule Set**
-- **Automatic ban** of strange behaviors based on HTTP status code
-- Apply **connections and requests limit** for clients
-- **Block bots** by asking them to solve a **challenge** (e.g. : cookie, javascript, captcha, hCaptcha or reCAPTCHA)
-- **Block known bad IPs** with external blacklists and DNSBL
-- And much more ...
+- **HTTPS** support with transparent **Let's Encrypt** automation : Easily secure your web services with automated Let's Encrypt integration, ensuring encrypted communication between clients and your server.
-Learn more about the core security features in the [security tuning](security-tuning.md) section of the documentation.
+- **State-of-the-art web security** : Benefit from cutting-edge web security measures, including comprehensive HTTP security headers, prevention of data leaks, and TLS hardening techniques.
+
+- Integrated **ModSecurity WAF** with the **OWASP Core Rule Set** : Enjoy enhanced protection against web application attacks with the integration of ModSecurity, fortified by the renowned OWASP Core Rule Set.
+
+- **Automatic ban** of strange behaviors based on HTTP status code : BunkerWeb intelligently identifies and blocks suspicious activities by automatically banning behaviors that trigger abnormal HTTP status codes.
+
+- Apply **connections and requests limit** for clients : Set limits on the number of connections and requests from clients, preventing resource exhaustion and ensuring fair usage of server resources.
+
+- **Block bots** with **challenge-based verification** : Keep malicious bots at bay by challenging them to solve puzzles such as cookies, JavaScript tests, captcha, hCaptcha, reCAPTCHA or Turnstile, effectively blocking unauthorized access.
+
+- **Block known bad IPs** with external blacklists and DNSBL : Utilize external blacklists and DNS-based blackhole lists (DNSBL) to proactively block known malicious IP addresses, bolstering your defense against potential threats.
+
+- **And much more...** : BunkerWeb is packed with a plethora of additional security features that go beyond this list, providing you with comprehensive protection and peace of mind.
+
+To delve deeper into the core security features, we invite you to explore the [security tuning](security-tuning.md) section of the documentation. Discover how BunkerWeb empowers you to fine-tune and optimize security measures according to your specific needs.
## Demo
diff --git a/docs/integrations.md b/docs/integrations.md
index d640e80bb..6efa1c22d 100644
--- a/docs/integrations.md
+++ b/docs/integrations.md
@@ -7,15 +7,28 @@
Docker integration
-Using BunkerWeb as a [Docker](https://www.docker.com/) container is a quick and easy way to test and use it as long as you are familiar with the Docker technology.
+Utilizing BunkerWeb as a [Docker](https://www.docker.com/) container offers a convenient and straightforward approach for testing and utilizing the solution, particularly if you are already familiar with Docker technology.
-We provide ready-to-use prebuilt images for x64, x86 armv8 and armv7 architectures on [Docker Hub](https://hub.docker.com/r/bunkerity/bunkerweb) :
+To facilitate your Docker deployment, we provide readily available prebuilt images on [Docker Hub](https://hub.docker.com/r/bunkerity/bunkerweb), supporting multiple architectures. These prebuilt images are optimized and prepared for use on the following architectures:
+
+- x64 (64-bit)
+- x86
+- armv8 (ARM 64-bit)
+- armv7 (ARM 32-bit)
+
+By accessing these prebuilt images from Docker Hub, you can quickly pull and run BunkerWeb within your Docker environment, eliminating the need for extensive configuration or setup processes. This streamlined approach allows you to focus on leveraging the capabilities of BunkerWeb without unnecessary complexities.
+
+Whether you're conducting tests, developing applications, or deploying BunkerWeb in production, the Docker containerization option provides flexibility and ease of use. Embracing this method empowers you to take full advantage of BunkerWeb's features while leveraging the benefits of Docker technology.
```shell
-docker pull bunkerity/bunkerweb:1.5.0
+docker pull bunkerity/bunkerweb:1.5.1
```
-Alternatively, you can build the Docker image directly from the [source](https://github.com/bunkerity/bunkerweb) (and get a coffee â because it may take a long time depending on your hardware) :
+Alternatively, if you prefer a more hands-on approach, you have the option to build the Docker image directly from the [source](https://github.com/bunkerity/bunkerweb). Building the image from source gives you greater control and customization over the deployment process. However, please note that this method may take some time to complete, depending on your hardware configuration.
+
+While the image is being built, you can take a moment to relax and enjoy a cup of coffee â, as the process may require some patience. Once the image is successfully built, you can proceed to deploy and utilize BunkerWeb within your Docker environment. This method allows you to tailor the image to your specific requirements and ensures a more personalized deployment of BunkerWeb.
+
+So, whether you choose to use the ready-to-use prebuilt images or embark on the journey of building the image from source, BunkerWeb in Docker provides you with the flexibility and options to seamlessly integrate it into your environment.
```shell
git clone https://github.com/bunkerity/bunkerweb.git && \
@@ -29,8 +42,16 @@ Docker integration key concepts are :
- **Scheduler** container to store configuration and execute jobs
- **Networks** to expose ports for clients and connect to upstream web services
+When integrating BunkerWeb with Docker, there are key concepts to keep in mind, ensuring a smooth and efficient deployment:
+
+- **Environment variables**: BunkerWeb can be easily configured using environment variables. These variables allow you to customize various aspects of BunkerWeb's behavior, such as network settings, security options, and other parameters.
+
+- **Scheduler container**: To effectively manage the configuration and execution of jobs, BunkerWeb utilizes a dedicated container called the [scheduler](concepts.md#scheduler).
+
+- **Networks**: Docker networks play a vital role in the integration of BunkerWeb. These networks serve two main purposes: exposing ports to clients and connecting to upstream web services. By exposing ports, BunkerWeb can accept incoming requests from clients, allowing them to access the protected web services. Additionally, by connecting to upstream web services, BunkerWeb can efficiently route and manage the traffic, providing enhanced security and performance.
+
!!! info "Database backend"
- Please note that we assume you are using SQLite as database backend (which is the default for the `DATABASE_URI` setting). Other backends for this integration are still possible if you want to : see docker-compose files in the [misc/integrations folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.0/misc/integrations) folder of the repostiory for more information.
+ Please be aware that our instructions assume you are using SQLite as the default database backend, as configured by the `DATABASE_URI` setting. However, we understand that you may prefer to utilize alternative backends for your Docker integration. If that is the case, rest assured that other database backends are still possible. See docker-compose files in the [misc/integrations folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.1/misc/integrations) folder of the repository for more information.
### Environment variables
@@ -40,7 +61,7 @@ Settings are passed to BunkerWeb using Docker environment variables :
...
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
labels:
- "bunkerweb.INSTANCE"
environment:
@@ -59,7 +80,7 @@ Please note that the `bunkerweb.INSTANCE` is mandatory to make sure the schedule
The [scheduler](concepts.md#scheduler) is executed in its own container which is also available on Docker Hub :
```shell
-docker pull bunkerity/bunkerweb-scheduler:1.5.0
+docker pull bunkerity/bunkerweb-scheduler:1.5.1
```
Alternatively, you can build the Docker image directly from the [source](https://github.com/bunkerity/bunkerweb) (less coffee â needed than BunkerWeb image) :
@@ -76,7 +97,7 @@ A volume is needed to store the SQLite database that will be used by the schedul
...
services:
mybunker:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
volumes:
- bw-data:/data
...
@@ -85,7 +106,6 @@ volumes:
```
!!! warning "Using local folder for persistent data"
-
The scheduler runs as an **unprivileged user with UID 101 and GID 101** inside the container. The reason behind this is security : in case a vulnerability is exploited, the attacker won't have full root (UID/GID 0) privileges.
But there is a downside : if you use a **local folder for the persistent data**, you will need to **set the correct permissions** so the unprivileged user can write data to it. Something like that should do the trick :
@@ -127,10 +147,11 @@ volumes:
When using Docker-based integrations, the scheduler will need to access the Docker API to get things working which is defined using the `DOCKER_HOST` environment variable.
!!! warning "Docker API access and security"
+ Due to Docker's limitations in supporting fine-grained authorizations, it's important to be aware of the potential security risks associated with accessing the API directly. Accessing the Docker API can pose a threat, as an attacker with API access can potentially obtain root privileges on the host machine. For more detailed information on this topic, we encourage you to refer to the provided link ([here](https://blog.quarkslab.com/why-is-exposing-the-docker-socket-a-really-bad-idea.html)).
- Since Docker doesn't support fine-grained authorizations, accessing the API poses a security risk. An attacker with access to the API can easily gain root privileges on the host machine (more info [here](https://blog.quarkslab.com/why-is-exposing-the-docker-socket-a-really-bad-idea.html)).
+ To mitigate these risks, we strongly advise against directly mounting the socket file located at `/var/run/docker.sock` within the BunkerWeb container. Instead, we recommend employing an alternative approach that enhances security. One such approach involves using a "proxy" container, such as `tecnativa/docker-socket-proxy`, which acts as an intermediary and allows only necessary API calls.
- We strongly recommend not to mount the socket file usually located at `/var/run/docker.sock` directly in the container. An alternative, which is described here, is to use a "proxy" container like [tecnativa/docker-socket-proxy](https://github.com/Tecnativa/docker-socket-proxy) that will allow only the necessary API calls.
+ By adopting this proxy container strategy, you can establish a more secure communication channel with the Docker API, minimizing the potential attack surface and enhancing overall system security.
You will need to create the Docker API proxy container, mount the socket and set the `DOCKER_HOST` environment variable to use the Docker API proxy :
@@ -138,16 +159,17 @@ You will need to create the Docker API proxy container, mount the socket and set
...
services:
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
env:
- DOCKER_HOST=tcp://bw-docker:2375
...
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
...
```
@@ -179,13 +201,13 @@ For defense in depth purposes, we strongly recommend to create at least three di
- `bw-universe` : for BunkerWeb and scheduler
- `bw-docker` : for scheduler and the Docker API proxy
-The scheduler needs to contact the API of BunkerWeb and for obvious security reason BunkerWeb needs to check if the caller is authorized to make API calls. The `API_WHITELIST_IP` setting lets you choose allowed IP addresses and subnets, usage of a static subnet for the `bw-universe` is strongly advised :
+To secure the communication between the scheduler and BunkerWeb API, it is important to authorize API calls. You can use the `API_WHITELIST_IP` setting to specify allowed IP addresses and subnets. It is strongly recommended to use a static subnet for the `bw-universe` network to enhance security. By implementing these measures, you can ensure that only authorized sources can access the BunkerWeb API, reducing the risk of unauthorized access or malicious activities:
```yaml
...
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -194,13 +216,13 @@ services:
- bw-universe
...
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
networks:
- bw-universe
- bw-docker
...
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
networks:
- bw-docker
...
@@ -224,7 +246,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -238,7 +260,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -251,11 +273,12 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -285,24 +308,28 @@ networks:
!!! info "Docker integration"
The Docker autoconf integration is an "evolution" of the Docker one. Please read the [Docker integration section](#docker) first if needed.
-The downside of using environment variables is that the container needs to be recreated each time there is an update which is not very convenient. To counter that issue, you can use another image called **autoconf** which will listen for Docker events and automatically reconfigure BunkerWeb in real-time without recreating the container.
+An alternative approach is available to address the inconvenience of recreating the container every time there is an update. By utilizing another image called **autoconf**, you can automate the real-time reconfiguration of BunkerWeb without the need for container recreation.
-Instead of defining environment variables for the BunkerWeb container, you simply add **labels** to your web applications containers and the **autoconf** will "automagically" take care of the rest.
+To leverage this functionality, instead of defining environment variables for the BunkerWeb container, you can add **labels** to your web application containers. The **autoconf** image will then listen for Docker events and seamlessly handle the configuration updates for BunkerWeb.
+
+This "automagical" process simplifies the management of BunkerWeb configurations. By adding labels to your web application containers, you can delegate the reconfiguration tasks to **autoconf** without the manual intervention of container recreation. This streamlines the update process and enhances convenience.
+
+By adopting this approach, you can enjoy real-time reconfiguration of BunkerWeb without the hassle of container recreation, making it more efficient and user-friendly.
!!! info "Multisite mode"
The Docker autoconf integration implies the use of **multisite mode**. Please refer to the [multisite section](concepts.md#multisite-mode) of the documentation for more information.
!!! info "Database backend"
- Please note that we assume you are using MariaDB as database backend (which is defined using the `DATABASE_URI` setting). Other backends for this integration are still possible if you want : see docker-compose files in the [misc/integrations folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.0/misc/integrations) folder of the repostiory for more information.
+ Please be aware that our instructions assume you are using MariaDB as the default database backend, as configured by the `DATABASE_URI` setting. However, we understand that you may prefer to utilize alternative backends for your Docker integration. If that is the case, rest assured that other database backends are still possible. See docker-compose files in the [misc/integrations folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.1/misc/integrations) folder of the repository for more information.
-Another container, named `bw-autoconf` for example, containing the autoconf service must be added to the stack. Since two services will generate the configuration for BunkerWeb, a "real" database backend (in other words, not SQLite) also needs to be added :
+To enable automated configuration updates, include an additional container called `bw-autoconf` in the stack. This container hosts the autoconf service, which manages dynamic configuration changes for BunkerWeb. To support this functionality, use a dedicated "real" database backend (e.g., MariaDB, MySQL, or PostgreSQL) for synchronized configuration storage. By integrating `bw-autoconf` and a suitable database backend, you establish the infrastructure for seamless automated configuration management in BunkerWeb.
```yaml
version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -319,7 +346,7 @@ services:
- bw-services
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -332,7 +359,7 @@ services:
- bw-docker
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -345,11 +372,12 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -381,6 +409,9 @@ networks:
name: bw-docker
```
+!!! info "Database in the `bw-docker` network"
+ The database container is intentionally not included in the `bw-universe` network. It is used by the `bw-autoconf` and `bw-scheduler` containers rather than directly by BunkerWeb. Therefore, the database container is part of the `bw-docker` network, which enhances security by making external access to the database more challenging. This deliberate design choice helps safeguard the database and strengthens the overall security perspective of the system.
+
!!! warning "Using Docker in rootless mode"
If you are using [Docker in rootless mode](https://docs.docker.com/engine/security/rootless), you will need to replace the mount of the docker socket with the following value : `$XDG_RUNTIME_DIR/docker.sock:/var/run/docker.sock:ro`.
@@ -416,18 +447,20 @@ networks:
!!! info "Docker autoconf"
The Swarm integration is similar to the Docker autoconf one (but with services instead of containers). Please read the [Docker autoconf integration section](#docker-autoconf) first if needed.
-To automatically configure BunkerWeb instances, a special service called **autoconf** needs to have access to the Docker API. That service will listen for Docker Swarm events like service creation or deletion and automatically configure the **BunkerWeb instances** in real-time without downtime. It also monitors other Swarm objects like [configs](https://docs.docker.com/engine/swarm/configs/) for custom configurations.
+To enable automatic configuration of BunkerWeb instances, the **autoconf** service requires access to the Docker API. This service listens for Docker Swarm events, such as service creation or deletion, and seamlessly configures the **BunkerWeb instances** in real-time without any downtime. It also monitors other Swarm objects, such as [configs](https://docs.docker.com/engine/swarm/configs/), for custom configurations.
-Like the [Docker autoconf integration](#docker-autoconf), configuration for web services is defined by using labels starting with the special **bunkerweb.** prefix.
+Similar to the [Docker autoconf integration](#docker-autoconf), configuration for web services is defined using labels that start with the **bunkerweb** prefix.
-The recommended setup is to schedule the **BunkerWeb service** as a **global service** on all nodes and the **autoconf, scheduler and Docker API proxy services** as **single replicated services**. Please note that the **Docker API proxy service** needs to be scheduled on a manager node unless you configure it to use a remote API (which is not covered in the documentation).
+For an optimal setup, it is recommended to schedule the **BunkerWeb service** as a ***global service*** on all nodes, while the **autoconf, scheduler, and Docker API proxy services** should be scheduled as ***single replicated services***. Please note that the Docker API proxy service needs to be scheduled on a manager node unless you configure it to use a remote API (which is not covered in the documentation).
-Since we have multiple instances of BunkerWeb running, a shared data store implemented as a [Redis](https://redis.io/) service must be created : the instances will use it to cache and share data. You will find more information about the Redis settings [here](settings.md#redis)
+Since multiple instances of BunkerWeb are running, a shared data store implemented as a [Redis](https://redis.io/) service must be created. These instances will utilize the Redis service to cache and share data. Further details regarding the Redis settings can be found [here](settings.md#redis).
-Using a shared folder or a specific driver for the database volume is left as an exercise for the reader (and depends on your own use-case).
+As for the database volume, the documentation does not specify a specific approach. Choosing either a shared folder or a specific driver for the database volume is dependent on your unique use-case and is left as an exercise for the reader.
!!! info "Database backend"
- Please note that we assume you are using MariaDB as database backend (which is defined using the `DATABASE_URI` setting). Other backends for this integration are still possible if you want : see docker-compose files in the [misc/integrations folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.0/misc/integrations) folder of the repostiory for more information. Clustered database backends setup are out-of-the-scope of this documentation.
+ Please be aware that our instructions assume you are using MariaDB as the default database backend, as configured by the `DATABASE_URI` setting. However, we understand that you may prefer to utilize alternative backends for your Docker integration. If that is the case, rest assured that other database backends are still possible. See docker-compose files in the [misc/integrations folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.1/misc/integrations) folder of the repository for more information.
+
+ Clustered database backends setup are out-of-the-scope of this documentation.
Here is the stack boilerplate that you can deploy using `docker stack deploy` :
@@ -436,7 +469,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- published: 80
target: 8080
@@ -466,7 +499,7 @@ services:
- "bunkerweb.INSTANCE"
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
@@ -480,7 +513,7 @@ services:
- "node.role == worker"
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
@@ -489,6 +522,7 @@ services:
- SERVICES=1
- SWARM=1
- TASKS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
deploy:
@@ -497,7 +531,7 @@ services:
- "node.role == manager"
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
@@ -556,7 +590,8 @@ networks:
attachable: true
```
-Please note that the `SWARM_MODE=yes` environment variable is mandatory when using the Swarm integration.
+!!! info "Swarm mandatory setting"
+ Please note that the `SWARM_MODE=yes` environment variable is mandatory when using the Swarm integration.
Once the BunkerWeb Swarm stack is set up and running (see autoconf and scheduler logs for more information), you will be able to deploy web applications in the cluster and use labels to dynamically configure BunkerWeb :
@@ -589,20 +624,22 @@ networks:
Kubernetes integration
-The autoconf acts as an [Ingress controller](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/) and will configure the BunkerWeb instances according to the [Ingress resources](https://kubernetes.io/docs/concepts/services-networking/ingress/). It also monitors other Kubernetes objects like [ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/) for custom configurations.
+To automate the configuration of BunkerWeb instances in a Kubernetes environment, the autoconf service serves as an [Ingress controller](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/). It configures the BunkerWeb instances based on [Ingress resources](https://kubernetes.io/docs/concepts/services-networking/ingress/) and also monitors other Kubernetes objects, such as [ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/), for custom configurations.
-The recommended setup is to define **BunkerWeb** as a **[DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/)** which will create a pod on all nodes and the **autoconf and scheduler** as **single replicated [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)**.
+For an optimal setup, it is recommended to define BunkerWeb as a **[DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/)**, which ensures that a pod is created on all nodes, while the **autoconf and scheduler** are defined as **single replicated [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)**.
-Since we have multiple instances of BunkerWeb running, a shared data store implemented as a [Redis](https://redis.io/) service must be created : the instances will use it to cache and share data. You will find more information about the Redis settings [here](settings.md#redis)
+Given the presence of multiple BunkerWeb instances, it is necessary to establish a shared data store implemented as a [Redis](https://redis.io/) service. This Redis service will be utilized by the instances to cache and share data among themselves. Further information about the Redis settings can be found [here](settings.md#redis).
!!! info "Database backend"
- Please note that we assume you are using MariaDB as database backend (which is defined using the `DATABASE_URI` setting). Other backends for this integration are still possible if you want : see yaml files in the [misc/integrations folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.0/misc/integrations) folder of the repostiory for more information. Clustered database backends setup are out-of-the-scope of this documentation.
+ Please be aware that our instructions assume you are using MariaDB as the default database backend, as configured by the `DATABASE_URI` setting. However, we understand that you may prefer to utilize alternative backends for your Docker integration. If that is the case, rest assured that other database backends are still possible. See docker-compose files in the [misc/integrations folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.1/misc/integrations) folder of the repository for more information.
+
+ Clustered database backends setup are out-of-the-scope of this documentation.
-Please note that both scheduler and autoconf services needs to access the Kubernetes API. The recommended way of doing it is using [RBAC authorization](https://kubernetes.io/docs/reference/access-authn-authz/rbac/).
+Please ensure that both the scheduler and autoconf services have access to the Kubernetes API. It is recommended to utilize [RBAC authorization](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) for this purpose.
-Another important thing is the `KUBERNETES_MODE=yes` environment variable which is mandatory when using the Kubernetes integration.
+Additionally, it is crucial to set the `KUBERNETES_MODE` environment variable to `yes` when utilizing the Kubernetes integration. This variable is mandatory for proper functionality.
-Here is the yaml boilerplate you can use as a base :
+To assist you, here is a YAML boilerplate that can serve as a foundation for your configuration:
```yaml
apiVersion: rbac.authorization.k8s.io/v1
@@ -655,7 +692,7 @@ spec:
containers:
# using bunkerweb as name is mandatory
- name: bunkerweb
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
imagePullPolicy: Always
securityContext:
runAsUser: 101
@@ -725,7 +762,7 @@ spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-controller
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
@@ -752,7 +789,7 @@ spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-scheduler
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
@@ -867,7 +904,9 @@ spec:
storage: 5Gi
```
-Once the BunkerWeb Kubernetes stack is set up and running (see autoconf logs for more information), you will be able to deploy web applications in the cluster and declare your Ingress resource. Please note that [settings](settings.md) need to be set as annotations for the Ingress resource with the special value **bunkerweb.io** for the domain part :
+Once the BunkerWeb Kubernetes stack is successfully set up and operational (refer to the autoconf logs for detailed information), you can proceed with deploying web applications within the cluster and declaring your Ingress resource.
+
+It is important to note that the BunkerWeb settings need to be specified as annotations for the Ingress resource. For the domain part, please use the special value "**bunkerweb.io**". By including the appropriate annotations, you can configure BunkerWeb accordingly for the Ingress resource.
```yaml
apiVersion: networking.k8s.io/v1
@@ -899,16 +938,16 @@ spec:
Linux integration
-List of supported Linux distros (amd64/x86_64 and arm64/aarch64 architectures) :
+Supported Linux distributions for BunkerWeb (amd64/x86_64 and arm64/aarch64 architectures) include:
- Debian 11 "Bullseye"
- Ubuntu 22.04 "Jammy"
- Fedora 38
-- RedHat Enterprise Linux (RHEL) 8.7
+- Red Hat Enterprise Linux (RHEL) 8.7
-Please note that you will need to **install NGINX 1.24.0 before BunkerWeb**. For all distros, except Fedora, using prebuilt packages from [official NGINX repository](https://nginx.org/en/linux_packages.html) is mandatory. Compiling NGINX from source or using packages from different repositories won't work with the official prebuilt packages of BunkerWeb but you can build it from source.
+Please ensure that you have **NGINX 1.24.0 installed before installing BunkerWeb**. For all distributions, except Fedora, it is mandatory to use prebuilt packages from the [official NGINX repository](https://nginx.org/en/linux_packages.html). Compiling NGINX from source or using packages from different repositories will not work with the official prebuilt packages of BunkerWeb. However, you have the option to build BunkerWeb from source.
-Repositories of Linux packages for BunkerWeb are available on [PackageCloud](https://packagecloud.io/bunkerity/bunkerweb). They provide a bash script to add and trust the repository automatically (but you can also follow the [manual installation](https://packagecloud.io/bunkerity/bunkerweb/install) instructions if you prefer).
+To simplify the installation process, Linux package repositories for BunkerWeb are available on [PackageCloud](https://packagecloud.io/bunkerity/bunkerweb). They provide a bash script that automatically adds and trusts the repository. You can follow the provided script for automatic setup, or opt for [manual installation](https://packagecloud.io/bunkerity/bunkerweb/install) instructions if you prefer.
=== "Debian"
@@ -930,12 +969,12 @@ Repositories of Linux packages for BunkerWeb are available on [PackageCloud](htt
sudo apt install -y nginx=1.24.0-1~$(lsb_release -cs)
```
- And finally install BunkerWeb 1.5.0 :
+ And finally install BunkerWeb 1.5.1 :
```shell
curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.deb.sh | sudo bash && \
sudo apt update && \
- sudo apt install -y bunkerweb=1.5.0
+ sudo apt install -y bunkerweb=1.5.1
```
To prevent upgrading NGINX and/or BunkerWeb packages when executing `apt upgrade`, you can use the following command :
@@ -964,12 +1003,12 @@ Repositories of Linux packages for BunkerWeb are available on [PackageCloud](htt
sudo apt install -y nginx=1.24.0-1~jammy
```
- And finally install BunkerWeb 1.5.0 :
+ And finally install BunkerWeb 1.5.1 :
```shell
curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.deb.sh | sudo bash && \
sudo apt update && \
- sudo apt install -y bunkerweb=1.5.0
+ sudo apt install -y bunkerweb=1.5.1
```
To prevent upgrading NGINX and/or BunkerWeb packages when executing `apt upgrade`, you can use the following command :
@@ -986,14 +1025,14 @@ Repositories of Linux packages for BunkerWeb are available on [PackageCloud](htt
sudo dnf install -y nginx-1.24.0
```
- And finally install BunkerWeb 1.5.0 :
+ And finally install BunkerWeb 1.5.1 :
```shell
curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.rpm.sh | \
sed 's/yum install -y pygpgme --disablerepo='\''bunkerity_bunkerweb'\''/yum install -y python-gnupg/g' | \
sed 's/pypgpme_check=`rpm -qa | grep -qw pygpgme`/python-gnupg_check=`rpm -qa | grep -qw python-gnupg`/g' | sudo bash && \
sudo dnf makecache && \
- sudo dnf install -y bunkerweb-1.5.0
+ sudo dnf install -y bunkerweb-1.5.1
```
To prevent upgrading NGINX and/or BunkerWeb packages when executing `dnf upgrade`, you can use the following command :
@@ -1030,13 +1069,13 @@ Repositories of Linux packages for BunkerWeb are available on [PackageCloud](htt
```shell
sudo dnf install nginx-1.24.0
```
- And finally install BunkerWeb 1.5.0 :
+ And finally install BunkerWeb 1.5.1 :
```shell
dnf install -y epel-release && \
curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.rpm.sh | sudo bash && \
sudo dnf check-update && \
- sudo dnf install -y bunkerweb-1.5.0
+ sudo dnf install -y bunkerweb-1.5.1
```
To prevent upgrading NGINX and/or BunkerWeb packages when executing `dnf upgrade`, you can use the following command :
@@ -1046,103 +1085,6 @@ Repositories of Linux packages for BunkerWeb are available on [PackageCloud](htt
sudo dnf versionlock add bunkerweb
```
-
-
The configuration of BunkerWeb is done by editing the `/etc/bunkerweb/variables.env` file :
```conf
@@ -1165,61 +1107,63 @@ BunkerWeb is managed using systemctl :
Ansible integration
-List of supported Linux distros (amd64/x86_64 and arm64/aarch64 architectures) :
+Supported Linux distributions for BunkerWeb (amd64/x86_64 and arm64/aarch64 architectures) include:
- Debian 11 "Bullseye"
- Ubuntu 22.04 "Jammy"
- Fedora 38
-- RedHat Enterprise Linux (RHEL) 8.7
+- Red Hat Enterprise Linux (RHEL) 8.7
-[Ansible](https://docs.ansible.com/ansible/latest/index.html) is an IT automation tool. It can configure systems, deploy software, and orchestrate more advanced IT tasks such as continuous deployments or zero downtime rolling updates.
+To simplify the deployment and configuration process, [Ansible](https://docs.ansible.com/ansible/latest/index.html) can be used as an IT automation tool. Ansible enables you to configure systems, deploy software, and perform advanced IT tasks such as continuous deployments or zero downtime rolling updates.
-A specific BunkerWeb Ansible role is available on [Ansible Galaxy](https://galaxy.ansible.com/bunkerity/bunkerweb).
+For BunkerWeb, there is a dedicated Ansible role available on [Ansible Galaxy](https://galaxy.ansible.com/bunkerity/bunkerweb).
-First of all, download the role from ansible-galaxy :
-```shell
-ansible-galaxy install bunkerity.bunkerweb
-```
+To proceed with the BunkerWeb Ansible role setup, follow these steps:
-Next, create an inventory by adding the IP adress or FQDN of one or more remote systems, either in `/etc/ansible/hosts` or in your own playbook `inventory.yml` :
-```toml
-[mybunkers]
-192.0.2.50
-192.0.2.51
-192.0.2.52
-```
+1. Begin by creating an inventory file that lists the IP addresses or FQDNs of the remote systems you want to manage. You can either add this information to the `/etc/ansible/hosts` file or create a separate inventory file such as `inventory.yml`. Here's an example using a TOML format:
-The next step we're going to set up is the SSH connection so Ansible can connect to the managed nodes. Add your public SSH keys to the `authorized_keys` file on each remote system and ensure you can successfully connect.
+ ```toml
+ [mybunkers]
+ 192.0.2.50
+ 192.0.2.51
+ 192.0.2.52
+ ```
-In order to use the role, we will create the playbook file named `playbook.yml` for example :
-```yaml
----
-- hosts: all
- become: true
- roles:
- - bunkerity.bunkerweb
-```
+2. Next, establish SSH connections to the managed nodes by adding your public SSH keys to the `authorized_keys` file on each remote system. Verify that you can successfully connect to the nodes using SSH.
-Run the playbook :
-```shell
-ansible-playbook -i inventory.yml playbook.yml
-```
+3. Create a playbook file, such as `playbook.yml`, which will define the desired configuration using the BunkerWeb Ansible role. Here's an example playbook configuration:
-Configuration of BunkerWeb is done by using specific role variables :
+ ```yaml
+ ---
+ - hosts: all
+ become: true
+ roles:
+ - bunkerity.bunkerweb
+ ```
-| Name | Type | Description | Default value |
-|:-----:|:-----:|--------------|----------------|
-| `bunkerweb_version` | string | Version of BunkerWeb to install. | `1.5.0` |
-| `nginx_version` | string | Version of NGINX to install. | `1.24.0` |
-| `freeze_versions` | boolean | Prevent upgrade of BunkerWeb and NGINX when performing packages upgrades. | `true` |
-| `variables_env` | string | Path of the variables.env file to configure BunkerWeb. | `files/variables.env` |
-| `enable_ui` | boolean | Activate the web UI. | `false` |
-| `custom_ui` | string | Path of the ui.env file to configure the web UI. | `files/ui.env` |
-| `custom_configs_path` | Dictionary | Each entry is a path of the folder containing custom configurations. Keys are the type of custom configs : `http`, `server-http`, `modsec`, `modsec-crs` and `default-server-http` | empty values |
-| `custom_www` | string | Path of the www directory to upload. | empty value |
-| `custom_plugins` | string | Path of the plugins directory to upload. | empty value |
-| `custom_www_owner` | string | Default owner for www files and folders. | `nginx` |
-| `custom_www_group` | string | Default group for www files and folders. | `nginx` |
+4. Execute the playbook using the `ansible-playbook` command, providing the inventory file and the playbook file as arguments. For example:
+
+ ```shell
+ ansible-playbook -i inventory.yml playbook.yml
+ ```
+
+By running the playbook, Ansible will apply the BunkerWeb role to all the hosts specified in the inventory, setting up the desired configuration.
+
+the configuration of BunkerWeb is done by using specific role variables :
+
+| Name | Type | Description | Default value |
+| :-------------------: | :--------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
+| `bunkerweb_version` | string | Version of BunkerWeb to install. | `1.5.1` |
+| `nginx_version` | string | Version of NGINX to install. | `1.24.0` |
+| `freeze_versions` | boolean | Prevent upgrade of BunkerWeb and NGINX when performing packages upgrades. | `true` |
+| `variables_env` | string | Path of the variables.env file to configure BunkerWeb. | `files/variables.env` |
+| `enable_ui` | boolean | Activate the web UI. | `false` |
+| `custom_ui` | string | Path of the ui.env file to configure the web UI. | `files/ui.env` |
+| `custom_configs_path` | Dictionary | Each entry is a path of the folder containing custom configurations. Keys are the type of custom configs : `http`, `server-http`, `modsec`, `modsec-crs` and `default-server-http` | empty values |
+| `custom_www` | string | Path of the www directory to upload. | empty value |
+| `custom_plugins` | string | Path of the plugins directory to upload. | empty value |
+| `custom_www_owner` | string | Default owner for www files and folders. | `nginx` |
+| `custom_www_group` | string | Default group for www files and folders. | `nginx` |
## Vagrant
@@ -1229,24 +1173,22 @@ Configuration of BunkerWeb is done by using specific role variables :
BunkerWeb integration with Vagrant
-->
+
List of supported providers :
-- vmware_desktop
- virtualbox
- libvirt
-**_Note on Supported Base Images_**
-
-Please be aware that the provided Vagrant boxes are based **exclusively on Ubuntu 22.04 "Jammy"**. While BunkerWeb supports other Linux distributions, the Vagrant setup currently only supports Ubuntu 22.04 as the base operating system. This ensures a consistent and reliable environment for users who want to deploy BunkerWeb using Vagrant.
+!!! note "Supported Base Images"
+ Please be aware that the provided Vagrant boxes are based **exclusively on Ubuntu 22.04 "Jammy"**. While BunkerWeb supports other Linux distributions, the Vagrant setup currently only supports Ubuntu 22.04 as the base operating system. This ensures a consistent and reliable environment for users who want to deploy BunkerWeb using Vagrant.
Similar to other BunkerWeb integrations, the Vagrant setup uses **NGINX version 1.24.0**. This specific version is required to ensure compatibility and smooth functioning with BunkerWeb. Additionally, the Vagrant box includes **PHP** pre-installed, providing a ready-to-use environment for hosting PHP-based applications alongside BunkerWeb.
By using the provided Vagrant box based on Ubuntu 22.04 "Jammy", you benefit from a well-configured and integrated setup, allowing you to focus on developing and securing your applications with BunkerWeb without worrying about the underlying infrastructure.
-Here are the steps to install BunkerWeb using Vagrant on Ubuntu with the supported virtualization providers (VirtualBox, VMware, and libvirt):
+Here are the steps to install BunkerWeb using Vagrant on Ubuntu with the supported virtualization providers (VirtualBox, and libvirt):
-
-1. Make sure you have Vagrant and one of the supported virtualization providers (VirtualBox, VMware, or libvirt) installed on your system.
+1. Make sure you have Vagrant and one of the supported virtualization providers (VirtualBox or libvirt) installed on your system.
2. There are two ways to install the Vagrant box with BunkerWeb: either by using a provided Vagrantfile to configure your virtual machine or by creating a new box based on the existing BunkerWeb Vagrant box, offering you flexibility in how you set up your development environment.
=== "Vagrantfile"
@@ -1259,7 +1201,6 @@ Here are the steps to install BunkerWeb using Vagrant on Ubuntu with the support
Depending on the virtualization provider you choose, you may need to install additional plugins:
- * For **VMware**, install the `vagrant-vmware-desktop` plugin. For more information, see the [Vagrant documentation](https://www.vagrantup.com/docs/providers).
* For **libvirt**, install the `vagrant-libvirt plugin`. For more information, see the [Vagrant documentation](https://www.vagrantup.com/docs/providers).
* For **VirtualBox**, install the `vagrant-vbguest` plugin. For more information, see the [Vagrant documentation](https://www.vagrantup.com/docs/providers).
@@ -1271,14 +1212,13 @@ Here are the steps to install BunkerWeb using Vagrant on Ubuntu with the support
Depending on the virtualization provider you choose, you may need to install additional plugins:
- * For **VMware**, install the `vagrant-vmware-desktop` plugin. For more information, see the [Vagrant documentation](https://www.vagrantup.com/docs/providers).
* For **libvirt**, install the `vagrant-libvirt plugin`. For more information, see the [Vagrant documentation](https://www.vagrantup.com/docs/providers).
* For **VirtualBox**, install the `vagrant-vbguest` plugin. For more information, see the [Vagrant documentation](https://www.vagrantup.com/docs/providers).
After installing the necessary plugins for your chosen virtualization provider, run the following command to start the virtual machine and install BunkerWeb:
```shell
-vagrant up --provider=virtualbox # or --provider=vmware_desktop or --provider=libvirt
+vagrant up --provider=virtualbox # or --provider=libvirt
```
Finally, to access the virtual machine using SSH, execute the following command:
@@ -1298,9 +1238,6 @@ Vagrant.configure("2") do |config|
# Uncomment the desired virtualization provider
# For VirtualBox (default)
config.vm.provider "virtualbox"
- # For VMware
- # config.vm.provider "vmware_desktop" # Windows
- # config.vm.provider "vmware_workstation" # Linux
# For libvirt
# config.vm.provider "libvirt"
end
diff --git a/docs/migrating.md b/docs/migrating.md
index efccfaf64..c5f577c90 100644
--- a/docs/migrating.md
+++ b/docs/migrating.md
@@ -2,7 +2,7 @@
!!! warning "Read this if you were a 1.4.X user"
- A lot of things changed since the 1.4.X releases. Container-based integrations stacks contain more services but, trust us, fundamental principles of BunkerWeb are still there. You will find ready to use boilerplates for various integrations in the [misc/integrations](https://github.com/bunkerity/bunkerweb/tree/v1.5.0/misc/integrations) folder of the repository.
+ A lot of things changed since the 1.4.X releases. Container-based integrations stacks contain more services but, trust us, fundamental principles of BunkerWeb are still there. You will find ready to use boilerplates for various integrations in the [misc/integrations](https://github.com/bunkerity/bunkerweb/tree/v1.5.1/misc/integrations) folder of the repository.
## Scheduler
diff --git a/docs/plugins.md b/docs/plugins.md
index 2cb10eeb9..4cd8477bf 100644
--- a/docs/plugins.md
+++ b/docs/plugins.md
@@ -8,11 +8,13 @@ Here is the list of "official" plugins that we maintain (see the [bunkerweb-plug
| Name | Version | Description | Link |
| :------------: | :-----: | :------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------: |
-| **ClamAV** | 1.0 | Automatically scans uploaded files with the ClamAV antivirus engine and denies the request when a file is detected as malicious. | [bunkerweb-plugins/clamav](https://github.com/bunkerity/bunkerweb-plugins/tree/main/clamav) |
-| **CrowdSec** | 1.0 | CrowdSec bouncer for BunkerWeb. | [bunkerweb-plugins/crowdsec](https://github.com/bunkerity/bunkerweb-plugins/tree/main/crowdsec) |
-| **Discord** | 1.0 | Send security notifications to a Discord channel using a Webhook. | [bunkerweb-plugins/discord](https://github.com/bunkerity/bunkerweb-plugins/tree/main/discord) |
-| **Slack** | 1.0 | Send security notifications to a Slack channel using a Webhook. | [bunkerweb-plugins/slack](https://github.com/bunkerity/bunkerweb-plugins/tree/main/slack) |
-| **VirusTotal** | 1.0 | Automatically scans uploaded files with the VirusTotal API and denies the request when a file is detected as malicious. | [bunkerweb-plugins/virustotal](https://github.com/bunkerity/bunkerweb-plugins/tree/main/virustotal) |
+| **ClamAV** | 1.1 | Automatically scans uploaded files with the ClamAV antivirus engine and denies the request when a file is detected as malicious. | [bunkerweb-plugins/clamav](https://github.com/bunkerity/bunkerweb-plugins/tree/main/clamav) |
+| **Coraza** | 1.1 | Inspect requests using a the Coraza WAF (alternative of ModSecurity). | [bunkerweb-plugins/coraza](https://github.com/bunkerity/bunkerweb-plugins/tree/main/coraza) |
+| **CrowdSec** | 1.1 | CrowdSec bouncer for BunkerWeb. | [bunkerweb-plugins/crowdsec](https://github.com/bunkerity/bunkerweb-plugins/tree/main/crowdsec) |
+| **Discord** | 1.1 | Send security notifications to a Discord channel using a Webhook. | [bunkerweb-plugins/discord](https://github.com/bunkerity/bunkerweb-plugins/tree/main/discord) |
+| **Slack** | 1.1 | Send security notifications to a Slack channel using a Webhook. | [bunkerweb-plugins/slack](https://github.com/bunkerity/bunkerweb-plugins/tree/main/slack) |
+| **VirusTotal** | 1.1 | Automatically scans uploaded files with the VirusTotal API and denies the request when a file is detected as malicious. | [bunkerweb-plugins/virustotal](https://github.com/bunkerity/bunkerweb-plugins/tree/main/virustotal) |
+| **WebHook** | 1.1 | Send security notifications to a custom HTTP endpoint using a Webhook. | [bunkerweb-plugins/webhook](https://github.com/bunkerity/bunkerweb-plugins/tree/main/webhook) |
## How to use a plugin
@@ -20,7 +22,7 @@ Here is the list of "official" plugins that we maintain (see the [bunkerweb-plug
If you want to quickly install external plugins, you can use the `EXTERNAL_PLUGIN_URLS` setting. It takes a list of URLs, separated with space, pointing to compressed (zip format) archive containing one or more plugin(s).
-You can use the following value if you want to automatically install the official plugins : `EXTERNAL_PLUGIN_URLS=https://github.com/bunkerity/bunkerweb-plugins/archive/refs/tags/v1.0.zip`
+You can use the following value if you want to automatically install the official plugins : `EXTERNAL_PLUGIN_URLS=https://github.com/bunkerity/bunkerweb-plugins/archive/refs/tags/v1.1.zip`
### Manual
@@ -56,7 +58,7 @@ The first step is to install the plugin by putting the plugin files inside the c
services:
...
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
volumes:
- ./bw-data:/data
...
@@ -93,7 +95,7 @@ The first step is to install the plugin by putting the plugin files inside the c
services:
...
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
volumes:
- ./bw-data:/data
...
@@ -132,7 +134,7 @@ The first step is to install the plugin by putting the plugin files inside the c
services:
...
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
volumes:
- /shared/bw-plugins:/data/plugins
...
@@ -179,7 +181,7 @@ The first step is to install the plugin by putting the plugin files inside the c
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-scheduler
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
@@ -260,7 +262,7 @@ The first step is to install the plugin by putting the plugin files inside the c
!!! 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.0/src/common/core) (already included in BunkerWeb but they are plugins, technically speaking).
+ 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.1/src/common/core) (already included in BunkerWeb but they are plugins, technically speaking).
The first step is to create a folder that will contain the plugin :
@@ -275,30 +277,29 @@ A file named **plugin.json** and written at the root of the plugin folder must c
```json
{
- "id": "myplugin",
- "order": 42,
- "name": "My Plugin",
- "description": "Just an example plugin.",
- "version": "1.0",
+ "id": "myplugin",
+ "name": "My Plugin",
+ "description": "Just an example plugin.",
+ "version": "1.0",
"stream": "partial",
- "settings": {
- "DUMMY_SETTING": {
- "context": "multisite",
- "default": "1234",
- "help": "Here is the help of the setting.",
- "id": "dummy-id",
- "label": "Dummy setting",
- "regex": "^.*$",
- "type": "text"
- }
- },
- "jobs": [
- {
- "name": "my-job",
- "file": "my-job.py",
- "every": "hour"
- }
- ]
+ "settings": {
+ "DUMMY_SETTING": {
+ "context": "multisite",
+ "default": "1234",
+ "help": "Here is the help of the setting.",
+ "id": "dummy-id",
+ "label": "Dummy setting",
+ "regex": "^.*$",
+ "type": "text"
+ }
+ },
+ "jobs": [
+ {
+ "name": "my-job",
+ "file": "my-job.py",
+ "every": "hour"
+ }
+ ]
}
```
@@ -307,7 +308,6 @@ Here are the details of the fields :
| Field | Mandatory | Type | Description |
| :-----------: | :-------: | :----: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id` | yes | string | Internal ID for the plugin : must be unique among other plugins (including "core" ones) and contain only lowercase chars. |
-| `order` | yes | int | When the plugin should be executed during the access phase : `1` for whitelisting, `2` for blacklisting, `3` for "standard security feature" or `999` if your settings don't use the access phase. |
| `name` | yes | string | Name of your plugin. |
| `description` | yes | string | Description of your plugin. |
| `version` | yes | string | Version of your plugin. |
@@ -507,7 +507,7 @@ end
!!! tip "More examples"
- If you want to see the full list of available functions, you can have a look at the files present in the [lua directory](https://github.com/bunkerity/bunkerweb/tree/v1.5.0/src/bw/lua/bunkerweb) of the repository.
+ If you want to see the full list of available functions, you can have a look at the files present in the [lua directory](https://github.com/bunkerity/bunkerweb/tree/v1.5.1/src/bw/lua/bunkerweb) of the repository.
### Jobs
diff --git a/docs/quickstart-guide.md b/docs/quickstart-guide.md
index 4daf13da5..fb721ade2 100644
--- a/docs/quickstart-guide.md
+++ b/docs/quickstart-guide.md
@@ -4,7 +4,7 @@
We assume that you're already familiar with the [core concepts](concepts.md) and you have followed the [integrations instructions](integrations.md) for your environment.
!!! tip "Going further"
- To demonstrate the use of BunkerWeb, we will deploy a dummy "Hello World" web application as an example. See the [examples folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.0/examples) of the repository to get real-world examples.
+ To demonstrate the use of BunkerWeb, we will deploy a dummy "Hello World" web application as an example. See the [examples folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.1/examples) of the repository to get real-world examples.
## Protect HTTP applications
@@ -35,7 +35,7 @@ You will find more settings about reverse proxy in the [settings section](settin
- bw-services
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -52,7 +52,7 @@ You will find more settings about reverse proxy in the [settings section](settin
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -65,11 +65,12 @@ You will find more settings about reverse proxy in the [settings section](settin
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -385,7 +386,7 @@ You will find more settings about reverse proxy in the [settings section](settin
- bw-services
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -405,7 +406,7 @@ You will find more settings about reverse proxy in the [settings section](settin
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -418,11 +419,12 @@ You will find more settings about reverse proxy in the [settings section](settin
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -820,7 +822,7 @@ REAL_IP_HEADER=X-Forwarded-For
```yaml
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
...
environment:
- USE_REAL_IP=yes
@@ -835,7 +837,7 @@ REAL_IP_HEADER=X-Forwarded-For
```yaml
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
...
environment:
- USE_REAL_IP=yes
@@ -850,7 +852,7 @@ REAL_IP_HEADER=X-Forwarded-For
```yaml
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
...
environment:
- USE_REAL_IP=yes
@@ -970,7 +972,7 @@ REAL_IP_HEADER=proxy_protocol
```yaml
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
...
environment:
- USE_REAL_IP=yes
@@ -986,7 +988,7 @@ REAL_IP_HEADER=proxy_protocol
```yaml
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
...
environment:
- USE_REAL_IP=yes
@@ -1002,7 +1004,7 @@ REAL_IP_HEADER=proxy_protocol
```yaml
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
...
environment:
- USE_REAL_IP=yes
@@ -1111,11 +1113,11 @@ REAL_IP_HEADER=proxy_protocol
!!! warning "Feature is in beta"
This feature is not production-ready. Feel free to test it and report us any bug using [issues](https://github.com/bunkerity/bunkerweb/issues) in the GitHub repository.
-BunkerWeb can also act as **generic UDP/TCP reverse proxy** : you can protect any network-based applications working at least on layer 4 of the OSI model. Behind the hood, it leverages the [stream module](https://nginx.org/en/docs/stream/ngx_stream_core_module.html) of NGINX instead of using the "classical" http one.
+BunkerWeb offers the capability to function as a **generic UDP/TCP reverse proxy**, allowing you to protect any network-based applications operating at least on layer 4 of the OSI model. Instead of utilizing the "classical" HTTP module, BunkerWeb leverages the [stream module](https://nginx.org/en/docs/stream/ngx_stream_core_module.html) of NGINX.
-Please note that not all settings and security features are available when using the stream module. You will find more info about that in the [security tuning](security-tuning.md) and [settings](settings.md) sections of the documentation.
+It's important to note that not all settings and security features are available when using the stream module. Additional information on this can be found in the [security tuning](security-tuning.md) and [settings](settings.md) sections of the documentation.
-Configuration for a basic reverse proxy is very similar to the HTTP one because it uses the same `USE_REVERSE_PROXY=yes` and `REVERSE_PROXY_HOST=myapp:4242` settings. Even the settings used when BunkerWeb is [behind a Load Balancer](#behind-load-balancer-or-reverse-proxy) are the same (but for obvious reasons, only **PROXY protocol** is supported).
+Configuring a basic reverse proxy is quite similar to the HTTP setup, as it involves using the same settings: `USE_REVERSE_PROXY=yes` and `REVERSE_PROXY_HOST=myapp:4242`. Even when BunkerWeb is positioned behind a Load Balancer, the settings remain the same (with **PROXY protocol** being the supported option due to evident reasons).
On top of that, the following specific settings are used :
@@ -1148,7 +1150,7 @@ For complete list of settings regarding `stream` mode, please refer to the [sett
- bw-services
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080 # Keep it if you want to use Let's Encrypt automation
- 10000:10000 # app1
@@ -1170,7 +1172,7 @@ For complete list of settings regarding `stream` mode, please refer to the [sett
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -1183,11 +1185,12 @@ For complete list of settings regarding `stream` mode, please refer to the [sett
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -1218,7 +1221,7 @@ For complete list of settings regarding `stream` mode, please refer to the [sett
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080 # Keep it if you want to use Let's Encrypt automation
- 10000:10000 # app1
@@ -1276,7 +1279,7 @@ For complete list of settings regarding `stream` mode, please refer to the [sett
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
# Keep it if you want to use Let's Encrypt automation
- published: 80
@@ -1426,21 +1429,23 @@ For complete list of settings regarding `stream` mode, please refer to the [sett
## Custom configurations
-Because BunkerWeb is based on the NGINX web server, you can add custom NGINX configurations in different NGINX contexts. You can also apply custom configurations for the ModSecurity WAF which is a core component of BunkerWeb (more info [here](security-tuning.md#modsecurity)). Here is the list of custom configurations types :
+To customize and add custom configurations to BunkerWeb, you can take advantage of its NGINX foundation. Custom NGINX configurations can be added in different NGINX contexts, including configurations for the ModSecurity Web Application Firewall (WAF), which is a core component of BunkerWeb. More details about ModSecurity configurations can be found [here](security-tuning.md#modsecurity).
-- **http** : http level of NGINX
-- **server-http** : http/server level of NGINX
-- **default-server-http** : server level of NGINX (only apply to the "default server" when the name supplied by the client doesn't match any server name in `SERVER_NAME`)
-- **modsec-crs** : before the OWASP Core Rule Set is loaded
-- **modsec** : after the OWASP Core Rule Set is loaded (also used if CRS is not loaded)
-- **stream** : stream level of NGINX
-- **server-stream** : stream/server level of NGINX
+Here are the available types of custom configurations:
-Custom configurations can be applied globally or only for a specific server when applicable and if the multisite mode is enabled.
+- **http**: Configurations at the HTTP level of NGINX.
+- **server-http**: Configurations at the HTTP/Server level of NGINX.
+- **default-server-http**: Configurations at the Server level of NGINX, specifically for the "default server" when the supplied client name doesn't match any server name in `SERVER_NAME`.
+- **modsec-crs**: Configurations applied before the OWASP Core Rule Set is loaded.
+- **modsec**: Configurations applied after the OWASP Core Rule Set is loaded, or used when the Core Rule Set is not loaded.
+- **stream**: Configurations at the Stream level of NGINX.
+- **server-stream**: Configurations at the Stream/Server level of NGINX.
-The howto depends on the integration used but under the hood, applying custom configurations is done by adding files ending with the .conf suffix in their name to specific folders. To apply a custom configuration for a specific server, the file is written to a subfolder which is named as the primary server name.
+Custom configurations can be applied globally or specifically for a particular server, depending on the applicable context and whether the [multisite mode](concepts.md#multisite-mode) is enabled.
-Some integrations offer a more convenient way of applying configurations such as using [Configs](https://docs.docker.com/engine/swarm/configs/) with Swarm or [ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/) with Kubernetes.
+The method for applying custom configurations depends on the integration being used. However, the underlying process involves adding files with the `.conf` suffix to specific folders. To apply a custom configuration for a specific server, the file should be placed in a subfolder named after the primary server name.
+
+Some integrations provide more convenient ways to apply configurations, such as using [Configs](https://docs.docker.com/engine/swarm/configs/) in Docker Swarm or [ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/) in Kubernetes. These options offer simpler approaches for managing and applying configurations.
=== "Docker"
@@ -1462,7 +1467,7 @@ Some integrations offer a more convenient way of applying configurations such as
```yaml
...
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
environment:
- |
CUSTOM_CONF_SERVER_HTTP_hello-world=
@@ -1505,7 +1510,7 @@ Some integrations offer a more convenient way of applying configurations such as
```yaml
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
volumes:
- ./bw-data:/data
...
@@ -1574,7 +1579,7 @@ Some integrations offer a more convenient way of applying configurations such as
```yaml
myautoconf:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
volumes:
- ./bw-data:/data
...
@@ -1807,7 +1812,7 @@ BunkerWeb supports PHP using external or remote [PHP-FPM](https://www.php.net/ma
- bw-services
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
volumes:
- ./www:/var/www/html
ports:
@@ -1830,7 +1835,7 @@ BunkerWeb supports PHP using external or remote [PHP-FPM](https://www.php.net/ma
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -1843,11 +1848,12 @@ BunkerWeb supports PHP using external or remote [PHP-FPM](https://www.php.net/ma
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -1907,7 +1913,7 @@ BunkerWeb supports PHP using external or remote [PHP-FPM](https://www.php.net/ma
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
volumes:
- ./www:/var/www/html
labels:
@@ -1921,7 +1927,7 @@ BunkerWeb supports PHP using external or remote [PHP-FPM](https://www.php.net/ma
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -1933,11 +1939,12 @@ BunkerWeb supports PHP using external or remote [PHP-FPM](https://www.php.net/ma
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -2064,7 +2071,7 @@ BunkerWeb supports PHP using external or remote [PHP-FPM](https://www.php.net/ma
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
volumes:
- /shared/www:/var/www/html
...
@@ -2343,7 +2350,7 @@ By default, BunkerWeb will only listen on IPv4 adresses and won't use IPv6 for n
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
environment:
- USE_IPv6=yes
@@ -2388,7 +2395,7 @@ By default, BunkerWeb will only listen on IPv4 adresses and won't use IPv6 for n
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
environment:
- USE_IPv6=yes
diff --git a/docs/requirements.txt b/docs/requirements.txt
index c56364e5c..d9fb74db5 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,6 +1,6 @@
-mkdocs==1.4.3
-mkdocs-material==9.1.13
-pytablewriter==0.64.2
+mkdocs==1.5.2
+mkdocs-material==9.1.21
+pytablewriter==1.0.0
mike==1.1.2
jinja2<3.1.0
-mkdocs-print-site-plugin==2.3.4
\ No newline at end of file
+mkdocs-print-site-plugin==2.3.5
\ No newline at end of file
diff --git a/docs/robots.txt b/docs/robots.txt
new file mode 100644
index 000000000..076a7bc16
--- /dev/null
+++ b/docs/robots.txt
@@ -0,0 +1,4 @@
+User-agent: *
+Allow: /latest/
+
+Sitemap: https://docs.bunkerweb.io/sitemap.xml
\ No newline at end of file
diff --git a/docs/security-tuning.md b/docs/security-tuning.md
index ad3c14d31..e008284aa 100644
--- a/docs/security-tuning.md
+++ b/docs/security-tuning.md
@@ -63,6 +63,12 @@ STREAM support :x:
You can automatically remove verbose headers in the HTTP responses by using the `REMOVE_HEADERS` setting (default : `Server X-Powered-By X-AspNet-Version X-AspNetMvc-Version`).
+#### Keep upstream headers
+
+STREAM support :x:
+
+You can automatically keep headers from upstream servers and prevent BunkerWeb from overriding them in the HTTP responses by using the `KEEP_UPSTREAM_HEADERS` setting (default : `Content-Security-Policy Permissions-Policy Feature-Policy X-Frame-Options`). A special value `*` is available to keep all headers. List of headers to keep must be separated with a space. Note that if the header is not present in the upstream response, it will be added by BunkerWeb.
+
#### Cookies
STREAM support :x:
@@ -127,12 +133,10 @@ Besides the HTTPS configuration, the following settings related to HTTPS can be
| :---------------------------: | :---------------: | :----------------------------------------------------------------------------------------------------------- |
| `REDIRECT_HTTP_TO_HTTPS` | `no` | When set to `yes`, will redirect every HTTP request to HTTPS even if BunkerWeb is not configured with HTTPS. |
| `AUTO_REDIRECT_HTTP_TO_HTTPS` | `yes` | When set to `yes`, will redirect every HTTP request to HTTPS only if BunkerWeb is configured with HTTPS. |
-| `HTTPS_PROTOCOLS` | `TLSv1.2 TLSv1.3` | List of supported SSL/TLS protocols when HTTPS is enabled. |
+| `SSL_PROTOCOLS` | `TLSv1.2 TLSv1.3` | List of supported SSL/TLS protocols when SSL is enabled. |
| `HTTP2` | `yes` | When set to `yes`, will enable HTTP2 protocol support when using HTTPS. |
| `LISTEN_HTTP` | `yes` | When set to `no`, BunkerWeb will not listen for HTTP requests. Useful if you want HTTPS only for example. |
-When using stream, the `SSL_PROTOCOLS` can be used which takes the same value as the `HTTPS_PROTOCOLS` one.
-
### Let's Encrypt
STREAM support :white_check_mark:
@@ -155,13 +159,14 @@ STREAM support :white_check_mark:
If you want to use your own certificates, here is the list of related settings :
-| Setting | Default | Description |
-| :-----------------: | :-----: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `USE_CUSTOM_SSL` | `no` | When set to `yes`, HTTPS will be enabled with custom certificates. |
-| `CUSTOM_SSL_CERT` | | Full path to the certificate. If you have one or more intermediate certificate(s) in your chain of trust, you will need to provide the bundle (more info [here](https://nginx.org/en/docs/http/configuring_https_servers.html#chains)). |
-| `CUSTOM_SSL_KEY` | | Full path to the private key. |
+| Setting |Default| Context |Multiple| Description |
+|-----------------|-------|---------|--------|--------------------------------------------------------------------------------|
+|`USE_CUSTOM_SSL` |`no` |multisite|no |Use custom HTTPS certificate. |
+|`CUSTOM_SSL_CERT`| |multisite|no |Full path of the certificate or bundle file (must be readable by the scheduler).|
+|`CUSTOM_SSL_KEY` | |multisite|no |Full path of the key file (must be readable by the scheduler). |
-When `USE_CUSTOM_HTTPS` is set to `yes`, BunkerWeb will check every day if the custom certificate specified in `CUSTOM_HTTPS_CERT` is modified and will reload NGINX if that's the case.
+
+When `USE_CUSTOM_SSL` is set to `yes`, BunkerWeb will check every day if the custom certificate specified in `CUSTOM_SSL_CERT` is modified and will reload NGINX if that's the case.
When using stream mode, you will need to use the `LISTEN_STREAM_PORT_SSL` setting in order to choose your listening SSL/TLS port.
@@ -250,6 +255,7 @@ That kind of security is implemented but not enabled by default in BunkerWeb and
- **Captcha** : force the client to solve a classical captcha (no external dependencies)
- **hCaptcha** : force the client to solve a captcha from hCaptcha
- **reCAPTCHA** : force the client to get a minimum score with Google reCAPTCHA
+- **Turnstile** : enforce rate limiting and access control for APIs and web applications using various mechanisms with Coudflare Turnstile
Here is the list of related settings :
@@ -262,6 +268,8 @@ Here is the list of related settings :
|`ANTIBOT_RECAPTCHA_SECRET` | |multisite|no |Secret for reCAPTCHA challenge. |
|`ANTIBOT_HCAPTCHA_SITEKEY` | |multisite|no |Sitekey for hCaptcha challenge. |
|`ANTIBOT_HCAPTCHA_SECRET` | |multisite|no |Secret for hCaptcha challenge. |
+|`ANTIBOT_TURNSTILE_SITEKEY`| |multisite|no |Sitekey for Turnstile challenge. |
+|`ANTIBOT_TURNSTILE_SECRET` | |multisite|no |Secret for Turnstile challenge. |
|`ANTIBOT_TIME_RESOLVE` |`60` |multisite|no |Maximum time (in seconds) clients have to resolve the challenge. Once this time has passed, a new challenge will be generated.|
|`ANTIBOT_TIME_VALID` |`86400` |multisite|no |Maximum validity time of solved challenges. Once this time has passed, clients will need to resolve a new one. |
@@ -476,7 +484,7 @@ You can quickly protect sensitive resources like the admin area for example, by
### Auth request
-You can deploy complex authentication (e.g. SSO), by using the auth request settings (see [here](https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-subrequest-authentication/) for more information on the feature). Please note that you will find [Authelia](https://www.authelia.com/) and [Authentik](https://goauthentik.io/) examples in the [repository](https://github.com/bunkerity/bunkerweb/tree/v1.5.0/examples).
+You can deploy complex authentication (e.g. SSO), by using the auth request settings (see [here](https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-subrequest-authentication/) for more information on the feature). Please note that you will find [Authelia](https://www.authelia.com/) and [Authentik](https://goauthentik.io/) examples in the [repository](https://github.com/bunkerity/bunkerweb/tree/v1.5.1/examples).
**Auth request settings are related to reverse proxy rules.**
diff --git a/docs/settings.md b/docs/settings.md
index fecd02f9f..051a63d81 100644
--- a/docs/settings.md
+++ b/docs/settings.md
@@ -67,6 +67,8 @@ Bot detection by using a challenge.
|`ANTIBOT_RECAPTCHA_SECRET` | |multisite|no |Secret for reCAPTCHA challenge. |
|`ANTIBOT_HCAPTCHA_SITEKEY` | |multisite|no |Sitekey for hCaptcha challenge. |
|`ANTIBOT_HCAPTCHA_SECRET` | |multisite|no |Secret for hCaptcha challenge. |
+|`ANTIBOT_TURNSTILE_SITEKEY`| |multisite|no |Sitekey for Turnstile challenge. |
+|`ANTIBOT_TURNSTILE_SECRET` | |multisite|no |Secret for Turnstile challenge. |
|`ANTIBOT_TIME_RESOLVE` |`60` |multisite|no |Maximum time (in seconds) clients have to resolve the challenge. Once this time has passed, a new challenge will be generated.|
|`ANTIBOT_TIME_VALID` |`86400` |multisite|no |Maximum validity time of solved challenges. Once this time has passed, clients will need to resolve a new one. |
@@ -159,16 +161,19 @@ STREAM support :x:
Cross-Origin Resource Sharing.
-| Setting | Default | Context |Multiple| Description |
-|------------------------|------------------------------------------------------------------------------------|---------|--------|-------------------------------------------------------------------|
-|`USE_CORS` |`no` |multisite|no |Use CORS |
-|`CORS_ALLOW_ORIGIN` |`*` |multisite|no |Allowed origins to make CORS requests : PCRE regex or *. |
-|`CORS_EXPOSE_HEADERS` |`Content-Length,Content-Range` |multisite|no |Value of the Access-Control-Expose-Headers header. |
-|`CORS_MAX_AGE` |`86400` |multisite|no |Value of the Access-Control-Max-Age header. |
-|`CORS_ALLOW_CREDENTIALS`|`no` |multisite|no |Send the Access-Control-Allow-Credentials header. |
-|`CORS_ALLOW_METHODS` |`GET, POST, OPTIONS` |multisite|no |Value of the Access-Control-Allow-Methods header. |
-|`CORS_ALLOW_HEADERS` |`DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range`|multisite|no |Value of the Access-Control-Allow-Headers header. |
-|`CORS_DENY_REQUEST` |`yes` |multisite|no |Deny request and don't send it to backend if Origin is not allowed.|
+| Setting | Default | Context |Multiple| Description |
+|------------------------------|------------------------------------------------------------------------------------|---------|--------|-------------------------------------------------------------------|
+|`USE_CORS` |`no` |multisite|no |Use CORS |
+|`CORS_ALLOW_ORIGIN` |`*` |multisite|no |Allowed origins to make CORS requests : PCRE regex or *. |
+|`CORS_EXPOSE_HEADERS` |`Content-Length,Content-Range` |multisite|no |Value of the Access-Control-Expose-Headers header. |
+|`CROSS_ORIGIN_OPENER_POLICY` | |multisite|no |Value for the Cross-Origin-Opener-Policy header. |
+|`CROSS_ORIGIN_EMBEDDER_POLICY`| |multisite|no |Value for the Cross-Origin-Embedder-Policy header. |
+|`CROSS_ORIGIN_RESOURCE_POLICY`| |multisite|no |Value for the Cross-Origin-Resource-Policy header. |
+|`CORS_MAX_AGE` |`86400` |multisite|no |Value of the Access-Control-Max-Age header. |
+|`CORS_ALLOW_CREDENTIALS` |`no` |multisite|no |Send the Access-Control-Allow-Credentials header. |
+|`CORS_ALLOW_METHODS` |`GET, POST, OPTIONS` |multisite|no |Value of the Access-Control-Allow-Methods header. |
+|`CORS_ALLOW_HEADERS` |`DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range`|multisite|no |Value of the Access-Control-Allow-Headers header. |
+|`CORS_DENY_REQUEST` |`yes` |multisite|no |Deny request and don't send it to backend if Origin is not allowed.|
### Client cache
@@ -200,11 +205,11 @@ STREAM support :white_check_mark:
Choose custom certificate for HTTPS.
-| Setting |Default| Context |Multiple| Description |
-|-----------------|-------|---------|--------|--------------------------------------------|
-|`USE_CUSTOM_SSL` |`no` |multisite|no |Use custom HTTPS certificate. |
-|`CUSTOM_SSL_CERT`| |multisite|no |Full path of the certificate or bundle file.|
-|`CUSTOM_SSL_KEY` | |multisite|no |Full path of the key file. |
+| Setting |Default| Context |Multiple| Description |
+|-----------------|-------|---------|--------|--------------------------------------------------------------------------------|
+|`USE_CUSTOM_SSL` |`no` |multisite|no |Use custom HTTPS certificate. |
+|`CUSTOM_SSL_CERT`| |multisite|no |Full path of the certificate or bundle file (must be readable by the scheduler).|
+|`CUSTOM_SSL_KEY` | |multisite|no |Full path of the key file (must be readable by the scheduler). |
### DB
@@ -288,20 +293,22 @@ STREAM support :x:
Manage HTTP headers sent to clients.
-| Setting | Default | Context |Multiple| Description |
-|---------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|----------------------------------------------------------------------------------------------|
-|`CUSTOM_HEADER` | |multisite|yes |Custom header to add (HeaderName: HeaderValue). |
-|`REMOVE_HEADERS` |`Server X-Powered-By X-AspNet-Version X-AspNetMvc-Version` |multisite|no |Headers to remove (Header1 Header2 Header3 ...) |
-|`STRICT_TRANSPORT_SECURITY`|`max-age=31536000` |multisite|no |Value for the Strict-Transport-Security header. |
-|`COOKIE_FLAGS` |`* HttpOnly SameSite=Lax` |multisite|yes |Cookie flags automatically added to all cookies (value accepted for nginx_cookie_flag_module).|
-|`COOKIE_AUTO_SECURE_FLAG` |`yes` |multisite|no |Automatically add the Secure flag to all cookies. |
-|`CONTENT_SECURITY_POLICY` |`object-src 'none'; form-action 'self'; frame-ancestors 'self';` |multisite|no |Value for the Content-Security-Policy header. |
-|`REFERRER_POLICY` |`strict-origin-when-cross-origin` |multisite|no |Value for the Referrer-Policy header. |
-|`PERMISSIONS_POLICY` |`accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), serial=(), usb=(), web-share=(), xr-spatial-tracking=()` |multisite|no |Value for the Permissions-Policy header. |
-|`FEATURE_POLICY` |`accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; execution-while-not-rendered 'none'; execution-while-out-of-viewport 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; layout-animation 'none'; legacy-image-formats 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; navigation-override 'none'; payment 'none'; picture-in-picture 'none'; publickey-credentials-get 'none'; speaker-selection 'none'; sync-xhr 'none'; unoptimized-images 'none'; unsized-media 'none'; usb 'none'; screen-wake-lock 'none'; web-share 'none'; xr-spatial-tracking 'none';`|multisite|no |Value for the Feature-Policy header. |
-|`X_FRAME_OPTIONS` |`SAMEORIGIN` |multisite|no |Value for the X-Frame-Options header. |
-|`X_CONTENT_TYPE_OPTIONS` |`nosniff` |multisite|no |Value for the X-Content-Type-Options header. |
-|`X_XSS_PROTECTION` |`1; mode=block` |multisite|no |Value for the X-XSS-Protection header. |
+| Setting | Default | Context |Multiple| Description |
+|-------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|----------------------------------------------------------------------------------------------|
+|`CUSTOM_HEADER` | |multisite|yes |Custom header to add (HeaderName: HeaderValue). |
+|`REMOVE_HEADERS` |`Server Expect-CT X-Powered-By X-AspNet-Version X-AspNetMvc-Version` |multisite|no |Headers to remove (Header1 Header2 Header3 ...) |
+|`KEEP_UPSTREAM_HEADERS` |`Content-Security-Policy Permissions-Policy Feature-Policy X-Frame-Options` |multisite|no |Headers to keep from upstream (Header1 Header2 Header3 ... or * for all). |
+|`STRICT_TRANSPORT_SECURITY` |`max-age=31536000` |multisite|no |Value for the Strict-Transport-Security header. |
+|`COOKIE_FLAGS` |`* HttpOnly SameSite=Lax` |multisite|yes |Cookie flags automatically added to all cookies (value accepted for nginx_cookie_flag_module).|
+|`COOKIE_AUTO_SECURE_FLAG` |`yes` |multisite|no |Automatically add the Secure flag to all cookies. |
+|`CONTENT_SECURITY_POLICY` |`object-src 'none'; form-action 'self'; frame-ancestors 'self';` |multisite|no |Value for the Content-Security-Policy header. |
+|`CONTENT_SECURITY_POLICY_REPORT_ONLY`|`no` |multisite|no |Send reports for violations of the Content-Security-Policy header instead of blocking them. |
+|`REFERRER_POLICY` |`strict-origin-when-cross-origin` |multisite|no |Value for the Referrer-Policy header. |
+|`PERMISSIONS_POLICY` |`accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), serial=(), usb=(), web-share=(), xr-spatial-tracking=()` |multisite|no |Value for the Permissions-Policy header. |
+|`FEATURE_POLICY` |`accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; execution-while-not-rendered 'none'; execution-while-out-of-viewport 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; layout-animation 'none'; legacy-image-formats 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; navigation-override 'none'; payment 'none'; picture-in-picture 'none'; publickey-credentials-get 'none'; speaker-selection 'none'; sync-xhr 'none'; unoptimized-images 'none'; unsized-media 'none'; usb 'none'; screen-wake-lock 'none'; web-share 'none'; xr-spatial-tracking 'none';`|multisite|no |Value for the Feature-Policy header. |
+|`X_FRAME_OPTIONS` |`SAMEORIGIN` |multisite|no |Value for the X-Frame-Options header. |
+|`X_CONTENT_TYPE_OPTIONS` |`nosniff` |multisite|no |Value for the X-Content-Type-Options header. |
+|`X_XSS_PROTECTION` |`1; mode=block` |multisite|no |Value for the X-XSS-Protection header. |
### Let's Encrypt
@@ -337,25 +344,25 @@ STREAM support :warning:
Miscellaneous settings.
-| Setting | Default | Context |Multiple| Description |
-|-----------------------------|-----------------------|---------|--------|----------------------------------------------------------------------------------------------------------------------|
-|`DISABLE_DEFAULT_SERVER` |`no` |global |no |Close connection if the request vhost is unknown. |
-|`REDIRECT_HTTP_TO_HTTPS` |`no` |multisite|no |Redirect all HTTP request to HTTPS. |
-|`AUTO_REDIRECT_HTTP_TO_HTTPS`|`yes` |multisite|no |Try to detect if HTTPS is used and activate HTTP to HTTPS redirection if that's the case. |
-|`ALLOWED_METHODS` |`GET|POST|HEAD` |multisite|no |Allowed HTTP and WebDAV methods, separated with pipes to be sent by clients. |
-|`MAX_CLIENT_SIZE` |`10m` |multisite|no |Maximum body size (0 for infinite). |
-|`SERVE_FILES` |`yes` |multisite|no |Serve files from the local folder. |
-|`ROOT_FOLDER` | |multisite|no |Root folder containing files to serve (/var/www/html/{server_name} if unset). |
-|`SSL_PROTOCOLS` |`TLSv1.2 TLSv1.3` |multisite|no |The supported version of TLS. We recommend the default value TLSv1.2 TLSv1.3 for compatibility reasons. |
-|`HTTP2` |`yes` |multisite|no |Support HTTP2 protocol when HTTPS is enabled. |
-|`LISTEN_HTTP` |`yes` |multisite|no |Respond to (insecure) HTTP requests. |
-|`USE_OPEN_FILE_CACHE` |`no` |multisite|no |Enable open file cache feature |
-|`OPEN_FILE_CACHE` |`max=1000 inactive=20s`|multisite|no |Open file cache directive |
-|`OPEN_FILE_CACHE_ERRORS` |`yes` |multisite|no |Enable open file cache for errors |
-|`OPEN_FILE_CACHE_MIN_USES` |`2` |multisite|no |Enable open file cache minimum uses |
-|`OPEN_FILE_CACHE_VALID` |`30s` |multisite|no |Open file cache valid time |
-|`EXTERNAL_PLUGIN_URLS` | |global |no |List of external plugins URLs (direct download to .zip file) to download and install (URLs are separated with space). |
-|`DENY_HTTP_STATUS` |`403` |global |no |HTTP status code to send when the request is denied (403 or 444). When using 444, BunkerWeb will close the connection.|
+| Setting | Default | Context |Multiple| Description |
+|-----------------------------|-----------------------|---------|--------|-----------------------------------------------------------------------------------------------------------------------------|
+|`DISABLE_DEFAULT_SERVER` |`no` |global |no |Close connection if the request vhost is unknown. |
+|`REDIRECT_HTTP_TO_HTTPS` |`no` |multisite|no |Redirect all HTTP request to HTTPS. |
+|`AUTO_REDIRECT_HTTP_TO_HTTPS`|`yes` |multisite|no |Try to detect if HTTPS is used and activate HTTP to HTTPS redirection if that's the case. |
+|`ALLOWED_METHODS` |`GET|POST|HEAD` |multisite|no |Allowed HTTP and WebDAV methods, separated with pipes to be sent by clients. |
+|`MAX_CLIENT_SIZE` |`10m` |multisite|no |Maximum body size (0 for infinite). |
+|`SERVE_FILES` |`yes` |multisite|no |Serve files from the local folder. |
+|`ROOT_FOLDER` | |multisite|no |Root folder containing files to serve (/var/www/html/{server_name} if unset). |
+|`SSL_PROTOCOLS` |`TLSv1.2 TLSv1.3` |multisite|no |The supported version of TLS. We recommend the default value TLSv1.2 TLSv1.3 for compatibility reasons. |
+|`HTTP2` |`yes` |multisite|no |Support HTTP2 protocol when HTTPS is enabled. |
+|`LISTEN_HTTP` |`yes` |multisite|no |Respond to (insecure) HTTP requests. |
+|`USE_OPEN_FILE_CACHE` |`no` |multisite|no |Enable open file cache feature |
+|`OPEN_FILE_CACHE` |`max=1000 inactive=20s`|multisite|no |Open file cache directive |
+|`OPEN_FILE_CACHE_ERRORS` |`yes` |multisite|no |Enable open file cache for errors |
+|`OPEN_FILE_CACHE_MIN_USES` |`2` |multisite|no |Enable open file cache minimum uses |
+|`OPEN_FILE_CACHE_VALID` |`30s` |multisite|no |Open file cache valid time |
+|`EXTERNAL_PLUGIN_URLS` | |global |no |List of external plugins URLs (direct download to .zip or .tar file) to download and install (URLs are separated with space).|
+|`DENY_HTTP_STATUS` |`403` |global |no |HTTP status code to send when the request is denied (403 or 444). When using 444, BunkerWeb will close the connection. |
### ModSecurity
@@ -409,6 +416,7 @@ Manage HTTP redirects.
|-------------------------|-------|---------|--------|-------------------------------------------------|
|`REDIRECT_TO` | |multisite|no |Redirect a whole site to another one. |
|`REDIRECT_TO_REQUEST_URI`|`no` |multisite|no |Append the requested URI to the redirect address.|
+|`REDIRECT_TO_STATUS_CODE`|`301` |multisite|no |Status code to send to client when redirecting. |
### Redis
@@ -517,18 +525,18 @@ STREAM support :warning:
Allow access based on internal and external IP/network/rDNS/ASN whitelists.
-| Setting | Default | Context |Multiple| Description |
-|---------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|----------------------------------------------------------------------------------|
-|`USE_WHITELIST` |`yes` |multisite|no |Activate whitelist feature. |
-|`WHITELIST_IP` |`20.191.45.212 40.88.21.235 40.76.173.151 40.76.163.7 20.185.79.47 52.142.26.175 20.185.79.15 52.142.24.149 40.76.162.208 40.76.163.23 40.76.162.191 40.76.162.247 54.208.102.37 107.21.1.8`|multisite|no |List of IP/network, separated with spaces, to put into the whitelist. |
-|`WHITELIST_IP_URLS` | |global |no |List of URLs, separated with spaces, containing good IP/network to whitelist. |
-|`WHITELIST_RDNS_GLOBAL` |`yes` |multisite|no |Only perform RDNS whitelist checks on global IP addresses. |
-|`WHITELIST_RDNS` |`.google.com .googlebot.com .yandex.ru .yandex.net .yandex.com .search.msn.com .baidu.com .baidu.jp .crawl.yahoo.net .fwd.linkedin.com .twitter.com .twttr.com .discord.com` |multisite|no |List of reverse DNS suffixes, separated with spaces, to whitelist. |
-|`WHITELIST_RDNS_URLS` | |global |no |List of URLs, separated with spaces, containing reverse DNS suffixes to whitelist.|
-|`WHITELIST_ASN` |`32934` |multisite|no |List of ASN numbers, separated with spaces, to whitelist. |
-|`WHITELIST_ASN_URLS` | |global |no |List of URLs, separated with spaces, containing ASN to whitelist. |
-|`WHITELIST_USER_AGENT` | |multisite|no |List of User-Agent (PCRE regex), separated with spaces, to whitelist. |
-|`WHITELIST_USER_AGENT_URLS`| |global |no |List of URLs, separated with spaces, containing good User-Agent to whitelist. |
-|`WHITELIST_URI` | |multisite|no |List of URI (PCRE regex), separated with spaces, to whitelist. |
-|`WHITELIST_URI_URLS` | |global |no |List of URLs, separated with spaces, containing bad URI to whitelist. |
+| Setting | Default | Context |Multiple| Description |
+|---------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|----------------------------------------------------------------------------------|
+|`USE_WHITELIST` |`yes` |multisite|no |Activate whitelist feature. |
+|`WHITELIST_IP` |`20.191.45.212 40.88.21.235 40.76.173.151 40.76.163.7 20.185.79.47 52.142.26.175 20.185.79.15 52.142.24.149 40.76.162.208 40.76.163.23 40.76.162.191 40.76.162.247` |multisite|no |List of IP/network, separated with spaces, to put into the whitelist. |
+|`WHITELIST_IP_URLS` | |global |no |List of URLs, separated with spaces, containing good IP/network to whitelist. |
+|`WHITELIST_RDNS_GLOBAL` |`yes` |multisite|no |Only perform RDNS whitelist checks on global IP addresses. |
+|`WHITELIST_RDNS` |`.google.com .googlebot.com .yandex.ru .yandex.net .yandex.com .search.msn.com .baidu.com .baidu.jp .crawl.yahoo.net .fwd.linkedin.com .twitter.com .twttr.com .discord.com`|multisite|no |List of reverse DNS suffixes, separated with spaces, to whitelist. |
+|`WHITELIST_RDNS_URLS` | |global |no |List of URLs, separated with spaces, containing reverse DNS suffixes to whitelist.|
+|`WHITELIST_ASN` |`32934` |multisite|no |List of ASN numbers, separated with spaces, to whitelist. |
+|`WHITELIST_ASN_URLS` | |global |no |List of URLs, separated with spaces, containing ASN to whitelist. |
+|`WHITELIST_USER_AGENT` | |multisite|no |List of User-Agent (PCRE regex), separated with spaces, to whitelist. |
+|`WHITELIST_USER_AGENT_URLS`| |global |no |List of URLs, separated with spaces, containing good User-Agent to whitelist. |
+|`WHITELIST_URI` | |multisite|no |List of URI (PCRE regex), separated with spaces, to whitelist. |
+|`WHITELIST_URI_URLS` | |global |no |List of URLs, separated with spaces, containing bad URI to whitelist. |
diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md
index 80e249c98..578c93fd3 100644
--- a/docs/troubleshooting.md
+++ b/docs/troubleshooting.md
@@ -80,10 +80,10 @@ Here is how you can access the logs, depending on your integration :
journalctl -u bunkerweb --no-pager
```
- Common logs are located inside the `/var/log/nginx` directory :
+ Common logs are located inside the `/var/log/bunkerweb` directory :
```shell
- cat /var/log/nginx/error.log
- cat /var/log/nginx/access.log
+ cat /var/log/bunkerweb/error.log
+ cat /var/log/bunkerweb/access.log
```
=== "Ansible"
@@ -93,10 +93,10 @@ Here is how you can access the logs, depending on your integration :
ansible -i inventory.yml all -a "journalctl -u bunkerweb --no-pager" --become
```
- Common logs are located inside the `/var/log/nginx` directory :
+ Common logs are located inside the `/var/log/bunkerweb` directory :
```shell
- ansible -i inventory.yml all -a "cat /var/log/nginx/error.log" --become
- ansible -i inventory.yml all -a "cat /var/log/nginx/access.log" --become
+ ansible -i inventory.yml all -a "cat /var/log/bunkerweb/error.log" --become
+ ansible -i inventory.yml all -a "cat /var/log/bunkerweb/access.log" --become
```
=== "Vagrant"
@@ -106,10 +106,10 @@ Here is how you can access the logs, depending on your integration :
journalctl -u bunkerweb --no-pager
```
- Common logs are located inside the `/var/log/nginx` directory :
+ Common logs are located inside the `/var/log/bunkerweb` directory :
```shell
- cat /var/log/nginx/error.log
- cat /var/log/nginx/access.log
+ cat /var/log/bunkerweb/error.log
+ cat /var/log/bunkerweb/access.log
```
## Permissions
@@ -280,4 +280,8 @@ If you have bots that need to access your website, the recommended way to avoid
- Healthcheck / status bot
- Callback like IPN or webhook
-- Social media crawler
\ No newline at end of file
+- Social media crawler
+
+## Timezone
+
+When using container-based integrations, the timezone of the container may not match the one of the host machine. To resolve that, you can set the `TZ` environment variable to the timezone of your choice on your containers (e.g. `TZ=Europe/Paris`). You will find the list of timezone identifers [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List).
\ No newline at end of file
diff --git a/docs/web-ui.md b/docs/web-ui.md
index 886ad11ec..a43af7723 100644
--- a/docs/web-ui.md
+++ b/docs/web-ui.md
@@ -55,13 +55,12 @@ Because the web UI is a web application, the recommended installation procedure
- `ADMIN_USERNAME` : username to access the web UI
- `ADMIN_PASSWORD` : password to access the web UI
- - `ABSOLUTE_URI` : full URI of your web UI instance (like `http://www.example.com/foo/`)
Accessing the web UI through BunkerWeb is a classical [reverse proxy setup](quickstart-guide.md#protect-http-applications). We recommend you to connect BunkerWeb and web UI using a dedicated network (like `bw-universe` also used by the scheduler) so it won't be on the same network of your web services for obvious security reasons. Please note that the web UI container is listening on the `7000` port.
!!! info "Database backend"
- If you want another Database backend than MariaDB please refer to the docker-compose files in the [misc/integrations folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.0/misc/integrations) of the repository.
+ If you want another Database backend than MariaDB please refer to the docker-compose files in the [misc/integrations folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.1/misc/integrations) of the repository.
Here is the docker-compose boilerplate that you can use (don't forget to edit the `changeme` data) :
@@ -70,7 +69,7 @@ Because the web UI is a web application, the recommended installation procedure
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -86,16 +85,15 @@ Because the web UI is a web application, the recommended installation procedure
- USE_GZIP=yes
- www.example.com_USE_UI=yes
- www.example.com_USE_REVERSE_PROXY=yes
- - www.example.com_REVERSE_PROXY_URL=/changeme/
+ - www.example.com_REVERSE_PROXY_URL=/changeme
- www.example.com_REVERSE_PROXY_HOST=http://bw-ui:7000
- - www.example.com_REVERSE_PROXY_HEADERS=X-Script-Name /changeme
- www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
networks:
- bw-universe
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -107,16 +105,17 @@ Because the web UI is a web application, the recommended installation procedure
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
bw-ui:
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
depends_on:
- bw-docker
environment:
@@ -124,7 +123,6 @@ Because the web UI is a web application, the recommended installation procedure
- DOCKER_HOST=tcp://bw-docker:2375
- ADMIN_USERNAME=changeme
- ADMIN_PASSWORD=changeme # Remember to set a stronger password for the changeme user
- - ABSOLUTE_URI=http://www.example.com/changeme/
networks:
- bw-universe
- bw-docker
@@ -177,13 +175,12 @@ Because the web UI is a web application, the recommended installation procedure
- `ADMIN_USERNAME` : username to access the web UI
- `ADMIN_PASSWORD` : password to access the web UI
- - `ABSOLUTE_URI` : full URI of your web UI instance (like `http://www.example.com/foo/`)
Accessing the web UI through BunkerWeb is a classical [reverse proxy setup](quickstart-guide.md#protect-http-applications). We recommend you to connect BunkerWeb and web UI using a dedicated network (like `bw-universe` also used by the scheduler and autoconf) so it won't be on the same network of your web services for obvious security reasons. Please note that the web UI container is listening on the `7000` port.
!!! info "Database backend"
- If you want another Database backend than MariaDB please refer to the docker-compose files in the [misc/integrations folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.0/misc/integrations) of the repository.
+ If you want another Database backend than MariaDB please refer to the docker-compose files in the [misc/integrations folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.1/misc/integrations) of the repository.
Here is the docker-compose boilerplate that you can use (don't forget to edit the `changeme` data) :
@@ -192,7 +189,7 @@ Because the web UI is a web application, the recommended installation procedure
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -209,7 +206,7 @@ Because the web UI is a web application, the recommended installation procedure
- bw-services
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -222,7 +219,7 @@ Because the web UI is a web application, the recommended installation procedure
- bw-docker
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -235,11 +232,12 @@ Because the web UI is a web application, the recommended installation procedure
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -256,7 +254,7 @@ Because the web UI is a web application, the recommended installation procedure
- bw-docker
bw-ui:
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
networks:
bw-docker:
bw-universe:
@@ -268,14 +266,12 @@ Because the web UI is a web application, the recommended installation procedure
- AUTOCONF_MODE=yes
- ADMIN_USERNAME=admin
- ADMIN_PASSWORD=changeme
- - ABSOLUTE_URI=http://www.example.com/changeme/
labels:
- "bunkerweb.SERVER_NAME=www.example.com"
- "bunkerweb.USE_UI=yes"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- - "bunkerweb.REVERSE_PROXY_URL=/changeme/"
+ - "bunkerweb.REVERSE_PROXY_URL=/changeme"
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
- - "bunkerweb.REVERSE_PROXY_HEADERS=X-Script-Name /changeme"
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
volumes:
@@ -314,13 +310,12 @@ Because the web UI is a web application, the recommended installation procedure
- `ADMIN_USERNAME` : username to access the web UI
- `ADMIN_PASSWORD` : password to access the web UI
- - `ABSOLUTE_URI` : full URI of your web UI instance (like `http://www.example.com/foo/`)
Accessing the web UI through BunkerWeb is a classical [reverse proxy setup](quickstart-guide.md#protect-http-applications). We recommend you to connect BunkerWeb and web UI using a dedicated network (like `bw-universe` also used by the scheduler and autoconf) so it won't be on the same network of your web services for obvious security reasons. Please note that the web UI container is listening on the `7000` port.
!!! info "Database backend"
- If you want another Database backend than MariaDB please refer to the stack files in the [misc/integrations folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.0/misc/integrations) of the repository.
+ If you want another Database backend than MariaDB please refer to the stack files in the [misc/integrations folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.1/misc/integrations) of the repository.
Here is the stack boilerplate that you can use (don't forget to edit the `changeme` data) :
@@ -329,7 +324,7 @@ Because the web UI is a web application, the recommended installation procedure
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- published: 80
target: 8080
@@ -359,7 +354,7 @@ Because the web UI is a web application, the recommended installation procedure
- "bunkerweb.INSTANCE"
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
@@ -369,7 +364,7 @@ Because the web UI is a web application, the recommended installation procedure
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
@@ -378,6 +373,7 @@ Because the web UI is a web application, the recommended installation procedure
- SERVICES=1
- SWARM=1
- TASKS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
deploy:
@@ -386,7 +382,7 @@ Because the web UI is a web application, the recommended installation procedure
- "node.role == manager"
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
@@ -413,13 +409,12 @@ Because the web UI is a web application, the recommended installation procedure
- bw-universe
bw-ui:
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
environment:
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db # Remember to set a stronger password for the database
- DOCKER_HOST=tcp://bw-docker:2375
- ADMIN_USERNAME=changeme
- ADMIN_PASSWORD=changeme # Remember to set a stronger password for the changeme user
- - ABSOLUTE_URI=http://www.example.com/changeme/
networks:
- bw-universe
- bw-docker
@@ -428,11 +423,10 @@ Because the web UI is a web application, the recommended installation procedure
- "bunkerweb.SERVER_NAME=www.example.com"
- "bunkerweb.USE_UI=yes"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- - "bunkerweb.REVERSE_PROXY_URL=/changeme/"
+ - "bunkerweb.REVERSE_PROXY_URL=/changeme"
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
- - "bunkerweb.REVERSE_PROXY_HEADERS=X-Script-Name /changeme"
- "bunkerweb.REVERSE_PROXY_INTERCEPT_ERRORS=no"
- - "INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
+ - "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
volumes:
bw-data:
@@ -463,13 +457,12 @@ Because the web UI is a web application, the recommended installation procedure
- `ADMIN_USERNAME` : username to access the web UI
- `ADMIN_PASSWORD` : password to access the web UI
- - `ABSOLUTE_URI` : full URI of your web UI instance (like `http://www.example.com/foo/`)
Accessing the web UI through BunkerWeb is a classical [reverse proxy setup](quickstart-guide.md#protect-http-applications). Network segmentation between web UI and web services is not covered in this documentation. Please note that the web UI container is listening on the `7000` port.
!!! info "Database backend"
- If you want another Database backend than MariaDB please refer to the yaml files in the [misc/integrations folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.0/misc/integrations) of the repository.
+ If you want another Database backend than MariaDB please refer to the yaml files in the [misc/integrations folder](https://github.com/bunkerity/bunkerweb/tree/v1.5.1/misc/integrations) of the repository.
Here is the yaml boilerplate that you can use (don't forget to edit the `changeme` data) :
@@ -524,7 +517,7 @@ Because the web UI is a web application, the recommended installation procedure
containers:
# using bunkerweb as name is mandatory
- name: bunkerweb
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
imagePullPolicy: Always
securityContext:
runAsUser: 101
@@ -594,7 +587,7 @@ Because the web UI is a web application, the recommended installation procedure
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-controller
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
@@ -621,7 +614,7 @@ Because the web UI is a web application, the recommended installation procedure
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-scheduler
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
@@ -705,15 +698,13 @@ Because the web UI is a web application, the recommended installation procedure
spec:
containers:
- name: bunkerweb-ui
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
imagePullPolicy: Always
env:
- name: ADMIN_USERNAME
value: "changeme"
- name: "ADMIN_PASSWORD"
value: "changeme"
- - name: "ABSOLUTE_URI"
- value: "http://www.example.com/changeme/"
- name: KUBERNETES_MODE
value: "YES"
- name: "DATABASE_URI"
@@ -788,14 +779,14 @@ Because the web UI is a web application, the recommended installation procedure
name: ingress
annotations:
bunkerweb.io/www.example.com_USE_UI: "yes"
- bunkerweb.io/www.example.com_REVERSE_PROXY_HEADERS_1: "X-Script-Name /changeme"
bunkerweb.io/www.example.com_REVERSE_PROXY_INTERCEPT_ERRORS: "no"
+ bunkerweb.io/www.example.com_INTERCEPTED_ERROR_CODES: '400 404 405 413 429 500 501 502 503 504'
spec:
rules:
- host: www.example.com
http:
paths:
- - path: /changeme/
+ - path: /changeme
pathType: Prefix
backend:
service:
@@ -819,7 +810,6 @@ Because the web UI is a web application, the recommended installation procedure
```conf
ADMIN_USERNAME=changeme
ADMIN_PASSWORD=changeme
- ABSOLUTE_URI=http://www.example.com/changeme/
```
Each time you edit the `/etc/bunkerweb/ui.env` file, you will need to restart the service :
@@ -841,9 +831,8 @@ Because the web UI is a web application, the recommended installation procedure
MULTISITE=yes
www.example.com_USE_UI=yes
www.example.com_USE_REVERSE_PROXY=yes
- www.example.com_REVERSE_PROXY_URL=/changeme/
+ www.example.com_REVERSE_PROXY_URL=/changeme
www.example.com_REVERSE_PROXY_HOST=http://127.0.0.1:7000
- www.example.com_REVERSE_PROXY_HEADERS=X-Script-Name /changeme
www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
```
@@ -862,7 +851,6 @@ Because the web UI is a web application, the recommended installation procedure
```conf
ADMIN_USERNAME=changeme
ADMIN_PASSWORD=changeme
- ABSOLUTE_URI=http://www.example.com/changeme/
```
Here is the `my_variables.env` boilerplate you can use :
@@ -875,9 +863,8 @@ Because the web UI is a web application, the recommended installation procedure
MULTISITE=yes
www.example.com_USE_UI=yes
www.example.com_USE_REVERSE_PROXY=yes
- www.example.com_REVERSE_PROXY_URL=/changeme/
+ www.example.com_REVERSE_PROXY_URL=/changeme
www.example.com_REVERSE_PROXY_HOST=http://127.0.0.1:7000
- www.example.com_REVERSE_PROXY_HEADERS=X-Script-Name /changeme
www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
```
@@ -929,7 +916,6 @@ Because the web UI is a web application, the recommended installation procedure
```conf
ADMIN_USERNAME=changeme
ADMIN_PASSWORD=changeme
- ABSOLUTE_URI=http://www.example.com/changeme/
```
Each time you edit the `/etc/bunkerweb/ui.env` file, you will need to restart the service :
@@ -950,9 +936,8 @@ Because the web UI is a web application, the recommended installation procedure
MULTISITE=yes
www.example.com_USE_UI=yes
www.example.com_USE_REVERSE_PROXY=yes
- www.example.com_REVERSE_PROXY_URL=/changeme/
+ www.example.com_REVERSE_PROXY_URL=/changeme
www.example.com_REVERSE_PROXY_HOST=http://127.0.0.1:7000
- www.example.com_REVERSE_PROXY_HEADERS=X-Script-Name /changeme
www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
```
diff --git a/examples/authelia/docker-compose.yml b/examples/authelia/docker-compose.yml
index 3f2afe2b1..91602de0d 100644
--- a/examples/authelia/docker-compose.yml
+++ b/examples/authelia/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3.4"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -44,7 +44,7 @@ services:
- app2.example.com_REVERSE_PROXY_HEADERS=Remote-User $$user;Remote-Groups $$groups;Remote-Name $$name;Remote-Email $$email
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -56,11 +56,12 @@ services:
- bw-data:/data
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/authelia/tests.json b/examples/authelia/tests.json
index 0b5245f9b..edb0fd9d6 100644
--- a/examples/authelia/tests.json
+++ b/examples/authelia/tests.json
@@ -1,7 +1,7 @@
{
"name": "authelia",
"kinds": ["docker", "autoconf", "swarm", "linux"],
- "timeout": 60,
+ "timeout": 120,
"delay": 60,
"tests": [
{
diff --git a/examples/authentik/docker-compose.yml b/examples/authentik/docker-compose.yml
index 5efadbaaa..11a903c23 100644
--- a/examples/authentik/docker-compose.yml
+++ b/examples/authentik/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3.4"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -53,7 +53,7 @@ services:
- app2.example.com_REVERSE_PROXY_HEADERS=X-authentik-username $$authentik_username;X-authentik-groups $$authentik_groups;X-authentik-email $$authentik_email;X-authentik-name $$authentik_name;X-authentik-uid $$authentik_uid
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -65,11 +65,12 @@ services:
- bw-data:/data
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/behind-reverse-proxy/docker-compose.yml b/examples/behind-reverse-proxy/docker-compose.yml
index 0c0cbb64a..ad6273363 100644
--- a/examples/behind-reverse-proxy/docker-compose.yml
+++ b/examples/behind-reverse-proxy/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
environment:
- SERVER_NAME=www.example.com # replace with your domains
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
@@ -24,7 +24,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -36,11 +36,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/bigbluebutton/docker-compose.yml b/examples/bigbluebutton/docker-compose.yml
index 615389ce2..264bf1b78 100644
--- a/examples/bigbluebutton/docker-compose.yml
+++ b/examples/bigbluebutton/docker-compose.yml
@@ -27,7 +27,7 @@ services:
...
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -50,7 +50,7 @@ services:
bw-universe:
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -62,11 +62,12 @@ services:
bw-docker:
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/certbot-dns-cloudflare/docker-compose.yml b/examples/certbot-dns-cloudflare/docker-compose.yml
index eb2e03eee..145d81e42 100644
--- a/examples/certbot-dns-cloudflare/docker-compose.yml
+++ b/examples/certbot-dns-cloudflare/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -17,9 +17,9 @@ services:
- USE_CLIENT_CACHE=yes
- USE_GZIP=yes
- USE_REVERSE_PROXY=yes
- - USE_CUSTOM_HTTPS=yes
- - CUSTOM_HTTPS_CERT=/certs/live/example.com/fullchain.pem
- - CUSTOM_HTTPS_KEY=/certs/live/example.com/privkey.pem
+ - USE_CUSTOM_SSL=yes
+ - CUSTOM_SSL_CERT=/certs/live/example.com/fullchain.pem
+ - CUSTOM_SSL_KEY=/certs/live/example.com/privkey.pem
- app1.example.com_REVERSE_PROXY_URL=/
- app1.example.com_REVERSE_PROXY_HOST=http://app1
- app2.example.com_REVERSE_PROXY_URL=/
@@ -33,7 +33,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -46,11 +46,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/certbot-dns-digitalocean/docker-compose.yml b/examples/certbot-dns-digitalocean/docker-compose.yml
index d0f363e74..ee1ea2aa1 100644
--- a/examples/certbot-dns-digitalocean/docker-compose.yml
+++ b/examples/certbot-dns-digitalocean/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -17,9 +17,9 @@ services:
- USE_CLIENT_CACHE=yes
- USE_GZIP=yes
- USE_REVERSE_PROXY=yes
- - USE_CUSTOM_HTTPS=yes
- - CUSTOM_HTTPS_CERT=/certs/live/example.com/fullchain.pem
- - CUSTOM_HTTPS_KEY=/certs/live/example.com/privkey.pem
+ - USE_CUSTOM_SSL=yes
+ - CUSTOM_SSL_CERT=/certs/live/example.com/fullchain.pem
+ - CUSTOM_SSL_KEY=/certs/live/example.com/privkey.pem
- app1.example.com_REVERSE_PROXY_URL=/
- app1.example.com_REVERSE_PROXY_HOST=http://app1
- app2.example.com_REVERSE_PROXY_URL=/
@@ -33,7 +33,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -46,11 +46,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/certbot-dns-google/docker-compose.yml b/examples/certbot-dns-google/docker-compose.yml
index 56bdff380..4b65b4801 100644
--- a/examples/certbot-dns-google/docker-compose.yml
+++ b/examples/certbot-dns-google/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -17,9 +17,9 @@ services:
- USE_CLIENT_CACHE=yes
- USE_GZIP=yes
- USE_REVERSE_PROXY=yes
- - USE_CUSTOM_HTTPS=yes
- - CUSTOM_HTTPS_CERT=/certs/live/example.com/fullchain.pem
- - CUSTOM_HTTPS_KEY=/certs/live/example.com/privkey.pem
+ - USE_CUSTOM_SSL=yes
+ - CUSTOM_SSL_CERT=/certs/live/example.com/fullchain.pem
+ - CUSTOM_SSL_KEY=/certs/live/example.com/privkey.pem
- app1.example.com_REVERSE_PROXY_URL=/
- app1.example.com_REVERSE_PROXY_HOST=http://app1
- app2.example.com_REVERSE_PROXY_URL=/
@@ -33,7 +33,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -46,11 +46,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/certbot-dns-ovh/docker-compose.yml b/examples/certbot-dns-ovh/docker-compose.yml
index e6fbe6885..69963d5ca 100644
--- a/examples/certbot-dns-ovh/docker-compose.yml
+++ b/examples/certbot-dns-ovh/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -17,9 +17,9 @@ services:
- USE_CLIENT_CACHE=yes
- USE_GZIP=yes
- USE_REVERSE_PROXY=yes
- - USE_CUSTOM_HTTPS=yes
- - CUSTOM_HTTPS_CERT=/certs/live/example.com/fullchain.pem
- - CUSTOM_HTTPS_KEY=/certs/live/example.com/privkey.pem
+ - USE_CUSTOM_SSL=yes
+ - CUSTOM_SSL_CERT=/certs/live/example.com/fullchain.pem
+ - CUSTOM_SSL_KEY=/certs/live/example.com/privkey.pem
- app1.example.com_REVERSE_PROXY_URL=/
- app1.example.com_REVERSE_PROXY_HOST=http://app1
- app2.example.com_REVERSE_PROXY_URL=/
@@ -33,7 +33,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -46,11 +46,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/certbot-dns-route53/docker-compose.yml b/examples/certbot-dns-route53/docker-compose.yml
index 7c1f901ea..aea2ec5dd 100644
--- a/examples/certbot-dns-route53/docker-compose.yml
+++ b/examples/certbot-dns-route53/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -17,9 +17,9 @@ services:
- USE_CLIENT_CACHE=yes
- USE_GZIP=yes
- USE_REVERSE_PROXY=yes
- - USE_CUSTOM_HTTPS=yes
- - CUSTOM_HTTPS_CERT=/certs/live/example.com/fullchain.pem
- - CUSTOM_HTTPS_KEY=/certs/live/example.com/privkey.pem
+ - USE_CUSTOM_SSL=yes
+ - CUSTOM_SSL_CERT=/certs/live/example.com/fullchain.pem
+ - CUSTOM_SSL_KEY=/certs/live/example.com/privkey.pem
- app1.example.com_REVERSE_PROXY_URL=/
- app1.example.com_REVERSE_PROXY_HOST=http://app1
- app2.example.com_REVERSE_PROXY_URL=/
@@ -33,7 +33,7 @@ services:
- bw-services
bbw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -46,11 +46,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/cors/docker-compose.yml b/examples/cors/docker-compose.yml
index 22cefbdd4..ab1cf9958 100644
--- a/examples/cors/docker-compose.yml
+++ b/examples/cors/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -38,7 +38,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -50,11 +50,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -101,4 +102,4 @@ networks:
bw-services:
volumes:
- bw-data:
\ No newline at end of file
+ bw-data:
diff --git a/examples/docker-configs/docker-compose.yml b/examples/docker-configs/docker-compose.yml
index 2ab2ad0ed..39cdaf770 100644
--- a/examples/docker-configs/docker-compose.yml
+++ b/examples/docker-configs/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -53,7 +53,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -65,11 +65,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/docker-configs/tests.json b/examples/docker-configs/tests.json
index 94f178484..54eb9ee94 100644
--- a/examples/docker-configs/tests.json
+++ b/examples/docker-configs/tests.json
@@ -1,6 +1,7 @@
{
"name": "docker-configs",
"kinds": ["docker"],
+ "delay": 30,
"timeout": 60,
"tests": [
{
diff --git a/examples/drupal/autoconf.yml b/examples/drupal/autoconf.yml
index f1f4b8475..509cfda9e 100644
--- a/examples/drupal/autoconf.yml
+++ b/examples/drupal/autoconf.yml
@@ -35,7 +35,7 @@ services:
- MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=drupaldb
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password
volumes:
db-data:
diff --git a/examples/drupal/docker-compose.yml b/examples/drupal/docker-compose.yml
index 679291eab..6a843d6ed 100644
--- a/examples/drupal/docker-compose.yml
+++ b/examples/drupal/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -28,7 +28,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -40,11 +40,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -66,7 +67,7 @@ services:
- MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=drupaldb
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password
networks:
- bw-services
diff --git a/examples/drupal/drupal-chart-values.yml b/examples/drupal/drupal-chart-values.yml
index 7f105fe7f..896a5e838 100644
--- a/examples/drupal/drupal-chart-values.yml
+++ b/examples/drupal/drupal-chart-values.yml
@@ -3,4 +3,4 @@ drupalPassword: "changeme42"
drupalEmail: "contact@example.com"
mariadb:
auth:
- password: "changeme1337"
\ No newline at end of file
+ password: "changeme1337"
diff --git a/examples/drupal/swarm.yml b/examples/drupal/swarm.yml
index 7564239c6..b7cbe079a 100644
--- a/examples/drupal/swarm.yml
+++ b/examples/drupal/swarm.yml
@@ -33,7 +33,7 @@ services:
- MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=drupaldb
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password
deploy:
placement:
constraints:
diff --git a/examples/ghost/autoconf.yml b/examples/ghost/autoconf.yml
index 23264fb2e..492f95ce1 100644
--- a/examples/ghost/autoconf.yml
+++ b/examples/ghost/autoconf.yml
@@ -24,4 +24,4 @@ volumes:
networks:
bw-services:
external: true
- name: bw-services
\ No newline at end of file
+ name: bw-services
diff --git a/examples/ghost/docker-compose.yml b/examples/ghost/docker-compose.yml
index 29ab2378f..8cd16628e 100644
--- a/examples/ghost/docker-compose.yml
+++ b/examples/ghost/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -24,7 +24,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -36,11 +36,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/ghost/ghost-chart-values.yml b/examples/ghost/ghost-chart-values.yml
index f9b7b6f5c..bb48fe096 100644
--- a/examples/ghost/ghost-chart-values.yml
+++ b/examples/ghost/ghost-chart-values.yml
@@ -3,4 +3,4 @@ ghostPassword: "changeme42"
ghostHost: "www.example.com"
mysql:
auth:
- password: "changeme1337"
\ No newline at end of file
+ password: "changeme1337"
diff --git a/examples/gogs/docker-compose.yml b/examples/gogs/docker-compose.yml
index df6a0e57d..96d3c7817 100644
--- a/examples/gogs/docker-compose.yml
+++ b/examples/gogs/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -28,7 +28,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -40,11 +40,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/hardened/docker-compose.yml b/examples/hardened/docker-compose.yml
index dac0b84c7..c7441222c 100644
--- a/examples/hardened/docker-compose.yml
+++ b/examples/hardened/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
# dropping all capabilities
cap_drop:
- ALL
@@ -15,6 +15,7 @@ services:
tmpfs:
- /tmp:mode=0770,uid=0,gid=101
- /var/tmp/bunkerweb:mode=0770,uid=0,gid=101
+ - /var/run/bunkerweb:mode=0770,uid=0,gid=101
- /var/cache/bunkerweb:mode=0770,uid=0,gid=101
- /etc/nginx:mode=0770,uid=0,gid=101
ports:
@@ -38,7 +39,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -50,11 +51,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/joomla/autoconf.yml b/examples/joomla/autoconf.yml
index 173b77d55..766d66877 100644
--- a/examples/joomla/autoconf.yml
+++ b/examples/joomla/autoconf.yml
@@ -36,7 +36,7 @@ services:
- MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=joomla_db
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match JOOMLA_DB_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match JOOMLA_DB_PASSWORD)
volumes:
joomla-data:
diff --git a/examples/joomla/docker-compose.yml b/examples/joomla/docker-compose.yml
index 522b10294..24a43b8b0 100644
--- a/examples/joomla/docker-compose.yml
+++ b/examples/joomla/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -28,7 +28,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -40,11 +40,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -68,7 +69,7 @@ services:
- MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=joomla_db
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match JOOMLA_DB_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match JOOMLA_DB_PASSWORD)
networks:
- bw-services
volumes:
diff --git a/examples/joomla/joomla-chart-values.yml b/examples/joomla/joomla-chart-values.yml
index eb1d42965..07f14e1f1 100644
--- a/examples/joomla/joomla-chart-values.yml
+++ b/examples/joomla/joomla-chart-values.yml
@@ -3,4 +3,4 @@ joomlaPassword: "changeme42"
joomlaEmail: "contact@example.com"
mariadb:
auth:
- password: "changeme1337"
\ No newline at end of file
+ password: "changeme1337"
diff --git a/examples/joomla/swarm.yml b/examples/joomla/swarm.yml
index 782704316..c69331651 100644
--- a/examples/joomla/swarm.yml
+++ b/examples/joomla/swarm.yml
@@ -36,13 +36,12 @@ services:
- MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=joomla_db
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match JOOMLA_DB_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match JOOMLA_DB_PASSWORD)
deploy:
placement:
constraints:
- "node.role==worker"
-
networks:
bw-services:
external: true
diff --git a/examples/load-balancer/docker-compose.yml b/examples/load-balancer/docker-compose.yml
index 4f91602aa..750471473 100644
--- a/examples/load-balancer/docker-compose.yml
+++ b/examples/load-balancer/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -31,7 +31,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -43,11 +43,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/load-balancer/tests.json b/examples/load-balancer/tests.json
index 153467472..a64188350 100644
--- a/examples/load-balancer/tests.json
+++ b/examples/load-balancer/tests.json
@@ -1,7 +1,7 @@
{
"name": "load-balancer",
"kinds": ["docker"],
- "timeout": 60,
+ "timeout": 120,
"no_copy_container": true,
"tests": [
{
diff --git a/examples/magento/autoconf.yml b/examples/magento/autoconf.yml
index 2b7bb3d59..05912a5fe 100644
--- a/examples/magento/autoconf.yml
+++ b/examples/magento/autoconf.yml
@@ -55,7 +55,7 @@ services:
- MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=magentodb
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match MAGENTO_DATABASE_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match MAGENTO_DATABASE_PASSWORD)
volumes:
magento-data:
diff --git a/examples/magento/docker-compose.yml b/examples/magento/docker-compose.yml
index d96f70775..cf2fd690f 100644
--- a/examples/magento/docker-compose.yml
+++ b/examples/magento/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -29,7 +29,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -41,11 +41,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -85,7 +86,7 @@ services:
- MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=magentodb
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match MAGENTO_DATABASE_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match MAGENTO_DATABASE_PASSWORD)
networks:
- bw-services
diff --git a/examples/magento/magento-chart-values.yml b/examples/magento/magento-chart-values.yml
index d65ff2d17..3be28f4b6 100644
--- a/examples/magento/magento-chart-values.yml
+++ b/examples/magento/magento-chart-values.yml
@@ -7,4 +7,4 @@ magentoLastName: "Doe"
magentoAdminUri: "admin"
mariadb:
auth:
- password: "changeme1337"
\ No newline at end of file
+ password: "changeme1337"
diff --git a/examples/magento/swarm.yml b/examples/magento/swarm.yml
index 61eb26485..3178cfa1e 100644
--- a/examples/magento/swarm.yml
+++ b/examples/magento/swarm.yml
@@ -50,7 +50,7 @@ services:
- MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=magentodb
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match MAGENTO_DATABASE_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match MAGENTO_DATABASE_PASSWORD)
deploy:
placement:
constraints:
diff --git a/examples/mattermost/docker-compose.yml b/examples/mattermost/docker-compose.yml
index d32b439cf..e4b7cf1e9 100644
--- a/examples/mattermost/docker-compose.yml
+++ b/examples/mattermost/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -44,7 +44,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -56,11 +56,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/mongo-express/docker-compose.yml b/examples/mongo-express/docker-compose.yml
index 35ee63dfc..1be9fa0f0 100644
--- a/examples/mongo-express/docker-compose.yml
+++ b/examples/mongo-express/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -27,7 +27,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -39,11 +39,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/moodle/autoconf.yml b/examples/moodle/autoconf.yml
index f9c5cedd6..0748d5089 100644
--- a/examples/moodle/autoconf.yml
+++ b/examples/moodle/autoconf.yml
@@ -13,10 +13,10 @@ services:
- moodle-files:/bitnami/moodle
- moodle-data:/bitnami/moodledata
environment:
- - MOODLE_USERNAME=admin # replace with your moodle admin username
- - MOODLE_PASSWORD=password # replace with your moodle admin password
- - MOODLE_EMAIL=moodle@example.com # replace with your moodle admin email
- - MOODLE_SITE_NAME=My Moodle # replace with your moodle site name
+ - MOODLE_USERNAME=admin # replace with your moodle admin username
+ - MOODLE_PASSWORD=password # replace with your moodle admin password
+ - MOODLE_EMAIL=moodle@example.com # replace with your moodle admin email
+ - MOODLE_SITE_NAME=My Moodle # replace with your moodle site name
- MOODLE_DATABASE_HOST=mydb
- MOODLE_DATABASE_NAME=moodle
- MOODLE_DATABASE_USER=user
@@ -36,10 +36,10 @@ services:
aliases:
- mydb
environment:
- - MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
+ - MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=moodle
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match MOODLE_DATABASE_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match MOODLE_DATABASE_PASSWORD)
- MARIADB_CHARACTER_SET=utf8mb4
- MARIADB_COLLATE=utf8mb4_unicode_ci
diff --git a/examples/moodle/docker-compose.yml b/examples/moodle/docker-compose.yml
index e55004575..c4204e7b5 100644
--- a/examples/moodle/docker-compose.yml
+++ b/examples/moodle/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -25,7 +25,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -37,11 +37,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -53,10 +54,10 @@ services:
- moodle-files:/bitnami/moodle
- moodle-data:/bitnami/moodledata
environment:
- - MOODLE_USERNAME=admin # replace with your moodle admin username
- - MOODLE_PASSWORD=password # replace with your moodle admin password
- - MOODLE_EMAIL=moodle@example.com # replace with your moodle admin email
- - MOODLE_SITE_NAME=My Moodle # replace with your moodle site name
+ - MOODLE_USERNAME=admin # replace with your moodle admin username
+ - MOODLE_PASSWORD=password # replace with your moodle admin password
+ - MOODLE_EMAIL=moodle@example.com # replace with your moodle admin email
+ - MOODLE_SITE_NAME=My Moodle # replace with your moodle site name
- MOODLE_DATABASE_HOST=mydb
- MOODLE_DATABASE_NAME=moodle
- MOODLE_DATABASE_USER=user
@@ -69,10 +70,10 @@ services:
volumes:
- db-data:/var/lib/mysql
environment:
- - MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
+ - MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=moodle
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match MOODLE_DATABASE_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match MOODLE_DATABASE_PASSWORD)
- MARIADB_CHARACTER_SET=utf8mb4
- MARIADB_COLLATE=utf8mb4_unicode_ci
networks:
diff --git a/examples/moodle/moodle-chart-values.yml b/examples/moodle/moodle-chart-values.yml
index b4597275d..3a93c2b67 100644
--- a/examples/moodle/moodle-chart-values.yml
+++ b/examples/moodle/moodle-chart-values.yml
@@ -4,4 +4,4 @@ moodlePassword: "changeme42"
moodleEmail: "admin@example.com"
mariadb:
auth:
- password: "changeme1337"
\ No newline at end of file
+ password: "changeme1337"
diff --git a/examples/moodle/swarm.yml b/examples/moodle/swarm.yml
index cf078434b..fe4b2a06a 100644
--- a/examples/moodle/swarm.yml
+++ b/examples/moodle/swarm.yml
@@ -36,10 +36,10 @@ services:
networks:
- bw-services
environment:
- - MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
+ - MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=moodle
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match MOODLE_DATABASE_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match MOODLE_DATABASE_PASSWORD)
- MARIADB_CHARACTER_SET=utf8mb4
- MARIADB_COLLATE=utf8mb4_unicode_ci
deploy:
diff --git a/examples/nextcloud/autoconf.yml b/examples/nextcloud/autoconf.yml
index ab7d6595f..35485e314 100644
--- a/examples/nextcloud/autoconf.yml
+++ b/examples/nextcloud/autoconf.yml
@@ -56,7 +56,6 @@ services:
bunkerweb.CUSTOM_CONF_MODSEC_nextcloud=
SecRule REQUEST_FILENAME "@rx ^/remote.php/dav/files/" "id:2000,ctl:ruleRemoveByTag=attack-protocol,ctl:ruleRemoveByTag=attack-generic,nolog"
-
mydb:
image: mariadb
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
@@ -70,7 +69,7 @@ services:
- MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=nc
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match MYSQL_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match MYSQL_PASSWORD)
volumes:
nc-files:
diff --git a/examples/nextcloud/docker-compose.yml b/examples/nextcloud/docker-compose.yml
index 781c3806a..d1165a347 100644
--- a/examples/nextcloud/docker-compose.yml
+++ b/examples/nextcloud/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -54,7 +54,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -66,11 +66,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -110,7 +111,6 @@ volumes:
db-data:
nc-files:
-
networks:
bw-universe:
ipam:
diff --git a/examples/nextcloud/swarm.yml b/examples/nextcloud/swarm.yml
index 8fb87729f..3bed05364 100644
--- a/examples/nextcloud/swarm.yml
+++ b/examples/nextcloud/swarm.yml
@@ -48,7 +48,7 @@ services:
- MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=nc
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match MYSQL_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match MYSQL_PASSWORD)
deploy:
placement:
constraints:
diff --git a/examples/passbolt/autoconf.yml b/examples/passbolt/autoconf.yml
index 9182fae77..3e349b57a 100644
--- a/examples/passbolt/autoconf.yml
+++ b/examples/passbolt/autoconf.yml
@@ -13,7 +13,7 @@ services:
environment:
- APP_FULL_BASE_URL=https://www.example.com # replace with your URL
- DATASOURCES_DEFAULT_HOST=mydb
- - DATASOURCES_DEFAULT_PASSWORD=db-user-pwd # replace with a stronger password (must match MYSQL_PASSWORD)
+ - DATASOURCES_DEFAULT_PASSWORD=db-user-pwd # replace with a stronger password (must match MYSQL_PASSWORD)
- DATASOURCES_DEFAULT_USERNAME=user
- DATASOURCES_DEFAULT_DATABASE=passbolt
volumes:
@@ -45,10 +45,10 @@ services:
aliases:
- mydb
environment:
- - MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
+ - MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=passbolt
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match DATASOURCES_DEFAULT_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match DATASOURCES_DEFAULT_PASSWORD)
volumes:
gpg-data:
diff --git a/examples/passbolt/docker-compose.yml b/examples/passbolt/docker-compose.yml
index 9854e02ba..d43362bb5 100644
--- a/examples/passbolt/docker-compose.yml
+++ b/examples/passbolt/docker-compose.yml
@@ -2,12 +2,12 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
environment:
- - SERVER_NAME=www.example.com # replace with your domain
+ - SERVER_NAME=www.example.com # replace with your domain
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
- AUTO_LETS_ENCRYPT=yes
- DISABLE_DEFAULT_SERVER=yes
@@ -26,7 +26,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -38,11 +38,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -58,7 +59,7 @@ services:
environment:
- APP_FULL_BASE_URL=https://www.example.com # replace with your URL
- DATASOURCES_DEFAULT_HOST=mydb
- - DATASOURCES_DEFAULT_PASSWORD=db-user-pwd # replace with a stronger password (must match MYSQL_PASSWORD)
+ - DATASOURCES_DEFAULT_PASSWORD=db-user-pwd # replace with a stronger password (must match MYSQL_PASSWORD)
- DATASOURCES_DEFAULT_USERNAME=user
- DATASOURCES_DEFAULT_DATABASE=passbolt
volumes:
@@ -81,10 +82,10 @@ services:
volumes:
- db-data:/var/lib/mysql
environment:
- - MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
+ - MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=passbolt
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match DATASOURCES_DEFAULT_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match DATASOURCES_DEFAULT_PASSWORD)
networks:
- bw-services
diff --git a/examples/passbolt/swarm.yml b/examples/passbolt/swarm.yml
index 39c27661f..090277c5a 100644
--- a/examples/passbolt/swarm.yml
+++ b/examples/passbolt/swarm.yml
@@ -11,7 +11,7 @@ services:
environment:
- APP_FULL_BASE_URL=https://www.example.com # replace with your URL
- DATASOURCES_DEFAULT_HOST=mydb
- - DATASOURCES_DEFAULT_PASSWORD=db-user-pwd # replace with a stronger password (must match MYSQL_PASSWORD)
+ - DATASOURCES_DEFAULT_PASSWORD=db-user-pwd # replace with a stronger password (must match MYSQL_PASSWORD)
- DATASOURCES_DEFAULT_USERNAME=user
- DATASOURCES_DEFAULT_DATABASE=passbolt
volumes:
@@ -45,10 +45,10 @@ services:
networks:
- bw-services
environment:
- - MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
+ - MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=passbolt
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match DATASOURCES_DEFAULT_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match DATASOURCES_DEFAULT_PASSWORD)
deploy:
placement:
constraints:
diff --git a/examples/php-cookie-flags/docker-compose.yml b/examples/php-cookie-flags/docker-compose.yml
index b5227e22a..3ddd6ce7a 100644
--- a/examples/php-cookie-flags/docker-compose.yml
+++ b/examples/php-cookie-flags/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -31,7 +31,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -43,11 +43,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -65,7 +66,6 @@ services:
volumes:
bw-data:
-
networks:
bw-universe:
ipam:
diff --git a/examples/php-multisite/docker-compose.yml b/examples/php-multisite/docker-compose.yml
index b41f75939..6a7511435 100644
--- a/examples/php-multisite/docker-compose.yml
+++ b/examples/php-multisite/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -34,7 +34,7 @@ services:
- net-app2
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -46,11 +46,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/php-singlesite/docker-compose.yml b/examples/php-singlesite/docker-compose.yml
index 89ebaf9b2..04aa557a3 100644
--- a/examples/php-singlesite/docker-compose.yml
+++ b/examples/php-singlesite/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -30,7 +30,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -42,11 +42,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/prestashop/docker-compose.yml b/examples/prestashop/docker-compose.yml
index 4aa1b446d..5986f51ed 100644
--- a/examples/prestashop/docker-compose.yml
+++ b/examples/prestashop/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -28,7 +28,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -40,11 +40,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/prestashop/prestashop-chart-values.yml b/examples/prestashop/prestashop-chart-values.yml
index d476d39ed..7c2b309c5 100644
--- a/examples/prestashop/prestashop-chart-values.yml
+++ b/examples/prestashop/prestashop-chart-values.yml
@@ -10,4 +10,4 @@ service:
type: ClusterIP
mariadb:
auth:
- password: "changeme1337"
\ No newline at end of file
+ password: "changeme1337"
diff --git a/examples/proxy-protocol/docker-compose.yml b/examples/proxy-protocol/docker-compose.yml
index 2d5cafdd2..31f3e8dbc 100644
--- a/examples/proxy-protocol/docker-compose.yml
+++ b/examples/proxy-protocol/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
environment:
- SERVER_NAME=www.example.com # replace with your domains
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
@@ -27,7 +27,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -39,11 +39,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/radarr/docker-compose.yml b/examples/radarr/docker-compose.yml
index 1eed50fc7..0e4381064 100644
--- a/examples/radarr/docker-compose.yml
+++ b/examples/radarr/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -34,7 +34,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -46,11 +46,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/radarr/tests.json b/examples/radarr/tests.json
index 2fea890ed..763183c9c 100644
--- a/examples/radarr/tests.json
+++ b/examples/radarr/tests.json
@@ -1,6 +1,7 @@
{
"name": "radarr",
"kinds": ["docker", "autoconf", "swarm"],
+ "delay": 180,
"timeout": 60,
"tests": [
{
diff --git a/examples/redmine/autoconf.yml b/examples/redmine/autoconf.yml
index ba3352972..d71898cfa 100644
--- a/examples/redmine/autoconf.yml
+++ b/examples/redmine/autoconf.yml
@@ -33,7 +33,7 @@ services:
- MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=redminedb
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match REDMINE_DB_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match REDMINE_DB_PASSWORD)
volumes:
redmine-data:
diff --git a/examples/redmine/docker-compose.yml b/examples/redmine/docker-compose.yml
index f83d2992b..ce7693b5d 100644
--- a/examples/redmine/docker-compose.yml
+++ b/examples/redmine/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -24,7 +24,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -36,11 +36,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -65,7 +66,7 @@ services:
- MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=redminedb
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match REDMINE_DB_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match REDMINE_DB_PASSWORD)
networks:
- bw-universe
- bw-services
diff --git a/examples/redmine/redmine-chart-values.yml b/examples/redmine/redmine-chart-values.yml
index b5311f6a5..8698d85b6 100644
--- a/examples/redmine/redmine-chart-values.yml
+++ b/examples/redmine/redmine-chart-values.yml
@@ -6,4 +6,4 @@ service:
type: ClusterIP
mariadb:
auth:
- password: "changeme1337"
\ No newline at end of file
+ password: "changeme1337"
diff --git a/examples/redmine/swarm.yml b/examples/redmine/swarm.yml
index 9475d356a..5c789c265 100644
--- a/examples/redmine/swarm.yml
+++ b/examples/redmine/swarm.yml
@@ -33,7 +33,7 @@ services:
- MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=redminedb
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match REDMINE_DB_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match REDMINE_DB_PASSWORD)
deploy:
placement:
constraints:
diff --git a/examples/reverse-proxy-multisite/docker-compose.yml b/examples/reverse-proxy-multisite/docker-compose.yml
index b72cf5de9..7883420ab 100644
--- a/examples/reverse-proxy-multisite/docker-compose.yml
+++ b/examples/reverse-proxy-multisite/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -27,7 +27,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -39,11 +39,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/reverse-proxy-multisite/tests.json b/examples/reverse-proxy-multisite/tests.json
index 07fdaf420..9ab43153e 100644
--- a/examples/reverse-proxy-multisite/tests.json
+++ b/examples/reverse-proxy-multisite/tests.json
@@ -2,7 +2,7 @@
"name": "reverse-proxy-multisite",
"kinds": ["docker", "autoconf", "swarm", "kubernetes", "linux"],
"timeout": 60,
- "delay": 60,
+ "delay": 90,
"tests": [
{
"type": "string",
diff --git a/examples/reverse-proxy-singlesite/docker-compose.yml b/examples/reverse-proxy-singlesite/docker-compose.yml
index 6ea2cf0fc..e23dd3728 100644
--- a/examples/reverse-proxy-singlesite/docker-compose.yml
+++ b/examples/reverse-proxy-singlesite/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -32,7 +32,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -44,11 +44,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/reverse-proxy-singlesite/tests.json b/examples/reverse-proxy-singlesite/tests.json
index c37b0090d..f52f139d1 100644
--- a/examples/reverse-proxy-singlesite/tests.json
+++ b/examples/reverse-proxy-singlesite/tests.json
@@ -1,6 +1,7 @@
{
"name": "reverse-proxy-singlesite",
"kinds": ["docker", "autoconf", "swarm", "linux"],
+ "delay": 120,
"timeout": 60,
"no_copy_container": true,
"tests": [
diff --git a/examples/reverse-proxy-websocket/docker-compose.yml b/examples/reverse-proxy-websocket/docker-compose.yml
index c364680c5..d72cd6662 100644
--- a/examples/reverse-proxy-websocket/docker-compose.yml
+++ b/examples/reverse-proxy-websocket/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -25,7 +25,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -37,11 +37,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/stream-multisite/docker-compose.yml b/examples/stream-multisite/docker-compose.yml
index b32deab56..a49dd4716 100644
--- a/examples/stream-multisite/docker-compose.yml
+++ b/examples/stream-multisite/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080 # required to resolve let's encrypt challenges
- 10000:10000 # app1 without SSL/TLS
@@ -33,7 +33,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -45,23 +45,24 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
app1:
image: istio/tcp-echo-server:1.2
- command: [ "9000", "app1" ]
+ command: ["9000", "app1"]
networks:
- bw-services
app2:
image: istio/tcp-echo-server:1.2
- command: [ "9000", "app2" ]
+ command: ["9000", "app2"]
networks:
- bw-services
diff --git a/examples/syslog/docker-compose.yml b/examples/syslog/docker-compose.yml
index b3c3bd21f..dc66ea564 100644
--- a/examples/syslog/docker-compose.yml
+++ b/examples/syslog/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
logging:
driver: syslog
options:
@@ -28,7 +28,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
logging:
driver: syslog
options:
@@ -45,11 +45,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/tomcat/docker-compose.yml b/examples/tomcat/docker-compose.yml
index 3939bf8a1..39a85468e 100644
--- a/examples/tomcat/docker-compose.yml
+++ b/examples/tomcat/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -23,7 +23,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -35,11 +35,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/tor-hidden-service/docker-compose.yml b/examples/tor-hidden-service/docker-compose.yml
index 3baebee71..aa7ffdee3 100644
--- a/examples/tor-hidden-service/docker-compose.yml
+++ b/examples/tor-hidden-service/docker-compose.yml
@@ -12,7 +12,7 @@ services:
- bw-universe
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
environment:
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
# disable common security measures based on IP
@@ -34,7 +34,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -46,11 +46,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/web-ui/docker-compose.yml b/examples/web-ui/docker-compose.yml
index d28cbe1d6..ee6b8e635 100644
--- a/examples/web-ui/docker-compose.yml
+++ b/examples/web-ui/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -17,10 +17,9 @@ services:
- www.example.com_USE_UI=yes
- www.example.com_SERVE_FILES=no
- www.example.com_USE_REVERSE_PROXY=yes
- - www.example.com_REVERSE_PROXY_URL=/changeme/ # replace with another url
+ - www.example.com_REVERSE_PROXY_URL=/changeme # replace with another url
- www.example.com_REVERSE_PROXY_HOST=http://bw-ui:7000
- - www.example.com_REVERSE_PROXY_HEADERS=X-Script-Name /changeme # replace with another url
- - www.example.com_REVERSE_PROXY_INTERCEPT_ERRORS=no
+ - www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
labels:
- "bunkerweb.INSTANCE"
networks:
@@ -28,7 +27,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -40,11 +39,10 @@ services:
- bw-docker
bw-ui:
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
depends_on:
- bw-docker-proxy
environment:
- - ABSOLUTE_URI=https://www.example.com/changeme/ # replace with another url
- DOCKER_HOST=tcp://bw-docker-proxy:2375
- ADMIN_USERNAME=changeme
- ADMIN_PASSWORD=changeme # replace with a stronger password
@@ -55,11 +53,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/examples/wordpress/autoconf.yml b/examples/wordpress/autoconf.yml
index 50b3459d2..a5db280b8 100644
--- a/examples/wordpress/autoconf.yml
+++ b/examples/wordpress/autoconf.yml
@@ -43,7 +43,7 @@ services:
- MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=wp
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match WORDPRESS_DB_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match WORDPRESS_DB_PASSWORD)
volumes:
wp-data:
diff --git a/examples/wordpress/docker-compose.yml b/examples/wordpress/docker-compose.yml
index 7123b8d22..fa4834990 100644
--- a/examples/wordpress/docker-compose.yml
+++ b/examples/wordpress/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3"
services:
mybunker:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -25,7 +25,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- mybunker
environment:
@@ -37,11 +37,12 @@ services:
- bw-docker
bw-docker-proxy:
- image: tecnativa/docker-socket-proxy:0.1
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -66,7 +67,7 @@ services:
- MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=wp
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match WORDPRESS_DB_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match WORDPRESS_DB_PASSWORD)
networks:
- bw-services
diff --git a/examples/wordpress/setup-kubernetes.sh b/examples/wordpress/setup-kubernetes.sh
index a2c88a775..dd13f41a6 100755
--- a/examples/wordpress/setup-kubernetes.sh
+++ b/examples/wordpress/setup-kubernetes.sh
@@ -1,4 +1,3 @@
#!/bin/bash
-helm repo add wordpress https://charts.bitnami.com/bitnami
-helm install -f wordpress-chart-values.yml wordpress bitnami/wordpress
+helm install -f wordpress-chart-values.yml wordpress oci://registry-1.docker.io/bitnamicharts/wordpress
diff --git a/examples/wordpress/swarm.yml b/examples/wordpress/swarm.yml
index 550714d2a..889368d53 100644
--- a/examples/wordpress/swarm.yml
+++ b/examples/wordpress/swarm.yml
@@ -34,7 +34,7 @@ services:
- MYSQL_ROOT_PASSWORD=db-root-pwd # replace with a stronger password
- MYSQL_DATABASE=wp
- MYSQL_USER=user
- - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match WORDPRESS_DB_PASSWORD)
+ - MYSQL_PASSWORD=db-user-pwd # replace with a stronger password (must match WORDPRESS_DB_PASSWORD)
deploy:
placement:
constraints:
diff --git a/examples/wordpress/tests.json b/examples/wordpress/tests.json
index fa465449f..5f87a4b3e 100644
--- a/examples/wordpress/tests.json
+++ b/examples/wordpress/tests.json
@@ -1,7 +1,7 @@
{
"name": "wordpress",
"kinds": ["docker", "autoconf", "swarm", "kubernetes", "linux"],
- "timeout": 60,
+ "timeout": 120,
"delay": 120,
"no_copy_container": true,
"tests": [
diff --git a/examples/wordpress/wordpress-chart-values.yml b/examples/wordpress/wordpress-chart-values.yml
index 259236d8c..a7bff53ff 100644
--- a/examples/wordpress/wordpress-chart-values.yml
+++ b/examples/wordpress/wordpress-chart-values.yml
@@ -8,4 +8,4 @@ wordpressTablePrefix: "changeme_"
wordpressScheme: "https"
mariadb:
auth:
- password: "changeme1337"
\ No newline at end of file
+ password: "changeme1337"
diff --git a/misc/integrations/autoconf.mariadb.ui.yml b/misc/integrations/autoconf.mariadb.ui.yml
index 2da422312..a7498f64b 100644
--- a/misc/integrations/autoconf.mariadb.ui.yml
+++ b/misc/integrations/autoconf.mariadb.ui.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -19,7 +19,7 @@ services:
- bw-services
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -32,7 +32,7 @@ services:
- bw-docker
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -45,11 +45,12 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -66,7 +67,7 @@ services:
- bw-docker
bw-ui:
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
networks:
bw-docker:
bw-universe:
@@ -78,14 +79,12 @@ services:
- AUTOCONF_MODE=yes
- ADMIN_USERNAME=admin
- ADMIN_PASSWORD=changeme
- - ABSOLUTE_URI=http://www.example.com/changeme/
labels:
- "bunkerweb.SERVER_NAME=www.example.com"
- "bunkerweb.USE_UI=yes"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- - "bunkerweb.REVERSE_PROXY_URL=/changeme/"
+ - "bunkerweb.REVERSE_PROXY_URL=/changeme"
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
- - "bunkerweb.REVERSE_PROXY_HEADERS=X-Script-Name /changeme"
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
volumes:
diff --git a/misc/integrations/autoconf.mariadb.yml b/misc/integrations/autoconf.mariadb.yml
index c85e08fda..235c4cdb7 100644
--- a/misc/integrations/autoconf.mariadb.yml
+++ b/misc/integrations/autoconf.mariadb.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -19,7 +19,7 @@ services:
- bw-services
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -32,7 +32,7 @@ services:
- bw-docker
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -45,11 +45,12 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/misc/integrations/autoconf.mysql.ui.yml b/misc/integrations/autoconf.mysql.ui.yml
index dac0e0e5c..30d436093 100644
--- a/misc/integrations/autoconf.mysql.ui.yml
+++ b/misc/integrations/autoconf.mysql.ui.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -19,7 +19,7 @@ services:
- bw-services
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -32,7 +32,7 @@ services:
- bw-docker
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -45,11 +45,12 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -66,7 +67,7 @@ services:
- bw-docker
bw-ui:
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
networks:
bw-docker:
bw-universe:
@@ -78,14 +79,12 @@ services:
- AUTOCONF_MODE=yes
- ADMIN_USERNAME=changeme
- ADMIN_PASSWORD=changeme
- - ABSOLUTE_URI=http://www.example.com/changeme/
labels:
- "bunkerweb.SERVER_NAME=www.example.com"
- "bunkerweb.USE_UI=yes"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- - "bunkerweb.REVERSE_PROXY_URL=/changeme/"
+ - "bunkerweb.REVERSE_PROXY_URL=/changeme"
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
- - "bunkerweb.REVERSE_PROXY_HEADERS=X-Script-Name /changeme"
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
volumes:
diff --git a/misc/integrations/autoconf.mysql.yml b/misc/integrations/autoconf.mysql.yml
index 3e66f69e3..cb5b47466 100644
--- a/misc/integrations/autoconf.mysql.yml
+++ b/misc/integrations/autoconf.mysql.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -19,7 +19,7 @@ services:
- bw-services
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -32,7 +32,7 @@ services:
- bw-docker
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -45,11 +45,12 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/misc/integrations/autoconf.postgres.ui.yml b/misc/integrations/autoconf.postgres.ui.yml
index 9dbb960eb..c7dd061bb 100644
--- a/misc/integrations/autoconf.postgres.ui.yml
+++ b/misc/integrations/autoconf.postgres.ui.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -19,7 +19,7 @@ services:
- bw-services
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -32,7 +32,7 @@ services:
- bw-docker
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -45,11 +45,12 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
@@ -65,7 +66,7 @@ services:
- bw-docker
bw-ui:
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
networks:
bw-docker:
bw-universe:
@@ -77,14 +78,12 @@ services:
- AUTOCONF_MODE=yes
- ADMIN_USERNAME=admin
- ADMIN_PASSWORD=changeme
- - ABSOLUTE_URI=http://www.example.com/changeme/
labels:
- "bunkerweb.SERVER_NAME=www.example.com"
- "bunkerweb.USE_UI=yes"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- - "bunkerweb.REVERSE_PROXY_URL=/changeme/"
+ - "bunkerweb.REVERSE_PROXY_URL=/changeme"
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
- - "bunkerweb.REVERSE_PROXY_HEADERS=X-Script-Name /changeme"
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
volumes:
diff --git a/misc/integrations/autoconf.postgres.yml b/misc/integrations/autoconf.postgres.yml
index 6924217b4..b88501afe 100644
--- a/misc/integrations/autoconf.postgres.yml
+++ b/misc/integrations/autoconf.postgres.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -19,7 +19,7 @@ services:
- bw-services
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -32,7 +32,7 @@ services:
- bw-docker
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -45,11 +45,12 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/misc/integrations/autoconf.ui.yml b/misc/integrations/autoconf.ui.yml
index 478debadc..9e11fb74c 100644
--- a/misc/integrations/autoconf.ui.yml
+++ b/misc/integrations/autoconf.ui.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -18,7 +18,7 @@ services:
- bw-services
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -32,7 +32,7 @@ services:
- bw-docker
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -46,16 +46,17 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
bw-ui:
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
networks:
bw-docker:
bw-universe:
@@ -68,14 +69,12 @@ services:
- AUTOCONF_MODE=yes
- ADMIN_USERNAME=admin
- ADMIN_PASSWORD=changeme
- - ABSOLUTE_URI=http://www.example.com/changeme/
labels:
- "bunkerweb.SERVER_NAME=www.example.com"
- "bunkerweb.USE_UI=yes"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- - "bunkerweb.REVERSE_PROXY_URL=/changeme/"
+ - "bunkerweb.REVERSE_PROXY_URL=/changeme"
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
- - "bunkerweb.REVERSE_PROXY_HEADERS=X-Script-Name /changeme"
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
volumes:
diff --git a/misc/integrations/autoconf.yml b/misc/integrations/autoconf.yml
index 46cd8ac75..ab55f503c 100644
--- a/misc/integrations/autoconf.yml
+++ b/misc/integrations/autoconf.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -18,7 +18,7 @@ services:
- bw-services
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -32,7 +32,7 @@ services:
- bw-docker
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -46,11 +46,12 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/misc/integrations/docker.mariadb.ui.yml b/misc/integrations/docker.mariadb.ui.yml
index 1dd4669f5..68449646a 100644
--- a/misc/integrations/docker.mariadb.ui.yml
+++ b/misc/integrations/docker.mariadb.ui.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -18,16 +18,15 @@ services:
- USE_GZIP=yes
- www.example.com_USE_UI=yes
- www.example.com_USE_REVERSE_PROXY=yes
- - www.example.com_REVERSE_PROXY_URL=/changeme/
+ - www.example.com_REVERSE_PROXY_URL=/changeme
- www.example.com_REVERSE_PROXY_HOST=http://bw-ui:7000
- - www.example.com_REVERSE_PROXY_HEADERS=X-Script-Name /changeme
- www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
networks:
- bw-universe
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -39,16 +38,17 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
bw-ui:
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
depends_on:
- bw-docker
environment:
@@ -56,7 +56,6 @@ services:
- DOCKER_HOST=tcp://bw-docker:2375
- ADMIN_USERNAME=changeme
- ADMIN_PASSWORD=changeme # Remember to set a stronger password for the changeme user
- - ABSOLUTE_URI=http://www.example.com/changeme/
networks:
- bw-universe
- bw-docker
diff --git a/misc/integrations/docker.mariadb.yml b/misc/integrations/docker.mariadb.yml
index f7a5a2a64..d60132f81 100644
--- a/misc/integrations/docker.mariadb.yml
+++ b/misc/integrations/docker.mariadb.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -17,7 +17,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -29,11 +29,12 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/misc/integrations/docker.mysql.ui.yml b/misc/integrations/docker.mysql.ui.yml
index ffd2039db..584c6c063 100644
--- a/misc/integrations/docker.mysql.ui.yml
+++ b/misc/integrations/docker.mysql.ui.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -18,16 +18,15 @@ services:
- USE_GZIP=yes
- www.example.com_USE_UI=yes
- www.example.com_USE_REVERSE_PROXY=yes
- - www.example.com_REVERSE_PROXY_URL=/admin/
+ - www.example.com_REVERSE_PROXY_URL=/changeme
- www.example.com_REVERSE_PROXY_HOST=http://bw-ui:7000
- - www.example.com_REVERSE_PROXY_HEADERS=X-Script-Name /admin
- www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
networks:
- bw-universe
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -39,16 +38,17 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
bw-ui:
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
depends_on:
- bw-docker
environment:
@@ -56,7 +56,6 @@ services:
- DOCKER_HOST=tcp://bw-docker:2375
- ADMIN_USERNAME=admin
- ADMIN_PASSWORD=changeme # Remember to set a stronger password for the admin user
- - ABSOLUTE_URI=http://www.example.com/changeme/
networks:
- bw-universe
- bw-docker
diff --git a/misc/integrations/docker.mysql.yml b/misc/integrations/docker.mysql.yml
index 83e882c4b..7fdd23052 100644
--- a/misc/integrations/docker.mysql.yml
+++ b/misc/integrations/docker.mysql.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -17,7 +17,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -29,11 +29,12 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/misc/integrations/docker.postgres.ui.yml b/misc/integrations/docker.postgres.ui.yml
index 07f3c1618..79a20e4ba 100644
--- a/misc/integrations/docker.postgres.ui.yml
+++ b/misc/integrations/docker.postgres.ui.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -19,16 +19,15 @@ services:
- www.example.com_USE_UI=yes
- www.example.com_SERVE_FILES=no
- www.example.com_USE_REVERSE_PROXY=yes
- - www.example.com_REVERSE_PROXY_URL=/admin/
+ - www.example.com_REVERSE_PROXY_URL=/changeme
- www.example.com_REVERSE_PROXY_HOST=http://bw-ui:7000
- - www.example.com_REVERSE_PROXY_HEADERS=X-Script-Name /admin
- www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
networks:
- bw-universe
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -40,16 +39,17 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
bw-ui:
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
depends_on:
- bw-docker
environment:
@@ -57,7 +57,6 @@ services:
- DOCKER_HOST=tcp://bw-docker:2375
- ADMIN_USERNAME=admin
- ADMIN_PASSWORD=changeme # Remember to set a stronger password for the admin user
- - ABSOLUTE_URI=http://www.example.com/changeme
networks:
- bw-universe
- bw-docker
diff --git a/misc/integrations/docker.postgres.yml b/misc/integrations/docker.postgres.yml
index 069a76523..672fa8798 100644
--- a/misc/integrations/docker.postgres.yml
+++ b/misc/integrations/docker.postgres.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -17,7 +17,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -29,11 +29,12 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/misc/integrations/docker.ui.yml b/misc/integrations/docker.ui.yml
index dfa8993af..16b11144e 100644
--- a/misc/integrations/docker.ui.yml
+++ b/misc/integrations/docker.ui.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -14,16 +14,15 @@ services:
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
- www.example.com_USE_UI=yes
- www.example.com_USE_REVERSE_PROXY=yes
- - www.example.com_REVERSE_PROXY_URL=/changeme/
+ - www.example.com_REVERSE_PROXY_URL=/changeme
- www.example.com_REVERSE_PROXY_HOST=http://bw-ui:7000
- - www.example.com_REVERSE_PROXY_HEADERS=X-Script-Name /changeme
- www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
networks:
- bw-universe
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -36,16 +35,17 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
bw-ui:
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
depends_on:
- bw-docker
volumes:
@@ -54,7 +54,6 @@ services:
- DOCKER_HOST=tcp://bw-docker:2375
- ADMIN_USERNAME=changeme
- ADMIN_PASSWORD=changeme
- - ABSOLUTE_URI=http://www.example.com/changeme/
networks:
- bw-universe
- bw-docker
diff --git a/misc/integrations/docker.yml b/misc/integrations/docker.yml
index 7da82339e..0a416bcbf 100644
--- a/misc/integrations/docker.yml
+++ b/misc/integrations/docker.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- 80:8080
- 443:8443
@@ -16,7 +16,7 @@ services:
- bw-services
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
depends_on:
- bunkerweb
- bw-docker
@@ -29,11 +29,12 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
diff --git a/misc/integrations/k8s.mariadb.ui.yml b/misc/integrations/k8s.mariadb.ui.yml
index b66e23c96..1c5ea146a 100644
--- a/misc/integrations/k8s.mariadb.ui.yml
+++ b/misc/integrations/k8s.mariadb.ui.yml
@@ -48,7 +48,7 @@ spec:
containers:
# using bunkerweb as name is mandatory
- name: bunkerweb
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
imagePullPolicy: Always
securityContext:
runAsUser: 101
@@ -118,7 +118,7 @@ spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-controller
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
@@ -145,7 +145,7 @@ spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-scheduler
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
@@ -230,15 +230,13 @@ spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-ui
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
imagePullPolicy: Always
env:
- name: ADMIN_USERNAME
value: "changeme"
- name: "ADMIN_PASSWORD"
value: "changeme"
- - name: "ABSOLUTE_URI"
- value: "http://www.example.com/changeme/"
- name: KUBERNETES_MODE
value: "YES"
- name: "DATABASE_URI"
@@ -313,14 +311,13 @@ metadata:
name: ingress
annotations:
bunkerweb.io/www.example.com_USE_UI: "yes"
- bunkerweb.io/www.example.com_REVERSE_PROXY_HEADERS_1: "X-Script-Name /changeme"
bunkerweb.io/www.example.com_INTERCEPTED_ERROR_CODES: "400 404 405 413 429 500 501 502 503 504"
spec:
rules:
- host: www.example.com
http:
paths:
- - path: /changeme/
+ - path: /changeme
pathType: Prefix
backend:
service:
diff --git a/misc/integrations/k8s.mariadb.yml b/misc/integrations/k8s.mariadb.yml
index 075ab500b..69b826df2 100644
--- a/misc/integrations/k8s.mariadb.yml
+++ b/misc/integrations/k8s.mariadb.yml
@@ -48,7 +48,7 @@ spec:
containers:
# using bunkerweb as name is mandatory
- name: bunkerweb
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
imagePullPolicy: Always
securityContext:
runAsUser: 101
@@ -118,7 +118,7 @@ spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-controller
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
@@ -145,7 +145,7 @@ spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-scheduler
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
diff --git a/misc/integrations/k8s.mysql.ui.yml b/misc/integrations/k8s.mysql.ui.yml
index 518d87b49..f8119d22a 100644
--- a/misc/integrations/k8s.mysql.ui.yml
+++ b/misc/integrations/k8s.mysql.ui.yml
@@ -48,7 +48,7 @@ spec:
containers:
# using bunkerweb as name is mandatory
- name: bunkerweb
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
imagePullPolicy: Always
securityContext:
runAsUser: 101
@@ -118,7 +118,7 @@ spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-controller
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
@@ -145,7 +145,7 @@ spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-scheduler
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
@@ -230,15 +230,13 @@ spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-ui
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
imagePullPolicy: Always
env:
- name: ADMIN_USERNAME
value: "changeme"
- name: "ADMIN_PASSWORD"
value: "changeme"
- - name: "ABSOLUTE_URI"
- value: "http://www.example.com/changeme/"
- name: KUBERNETES_MODE
value: "YES"
- name: "DATABASE_URI"
@@ -312,14 +310,13 @@ metadata:
name: ingress
annotations:
bunkerweb.io/www.example.com_USE_UI: "yes"
- bunkerweb.io/www.example.com_REVERSE_PROXY_HEADERS_1: "X-Script-Name /changeme"
bunkerweb.io/www.example.com_INTERCEPTED_ERROR_CODES: "400 404 405 413 429 500 501 502 503 504"
spec:
rules:
- host: www.example.com
http:
paths:
- - path: /changeme/
+ - path: /changeme
pathType: Prefix
backend:
service:
diff --git a/misc/integrations/k8s.mysql.yml b/misc/integrations/k8s.mysql.yml
index 9d77a08b1..59f0cc95f 100644
--- a/misc/integrations/k8s.mysql.yml
+++ b/misc/integrations/k8s.mysql.yml
@@ -48,7 +48,7 @@ spec:
containers:
# using bunkerweb as name is mandatory
- name: bunkerweb
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
imagePullPolicy: Always
securityContext:
runAsUser: 101
@@ -118,7 +118,7 @@ spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-controller
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
@@ -144,7 +144,7 @@ spec:
spec:
containers:
- name: bunkerweb-controller
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
diff --git a/misc/integrations/k8s.postgres.ui.yml b/misc/integrations/k8s.postgres.ui.yml
index 135d7e239..d3c73b71e 100644
--- a/misc/integrations/k8s.postgres.ui.yml
+++ b/misc/integrations/k8s.postgres.ui.yml
@@ -48,7 +48,7 @@ spec:
containers:
# using bunkerweb as name is mandatory
- name: bunkerweb
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
imagePullPolicy: Always
securityContext:
runAsUser: 101
@@ -118,7 +118,7 @@ spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-controller
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
@@ -145,7 +145,7 @@ spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-scheduler
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
@@ -230,15 +230,13 @@ spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-ui
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
imagePullPolicy: Always
env:
- name: ADMIN_USERNAME
value: "changeme"
- name: "ADMIN_PASSWORD"
value: "changeme"
- - name: "ABSOLUTE_URI"
- value: "http://www.example.com/changeme/"
- name: KUBERNETES_MODE
value: "YES"
- name: "DATABASE_URI"
@@ -312,14 +310,13 @@ metadata:
name: ingress
annotations:
bunkerweb.io/www.example.com_USE_UI: "yes"
- bunkerweb.io/www.example.com_REVERSE_PROXY_HEADERS_1: "X-Script-Name /changeme"
bunkerweb.io/www.example.com_INTERCEPTED_ERROR_CODES: "400 404 405 413 429 500 501 502 503 504"
spec:
rules:
- host: www.example.com
http:
paths:
- - path: /changeme/
+ - path: /changeme
pathType: Prefix
backend:
service:
diff --git a/misc/integrations/k8s.postgres.yml b/misc/integrations/k8s.postgres.yml
index ca75e2ea7..071b0893f 100644
--- a/misc/integrations/k8s.postgres.yml
+++ b/misc/integrations/k8s.postgres.yml
@@ -48,7 +48,7 @@ spec:
containers:
# using bunkerweb as name is mandatory
- name: bunkerweb
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
imagePullPolicy: Always
securityContext:
runAsUser: 101
@@ -118,7 +118,7 @@ spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-controller
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
@@ -144,7 +144,7 @@ spec:
spec:
containers:
- name: bunkerweb-controller
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
diff --git a/misc/integrations/swarm.mariadb.ui.yml b/misc/integrations/swarm.mariadb.ui.yml
index 57c48666b..ca8668487 100644
--- a/misc/integrations/swarm.mariadb.ui.yml
+++ b/misc/integrations/swarm.mariadb.ui.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- published: 80
target: 8080
@@ -32,7 +32,7 @@ services:
- "bunkerweb.INSTANCE"
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
@@ -42,7 +42,7 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
@@ -51,6 +51,7 @@ services:
- SERVICES=1
- SWARM=1
- TASKS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
deploy:
@@ -59,7 +60,7 @@ services:
- "node.role == manager"
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
@@ -86,13 +87,12 @@ services:
- bw-universe
bw-ui:
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
environment:
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db # Remember to set a stronger password for the database
- DOCKER_HOST=tcp://bw-docker:2375
- ADMIN_USERNAME=changeme
- ADMIN_PASSWORD=changeme # Remember to set a stronger password for the changeme user
- - ABSOLUTE_URI=http://www.example.com/changeme/
networks:
- bw-universe
- bw-docker
@@ -101,9 +101,8 @@ services:
- "bunkerweb.SERVER_NAME=www.example.com"
- "bunkerweb.USE_UI=yes"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- - "bunkerweb.REVERSE_PROXY_URL=/changeme/"
+ - "bunkerweb.REVERSE_PROXY_URL=/changeme"
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
- - "bunkerweb.REVERSE_PROXY_HEADERS=X-Script-Name /changeme"
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
volumes:
diff --git a/misc/integrations/swarm.mariadb.yml b/misc/integrations/swarm.mariadb.yml
index e95af2ef6..a7270c06e 100644
--- a/misc/integrations/swarm.mariadb.yml
+++ b/misc/integrations/swarm.mariadb.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- published: 80
target: 8080
@@ -32,7 +32,7 @@ services:
- "bunkerweb.INSTANCE"
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
@@ -46,7 +46,7 @@ services:
- "node.role == worker"
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
@@ -55,6 +55,7 @@ services:
- SERVICES=1
- SWARM=1
- TASKS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
deploy:
@@ -63,7 +64,7 @@ services:
- "node.role == manager"
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
diff --git a/misc/integrations/swarm.mysql.ui.yml b/misc/integrations/swarm.mysql.ui.yml
index b3401a304..e6f470c77 100644
--- a/misc/integrations/swarm.mysql.ui.yml
+++ b/misc/integrations/swarm.mysql.ui.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- published: 80
target: 8080
@@ -32,7 +32,7 @@ services:
- "bunkerweb.INSTANCE"
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
@@ -42,7 +42,7 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
@@ -51,6 +51,7 @@ services:
- SERVICES=1
- SWARM=1
- TASKS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
deploy:
@@ -59,7 +60,7 @@ services:
- "node.role == manager"
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
@@ -86,13 +87,12 @@ services:
- bw-universe
bw-ui:
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
environment:
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db # Remember to set a stronger password for the database
- DOCKER_HOST=tcp://bw-docker:2375
- ADMIN_USERNAME=changeme
- ADMIN_PASSWORD=changeme # Remember to set a stronger password for the changeme user
- - ABSOLUTE_URI=http://www.example.com/changeme/
networks:
- bw-universe
- bw-docker
@@ -101,9 +101,8 @@ services:
- "bunkerweb.SERVER_NAME=www.example.com"
- "bunkerweb.USE_UI=yes"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- - "bunkerweb.REVERSE_PROXY_URL=/changeme/"
+ - "bunkerweb.REVERSE_PROXY_URL=/changeme"
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
- - "bunkerweb.REVERSE_PROXY_HEADERS=X-Script-Name /changeme"
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
volumes:
diff --git a/misc/integrations/swarm.mysql.yml b/misc/integrations/swarm.mysql.yml
index e46142a7c..302323e0e 100644
--- a/misc/integrations/swarm.mysql.yml
+++ b/misc/integrations/swarm.mysql.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- published: 80
target: 8080
@@ -32,7 +32,7 @@ services:
- "bunkerweb.INSTANCE"
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
@@ -42,7 +42,7 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
@@ -51,6 +51,7 @@ services:
- SERVICES=1
- SWARM=1
- TASKS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
deploy:
@@ -59,7 +60,7 @@ services:
- "node.role == manager"
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
diff --git a/misc/integrations/swarm.postgres.ui.yml b/misc/integrations/swarm.postgres.ui.yml
index 9f9513809..e3cc2a070 100644
--- a/misc/integrations/swarm.postgres.ui.yml
+++ b/misc/integrations/swarm.postgres.ui.yml
@@ -1,8 +1,8 @@
-version: "3.5"
+ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- published: 80
target: 8080
@@ -32,7 +32,7 @@ services:
- "bunkerweb.INSTANCE"
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
@@ -42,7 +42,7 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
@@ -51,6 +51,7 @@ services:
- SERVICES=1
- SWARM=1
- TASKS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
deploy:
@@ -59,7 +60,7 @@ services:
- "node.role == manager"
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
@@ -85,13 +86,12 @@ services:
- bw-universe
bw-ui:
- image: bunkerity/bunkerweb-ui:1.5.0
+ image: bunkerity/bunkerweb-ui:1.5.1
environment:
- DATABASE_URI=postgresql://bunkerweb:changeme@bw-db:5432/db
- DOCKER_HOST=tcp://bw-docker:2375
- ADMIN_USERNAME=changeme
- ADMIN_PASSWORD=changeme
- - ABSOLUTE_URI=http://www.example.com/changeme/
networks:
- bw-universe
- bw-docker
@@ -100,9 +100,8 @@ services:
- "bunkerweb.SERVER_NAME=www.example.com"
- "bunkerweb.USE_UI=yes"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- - "bunkerweb.REVERSE_PROXY_URL=/changeme/"
+ - "bunkerweb.REVERSE_PROXY_URL=/changeme"
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
- - "bunkerweb.REVERSE_PROXY_HEADERS=X-Script-Name /changeme"
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
volumes:
diff --git a/misc/integrations/swarm.postgres.yml b/misc/integrations/swarm.postgres.yml
index 908308bc7..bcc57609d 100644
--- a/misc/integrations/swarm.postgres.yml
+++ b/misc/integrations/swarm.postgres.yml
@@ -2,7 +2,7 @@ version: "3.5"
services:
bunkerweb:
- image: bunkerity/bunkerweb:1.5.0
+ image: bunkerity/bunkerweb:1.5.1
ports:
- published: 80
target: 8080
@@ -32,7 +32,7 @@ services:
- "bunkerweb.INSTANCE"
bw-autoconf:
- image: bunkerity/bunkerweb-autoconf:1.5.0
+ image: bunkerity/bunkerweb-autoconf:1.5.1
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
@@ -42,7 +42,7 @@ services:
- bw-docker
bw-docker:
- image: tecnativa/docker-socket-proxy
+ image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
@@ -51,6 +51,7 @@ services:
- SERVICES=1
- SWARM=1
- TASKS=1
+ - LOG_LEVEL=warning
networks:
- bw-docker
deploy:
@@ -59,7 +60,7 @@ services:
- "node.role == manager"
bw-scheduler:
- image: bunkerity/bunkerweb-scheduler:1.5.0
+ image: bunkerity/bunkerweb-scheduler:1.5.1
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
diff --git a/misc/update-version.sh b/misc/update-version.sh
index a5ffab00b..e227d865b 100755
--- a/misc/update-version.sh
+++ b/misc/update-version.sh
@@ -24,4 +24,8 @@ sed -i "s@${OLD_VERSION}@${NEW_VERSION}@g" README.md
sed -i "s@${OLD_VERSION}@${NEW_VERSION}@g" tests/ui/docker-compose.yml
for test in tests/core/* ; do
sed -i "s@${OLD_VERSION}@${NEW_VERSION}@g" ${test}/docker-compose.yml
-done
\ No newline at end of file
+done
+# 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/model.py
diff --git a/mkdocs.yml b/mkdocs.yml
index 534172471..cdd05b98b 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -68,4 +68,6 @@ extra:
plugins:
- search
- - print-site
\ No newline at end of file
+ - print-site
+ - mike:
+ canonical_version: latest
\ No newline at end of file
diff --git a/src/VERSION b/src/VERSION
index 3e1ad720b..8e03717dc 100644
--- a/src/VERSION
+++ b/src/VERSION
@@ -1 +1 @@
-1.5.0
\ No newline at end of file
+1.5.1
\ No newline at end of file
diff --git a/src/autoconf/Config.py b/src/autoconf/Config.py
index f0b6ff2b2..3726540d2 100644
--- a/src/autoconf/Config.py
+++ b/src/autoconf/Config.py
@@ -1,16 +1,17 @@
+#!/usr/bin/python3
+
from os import getenv
from time import sleep
+from typing import Optional
-from ConfigCaller import ConfigCaller
-from Database import Database
-from logger import setup_logger
+from ConfigCaller import ConfigCaller # type: ignore
+from Database import Database # type: ignore
+from logger import setup_logger # type: ignore
class Config(ConfigCaller):
- def __init__(self, ctrl_type, lock=None):
+ def __init__(self):
super().__init__()
- self.__ctrl_type = ctrl_type
- self.__lock = lock
self.__logger = setup_logger("Config", getenv("LOG_LEVEL", "INFO"))
self.__instances = []
self.__services = []
diff --git a/src/autoconf/Controller.py b/src/autoconf/Controller.py
index 44c3208f7..26d901f41 100644
--- a/src/autoconf/Controller.py
+++ b/src/autoconf/Controller.py
@@ -1,14 +1,21 @@
+#!/usr/bin/python3
+
from abc import ABC, abstractmethod
from os import getenv
from time import sleep
+from typing import Literal, Optional, Union
from Config import Config
-from logger import setup_logger
+from logger import setup_logger # type: ignore
-class Controller(ABC):
- def __init__(self, ctrl_type, lock=None):
+class Controller(Config):
+ def __init__(
+ self,
+ ctrl_type: Union[Literal["docker"], Literal["swarm"], Literal["kubernetes"]],
+ ):
+ super().__init__()
self._type = ctrl_type
self._instances = []
self._services = []
@@ -24,15 +31,16 @@ class Controller(ABC):
self._configs = {
config_type: {} for config_type in self._supported_config_types
}
- self._config = Config(ctrl_type, lock)
- self.__logger = setup_logger("Controller", getenv("LOG_LEVEL", "INFO"))
+ self._logger = setup_logger(
+ f"{self._type}-controller", getenv("LOG_LEVEL", "INFO")
+ )
- def wait(self, wait_time):
+ def wait(self, wait_time: int) -> list:
all_ready = False
while not all_ready:
self._instances = self.get_instances()
if not self._instances:
- self.__logger.warning(
+ self._logger.warning(
f"No instance found, waiting {wait_time}s ...",
)
sleep(wait_time)
@@ -40,7 +48,7 @@ class Controller(ABC):
all_ready = True
for instance in self._instances:
if not instance["health"]:
- self.__logger.warning(
+ self._logger.warning(
f"Instance {instance['name']} is not ready, waiting {wait_time}s ...",
)
sleep(wait_time)
@@ -59,8 +67,7 @@ class Controller(ABC):
def get_instances(self):
instances = []
for controller_instance in self._get_controller_instances():
- for instance in self._to_instances(controller_instance):
- instances.append(instance)
+ instances.extend(self._to_instances(controller_instance))
return instances
@abstractmethod
@@ -76,20 +83,18 @@ class Controller(ABC):
pass
def _set_autoconf_load_db(self):
- if not self._config._db.is_autoconf_loaded():
- ret = self._config._db.set_autoconf_load(True)
+ if not self._db.is_autoconf_loaded():
+ ret = self._db.set_autoconf_load(True)
if ret:
- self.__logger.warning(
+ self._logger.warning(
f"Can't set autoconf loaded metadata to true in database: {ret}",
)
def get_services(self):
services = []
for controller_service in self._get_controller_services():
- for service in self._to_services(controller_service):
- services.append(service)
- for static_service in self._get_static_services():
- services.append(static_service)
+ services.extend(self._to_services(controller_service))
+ services.extend(self._get_static_services())
return services
@abstractmethod
@@ -106,8 +111,8 @@ class Controller(ABC):
def _is_service_present(self, server_name):
for service in self._services:
- if not "SERVER_NAME" in service or service["SERVER_NAME"] == "":
+ if not "SERVER_NAME" in service or not service["SERVER_NAME"]:
continue
- if server_name == service["SERVER_NAME"].split(" ")[0]:
+ if server_name == service["SERVER_NAME"].strip().split(" ")[0]:
return True
return False
diff --git a/src/autoconf/DockerController.py b/src/autoconf/DockerController.py
index 21a840b8c..994fdaa49 100644
--- a/src/autoconf/DockerController.py
+++ b/src/autoconf/DockerController.py
@@ -1,30 +1,29 @@
-from os import getenv
+#!/usr/bin/python3
+
+from typing import Any, Dict, List
from docker import DockerClient
from re import compile as re_compile
from traceback import format_exc
+from docker.models.containers import Container
from Controller import Controller
-from ConfigCaller import ConfigCaller
-from logger import setup_logger
-class DockerController(Controller, ConfigCaller):
+class DockerController(Controller):
def __init__(self, docker_host):
- Controller.__init__(self, "docker")
- ConfigCaller.__init__(self)
+ super().__init__("docker")
self.__client = DockerClient(base_url=docker_host)
- self.__logger = setup_logger("docker-controller", getenv("LOG_LEVEL", "INFO"))
self.__custom_confs_rx = re_compile(
r"^bunkerweb.CUSTOM_CONF_(SERVER_HTTP|MODSEC_CRS|MODSEC)_(.+)$"
)
- def _get_controller_instances(self):
+ def _get_controller_instances(self) -> List[Container]:
return self.__client.containers.list(filters={"label": "bunkerweb.INSTANCE"})
- def _get_controller_services(self):
+ def _get_controller_services(self) -> List[Container]:
return self.__client.containers.list(filters={"label": "bunkerweb.SERVER_NAME"})
- def _to_instances(self, controller_instance):
+ def _to_instances(self, controller_instance) -> List[dict]:
instance = {}
instance["name"] = controller_instance.name
instance["hostname"] = controller_instance.name
@@ -40,18 +39,18 @@ class DockerController(Controller, ConfigCaller):
instance["env"][variable] = value
return [instance]
- def _to_services(self, controller_service):
+ def _to_services(self, controller_service) -> List[dict]:
service = {}
for variable, value in controller_service.labels.items():
if not variable.startswith("bunkerweb."):
continue
real_variable = variable.replace("bunkerweb.", "", 1)
- if not self._is_multisite_setting(real_variable):
+ if not self._is_setting_context(real_variable, "multisite"):
continue
service[real_variable] = value
return [service]
- def _get_static_services(self):
+ def _get_static_services(self) -> List[dict]:
services = []
variables = {}
for instance in self.__client.containers.list(
@@ -71,14 +70,14 @@ class DockerController(Controller, ConfigCaller):
for variable, value in variables.items():
prefix = variable.split("_")[0]
real_variable = variable.replace(f"{prefix}_", "", 1)
- if prefix == server_name and self._is_multisite_setting(
- real_variable
+ if prefix == server_name and self._is_setting_context(
+ real_variable, "multisite"
):
service[real_variable] = value
services.append(service)
return services
- def get_configs(self):
+ def get_configs(self) -> Dict[str, Dict[str, Any]]:
configs = {config_type: {} for config_type in self._supported_config_types}
# get site configs from labels
for container in self.__client.containers.list(
@@ -106,10 +105,8 @@ class DockerController(Controller, ConfigCaller):
] = value
return configs
- def apply_config(self):
- return self._config.apply(
- self._instances, self._services, configs=self._configs
- )
+ def apply_config(self) -> bool:
+ return self.apply(self._instances, self._services, configs=self._configs)
def process_events(self):
self._set_autoconf_load_db()
@@ -118,27 +115,22 @@ class DockerController(Controller, ConfigCaller):
self._instances = self.get_instances()
self._services = self.get_services()
self._configs = self.get_configs()
- if not self._config.update_needed(
+ if not self.update_needed(
self._instances, self._services, configs=self._configs
):
continue
- self.__logger.info(
+ self._logger.info(
"Caught Docker event, deploying new configuration ..."
)
if not self.apply_config():
- self.__logger.error("Error while deploying new configuration")
+ self._logger.error("Error while deploying new configuration")
else:
- self.__logger.info(
+ self._logger.info(
"Successfully deployed new configuration đ",
)
- if not self._config._db.is_autoconf_loaded():
- ret = self._config._db.set_autoconf_load(True)
- if ret:
- self.__logger.warning(
- f"Can't set autoconf loaded metadata to true in database: {ret}",
- )
+ self._set_autoconf_load_db()
except:
- self.__logger.error(
+ self._logger.error(
f"Exception while processing events :\n{format_exc()}"
)
diff --git a/src/autoconf/Dockerfile b/src/autoconf/Dockerfile
index 00ad53a4e..eff6f29aa 100644
--- a/src/autoconf/Dockerfile
+++ b/src/autoconf/Dockerfile
@@ -1,4 +1,4 @@
-FROM python:3.11.3-alpine AS builder
+FROM python:3.11.4-alpine AS builder
# Copy python requirements
COPY src/common/gen/requirements.txt /tmp/req/requirements.txt
@@ -14,12 +14,13 @@ RUN apk add --no-cache --virtual .build-deps g++ gcc musl-dev jpeg-dev zlib-dev
# Install python requirements
RUN export MAKEFLAGS="-j$(nproc)" && \
pip install --no-cache-dir --upgrade pip && \
- pip install --no-cache-dir --upgrade wheel && \
+ pip install --no-cache-dir --upgrade pip-tools wheel setuptools && \
mkdir -p /usr/share/bunkerweb/deps/python && \
pip install --no-cache-dir --require-hashes --target /usr/share/bunkerweb/deps/python -r /usr/share/bunkerweb/deps/requirements.txt
# Remove build dependencies
-RUN apk del .build-deps
+RUN apk del .build-deps && \
+ rm -rf /var/cache/apk/*
# Copy files
# can't exclude specific files/dir from . so we are copying everything by hand
@@ -32,7 +33,7 @@ COPY src/common/helpers /usr/share/bunkerweb/helpers
COPY src/common/settings.json /usr/share/bunkerweb/settings.json
COPY src/common/utils /usr/share/bunkerweb/utils
-FROM python:3.11.3-alpine
+FROM python:3.11.4-alpine
# Set default umask to prevent huge recursive chmod increasing the final image size
RUN umask 027
@@ -60,7 +61,7 @@ RUN apk add --no-cache bash && \
chmod 750 /usr/share/bunkerweb/cli/main.py /usr/share/bunkerweb/helpers/*.sh /usr/bin/bwcli /usr/share/bunkerweb/autoconf/main.py /usr/share/bunkerweb/deps/python/bin/*
# Fix CVEs
-RUN apk add "libcrypto3>=3.0.8-r4" "libssl3>=3.0.8-r4"
+RUN apk add "libcrypto3>=3.1.1-r2" "libssl3>=3.1.1-r2"
VOLUME /data /etc/nginx
diff --git a/src/autoconf/IngressController.py b/src/autoconf/IngressController.py
index 4856b8fd2..ad7b71542 100644
--- a/src/autoconf/IngressController.py
+++ b/src/autoconf/IngressController.py
@@ -1,26 +1,24 @@
-from os import getenv
+#!/usr/bin/python3
+
from time import sleep
from traceback import format_exc
+from typing import List
from kubernetes import client, config, watch
from kubernetes.client.exceptions import ApiException
from threading import Thread, Lock
from Controller import Controller
-from ConfigCaller import ConfigCaller
-from logger import setup_logger
-class IngressController(Controller, ConfigCaller):
+class IngressController(Controller):
def __init__(self):
- Controller.__init__(self, "kubernetes")
- ConfigCaller.__init__(self)
+ self.__internal_lock = Lock()
+ super().__init__("kubernetes")
config.load_incluster_config()
self.__corev1 = client.CoreV1Api()
self.__networkingv1 = client.NetworkingV1Api()
- self.__internal_lock = Lock()
- self.__logger = setup_logger("Ingress-controller", getenv("LOG_LEVEL", "INFO"))
- def _get_controller_instances(self):
+ def _get_controller_instances(self) -> list:
return [
pod
for pod in self.__corev1.list_pod_for_all_namespaces(watch=False).items
@@ -30,10 +28,12 @@ class IngressController(Controller, ConfigCaller):
)
]
- def _to_instances(self, controller_instance):
+ def _to_instances(self, controller_instance) -> List[dict]:
instance = {}
instance["name"] = controller_instance.metadata.name
- instance["hostname"] = controller_instance.status.pod_ip
+ instance["hostname"] = (
+ controller_instance.status.pod_ip or controller_instance.metadata.name
+ )
health = False
if controller_instance.status.conditions:
for condition in controller_instance.status.conditions:
@@ -48,7 +48,9 @@ class IngressController(Controller, ConfigCaller):
pod = container
break
if not pod:
- self.__logger.warning(f"Missing container bunkerweb in pod {controller_instance.metadata.name}")
+ self._logger.warning(
+ f"Missing container bunkerweb in pod {controller_instance.metadata.name}"
+ )
else:
for env in pod.env:
instance["env"][env.name] = env.value or ""
@@ -65,18 +67,18 @@ class IngressController(Controller, ConfigCaller):
instance["env"][variable] = value
return [instance]
- def _get_controller_services(self):
+ def _get_controller_services(self) -> list:
return self.__networkingv1.list_ingress_for_all_namespaces(watch=False).items
- def _to_services(self, controller_service):
+ def _to_services(self, controller_service) -> List[dict]:
if not controller_service.spec or not controller_service.spec.rules:
return []
-
+ namespace = controller_service.metadata.namespace
services = []
# parse rules
for rule in controller_service.spec.rules:
if not rule.host:
- self.__logger.warning(
+ self._logger.warning(
"Ignoring unsupported ingress rule without host.",
)
continue
@@ -88,38 +90,38 @@ class IngressController(Controller, ConfigCaller):
location = 1
for path in rule.http.paths:
if not path.path:
- self.__logger.warning(
+ self._logger.warning(
"Ignoring unsupported ingress rule without path.",
)
continue
elif not path.backend.service:
- self.__logger.warning(
+ self._logger.warning(
"Ignoring unsupported ingress rule without backend service.",
)
continue
elif not path.backend.service.port:
- self.__logger.warning(
+ self._logger.warning(
"Ignoring unsupported ingress rule without backend service port.",
)
continue
elif not path.backend.service.port.number:
- self.__logger.warning(
+ self._logger.warning(
"Ignoring unsupported ingress rule without backend service port number.",
)
continue
service_list = self.__corev1.list_service_for_all_namespaces(
watch=False,
- field_selector=f"metadata.name={path.backend.service.name}",
+ field_selector=f"metadata.name={path.backend.service.name},metadata.namespace={namespace}",
).items
if not service_list:
- self.__logger.warning(
+ self._logger.warning(
f"Ignoring ingress rule with service {path.backend.service.name} : service not found.",
)
continue
- reverse_proxy_host = f"http://{path.backend.service.name}.{service_list[0].metadata.namespace}.svc.cluster.local:{path.backend.service.port.number}"
+ reverse_proxy_host = f"http://{path.backend.service.name}.{namespace}.svc.cluster.local:{path.backend.service.port.number}"
service.update(
{
"USE_REVERSE_PROXY": "yes",
@@ -132,7 +134,7 @@ class IngressController(Controller, ConfigCaller):
# parse tls
if controller_service.spec.tls: # TODO: support tls
- self.__logger.warning("Ignoring unsupported tls.")
+ self._logger.warning("Ignoring unsupported tls.")
# parse annotations
if controller_service.metadata.annotations:
@@ -145,15 +147,15 @@ class IngressController(Controller, ConfigCaller):
continue
variable = annotation.replace("bunkerweb.io/", "", 1)
- server_name = service["SERVER_NAME"].split(" ")[0]
+ server_name = service["SERVER_NAME"].strip().split(" ")[0]
if not variable.startswith(f"{server_name}_"):
continue
variable = variable.replace(f"{server_name}_", "", 1)
- if self._is_multisite_setting(variable):
+ if self._is_setting_context(variable, "multisite"):
service[variable] = value
return services
- def _get_static_services(self):
+ def _get_static_services(self) -> List[dict]:
services = []
variables = {}
for instance in self.__corev1.list_pod_for_all_namespaces(watch=False).items:
@@ -168,12 +170,10 @@ class IngressController(Controller, ConfigCaller):
if container.name == "bunkerweb":
pod = container
break
- if not pod :
+ if not pod:
continue
- variables = {
- env.name: env.value or "" for env in pod.env
- }
+ variables = {env.name: env.value or "" for env in pod.env}
if "SERVER_NAME" in variables and variables["SERVER_NAME"].strip():
for server_name in variables["SERVER_NAME"].strip().split(" "):
@@ -181,14 +181,14 @@ class IngressController(Controller, ConfigCaller):
for variable, value in variables.items():
prefix = variable.split("_")[0]
real_variable = variable.replace(f"{prefix}_", "", 1)
- if prefix == server_name and self._is_multisite_setting(
- real_variable
+ if prefix == server_name and self._is_setting_context(
+ real_variable, "multisite"
):
service[real_variable] = value
services.append(service)
return services
- def get_configs(self):
+ def get_configs(self) -> dict:
configs = {config_type: {} for config_type in self._supported_config_types}
for configmap in self.__corev1.list_config_map_for_all_namespaces(
watch=False
@@ -201,12 +201,12 @@ class IngressController(Controller, ConfigCaller):
config_type = configmap.metadata.annotations["bunkerweb.io/CONFIG_TYPE"]
if config_type not in self._supported_config_types:
- self.__logger.warning(
+ self._logger.warning(
f"Ignoring unsupported CONFIG_TYPE {config_type} for ConfigMap {configmap.metadata.name}",
)
continue
elif not configmap.data:
- self.__logger.warning(
+ self._logger.warning(
f"Ignoring blank ConfigMap {configmap.metadata.name}",
)
continue
@@ -215,7 +215,7 @@ class IngressController(Controller, ConfigCaller):
if not self._is_service_present(
configmap.metadata.annotations["bunkerweb.io/CONFIG_SITE"]
):
- self.__logger.warning(
+ self._logger.warning(
f"Ignoring config {configmap.metadata.name} because {configmap.metadata.annotations['bunkerweb.io/CONFIG_SITE']} doesn't exist",
)
continue
@@ -250,46 +250,41 @@ class IngressController(Controller, ConfigCaller):
self._instances = self.get_instances()
self._services = self.get_services()
self._configs = self.get_configs()
- if not self._config.update_needed(
+ if not self.update_needed(
self._instances, self._services, configs=self._configs
):
self.__internal_lock.release()
locked = False
continue
- self.__logger.info(
+ self._logger.info(
f"Catched kubernetes event ({watch_type}), deploying new configuration ...",
)
try:
ret = self.apply_config()
if not ret:
- self.__logger.error(
+ self._logger.error(
"Error while deploying new configuration ...",
)
else:
- self.__logger.info(
+ self._logger.info(
"Successfully deployed new configuration đ",
)
- if not self._config._db.is_autoconf_loaded():
- ret = self._config._db.set_autoconf_load(True)
- if ret:
- self.__logger.warning(
- f"Can't set autoconf loaded metadata to true in database: {ret}",
- )
+ self._set_autoconf_load_db()
except:
- self.__logger.error(
+ self._logger.error(
f"Exception while deploying new configuration :\n{format_exc()}",
)
self.__internal_lock.release()
locked = False
except ApiException as e:
if e.status != 410:
- self.__logger.error(
+ self._logger.error(
f"API exception while reading k8s event (type = {watch_type}) :\n{format_exc()}",
)
error = True
except:
- self.__logger.error(
+ self._logger.error(
f"Unknown exception while reading k8s event (type = {watch_type}) :\n{format_exc()}",
)
error = True
@@ -299,13 +294,11 @@ class IngressController(Controller, ConfigCaller):
locked = False
if error is True:
- self.__logger.warning("Got exception, retrying in 10 seconds ...")
+ self._logger.warning("Got exception, retrying in 10 seconds ...")
sleep(10)
- def apply_config(self):
- return self._config.apply(
- self._instances, self._services, configs=self._configs
- )
+ def apply_config(self) -> bool:
+ return self.apply(self._instances, self._services, configs=self._configs)
def process_events(self):
self._set_autoconf_load_db()
diff --git a/src/autoconf/SwarmController.py b/src/autoconf/SwarmController.py
index f6095ef7a..d7cf99fcc 100644
--- a/src/autoconf/SwarmController.py
+++ b/src/autoconf/SwarmController.py
@@ -1,30 +1,29 @@
-from os import getenv
+#!/usr/bin/python3
+
from time import sleep
from traceback import format_exc
from threading import Thread, Lock
+from typing import Any, Dict, List
from docker import DockerClient
from base64 import b64decode
+from docker.models.services import Service
from Controller import Controller
-from ConfigCaller import ConfigCaller
-from logger import setup_logger
-class SwarmController(Controller, ConfigCaller):
+class SwarmController(Controller):
def __init__(self, docker_host):
- Controller.__init__(self, "swarm")
- ConfigCaller.__init__(self)
+ super().__init__("swarm")
self.__client = DockerClient(base_url=docker_host)
self.__internal_lock = Lock()
- self.__logger = setup_logger("Swarm-controller", getenv("LOG_LEVEL", "INFO"))
- def _get_controller_instances(self):
+ def _get_controller_instances(self) -> List[Service]:
return self.__client.services.list(filters={"label": "bunkerweb.INSTANCE"})
- def _get_controller_services(self):
+ def _get_controller_services(self) -> List[Service]:
return self.__client.services.list(filters={"label": "bunkerweb.SERVER_NAME"})
- def _to_instances(self, controller_instance):
+ def _to_instances(self, controller_instance) -> List[dict]:
instances = []
instance_env = {}
for env in controller_instance.attrs["Spec"]["TaskTemplate"]["ContainerSpec"][
@@ -48,18 +47,18 @@ class SwarmController(Controller, ConfigCaller):
)
return instances
- def _to_services(self, controller_service):
+ def _to_services(self, controller_service) -> List[dict]:
service = {}
for variable, value in controller_service.attrs["Spec"]["Labels"].items():
if not variable.startswith("bunkerweb."):
continue
real_variable = variable.replace("bunkerweb.", "", 1)
- if not self._is_multisite_setting(real_variable):
+ if not self._is_setting_context(real_variable, "multisite"):
continue
service[real_variable] = value
return [service]
- def _get_static_services(self):
+ def _get_static_services(self) -> List[dict]:
services = []
variables = {}
for instance in self.__client.services.list(
@@ -81,14 +80,14 @@ class SwarmController(Controller, ConfigCaller):
for variable, value in variables.items():
prefix = variable.split("_")[0]
real_variable = variable.replace(f"{prefix}_", "", 1)
- if prefix == server_name and self._is_multisite_setting(
- real_variable
+ if prefix == server_name and self._is_setting_context(
+ real_variable, "multisite"
):
service[real_variable] = value
services.append(service)
return services
- def get_configs(self):
+ def get_configs(self) -> Dict[str, Dict[str, Any]]:
configs = {}
for config_type in self._supported_config_types:
configs[config_type] = {}
@@ -106,7 +105,7 @@ class SwarmController(Controller, ConfigCaller):
config_type = config.attrs["Spec"]["Labels"]["bunkerweb.CONFIG_TYPE"]
config_name = config.name
if config_type not in self._supported_config_types:
- self.__logger.warning(
+ self._logger.warning(
f"Ignoring unsupported CONFIG_TYPE {config_type} for Config {config_name}",
)
continue
@@ -115,7 +114,7 @@ class SwarmController(Controller, ConfigCaller):
if not self._is_service_present(
config.attrs["Spec"]["Labels"]["bunkerweb.CONFIG_SITE"]
):
- self.__logger.warning(
+ self._logger.warning(
f"Ignoring config {config_name} because {config.attrs['Spec']['Labels']['bunkerweb.CONFIG_SITE']} doesn't exist",
)
continue
@@ -127,10 +126,8 @@ class SwarmController(Controller, ConfigCaller):
)
return configs
- def apply_config(self):
- return self._config.apply(
- self._instances, self._services, configs=self._configs
- )
+ def apply_config(self) -> bool:
+ return self.apply(self._instances, self._services, configs=self._configs)
def __event(self, event_type):
while True:
@@ -146,31 +143,31 @@ class SwarmController(Controller, ConfigCaller):
self._instances = self.get_instances()
self._services = self.get_services()
self._configs = self.get_configs()
- if not self._config.update_needed(
+ if not self.update_needed(
self._instances, self._services, configs=self._configs
):
self.__internal_lock.release()
locked = False
continue
- self.__logger.info(
+ self._logger.info(
f"Catched Swarm event ({event_type}), deploying new configuration ..."
)
if not self.apply_config():
- self.__logger.error(
+ self._logger.error(
"Error while deploying new configuration"
)
else:
- self.__logger.info(
+ self._logger.info(
"Successfully deployed new configuration đ",
)
except:
- self.__logger.error(
+ self._logger.error(
f"Exception while processing Swarm event ({event_type}) :\n{format_exc()}"
)
self.__internal_lock.release()
locked = False
except:
- self.__logger.error(
+ self._logger.error(
f"Exception while reading Swarm event ({event_type}) :\n{format_exc()}",
)
error = True
@@ -179,7 +176,7 @@ class SwarmController(Controller, ConfigCaller):
self.__internal_lock.release()
locked = False
if error is True:
- self.__logger.warning("Got exception, retrying in 10 seconds ...")
+ self._logger.warning("Got exception, retrying in 10 seconds ...")
sleep(10)
def process_events(self):
diff --git a/src/autoconf/main.py b/src/autoconf/main.py
index c9753c59a..7a69468d3 100644
--- a/src/autoconf/main.py
+++ b/src/autoconf/main.py
@@ -1,21 +1,20 @@
#!/usr/bin/python3
-from os import _exit, getenv
+from os import _exit, getenv, sep
+from os.path import join
from signal import SIGINT, SIGTERM, signal
from sys import exit as sys_exit, path as sys_path
from traceback import format_exc
from pathlib import Path
-sys_path.extend(
- (
- "/usr/share/bunkerweb/deps/python",
- "/usr/share/bunkerweb/utils",
- "/usr/share/bunkerweb/api",
- "/usr/share/bunkerweb/db",
- )
-)
+for deps_path in [
+ join(sep, "usr", "share", "bunkerweb", *paths)
+ for paths in (("deps", "python"), ("utils",), ("api",), ("db",))
+]:
+ if deps_path not in sys_path:
+ sys_path.append(deps_path)
-from logger import setup_logger
+from logger import setup_logger # type: ignore
from SwarmController import SwarmController
from IngressController import IngressController
from DockerController import DockerController
@@ -70,12 +69,11 @@ try:
_exit(1)
# Process events
- Path("/var/tmp/bunkerweb/autoconf.healthy").write_text("ok")
+ Path(sep, "var", "tmp", "bunkerweb", "autoconf.healthy").write_text("ok")
logger.info("Processing events ...")
controller.process_events()
-
except:
logger.error(f"Exception while running autoconf :\n{format_exc()}")
sys_exit(1)
finally:
- Path("/var/tmp/bunkerweb/autoconf.healthy").unlink(missing_ok=True)
+ Path(sep, "var", "tmp", "bunkerweb", "autoconf.healthy").unlink(missing_ok=True)
diff --git a/src/bw/Dockerfile b/src/bw/Dockerfile
index a634081ad..e1e917612 100644
--- a/src/bw/Dockerfile
+++ b/src/bw/Dockerfile
@@ -1,26 +1,32 @@
FROM nginx:1.24.0-alpine AS builder
+# Install temporary requirements for the 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
+
# Copy dependencies sources folder
COPY src/deps /tmp/bunkerweb/deps
# 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 && \
+RUN mkdir -p /usr/share/bunkerweb/deps && \
chmod +x /tmp/bunkerweb/deps/install.sh && \
- bash /tmp/bunkerweb/deps/install.sh && \
- apk del .build-deps
+ bash /tmp/bunkerweb/deps/install.sh
+
+# Clean up temporary dependencies
+RUN apk del .build-deps && \
+ rm -rf /var/cache/apk/*
# Copy python requirements
COPY src/common/gen/requirements.txt /usr/share/bunkerweb/deps/requirements.txt
# Install python requirements
RUN apk add --no-cache --virtual .build-deps py3-pip && \
- pip install --no-cache-dir --upgrade pip && \
- pip install wheel && \
mkdir -p /usr/share/bunkerweb/deps/python && \
export MAKEFLAGS="-j$(nproc)" && \
+ pip install --no-cache-dir --upgrade pip && \
+ pip install --no-cache-dir --upgrade pip-tools wheel setuptools && \
pip install --no-cache-dir --require-hashes --target /usr/share/bunkerweb/deps/python -r /usr/share/bunkerweb/deps/requirements.txt && \
- apk del .build-deps
+ apk del .build-deps && \
+ rm -rf /var/cache/apk/*
# Copy files
# can't exclude deps from . so we are copying everything by hand
@@ -51,25 +57,23 @@ COPY --from=builder --chown=0:101 /usr/share/bunkerweb /usr/share/bunkerweb
RUN apk add --no-cache pcre bash python3 && \
cp /usr/share/bunkerweb/helpers/bwcli /usr/bin/ && \
mkdir -p /var/tmp/bunkerweb && \
+ mkdir -p /var/run/bunkerweb && \
+ mkdir -p /var/log/bunkerweb && \
mkdir -p /var/www/html && \
mkdir -p /etc/bunkerweb && \
mkdir -p /data/cache && ln -s /data/cache /var/cache/bunkerweb && \
for dir in $(echo "configs plugins") ; do mkdir -p "/data/${dir}" && ln -s "/data/${dir}" "/etc/bunkerweb/${dir}" ; done && \
for dir in $(echo "configs/http configs/stream configs/server-http configs/server-stream configs/default-server-http configs/default-server-stream configs/modsec configs/modsec-crs") ; do mkdir "/data/${dir}" ; done && \
- chown -R root:nginx /data && \
- chmod -R 770 /data && \
- chown -R root:nginx /var/cache/bunkerweb /etc/bunkerweb /var/tmp/bunkerweb /usr/bin/bwcli && \
- chmod 770 /var/cache/bunkerweb /var/tmp/bunkerweb && \
+ chown -R root:nginx /data /etc/nginx /var/cache/bunkerweb /etc/bunkerweb /var/tmp/bunkerweb /var/run/bunkerweb /var/log/bunkerweb /usr/bin/bwcli && \
+ chmod -R 770 /data /etc/nginx /var/cache/bunkerweb /var/tmp/bunkerweb /var/log/bunkerweb /var/run/bunkerweb && \
chmod 750 /usr/share/bunkerweb/cli/main.py /usr/share/bunkerweb/gen/main.py /usr/share/bunkerweb/helpers/*.sh /usr/share/bunkerweb/entrypoint.sh /usr/bin/bwcli /usr/share/bunkerweb/deps/python/bin/* && \
- chown -R root:nginx /etc/nginx && \
- chmod -R 770 /etc/nginx && \
- rm -f /var/log/nginx/* && \
- ln -s /proc/1/fd/2 /var/log/nginx/error.log && \
- ln -s /proc/1/fd/2 /var/log/nginx/modsec_audit.log && \
- ln -s /proc/1/fd/1 /var/log/nginx/access.log
+ rm -f /var/log/bunkerweb/* && \
+ ln -s /proc/1/fd/2 /var/log/bunkerweb/error.log && \
+ ln -s /proc/1/fd/2 /var/log/bunkerweb/modsec_audit.log && \
+ ln -s /proc/1/fd/1 /var/log/bunkerweb/access.log
# Fix CVEs
-RUN apk add "libcrypto3>=3.0.8-r4" "libssl3>=3.0.8-r4" "curl>=8.1.0-r0" "libcurl>=8.1.0-r0"
+RUN apk add "libx11>=1.8.4-r1" "tiff>=4.4.0-r4" "libcrypto3>=3.0.9-r2" "libssl3>=3.0.9-r2" "nghttp2-libs>=1.51.0-r1"
VOLUME /data /etc/nginx
diff --git a/src/bw/entrypoint.sh b/src/bw/entrypoint.sh
index 1331a3482..6721dc4e0 100644
--- a/src/bw/entrypoint.sh
+++ b/src/bw/entrypoint.sh
@@ -21,7 +21,7 @@ trap "trap_exit" TERM INT QUIT
# trap SIGHUP
function trap_reload() {
log "ENTRYPOINT" "âšī¸" "Catched reload operation"
- if [ -f /var/tmp/bunkerweb/nginx.pid ] ; then
+ if [ -f /var/run/bunkerweb/nginx.pid ] ; then
log "ENTRYPOINT" "âšī¸" "Reloading nginx ..."
nginx -s reload
if [ $? -eq 0 ] ; then
@@ -39,7 +39,7 @@ if [ -f "/etc/nginx/variables.env" ] ; then
log "ENTRYPOINT" "â ī¸ " "Looks like BunkerWeb has already been loaded, will not generate temp config"
else
# generate "temp" config
- echo -e "IS_LOADING=yes\nSERVER_NAME=\nAPI_HTTP_PORT=${API_HTTP_PORT:-5000}\nAPI_SERVER_NAME=${API_SERVER_NAME:-bwapi}\nAPI_WHITELIST_IP=${API_WHITELIST_IP:-127.0.0.0/8}\nUSE_REAL_IP=${USE_REAL_IP:-no}\nUSE_REAL_IP=${USE_REAL_IP:-no}\nUSE_PROXY_PROTOCOL=${USE_PROXY_PROTOCOL:-no}\nREAL_IP_FROM=${REAL_IP_FROM:-192.168.0.0/16 172.16.0.0/12 10.0.0.0/8}\nREAL_IP_HEADER=${REAL_IP_HEADER:-X-Forwarded-For}" > /tmp/variables.env
+ echo -e "IS_LOADING=yes\nSERVER_NAME=\nAPI_HTTP_PORT=${API_HTTP_PORT:-5000}\nAPI_SERVER_NAME=${API_SERVER_NAME:-bwapi}\nAPI_WHITELIST_IP=${API_WHITELIST_IP:-127.0.0.0/8}\nUSE_REAL_IP=${USE_REAL_IP:-no}\nUSE_PROXY_PROTOCOL=${USE_PROXY_PROTOCOL:-no}\nREAL_IP_FROM=${REAL_IP_FROM:-192.168.0.0/16 172.16.0.0/12 10.0.0.0/8}\nREAL_IP_HEADER=${REAL_IP_HEADER:-X-Forwarded-For}\nHTTP_PORT=${HTTP_PORT:-8080}\nHTTPS_PORT=${HTTPS_PORT:-8443}" > /tmp/variables.env
python3 /usr/share/bunkerweb/gen/main.py --variables /tmp/variables.env
fi
@@ -50,7 +50,7 @@ pid="$!"
# wait while nginx is running
wait "$pid"
-while [ -f "/var/tmp/bunkerweb/nginx.pid" ] ; do
+while [ -f "/var/run/bunkerweb/nginx.pid" ] ; do
wait "$pid"
done
diff --git a/src/bw/lua/bunkerweb/api.lua b/src/bw/lua/bunkerweb/api.lua
index 3139ba6b0..a6d615a08 100644
--- a/src/bw/lua/bunkerweb/api.lua
+++ b/src/bw/lua/bunkerweb/api.lua
@@ -1,11 +1,11 @@
local class = require "middleclass"
local datastore = require "bunkerweb.datastore"
local utils = require "bunkerweb.utils"
-local logger = require "bunkerweb.logger"
+local logger = require "bunkerweb.logger"
local cjson = require "cjson"
local upload = require "resty.upload"
-local rsignal = require "resty.signal"
-local process = require "ngx.process"
+local rsignal = require "resty.signal"
+local process = require "ngx.process"
local api = class("api")
@@ -14,6 +14,16 @@ api.global = { GET = {}, POST = {}, PUT = {}, DELETE = {} }
function api:initialize()
self.datastore = datastore:new()
self.logger = logger:new("API")
+ self.ctx = ngx.ctx
+ local data, err = utils.get_variable("API_WHITELIST_IP", false)
+ self.ips = {}
+ if not data then
+ self.logger.log(ngx.ERR, "can't get API_WHITELIST_IP variable : " .. err)
+ else
+ for ip in data:gmatch("%S+") do
+ table.insert(self.ips, ip)
+ end
+ end
end
function api:log_cmd(cmd, status, stdout, stderr)
@@ -71,17 +81,17 @@ api.global.POST["^/stop$"] = function(self)
end
api.global.POST["^/confs$"] = function(self)
- local tmp = "/var/tmp/bunkerweb/api_" .. ngx.ctx.bw.uri:sub(2) .. ".tar.gz"
- local destination = "/usr/share/bunkerweb/" .. ngx.ctx.bw.uri:sub(2)
- if ngx.ctx.bw.uri == "/confs" then
+ local tmp = "/var/tmp/bunkerweb/api_" .. self.ctx.bw.uri:sub(2) .. ".tar.gz"
+ local destination = "/usr/share/bunkerweb/" .. self.ctx.bw.uri:sub(2)
+ if self.ctx.bw.uri == "/confs" then
destination = "/etc/nginx"
- elseif ngx.ctx.bw.uri == "/data" then
+ elseif self.ctx.bw.uri == "/data" then
destination = "/data"
- elseif ngx.ctx.bw.uri == "/cache" then
+ elseif self.ctx.bw.uri == "/cache" then
destination = "/var/cache/bunkerweb"
- elseif ngx.ctx.bw.uri == "/custom_configs" then
+ elseif self.ctx.bw.uri == "/custom_configs" then
destination = "/etc/bunkerweb/configs"
- elseif ngx.ctx.bw.uri == "/plugins" then
+ elseif self.ctx.bw.uri == "/plugins" then
destination = "/etc/bunkerweb/plugins"
end
local form, err = upload:new(4096)
@@ -185,21 +195,25 @@ api.global.GET["^/bans$"] = function(self)
return self:response(ngx.HTTP_OK, "success", data)
end
-function api:is_allowed_ip()
- local data, err = self.datastore:get("api_whitelist_ip")
- if not data then
- return false, "can't access api_allowed_ips in datastore"
+api.global.GET["^/variables$"] = function(self)
+ local variables, err = datastore:get('variables', true)
+ if not variables then
+ return self:response(ngx.HTTP_INTERNAL_SERVER_ERROR, "error", "can't access variables from datastore : " .. err)
end
- if utils.is_ip_in_networks(ngx.ctx.bw.remote_addr, cjson.decode(data)) then
+ return self:response(ngx.HTTP_OK, "success", variables)
+end
+
+function api:is_allowed_ip()
+ if utils.is_ip_in_networks(self.ctx.bw.remote_addr, self.ips) then
return true, "ok"
end
return false, "IP is not in API_WHITELIST_IP"
end
function api:do_api_call()
- if self.global[ngx.ctx.bw.request_method] ~= nil then
- for uri, api_fun in pairs(self.global[ngx.ctx.bw.request_method]) do
- if string.match(ngx.ctx.bw.uri, uri) then
+ if self.global[self.ctx.bw.request_method] ~= nil then
+ for uri, api_fun in pairs(self.global[self.ctx.bw.request_method]) do
+ if string.match(self.ctx.bw.uri, uri) then
local status, resp = api_fun(self)
local ret = true
if status ~= ngx.HTTP_OK then
@@ -215,17 +229,16 @@ function api:do_api_call()
end
end
end
- local list, err = self.datastore:get("plugins")
+ local list, err = self.datastore:get("plugins", true)
if not list then
local status, resp = self:response(ngx.HTTP_INTERNAL_SERVER_ERROR, "error", "can't list loaded plugins : " .. err)
- return false, resp["msg"], ngx.HTTP_INTERNAL_SERVER_ERROR, resp
+ return false, resp["msg"], ngx.HTTP_INTERNAL_SERVER_ERROR, cjson.encode(resp)
end
- list = cjson.decode(list)
for i, plugin in ipairs(list) do
if pcall(require, plugin.id .. "/" .. plugin.id) then
local plugin_lua = require(plugin.id .. "/" .. plugin.id)
if plugin_lua.api ~= nil then
- local matched, status, resp = plugin_lua.api()
+ local matched, status, resp = plugin_lua:api(self.ctx)
if matched then
local ret = true
if status ~= ngx.HTTP_OK then
diff --git a/src/bw/lua/bunkerweb/cachestore.lua b/src/bw/lua/bunkerweb/cachestore.lua
index 0041af7df..4b1bd5aa7 100644
--- a/src/bw/lua/bunkerweb/cachestore.lua
+++ b/src/bw/lua/bunkerweb/cachestore.lua
@@ -1,16 +1,16 @@
-local mlcache = require "resty.mlcache"
+local mlcache = require "resty.mlcache"
local clusterstore = require "bunkerweb.clusterstore"
-local logger = require "bunkerweb.logger"
-local utils = require "bunkerweb.utils"
-local class = require "middleclass"
-local cachestore = class("cachestore")
+local logger = require "bunkerweb.logger"
+local utils = require "bunkerweb.utils"
+local class = require "middleclass"
+local cachestore = class("cachestore")
-- Instantiate mlcache object at module level (which will be cached when running init phase)
-- TODO : custom settings
-local shm = "cachestore"
-local ipc_shm = "cachestore_ipc"
-local shm_miss = "cachestore_miss"
-local shm_locks = "cachestore_locks"
+local shm = "cachestore"
+local ipc_shm = "cachestore_ipc"
+local shm_miss = "cachestore_miss"
+local shm_locks = "cachestore_locks"
if not ngx.shared.cachestore then
shm = "cachestore_stream"
ipc_shm = "cachestore_ipc_stream"
@@ -42,7 +42,8 @@ if not cache then
module_logger:log(ngx.ERR, "can't instantiate mlcache : " .. err)
end
-function cachestore:initialize(use_redis, new_cs)
+function cachestore:initialize(use_redis, new_cs, ctx)
+ self.ctx = ctx
self.cache = cache
self.use_redis = use_redis or false
self.logger = module_logger
@@ -50,7 +51,7 @@ function cachestore:initialize(use_redis, new_cs)
self.clusterstore = clusterstore:new(false)
self.shared_cs = false
else
- self.clusterstore = utils.get_ctx_obj("clusterstore")
+ self.clusterstore = utils.get_ctx_obj("clusterstore", self.ctx)
self.shared_cs = true
end
end
diff --git a/src/bw/lua/bunkerweb/clusterstore.lua b/src/bw/lua/bunkerweb/clusterstore.lua
index 1f96aabc3..d6528c3a0 100644
--- a/src/bw/lua/bunkerweb/clusterstore.lua
+++ b/src/bw/lua/bunkerweb/clusterstore.lua
@@ -77,7 +77,8 @@ function clusterstore:close()
if self.redis_client then
-- Equivalent to close but keep a pool of connections
if self.pool then
- local ok, err = self.redis_client:set_keepalive(tonumber(self.variables["REDIS_KEEPALIVE_IDLE"]), tonumber(self.variables["REDIS_KEEPALIVE_POOL"]))
+ local ok, err = self.redis_client:set_keepalive(tonumber(self.variables["REDIS_KEEPALIVE_IDLE"]),
+ tonumber(self.variables["REDIS_KEEPALIVE_POOL"]))
self.redis_client = nil
if not ok then
require "bunkerweb.logger":new("clusterstore-close"):log(ngx.ERR, err)
diff --git a/src/bw/lua/bunkerweb/datastore.lua b/src/bw/lua/bunkerweb/datastore.lua
index 3fee5d305..6be6b4c4a 100644
--- a/src/bw/lua/bunkerweb/datastore.lua
+++ b/src/bw/lua/bunkerweb/datastore.lua
@@ -1,6 +1,13 @@
local class = require "middleclass"
+local lrucache = require "resty.lrucache"
local datastore = class("datastore")
+local lru, err = lrucache.new(100000)
+if not lru then
+ require "bunkerweb.logger":new("DATASTORE"):log(ngx.ERR,
+ "failed to instantiate LRU cache : " .. (err or "unknown error"))
+end
+
function datastore:initialize()
self.dict = ngx.shared.datastore
if not self.dict then
@@ -8,7 +15,11 @@ function datastore:initialize()
end
end
-function datastore:get(key)
+function datastore:get(key, worker)
+ if worker then
+ local value, err = lru:get(key)
+ return value, err or "not found"
+ end
local value, err = self.dict:get(key)
if not value and not err then
err = "not found"
@@ -16,21 +27,35 @@ function datastore:get(key)
return value, err
end
-function datastore:set(key, value, exptime)
+function datastore:set(key, value, exptime, worker)
+ if worker then
+ lru:set(key, value, exptime)
+ return true, "success"
+ end
exptime = exptime or 0
return self.dict:safe_set(key, value, exptime)
end
-function datastore:delete(key)
+function datastore:delete(key, worker)
+ if worker then
+ lru:delete(key)
+ return true, "success"
+ end
self.dict:delete(key)
return true, "success"
end
-function datastore:keys()
+function datastore:keys(worker)
+ if worker then
+ return lru:keys(0)
+ end
return self.dict:get_keys(0)
end
function datastore:ttl(key)
+ if worker then
+ return false, "not supported by LRU"
+ end
local ttl, err = self.dict:ttl(key)
if not ttl then
return false, err
@@ -38,8 +63,13 @@ function datastore:ttl(key)
return true, ttl
end
-function datastore:delete_all(pattern)
- local keys = self.dict:get_keys(0)
+function datastore:delete_all(pattern, worker)
+ local keys = {}
+ if worker then
+ keys = lru:keys(0)
+ else
+ keys = self.dict:get_keys(0)
+ end
for i, key in ipairs(keys) do
if key:match(pattern) then
self.dict:delete(key)
@@ -48,4 +78,8 @@ function datastore:delete_all(pattern)
return true, "success"
end
+function datastore:flush_lru()
+ lru:flush_all()
+end
+
return datastore
diff --git a/src/bw/lua/bunkerweb/helpers.lua b/src/bw/lua/bunkerweb/helpers.lua
index e2248039b..cc4d11462 100644
--- a/src/bw/lua/bunkerweb/helpers.lua
+++ b/src/bw/lua/bunkerweb/helpers.lua
@@ -108,9 +108,9 @@ helpers.require_plugin = function(id)
return plugin_lua, "require() call successful for plugin " .. id
end
-helpers.new_plugin = function(plugin_lua)
+helpers.new_plugin = function(plugin_lua, ctx)
-- Require call
- local ok, plugin_obj = pcall(plugin_lua.new, plugin_lua)
+ local ok, plugin_obj = pcall(plugin_lua.new, plugin_lua, ctx)
if not ok then
return false, "new error for plugin " .. plugin_lua.name .. " : " .. plugin_obj
end
@@ -148,8 +148,9 @@ end
helpers.fill_ctx = function()
-- Return errors as table
local errors = {}
+ local ctx = ngx.ctx
-- Check if ctx is already filled
- if not ngx.ctx.bw then
+ if not ctx.bw then
-- Instantiate bw table
local data = {}
-- Common vars
@@ -158,14 +159,20 @@ helpers.fill_ctx = function()
data.kind = "stream"
end
data.remote_addr = ngx.var.remote_addr
- data.uri = ngx.var.uri
- data.request_uri = ngx.var.request_uri
- data.request_method = ngx.var.request_method
- data.http_user_agent = ngx.var.http_user_agent
- data.http_host = ngx.var.http_host
data.server_name = ngx.var.server_name
- data.http_content_type = ngx.var.http_content_type
- data.http_origin = ngx.var.http_origin
+ if data.kind == "http" then
+ data.uri = ngx.var.uri
+ data.request_uri = ngx.var.request_uri
+ data.request_method = ngx.var.request_method
+ data.http_user_agent = ngx.var.http_user_agent
+ data.http_host = ngx.var.http_host
+ data.server_name = ngx.var.server_name
+ data.http_content_type = ngx.var.http_content_type
+ data.http_content_length = ngx.var.http_content_length
+ data.http_origin = ngx.var.http_origin
+ data.http_version = ngx.req.http_version()
+ data.scheme = ngx.var.scheme
+ end
-- IP data : global
local ip_is_global, err = utils.ip_is_global(data.remote_addr)
if ip_is_global == nil then
@@ -180,17 +187,76 @@ helpers.fill_ctx = function()
data.integration = utils.get_integration()
data.version = utils.get_version()
-- Fill ctx
- ngx.ctx.bw = data
+ ctx.bw = data
end
-- Always create new objects for current phases in case of cosockets
local use_redis, err = utils.get_variable("USE_REDIS", false)
if not use_redis then
table.insert(errors, "can't get variable from datastore : " .. err)
end
- ngx.ctx.bw.datastore = require "bunkerweb.datastore":new()
- ngx.ctx.bw.clusterstore = require "bunkerweb.clusterstore":new()
- ngx.ctx.bw.cachestore = require "bunkerweb.cachestore":new(use_redis == "yes")
- return true, "ctx filled", errors
+ ctx.bw.datastore = require "bunkerweb.datastore":new()
+ ctx.bw.clusterstore = require "bunkerweb.clusterstore":new()
+ ctx.bw.cachestore = require "bunkerweb.cachestore":new(use_redis == "yes")
+ return true, "ctx filled", errors, ctx
+end
+
+function helpers.load_variables(all_variables, plugins)
+ -- Extract settings from plugins and global ones
+ local all_settings = {}
+ for i, plugin in ipairs(plugins) do
+ if plugin.settings then
+ for setting, data in pairs(plugin.settings) do
+ all_settings[setting] = data
+ end
+ end
+ end
+ local file = io.open("/usr/share/bunkerweb/settings.json")
+ if not file then
+ return false, "can't open settings.json"
+ end
+ local ok, settings = pcall(cjson.decode, file:read("*a"))
+ file:close()
+ if not ok then
+ return false, "invalid settings.json : " .. err
+ end
+ for setting, data in pairs(settings) do
+ all_settings[setting] = data
+ end
+ -- Extract vars
+ local variables = { ["global"] = {} }
+ local multisite = all_variables["MULTISITE"] == "yes"
+ local server_names = {}
+ if multisite then
+ for server_name in all_variables["SERVER_NAME"]:gmatch("%S+") do
+ variables[server_name] = {}
+ table.insert(server_names, server_name)
+ end
+ end
+ for setting, data in pairs(all_settings) do
+ if all_variables[setting] then
+ variables["global"][setting] = all_variables[setting]
+ end
+ if multisite then
+ for i, server_name in ipairs(server_names) do
+ local key = server_name .. "_" .. setting
+ if all_variables[key] then
+ variables[server_name][setting] = all_variables[key]
+ end
+ end
+ end
+ if data.multiple then
+ for variable, value in pairs(all_variables) do
+ local found, _, prefix = variable:find("^([^_]*)_?" .. setting .. "_[0-9]+$")
+ if found then
+ if multisite and prefix and prefix ~= "" then
+ variables[prefix][variable] = value
+ end
+ variables["global"][variable] = value
+ end
+ end
+ end
+ end
+ return true, variables
end
return helpers
diff --git a/src/bw/lua/bunkerweb/plugin.lua b/src/bw/lua/bunkerweb/plugin.lua
index b4e791134..3ad967e3e 100644
--- a/src/bw/lua/bunkerweb/plugin.lua
+++ b/src/bw/lua/bunkerweb/plugin.lua
@@ -1,18 +1,19 @@
-local class = require "middleclass"
-local logger = require "bunkerweb.logger"
-local datastore = require "bunkerweb.datastore"
-local cachestore = require "bunkerweb.cachestore"
+local class = require "middleclass"
+local logger = require "bunkerweb.logger"
+local datastore = require "bunkerweb.datastore"
+local cachestore = require "bunkerweb.cachestore"
local clusterstore = require "bunkerweb.clusterstore"
-local utils = require "bunkerweb.utils"
-local cjson = require "cjson"
-local plugin = class("plugin")
+local utils = require "bunkerweb.utils"
+local cjson = require "cjson"
+local plugin = class("plugin")
-function plugin:initialize(id)
+function plugin:initialize(id, ctx)
-- Store common, values
self.id = id
local multisite = false
local current_phase = ngx.get_phase()
- for i, check_phase in ipairs({ "set", "access", "content", "header", "log", "preread", "log_stream", "log_default" }) do
+ for i, check_phase in ipairs({ "set", "access", "content", "header_filter", "log", "preread", "log_stream",
+ "log_default" }) do
if current_phase == check_phase then
multisite = true
break
@@ -21,35 +22,46 @@ function plugin:initialize(id)
self.is_request = multisite
-- Store common objets
self.logger = logger:new(self.id)
- local use_redis, err = utils.get_variable("USE_REDIS", false)
- if not use_redis then
- self.logger:log(ngx.ERR, err)
- end
- self.use_redis = use_redis == "yes"
+ local use_redis, err = utils.get_variable("USE_REDIS", false)
+ if not use_redis then
+ self.logger:log(ngx.ERR, err)
+ end
+ self.use_redis = use_redis == "yes"
if self.is_request then
- self.datastore = utils.get_ctx_obj("datastore") or datastore:new()
- self.cachestore = utils.get_ctx_obj("cachestore") or cachestore:new(use_redis == "yes", true)
- self.clusterstore = utils.get_ctx_obj("clusterstore") or clusterstore:new(false)
+ -- Store ctx
+ self.ctx = ctx or ngx.ctx
+ self.datastore = utils.get_ctx_obj("datastore", self.ctx) or datastore:new()
+ self.cachestore = utils.get_ctx_obj("cachestore", self.ctx) or cachestore:new(use_redis == "yes", true, self.ctx)
+ self.clusterstore = utils.get_ctx_obj("clusterstore", self.ctx) or clusterstore:new(false)
else
self.datastore = datastore:new()
self.cachestore = cachestore:new(use_redis == "yes", true)
self.clusterstore = clusterstore:new(false)
end
-- Get metadata
- local encoded_metadata, err = self.datastore:get("plugin_" .. id)
- if not encoded_metadata then
+ local metadata, err = self.datastore:get("plugin_" .. id, true)
+ if not metadata then
self.logger:log(ngx.ERR, err)
return
end
-- Store variables
self.variables = {}
- local metadata = cjson.decode(encoded_metadata)
+ self.multiples = {}
for k, v in pairs(metadata.settings) do
local value, err = utils.get_variable(k, v.context == "multisite" and multisite)
if value == nil then
self.logger:log(ngx.ERR, "can't get " .. k .. " variable : " .. err)
end
self.variables[k] = value
+ -- if v.multiple then
+ -- local multiples, err = utils.get_multiple_variables(k)
+ -- if not multiples then
+ -- self.logger:log(ngx.ERR, "can't get " .. k .. " multiple variable : " .. err)
+ -- self.multiples[k] = {}
+ -- else
+ -- self.multiples[k] = multiples
+ -- end
+ -- end
end
-- Is loading
local is_loading, err = utils.get_variable("IS_LOADING", false)
diff --git a/src/bw/lua/bunkerweb/utils.lua b/src/bw/lua/bunkerweb/utils.lua
index 95c0ed7e1..dcf267f59 100644
--- a/src/bw/lua/bunkerweb/utils.lua
+++ b/src/bw/lua/bunkerweb/utils.lua
@@ -1,16 +1,16 @@
-local cdatastore = require "bunkerweb.datastore"
-local mmdb = require "bunkerweb.mmdb"
-local clogger = require "bunkerweb.logger"
+local cdatastore = require "bunkerweb.datastore"
+local mmdb = require "bunkerweb.mmdb"
+local clogger = require "bunkerweb.logger"
-local ipmatcher = require "resty.ipmatcher"
-local resolver = require "resty.dns.resolver"
-local session = require "resty.session"
-local cjson = require "cjson"
+local ipmatcher = require "resty.ipmatcher"
+local resolver = require "resty.dns.resolver"
+local session = require "resty.session"
+local cjson = require "cjson"
-local logger = clogger:new("UTILS")
-local datastore = cdatastore:new()
+local logger = clogger:new("UTILS")
+local datastore = cdatastore:new()
-local utils = {}
+local utils = {}
math.randomseed(os.time())
@@ -20,49 +20,32 @@ utils.get_variable = function(var, site_search)
site_search = true
end
-- Get global value
- local value, err = datastore:get("variable_" .. var)
- if not value then
- return nil, "can't access variable " .. var .. " from datastore : " .. err
+ local variables, err = datastore:get('variables', true)
+ if not variables then
+ return nil, "can't access variables from datastore : " .. err
end
+ local value = variables["global"][var]
-- Site search case
- if site_search then
- -- Check if multisite is set to yes
- local multisite, err = datastore:get("variable_MULTISITE")
- if not multisite then
- return nil, "can't access variable MULTISITE from datastore : " .. err
- end
- -- Multisite case
- if multisite == "yes" and ngx.var.server_name then
- local value_site, err = datastore:get("variable_" .. ngx.var.server_name .. "_" .. var)
- if value_site then
- value = value_site
- end
- end
+ local multisite = site_search and variables["global"]["MULTISITE"] == "yes" and ngx.var.server_name ~= "_"
+ if multisite then
+ value = variables[ngx.var.server_name][var]
end
return value, "success"
end
utils.has_variable = function(var, value)
-- Get global variable
- local check_value, err = datastore:get("variable_" .. var)
- if not value then
- return nil, "Can't access variable " .. var .. " from datastore : " .. err
- end
- -- Check if multisite is set to yes
- local multisite, err = datastore:get("variable_MULTISITE")
- if not multisite then
- return nil, "Can't access variable MULTISITE from datastore : " .. err
+ local variables, err = datastore:get('variables', true)
+ if not variables then
+ return nil, "can't access variables " .. var .. " from datastore : " .. err
end
-- Multisite case
- if multisite == "yes" then
- local servers, err = datastore:get("variable_SERVER_NAME")
- if not servers then
- return nil, "Can't access variable SERVER_NAME from datastore : " .. err
- end
+ local multisite = variables["global"]["MULTISITE"] == "yes"
+ if multisite then
+ local servers = variables["global"]["SERVER_NAME"]
-- Check each server
for server in servers:gmatch("%S+") do
- local check_value_site, err = datastore:get("variable_" .. server .. "_" .. var)
- if check_value_site and check_value_site == value then
+ if variables[server][var] == value then
return true, "success"
end
end
@@ -70,30 +53,22 @@ utils.has_variable = function(var, value)
return false, "success"
end
end
- return check_value == value, "success"
+ return variables["global"][var] == value, "success"
end
utils.has_not_variable = function(var, value)
-- Get global variable
- local check_value, err = datastore:get("variable_" .. var)
- if not value then
- return nil, "Can't access variable " .. var .. " from datastore : " .. err
- end
- -- Check if multisite is set to yes
- local multisite, err = datastore:get("variable_MULTISITE")
- if not multisite then
- return nil, "Can't access variable MULTISITE from datastore : " .. err
+ local variables, err = datastore:get('variables', true)
+ if not variables then
+ return nil, "can't access variables " .. var .. " from datastore : " .. err
end
-- Multisite case
- if multisite == "yes" then
- local servers, err = datastore:get("variable_SERVER_NAME")
- if not servers then
- return nil, "Can't access variable SERVER_NAME from datastore : " .. err
- end
+ local multisite = variables["global"]["MULTISITE"] == "yes"
+ if multisite then
+ local servers = variables["global"]["SERVER_NAME"]
-- Check each server
for server in servers:gmatch("%S+") do
- local check_value_site, err = datastore:get("variable_" .. server .. "_" .. var)
- if check_value_site and check_value_site ~= value then
+ if variables[server][var] ~= "value" then
return true, "success"
end
end
@@ -101,33 +76,24 @@ utils.has_not_variable = function(var, value)
return false, "success"
end
end
- return check_value ~= value, "success"
+ return variables["global"][var] ~= value, "success"
end
utils.get_multiple_variables = function(vars)
- -- Get all keys
- local keys = datastore:keys()
+ local variables, err = datastore:get('variables', true)
+ if not variables then
+ return nil, "can't access variables " .. var .. " from datastore : " .. err
+ end
local result = {}
- -- Loop on keys
- for i, key in ipairs(keys) do
+ -- Loop on scoped vars
+ for scope, scoped_vars in pairs(variables) do
+ result[scope] = {}
-- Loop on vars
- for j, var in ipairs(vars) do
- -- Filter on good ones
- local _, _, server, subvar = key:find("variable_(.*)_?(" .. var .. "_?%d*)")
- if subvar then
- if not server or server == "" then
- server = "global"
- else
- server = server:sub(1, -2)
+ for variable, value in pairs(scoped_vars) do
+ for i, var in ipairs(vars) do
+ if variable:find("^" .. var .. "_?[0-9]*$") then
+ result[scope][variable] = value
end
- if result[server] == nil then
- result[server] = {}
- end
- local value, err = datastore:get(key)
- if not value then
- return nil, err
- end
- result[server][subvar] = value
end
end
end
@@ -205,23 +171,25 @@ end
utils.get_integration = function()
-- Check if already in datastore
- local integration, err = datastore:get("misc_integration")
+ local integration, err = datastore:get("misc_integration", true)
if integration then
return integration
end
+ local variables, err = datastore:get("variables", true)
+ if not variables then
+ logger:log(ngx.ERR, "can't get variables from datastore : " .. err)
+ return "unknown"
+ end
-- Swarm
- local var, err = datastore:get("variable_SWARM_MODE")
- if var == "yes" then
+ if variables["global"]["SWARM_MODE"] == "yes" then
integration = "swarm"
else
-- Kubernetes
- local var, err = datastore:get("variable_KUBERNETES_MODE")
- if var == "yes" then
+ if variables["global"]["KUBERNETES_MODE"] == "yes" then
integration = "kubernetes"
else
-- Autoconf
- local var, err = datastore:get("variable_AUTOCONF_MODE")
- if var == "yes" then
+ if variables["global"]["AUTOCONF_MODE"] == "yes" then
integration = "autoconf"
else
-- Already present (e.g. : linux)
@@ -247,7 +215,7 @@ utils.get_integration = function()
end
end
-- Save integration
- local ok, err = datastore:set("misc_integration", integration)
+ local ok, err = datastore:set("misc_integration", integration, nil, true)
if not ok then
logger:log(ngx.ERR, "can't cache integration to datastore : " .. err)
end
@@ -256,7 +224,7 @@ end
utils.get_version = function()
-- Check if already in datastore
- local version, err = datastore:get("misc_version")
+ local version, err = datastore:get("misc_version", true)
if version then
return version
end
@@ -269,17 +237,17 @@ utils.get_version = function()
version = f:read("*a"):gsub("[\n\r]", "")
f:close()
-- Save it to datastore
- local ok, err = datastore:set("misc_version", version)
+ local ok, err = datastore:set("misc_version", version, nil, true)
if not ok then
logger:log(ngx.ERR, "can't cache version to datastore : " .. err)
end
return version
end
-utils.get_reason = function()
+utils.get_reason = function(ctx)
-- ngx.ctx
- if ngx.ctx.reason then
- return ngx.ctx.reason
+ if ctx.bw.reason then
+ return ctx.bw.reason
end
-- ngx.var
if ngx.var.reason and ngx.var.reason ~= "" then
@@ -295,7 +263,7 @@ utils.get_reason = function()
return banned
end
-- unknown
- if ngx.status == utils.get_deny_status() then
+ if ngx.status == utils.get_deny_status(ctx) then
return "unknown"
end
return nil
@@ -303,30 +271,30 @@ end
utils.get_resolvers = function()
-- Get resolvers from datastore if existing
- local str_resolvers, err = datastore:get("misc_resolvers")
- if str_resolvers then
- return cjson.decode(str_resolvers)
+ local resolvers, err = datastore:get("misc_resolvers", true)
+ if resolvers then
+ return resolvers
end
-- Otherwise extract DNS_RESOLVERS variable
- local var_resolvers, err = datastore:get("variable_DNS_RESOLVERS")
- if not var_resolvers then
- logger:log(ngx.ERR, "can't get variable DNS_RESOLVERS from datastore : " .. err)
- return nil, err
+ local variables, err = datastore:get("variables", true)
+ if not variables then
+ logger:log(ngx.ERR, "can't get variables from datastore : " .. err)
+ return "unknown"
end
-- Make table for resolver1 resolver2 ... string
local resolvers = {}
- for str_resolver in var_resolvers:gmatch("%S+") do
+ for str_resolver in variables["global"]["DNS_RESOLVERS"]:gmatch("%S+") do
table.insert(resolvers, str_resolver)
end
-- Add it to the datastore
- local ok, err = datastore:set("misc_resolvers", cjson.encode(resolvers))
+ local ok, err = datastore:set("misc_resolvers", resolvers, nil, true)
if not ok then
logger:log(ngx.ERR, "can't save misc_resolvers to datastore : " .. err)
end
return resolvers
end
-utils.get_rdns = function(ip)
+utils.get_rdns = function(ip)
-- Check cache
local cachestore = utils.new_cachestore()
local ok, value = cachestore:get("rdns_" .. ip)
@@ -376,7 +344,7 @@ utils.get_rdns = function(ip)
return ptrs, ret_err
end
-utils.get_ips = function(fqdn, ipv6)
+utils.get_ips = function(fqdn, ipv6)
-- Check cache
local cachestore = utils.new_cachestore()
local ok, value = cachestore:get("dns_" .. fqdn)
@@ -497,38 +465,38 @@ utils.rand = function(nb, no_numbers)
return result
end
-utils.get_deny_status = function()
+utils.get_deny_status = function(ctx)
-- Stream case
- if ngx.ctx.bw and ngx.ctx.bw.kind == "stream" then
+ if ctx.bw and ctx.bw.kind == "stream" then
return 444
end
-- http case
- local status, err = datastore:get("variable_DENY_HTTP_STATUS")
- if not status then
- logger:log(ngx.ERR, "can't get DENY_HTTP_STATUS variable " .. err)
+ local variables, err = datastore:get("variables", true)
+ if not variables then
+ logger:log(ngx.ERR, "can't get variables from datastore : " .. err)
return 403
end
- return tonumber(status)
+ return tonumber(variables["global"]["DENY_HTTP_STATUS"])
end
-utils.check_session = function()
- local _session, err, exists, refreshed = session.start({audience = "metadata"})
+utils.check_session = function(ctx)
+ local _session, err, exists, refreshed = session.start({ audience = "metadata" })
if exists then
- for i, check in ipairs(ngx.ctx.bw.sessions_checks) do
+ for i, check in ipairs(ctx.bw.sessions_checks) do
local key = check[1]
local value = check[2]
if _session:get(key) ~= value then
+ _session:clear_request_cookie()
local ok, err = _session:destroy()
if not ok then
- _session:close()
- return false, "session:destroy() error : " .. err
+ return false, "session:destroy() error : " .. err
end
logger:log(ngx.WARN, "session check " .. key .. " failed, destroying session")
- return utils.check_session()
+ return utils.check_session(ctx)
end
end
else
- for i, check in ipairs(ngx.ctx.bw.sessions_checks) do
+ for i, check in ipairs(ctx.bw.sessions_checks) do
_session:set(check[1], check[2])
end
local ok, err = _session:save()
@@ -537,41 +505,40 @@ utils.check_session = function()
return false, "session:save() error : " .. err
end
end
- ngx.ctx.bw.sessions_is_checked = true
- _session:close()
+ ctx.bw.sessions_is_checked = true
return true, exists
end
-utils.get_session = function(audience)
+utils.get_session = function(audience, ctx)
-- Check session
- if not ngx.ctx.bw.sessions_is_checked then
- local ok, err = utils.check_session()
+ if not ctx.bw.sessions_is_checked then
+ local ok, err = utils.check_session(ctx)
if not ok then
return false, "error while checking session, " .. err
end
end
-- Open session with specific audience
- local _session, err, exists = session.open({audience = audience})
+ local _session, err, exists = session.open({ audience = audience })
if err then
logger:log(ngx.INFO, "session:open() error : " .. err)
end
return _session
end
-utils.get_session_data = function(_session, site)
+utils.get_session_data = function(_session, site, ctx)
local site_only = site == nil or site
local data = _session:get_data()
if site_only then
- return data[ngx.ctx.bw.server_name] or {}
+ return data[ctx.bw.server_name] or {}
end
return data
end
-utils.set_session_data = function(_session, data, site)
+utils.set_session_data = function(_session, data, site, ctx)
local site_only = site == nil or site
if site_only then
local all_data = _session:get_data()
- all_data[ngx.ctx.bw.server_name] = data
+ all_data[ctx.bw.server_name] = data
_session:set_data(all_data)
return _session:save()
end
@@ -683,7 +650,7 @@ utils.new_cachestore = function()
return require "bunkerweb.cachestore":new(use_redis, true)
end
-utils.regex_match = function(str, regex, options)
+utils.regex_match = function(str, regex, options)
local all_options = "o"
if options then
all_options = all_options .. options
@@ -696,7 +663,7 @@ utils.regex_match = function(str, regex, options)
return match
end
-utils.get_phases = function()
+utils.get_phases = function()
return {
"init",
"init_worker",
@@ -710,7 +677,7 @@ utils.get_phases = function()
}
end
-utils.is_cosocket_available = function()
+utils.is_cosocket_available = function()
local phases = {
"timer",
"access",
@@ -725,7 +692,7 @@ utils.is_cosocket_available = function()
return false
end
-utils.kill_all_threads = function(threads)
+utils.kill_all_threads = function(threads)
for i, thread in ipairs(threads) do
local ok, err = ngx.thread.kill(thread)
if not ok then
@@ -734,7 +701,7 @@ utils.kill_all_threads = function(threads)
end
end
-utils.get_ctx_obj = function(obj)
+utils.get_ctx_obj = function(obj)
if ngx.ctx and ngx.ctx.bw then
return ngx.ctx.bw[obj]
end
diff --git a/src/bw/lua/middleclass.lua b/src/bw/lua/middleclass.lua
index e4f9aa21b..0cafe197f 100644
--- a/src/bw/lua/middleclass.lua
+++ b/src/bw/lua/middleclass.lua
@@ -41,7 +41,7 @@ local function _createIndexWrapper(aClass, f)
return (f(self, name))
end
end
- else -- if type(f) == "table" then
+ else -- if type(f) == "table" then
return function(self, name)
local value = aClass.__instanceDict[name]
diff --git a/src/bw/misc/asn.mmdb b/src/bw/misc/asn.mmdb
index 474a6a7b7..837f9f219 100644
Binary files a/src/bw/misc/asn.mmdb and b/src/bw/misc/asn.mmdb differ
diff --git a/src/bw/misc/country.mmdb b/src/bw/misc/country.mmdb
index 0bc884f92..8a76af1f6 100644
Binary files a/src/bw/misc/country.mmdb and b/src/bw/misc/country.mmdb differ
diff --git a/src/common/api/API.py b/src/common/api/API.py
index e300d9ac8..4a94f5474 100644
--- a/src/common/api/API.py
+++ b/src/common/api/API.py
@@ -1,52 +1,52 @@
+#!/usr/bin/python3
+
+from typing import Literal, Optional, Union
from requests import request
class API:
- def __init__(self, endpoint, host="bwapi"):
+ def __init__(self, endpoint: str, host: str = "bwapi"):
self.__endpoint = endpoint
+ if not self.__endpoint.endswith("/"):
+ self.__endpoint += "/"
self.__host = host
- def get_endpoint(self):
+ @property
+ def endpoint(self) -> str:
return self.__endpoint
- def get_host(self):
+ @property
+ def host(self) -> str:
return self.__host
- def request(self, method, url, data=None, files=None, timeout=(10, 30)):
+ def request(
+ self,
+ method: Union[Literal["POST"], Literal["GET"]],
+ url: str,
+ data: Optional[Union[dict, bytes]] = None,
+ files=None,
+ timeout=(10, 30),
+ ) -> tuple[bool, str, Optional[int], Optional[dict]]:
try:
- headers = {}
- headers["User-Agent"] = "bwapi"
- headers["Host"] = self.__host
+ kwargs = {}
if isinstance(data, dict):
- resp = request(
- method,
- f"{self.__endpoint}{url}",
- json=data,
- timeout=timeout,
- headers=headers,
- )
+ kwargs["json"] = data
elif isinstance(data, bytes):
- resp = request(
- method,
- f"{self.__endpoint}{url}",
- data=data,
- timeout=timeout,
- headers=headers,
- )
- elif files:
- resp = request(
- method,
- f"{self.__endpoint}{url}",
- files=files,
- timeout=timeout,
- headers=headers,
- )
- elif not data:
- resp = request(
- method, f"{self.__endpoint}{url}", timeout=timeout, headers=headers
- )
- else:
- return False, "unsupported data type", None, None
+ kwargs["data"] = data
+ elif data is not None:
+ return False, f"Unsupported data type: {type(data)}", None, None
+
+ if files:
+ kwargs["files"] = files
+
+ resp = request(
+ method,
+ f"{self.__endpoint}{url if not url.startswith('/') else url[1:]}",
+ timeout=timeout,
+ headers={"User-Agent": "bwapi", "Host": self.__host},
+ **kwargs,
+ )
except Exception as e:
- return False, str(e), None, None
+ return False, f"Request failed: {e}", None, None
+
return True, "ok", resp.status_code, resp.json()
diff --git a/src/common/cli/CLI.py b/src/common/cli/CLI.py
index ba495ba11..60cd44fb9 100644
--- a/src/common/cli/CLI.py
+++ b/src/common/cli/CLI.py
@@ -1,17 +1,20 @@
-from os import getenv
+#!/usr/bin/python3
+
from dotenv import dotenv_values
+from os import getenv, sep
+from os.path import join
from pathlib import Path
from redis import StrictRedis
from sys import path as sys_path
from typing import Tuple
-if "/usr/share/bunkerweb/utils" not in sys_path:
- sys_path.append("/usr/share/bunkerweb/utils")
+if join(sep, "usr", "share", "bunkerweb", "utils") not in sys_path:
+ sys_path.append(join(sep, "usr", "share", "bunkerweb", "utils"))
-from API import API
-from ApiCaller import ApiCaller
-from logger import setup_logger
+from API import API # type: ignore
+from ApiCaller import ApiCaller # type: ignore
+from logger import setup_logger # type: ignore
def format_remaining_time(seconds):
@@ -37,14 +40,15 @@ def format_remaining_time(seconds):
class CLI(ApiCaller):
def __init__(self):
self.__logger = setup_logger("CLI", getenv("LOG_LEVEL", "INFO"))
+ db_path = Path(sep, "usr", "share", "bunkerweb", "db")
- if not Path("/usr/share/bunkerweb/db").is_dir():
- self.__variables = dotenv_values("/etc/nginx/variables.env")
+ if not db_path.is_dir():
+ self.__variables = dotenv_values(join(sep, "etc", "nginx", "variables.env"))
else:
- if "/usr/share/bunkerweb/db" not in sys_path:
- sys_path.append("/usr/share/bunkerweb/db")
+ if str(db_path) not in sys_path:
+ sys_path.append(str(db_path))
- from Database import Database
+ from Database import Database # type: ignore
db = Database(
self.__logger,
@@ -110,14 +114,14 @@ class CLI(ApiCaller):
)
self.__use_redis = False
- if not Path("/usr/share/bunkerweb/db").is_dir() or self.__integration not in (
+ if not db_path.is_dir() or self.__integration not in (
"kubernetes",
"swarm",
"autoconf",
):
# Docker & Linux case
super().__init__(
- apis=[
+ [
API(
f"http://127.0.0.1:{self.__variables.get('API_HTTP_PORT', '5000')}",
host=self.__variables.get("API_SERVER_NAME", "bwapi"),
@@ -129,17 +133,18 @@ class CLI(ApiCaller):
self.auto_setup(self.__integration)
def __detect_integration(self) -> str:
+ integration_path = Path(sep, "usr", "share", "bunkerweb", "INTEGRATION")
+ os_release_path = Path(sep, "etc", "os-release")
if self.__variables.get("KUBERNETES_MODE", "no").lower() == "yes":
return "kubernetes"
elif self.__variables.get("SWARM_MODE", "no").lower() == "yes":
return "swarm"
elif self.__variables.get("AUTOCONF_MODE", "no").lower() == "yes":
return "autoconf"
- elif Path("/usr/share/bunkerweb/INTEGRATION").is_file():
- return Path("/usr/share/bunkerweb/INTEGRATION").read_text().strip().lower()
- elif (
- Path("/etc/os-release").is_file()
- and "Alpine" in Path("/etc/os-release").read_text()
+ elif integration_path.is_file():
+ return integration_path.read_text(encoding="utf-8").strip().lower()
+ elif os_release_path.is_file() and "Alpine" in os_release_path.read_text(
+ encoding="utf-8"
):
return "docker"
@@ -151,7 +156,7 @@ class CLI(ApiCaller):
if not ok:
self.__logger.error(f"Failed to delete ban for {ip} from redis")
- if self._send_to_apis("POST", "/unban", data={"ip": ip}):
+ if self.send_to_apis("POST", "/unban", data={"ip": ip}):
return True, f"IP {ip} has been unbanned"
return False, "error"
@@ -165,7 +170,7 @@ class CLI(ApiCaller):
if not ok:
self.__logger.error(f"Failed to ban {ip} in redis")
- if self._send_to_apis("POST", "/ban", data={"ip": ip, "exp": exp}):
+ if self.send_to_apis("POST", "/ban", data={"ip": ip, "exp": exp}):
return (
True,
f"IP {ip} has been banned for {format_remaining_time(exp)}",
@@ -175,7 +180,7 @@ class CLI(ApiCaller):
def bans(self) -> Tuple[bool, str]:
servers = {}
- ret, resp = self._send_to_apis("GET", "/bans", response=True)
+ ret, resp = self.send_to_apis("GET", "/bans", response=True)
if not ret:
return False, "error"
@@ -203,7 +208,6 @@ class CLI(ApiCaller):
for ban in bans:
cli_str += f"- {ban['ip']} for {format_remaining_time(ban['exp'])} : {ban.get('reason', 'no reason given')}\n"
- else:
- cli_str += "\n"
+ cli_str += "\n"
return True, cli_str
diff --git a/src/common/cli/main.py b/src/common/cli/main.py
index 15d2642b0..fe61834b2 100644
--- a/src/common/cli/main.py
+++ b/src/common/cli/main.py
@@ -1,20 +1,19 @@
-#!/usr/bin/env python3
+#!/usr/bin/python3
from argparse import ArgumentParser
-from os import _exit, getenv
-from sys import exit as sys_exit, path
+from os import _exit, getenv, sep
+from os.path import join
+from sys import exit as sys_exit, path as sys_path
from traceback import format_exc
-path.extend(
- (
- "/usr/share/bunkerweb/deps/python",
- "/usr/share/bunkerweb/cli",
- "/usr/share/bunkerweb/utils",
- "/usr/share/bunkerweb/api",
- )
-)
+for deps_path in [
+ join(sep, "usr", "share", "bunkerweb", *paths)
+ for paths in (("deps", "python"), ("utils",), ("api",), ("db",))
+]:
+ if deps_path not in sys_path:
+ sys_path.append(deps_path)
-from logger import setup_logger
+from logger import setup_logger # type: ignore
from CLI import CLI
if __name__ == "__main__":
diff --git a/src/common/confs/api.conf b/src/common/confs/api.conf
index 86958850b..8ee335650 100644
--- a/src/common/confs/api.conf
+++ b/src/common/confs/api.conf
@@ -5,7 +5,7 @@ server {
listen {{ API_LISTEN_IP }}:{{ API_HTTP_PORT }};
{% if API_LISTEN_IP != "127.0.0.1" +%}
listen 127.0.0.1:{{ API_HTTP_PORT }};
-{% endif +%}
+{% endif %}
# maximum body size for API
client_max_body_size 1G;
@@ -25,7 +25,7 @@ server {
-- Fill ctx
logger:log(ngx.INFO, "filling ngx.ctx ...")
- local ok, ret, errors = helpers.fill_ctx()
+ local ok, ret, errors, ctx = helpers.fill_ctx()
if not ok then
logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
elseif errors then
@@ -36,30 +36,33 @@ server {
logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
-- Check host header
- if not ngx.ctx.bw.http_host or ngx.ctx.bw.http_host ~= "{{ API_SERVER_NAME }}" then
- logger:log(ngx.WARN, "wrong Host header from IP " .. ngx.ctx.bw.remote_addr)
+ if not ctx.bw.http_host or ctx.bw.http_host ~= "{{ API_SERVER_NAME }}" then
+ logger:log(ngx.WARN, "wrong Host header from IP " .. ctx.bw.remote_addr)
return ngx.exit(ngx.HTTP_CLOSE)
end
-- Check IP
local ok, err = api:is_allowed_ip()
if not ok then
- logger:log(ngx.WARN, "can't validate access from IP " .. ngx.ctx.bw.remote_addr .. " : " .. err)
+ logger:log(ngx.WARN, "can't validate access from IP " .. ctx.bw.remote_addr .. " : " .. err)
return ngx.exit(ngx.HTTP_CLOSE)
end
- logger:log(ngx.NOTICE, "validated access from IP " .. ngx.ctx.bw.remote_addr)
+ logger:log(ngx.NOTICE, "validated access from IP " .. ctx.bw.remote_addr)
-- Do API call
local ok, err, status, resp = api:do_api_call()
if not ok then
- logger:log(ngx.WARN, "call from " .. ngx.ctx.bw.remote_addr .. " on " .. ngx.ctx.bw.uri .. " failed : " .. err)
+ logger:log(ngx.WARN, "call from " .. ctx.bw.remote_addr .. " on " .. ctx.bw.uri .. " failed : " .. err)
else
- logger:log(ngx.NOTICE, "successful call from " .. ngx.ctx.bw.remote_addr .. " on " .. ngx.ctx.bw.uri .. " : " .. err)
+ logger:log(ngx.NOTICE, "successful call from " .. ctx.bw.remote_addr .. " on " .. ctx.bw.uri .. " : " .. err)
end
-- Start API handler
logger:log(ngx.INFO, "API handler ended")
+ -- Save ctx
+ ngx.ctx = ctx
+
-- Send response
ngx.status = status
ngx.say(resp)
diff --git a/src/common/confs/default-server-http.conf b/src/common/confs/default-server-http.conf
index e6f600c46..a0b702adc 100644
--- a/src/common/confs/default-server-http.conf
+++ b/src/common/confs/default-server-http.conf
@@ -52,7 +52,7 @@ server {
-- Fill ctx
logger:log(ngx.INFO, "filling ngx.ctx ...")
- local ok, ret, errors = helpers.fill_ctx()
+ local ok, ret, errors, ctx = helpers.fill_ctx()
if not ok then
logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
elseif errors then
@@ -63,12 +63,11 @@ server {
logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
-- Get plugins order
- local order, err = datastore:get("plugins_order")
+ local order, err = datastore:get("plugins_order", true)
if not order then
logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
return
end
- order = cjson.decode(order)
-- Call log_default() methods
logger:log(ngx.INFO, "calling log_default() methods of plugins ...")
@@ -102,10 +101,13 @@ server {
logger:log(ngx.INFO, "called log_default() methods of plugins")
-- Display reason at info level
- if ngx.ctx.reason then
+ if ctx.reason then
logger:log(ngx.INFO, "client was denied with reason : " .. reason)
end
+ -- Save ctx
+ ngx.ctx = ctx
+
logger:log(ngx.INFO, "log_default phase ended")
}
diff --git a/src/common/confs/http.conf b/src/common/confs/http.conf
index 8494be3bb..6eef32804 100644
--- a/src/common/confs/http.conf
+++ b/src/common/confs/http.conf
@@ -15,7 +15,7 @@ default_type application/octet-stream;
# access log format
log_format logf '{{ LOG_FORMAT }}';
-access_log /var/log/nginx/access.log logf;
+access_log /var/log/bunkerweb/access.log logf;
# temp paths
proxy_temp_path /var/tmp/bunkerweb/proxy_temp;
@@ -53,6 +53,7 @@ lua_shared_dict cachestore_locks {{ CACHESTORE_LOCKS_MEMORY_SIZE }};
{% if LOG_LEVEL != "info" and LOG_LEVEL != "debug" %}
lua_socket_log_errors off;
{% endif %}
+access_by_lua_no_postpone on;
# LUA init block
include /etc/nginx/init-lua.conf;
diff --git a/src/common/confs/init-lua.conf b/src/common/confs/init-lua.conf
index 66831f70c..bdcd80529 100644
--- a/src/common/confs/init-lua.conf
+++ b/src/common/confs/init-lua.conf
@@ -1,157 +1,136 @@
init_by_lua_block {
+ local class = require "middleclass"
+ local clogger = require "bunkerweb.logger"
+ local helpers = require "bunkerweb.helpers"
+ local cdatastore = require "bunkerweb.datastore"
+ local cjson = require "cjson"
-local class = require "middleclass"
-local clogger = require "bunkerweb.logger"
-local helpers = require "bunkerweb.helpers"
-local cdatastore = require "bunkerweb.datastore"
-local cjson = require "cjson"
+ -- Start init phase
+ local logger = clogger:new("INIT")
+ local datastore = cdatastore:new()
+ logger:log(ngx.NOTICE, "init phase started")
--- Start init phase
-local logger = clogger:new("INIT")
-local datastore = cdatastore:new()
-logger:log(ngx.NOTICE, "init phase started")
-
--- Remove previous data from the datastore
-logger:log(ngx.NOTICE, "deleting old keys from datastore ...")
-local data_keys = {"^plugin", "^variable_", "^api_", "^misc_"}
-for i, key in pairs(data_keys) do
- local ok, err = datastore:delete_all(key)
- if not ok then
- logger:log(ngx.ERR, "can't delete " .. key .. " from datastore : " .. err)
- return false
- end
- logger:log(ngx.INFO, "deleted " .. key .. " from datastore")
-end
-logger:log(ngx.NOTICE, "deleted old keys from datastore")
-
--- Load variables into the datastore
-logger:log(ngx.NOTICE, "saving variables into datastore ...")
-local file = io.open("/etc/nginx/variables.env")
-if not file then
- logger:log(ngx.ERR, "can't open /etc/nginx/variables.env file")
- return false
-end
-file:close()
-for line in io.lines("/etc/nginx/variables.env") do
- local variable, value = line:match("^([^=]+)=(.*)$")
- local ok, err = datastore:set("variable_" .. variable, value)
- if not ok then
- logger:log(ngx.ERR, "can't save variable " .. variable .. " into datastore : " .. err)
- return false
- end
- logger:log(ngx.INFO, "saved variable " .. variable .. "=" .. value .. " into datastore")
-end
-logger:log(ngx.NOTICE, "saved variables into datastore")
-
--- Purge cache
-local cachestore = require "bunkerweb.cachestore":new(false, true)
-local ok, err = cachestore:purge()
-if not ok then
- logger:log(ngx.ERR, "can't purge cachestore : " .. err)
-end
-
--- Set API values into the datastore
-logger:log(ngx.NOTICE, "saving API values into datastore ...")
-local value, err = datastore:get("variable_USE_API")
-if not value then
- logger:log(ngx.ERR, "can't get variable USE_API from the datastore : " .. err)
- return false
-end
-if value == "yes" then
- local value, err = datastore:get("variable_API_WHITELIST_IP")
- if not value then
- logger:log(ngx.ERR, "can't get variable API_WHITELIST_IP from the datastore : " .. err)
- return false
- end
- local whitelists = {}
- for whitelist in value:gmatch("%S+") do
- table.insert(whitelists, whitelist)
- end
- local ok, err = datastore:set("api_whitelist_ip", cjson.encode(whitelists))
- if not ok then
- logger:log(ngx.ERR, "can't save API whitelist_ip to datastore : " .. err)
- return false
- end
- logger:log(ngx.INFO, "saved API whitelist_ip into datastore")
-end
-logger:log(ngx.NOTICE, "saved API values into datastore")
-
--- Load plugins into the datastore
-logger:log(ngx.NOTICE, "saving plugins into datastore ...")
-local plugins = {}
-local plugin_paths = {"/usr/share/bunkerweb/core", "/etc/bunkerweb/plugins"}
-for i, plugin_path in ipairs(plugin_paths) do
- local paths = io.popen("find -L " .. plugin_path .. " -maxdepth 1 -type d ! -path " .. plugin_path)
- for path in paths:lines() do
- local ok, plugin = helpers.load_plugin(path .. "/plugin.json")
+ -- Remove previous data from the datastore
+ logger:log(ngx.NOTICE, "deleting old keys from datastore ...")
+ datastore:flush_lru()
+ local data_keys = { "^plugin", "^misc_" }
+ for i, key in pairs(data_keys) do
+ local ok, err = datastore:delete_all(key)
if not ok then
- logger:log(ngx.ERR, plugin)
- else
- local ok, err = datastore:set("plugin_" .. plugin.id, cjson.encode(plugin))
- if not ok then
- logger:log(ngx.ERR, "can't save " .. plugin.id .. " into datastore : " .. err)
- else
- table.insert(plugins, plugin)
- logger:log(ngx.NOTICE, "loaded plugin " .. plugin.id .. " v" .. plugin.version)
- end
+ logger:log(ngx.ERR, "can't delete " .. key .. " from datastore : " .. err)
+ return false
end
+ logger:log(ngx.INFO, "deleted " .. key .. " from datastore")
end
-end
-local ok, err = datastore:set("plugins", cjson.encode(plugins))
-if not ok then
- logger:log(ngx.ERR, "can't save plugins into datastore : " .. err)
- return false
-end
+ logger:log(ngx.NOTICE, "deleted old keys from datastore")
-logger:log(ngx.NOTICE, "saving plugins order into datastore ...")
-local ok, order = helpers.order_plugins(plugins)
-if not ok then
- logger:log(ngx.ERR, "can't compute plugins order : " .. err)
- return false
-end
-for phase, id_list in pairs(order) do
- logger:log(ngx.NOTICE, "plugins order for phase " .. phase .. " : " .. cjson.encode(id_list))
-end
-local ok, err = datastore:set("plugins_order", cjson.encode(order))
-if not ok then
- logger:log(ngx.ERR, "can't save plugins order into datastore : " .. err)
- return false
-end
-logger:log(ngx.NOTICE, "saved plugins order into datastore")
-
--- Call init() method
-logger:log(ngx.NOTICE, "calling init() methods of plugins ...")
-for i, plugin_id in ipairs(order["init"]) do
- -- Require call
- local plugin_lua, err = helpers.require_plugin(plugin_id)
- if plugin_lua == false then
- logger:log(ngx.ERR, err)
- elseif plugin_lua == nil then
- logger:log(ngx.NOTICE, err)
- else
- -- Check if plugin has init method
- if plugin_lua.init ~= nil then
- -- New call
- local ok, plugin_obj = helpers.new_plugin(plugin_lua)
+ -- Load plugins into the datastore
+ logger:log(ngx.NOTICE, "saving plugins into datastore ...")
+ local plugins = {}
+ local plugin_paths = { "/usr/share/bunkerweb/core", "/etc/bunkerweb/plugins" }
+ for i, plugin_path in ipairs(plugin_paths) do
+ local paths = io.popen("find -L " .. plugin_path .. " -maxdepth 1 -type d ! -path " .. plugin_path)
+ for path in paths:lines() do
+ local ok, plugin = helpers.load_plugin(path .. "/plugin.json")
if not ok then
- logger:log(ngx.ERR, plugin_obj)
+ logger:log(ngx.ERR, plugin)
else
- local ok, ret = helpers.call_plugin(plugin_obj, "init")
+ local ok, err = datastore:set("plugin_" .. plugin.id, plugin, nil, true)
if not ok then
- logger:log(ngx.ERR, ret)
- elseif not ret.ret then
- logger:log(ngx.ERR, plugin_id .. ":init() call failed : " .. ret.msg)
+ logger:log(ngx.ERR, "can't save " .. plugin.id .. " into datastore : " .. err)
else
- logger:log(ngx.NOTICE, plugin_id .. ":init() call successful : " .. ret.msg)
+ table.insert(plugins, plugin)
+ logger:log(ngx.NOTICE, "loaded plugin " .. plugin.id .. " v" .. plugin.version)
end
end
- else
- logger:log(ngx.NOTICE, "skipped execution of " .. plugin.id .. " because method init() is not defined")
end
end
-end
-logger:log(ngx.NOTICE, "called init() methods of plugins")
+ local ok, err = datastore:set("plugins", plugins, nil, true)
+ if not ok then
+ logger:log(ngx.ERR, "can't save plugins into datastore : " .. err)
+ return false
+ end
-logger:log(ngx.NOTICE, "init phase ended")
+ -- Load variables into the datastore
+ logger:log(ngx.NOTICE, "saving variables into datastore ...")
+ local file = io.open("/etc/nginx/variables.env")
+ if not file then
+ logger:log(ngx.ERR, "can't open /etc/nginx/variables.env file")
+ return false
+ end
+ file:close()
+ local all_variables = {}
+ for line in io.lines("/etc/nginx/variables.env") do
+ local variable, value = line:match("^([^=]+)=(.*)$")
+ all_variables[variable] = value
+ end
+ local ok, variables = helpers.load_variables(all_variables, plugins)
+ if not ok then
+ logger:log(ngx.ERR, "error while loading variables : " .. variables)
+ return false
+ end
+ local ok, err = datastore:set("variables", variables, nil, true)
+ if not ok then
+ logger:log(ngx.ERR, "can't save plugins into datastore : " .. err)
+ return false
+ end
+ logger:log(ngx.NOTICE, "saved variables into datastore")
+ -- Purge cache
+ local cachestore = require "bunkerweb.cachestore":new(false, true)
+ local ok, err = cachestore:purge()
+ if not ok then
+ logger:log(ngx.ERR, "can't purge cachestore : " .. err)
+ end
+
+ logger:log(ngx.NOTICE, "saving plugins order into datastore ...")
+ local ok, order = helpers.order_plugins(plugins)
+ if not ok then
+ logger:log(ngx.ERR, "can't compute plugins order : " .. err)
+ return false
+ end
+ for phase, id_list in pairs(order) do
+ logger:log(ngx.NOTICE, "plugins order for phase " .. phase .. " : " .. cjson.encode(id_list))
+ end
+ local ok, err = datastore:set("plugins_order", order, nil, true)
+ if not ok then
+ logger:log(ngx.ERR, "can't save plugins order into datastore : " .. err)
+ return false
+ end
+ logger:log(ngx.NOTICE, "saved plugins order into datastore")
+
+ -- Call init() method
+ logger:log(ngx.NOTICE, "calling init() methods of plugins ...")
+ for i, plugin_id in ipairs(order["init"]) do
+ -- Require call
+ local plugin_lua, err = helpers.require_plugin(plugin_id)
+ if plugin_lua == false then
+ logger:log(ngx.ERR, err)
+ elseif plugin_lua == nil then
+ logger:log(ngx.NOTICE, err)
+ else
+ -- Check if plugin has init method
+ if plugin_lua.init ~= nil then
+ -- New call
+ local ok, plugin_obj = helpers.new_plugin(plugin_lua)
+ if not ok then
+ logger:log(ngx.ERR, plugin_obj)
+ else
+ local ok, ret = helpers.call_plugin(plugin_obj, "init")
+ if not ok then
+ logger:log(ngx.ERR, ret)
+ elseif not ret.ret then
+ logger:log(ngx.ERR, plugin_id .. ":init() call failed : " .. ret.msg)
+ else
+ logger:log(ngx.NOTICE, plugin_id .. ":init() call successful : " .. ret.msg)
+ end
+ end
+ else
+ logger:log(ngx.NOTICE, "skipped execution of " .. plugin.id .. " because method init() is not defined")
+ end
+ end
+ end
+ logger:log(ngx.NOTICE, "called init() methods of plugins")
+
+ logger:log(ngx.NOTICE, "init phase ended")
}
diff --git a/src/common/confs/init-stream-lua.conf b/src/common/confs/init-stream-lua.conf
index 3b994be18..3598f5bb1 100644
--- a/src/common/confs/init-stream-lua.conf
+++ b/src/common/confs/init-stream-lua.conf
@@ -1,157 +1,136 @@
init_by_lua_block {
+ local class = require "middleclass"
+ local clogger = require "bunkerweb.logger"
+ local helpers = require "bunkerweb.helpers"
+ local cdatastore = require "bunkerweb.datastore"
+ local cjson = require "cjson"
-local class = require "middleclass"
-local clogger = require "bunkerweb.logger"
-local helpers = require "bunkerweb.helpers"
-local cdatastore = require "bunkerweb.datastore"
-local cjson = require "cjson"
+ -- Start init phase
+ local logger = clogger:new("INIT")
+ local datastore = cdatastore:new()
+ logger:log(ngx.NOTICE, "init-stream phase started")
--- Start init phase
-local logger = clogger:new("INIT")
-local datastore = cdatastore:new()
-logger:log(ngx.NOTICE, "init-stream phase started")
-
--- Remove previous data from the datastore
-logger:log(ngx.NOTICE, "deleting old keys from datastore ...")
-local data_keys = {"^plugin", "^variable_", "^api_", "^misc_"}
-for i, key in pairs(data_keys) do
- local ok, err = datastore:delete_all(key)
- if not ok then
- logger:log(ngx.ERR, "can't delete " .. key .. " from datastore : " .. err)
- return false
- end
- logger:log(ngx.INFO, "deleted " .. key .. " from datastore")
-end
-logger:log(ngx.NOTICE, "deleted old keys from datastore")
-
--- Load variables into the datastore
-logger:log(ngx.NOTICE, "saving variables into datastore ...")
-local file = io.open("/etc/nginx/variables.env")
-if not file then
- logger:log(ngx.ERR, "can't open /etc/nginx/variables.env file")
- return false
-end
-file:close()
-for line in io.lines("/etc/nginx/variables.env") do
- local variable, value = line:match("^([^=]+)=(.*)$")
- local ok, err = datastore:set("variable_" .. variable, value)
- if not ok then
- logger:log(ngx.ERR, "can't save variable " .. variable .. " into datastore : " .. err)
- return false
- end
- logger:log(ngx.INFO, "saved variable " .. variable .. "=" .. value .. " into datastore")
-end
-logger:log(ngx.NOTICE, "saved variables into datastore")
-
--- Purge cache
-local cachestore = require "bunkerweb.cachestore":new(false, true)
-local ok, err = cachestore:purge()
-if not ok then
- logger:log(ngx.ERR, "can't purge cachestore : " .. err)
-end
-
--- Set API values into the datastore
-logger:log(ngx.NOTICE, "saving API values into datastore ...")
-local value, err = datastore:get("variable_USE_API")
-if not value then
- logger:log(ngx.ERR, "can't get variable USE_API from the datastore : " .. err)
- return false
-end
-if value == "yes" then
- local value, err = datastore:get("variable_API_WHITELIST_IP")
- if not value then
- logger:log(ngx.ERR, "can't get variable API_WHITELIST_IP from the datastore : " .. err)
- return false
- end
- local whitelists = {}
- for whitelist in value:gmatch("%S+") do
- table.insert(whitelists, whitelist)
- end
- local ok, err = datastore:set("api_whitelist_ip", cjson.encode(whitelists))
- if not ok then
- logger:log(ngx.ERR, "can't save API whitelist_ip to datastore : " .. err)
- return false
- end
- logger:log(ngx.INFO, "saved API whitelist_ip into datastore")
-end
-logger:log(ngx.NOTICE, "saved API values into datastore")
-
--- Load plugins into the datastore
-logger:log(ngx.NOTICE, "saving plugins into datastore ...")
-local plugins = {}
-local plugin_paths = {"/usr/share/bunkerweb/core", "/etc/bunkerweb/plugins"}
-for i, plugin_path in ipairs(plugin_paths) do
- local paths = io.popen("find -L " .. plugin_path .. " -maxdepth 1 -type d ! -path " .. plugin_path)
- for path in paths:lines() do
- local ok, plugin = helpers.load_plugin(path .. "/plugin.json")
+ -- Remove previous data from the datastore
+ logger:log(ngx.NOTICE, "deleting old keys from datastore ...")
+ datastore:flush_lru()
+ local data_keys = { "^plugin", "^misc_" }
+ for i, key in pairs(data_keys) do
+ local ok, err = datastore:delete_all(key)
if not ok then
- logger:log(ngx.ERR, plugin)
- else
- local ok, err = datastore:set("plugin_" .. plugin.id, cjson.encode(plugin))
- if not ok then
- logger:log(ngx.ERR, "can't save " .. plugin.id .. " into datastore : " .. err)
- else
- table.insert(plugins, plugin)
- logger:log(ngx.NOTICE, "loaded plugin " .. plugin.id .. " v" .. plugin.version)
- end
+ logger:log(ngx.ERR, "can't delete " .. key .. " from datastore : " .. err)
+ return false
end
+ logger:log(ngx.INFO, "deleted " .. key .. " from datastore")
end
-end
-local ok, err = datastore:set("plugins", cjson.encode(plugins))
-if not ok then
- logger:log(ngx.ERR, "can't save plugins into datastore : " .. err)
- return false
-end
+ logger:log(ngx.NOTICE, "deleted old keys from datastore")
-logger:log(ngx.NOTICE, "saving plugins order into datastore ...")
-local ok, order = helpers.order_plugins(plugins)
-if not ok then
- logger:log(ngx.ERR, "can't compute plugins order : " .. err)
- return false
-end
-for phase, id_list in pairs(order) do
- logger:log(ngx.NOTICE, "plugins order for phase " .. phase .. " : " .. cjson.encode(id_list))
-end
-local ok, err = datastore:set("plugins_order", cjson.encode(order))
-if not ok then
- logger:log(ngx.ERR, "can't save plugins order into datastore : " .. err)
- return false
-end
-logger:log(ngx.NOTICE, "saved plugins order into datastore")
-
--- Call init() method
-logger:log(ngx.NOTICE, "calling init() methods of plugins ...")
-for i, plugin_id in ipairs(order["init"]) do
- -- Require call
- local plugin_lua, err = helpers.require_plugin(plugin_id)
- if plugin_lua == false then
- logger:log(ngx.ERR, err)
- elseif plugin_lua == nil then
- logger:log(ngx.NOTICE, err)
- else
- -- Check if plugin has init method
- if plugin_lua.init ~= nil then
- -- New call
- local ok, plugin_obj = helpers.new_plugin(plugin_lua)
+ -- Load plugins into the datastore
+ logger:log(ngx.NOTICE, "saving plugins into datastore ...")
+ local plugins = {}
+ local plugin_paths = { "/usr/share/bunkerweb/core", "/etc/bunkerweb/plugins" }
+ for i, plugin_path in ipairs(plugin_paths) do
+ local paths = io.popen("find -L " .. plugin_path .. " -maxdepth 1 -type d ! -path " .. plugin_path)
+ for path in paths:lines() do
+ local ok, plugin = helpers.load_plugin(path .. "/plugin.json")
if not ok then
- logger:log(ngx.ERR, plugin_obj)
+ logger:log(ngx.ERR, plugin)
else
- local ok, ret = helpers.call_plugin(plugin_obj, "init")
+ local ok, err = datastore:set("plugin_" .. plugin.id, plugin, true)
if not ok then
- logger:log(ngx.ERR, ret)
- elseif not ret.ret then
- logger:log(ngx.ERR, plugin_id .. ":init() call failed : " .. ret.msg)
+ logger:log(ngx.ERR, "can't save " .. plugin.id .. " into datastore : " .. err)
else
- logger:log(ngx.NOTICE, plugin_id .. ":init() call successful : " .. ret.msg)
+ table.insert(plugins, plugin)
+ logger:log(ngx.NOTICE, "loaded plugin " .. plugin.id .. " v" .. plugin.version)
end
end
- else
- logger:log(ngx.NOTICE, "skipped execution of " .. plugin.id .. " because method init() is not defined")
end
end
-end
-logger:log(ngx.NOTICE, "called init() methods of plugins")
+ local ok, err = datastore:set("plugins", plugins, nil, true)
+ if not ok then
+ logger:log(ngx.ERR, "can't save plugins into datastore : " .. err)
+ return false
+ end
-logger:log(ngx.NOTICE, "init-stream phase ended")
+ -- Load variables into the datastore
+ logger:log(ngx.NOTICE, "saving variables into datastore ...")
+ local file = io.open("/etc/nginx/variables.env")
+ if not file then
+ logger:log(ngx.ERR, "can't open /etc/nginx/variables.env file")
+ return false
+ end
+ file:close()
+ local all_variables = {}
+ for line in io.lines("/etc/nginx/variables.env") do
+ local variable, value = line:match("^([^=]+)=(.*)$")
+ all_variables[variable] = value
+ end
+ local ok, variables = helpers.load_variables(all_variables, plugins)
+ if not ok then
+ logger:log(ngx.ERR, "error while loading variables : " .. variables)
+ return false
+ end
+ local ok, err = datastore:set("variables", variables, nil, true)
+ if not ok then
+ logger:log(ngx.ERR, "can't save plugins into datastore : " .. err)
+ return false
+ end
+ logger:log(ngx.NOTICE, "saved variables into datastore")
+ -- Purge cache
+ local cachestore = require "bunkerweb.cachestore":new(false, true)
+ local ok, err = cachestore:purge()
+ if not ok then
+ logger:log(ngx.ERR, "can't purge cachestore : " .. err)
+ end
+
+ logger:log(ngx.NOTICE, "saving plugins order into datastore ...")
+ local ok, order = helpers.order_plugins(plugins)
+ if not ok then
+ logger:log(ngx.ERR, "can't compute plugins order : " .. err)
+ return false
+ end
+ for phase, id_list in pairs(order) do
+ logger:log(ngx.NOTICE, "plugins order for phase " .. phase .. " : " .. cjson.encode(id_list))
+ end
+ local ok, err = datastore:set("plugins_order", order, nil, true)
+ if not ok then
+ logger:log(ngx.ERR, "can't save plugins order into datastore : " .. err)
+ return false
+ end
+ logger:log(ngx.NOTICE, "saved plugins order into datastore")
+
+ -- Call init() method
+ logger:log(ngx.NOTICE, "calling init() methods of plugins ...")
+ for i, plugin_id in ipairs(order["init"]) do
+ -- Require call
+ local plugin_lua, err = helpers.require_plugin(plugin_id)
+ if plugin_lua == false then
+ logger:log(ngx.ERR, err)
+ elseif plugin_lua == nil then
+ logger:log(ngx.NOTICE, err)
+ else
+ -- Check if plugin has init method
+ if plugin_lua.init ~= nil then
+ -- New call
+ local ok, plugin_obj = helpers.new_plugin(plugin_lua)
+ if not ok then
+ logger:log(ngx.ERR, plugin_obj)
+ else
+ local ok, ret = helpers.call_plugin(plugin_obj, "init")
+ if not ok then
+ logger:log(ngx.ERR, ret)
+ elseif not ret.ret then
+ logger:log(ngx.ERR, plugin_id .. ":init() call failed : " .. ret.msg)
+ else
+ logger:log(ngx.NOTICE, plugin_id .. ":init() call successful : " .. ret.msg)
+ end
+ end
+ else
+ logger:log(ngx.NOTICE, "skipped execution of " .. plugin.id .. " because method init() is not defined")
+ end
+ end
+ end
+ logger:log(ngx.NOTICE, "called init() methods of plugins")
+
+ logger:log(ngx.NOTICE, "init-stream phase ended")
}
diff --git a/src/common/confs/init-worker-lua.conf b/src/common/confs/init-worker-lua.conf
index b7629f12c..f2a3edf86 100644
--- a/src/common/confs/init-worker-lua.conf
+++ b/src/common/confs/init-worker-lua.conf
@@ -1,121 +1,116 @@
lua_shared_dict worker_lock 16k;
init_worker_by_lua_block {
+ -- Our timer function
+ local ready_work = function(premature)
+ -- Libs
+ local helpers = require "bunkerweb.helpers"
+ local cjson = require "cjson"
--- Our timer function
-local ready_work = function(premature)
+ -- Instantiate objects
+ local logger = require "bunkerweb.logger":new("INIT-WORKER")
+ local datastore = require "bunkerweb.datastore":new()
- -- Libs
- local helpers = require "bunkerweb.helpers"
- local cjson = require "cjson"
-
- -- Instantiate objects
- local logger = require "bunkerweb.logger":new("INIT-WORKER")
- local datastore = require "bunkerweb.datastore":new()
-
- -- Don't go further we are in loading state
- local is_loading, err = require "bunkerweb.utils".get_variable("IS_LOADING", false)
- if not is_loading then
- logger:log(ngx.ERR, "utils.get_variable() failed : " .. err)
- return
- elseif is_loading == "yes" then
- return
- end
-
- -- Instantiate lock
- local lock = require "resty.lock":new("worker_lock", {timeout = 10})
- if not lock then
- logger:log(ngx.ERR, "lock:new() failed : " .. err)
- return
- end
-
- -- Acquire lock
- local elapsed, err = lock:lock("ready")
- if elapsed == nil then
- logger:log(ngx.ERR, "lock:lock() failed : " .. err)
- return
- end
-
- -- Check if work is done
- local ok, err = datastore:get("misc_ready")
- if not ok and err ~= "not found" then
- logger:log(ngx.ERR, "datastore:get() failed : " .. err)
- local ok, err = lock:unlock()
- if not ok then
- logger:log(ngx.ERR, "lock:unlock() failed : " .. err)
+ -- Don't go further we are in loading state
+ local is_loading, err = require "bunkerweb.utils".get_variable("IS_LOADING", false)
+ if not is_loading then
+ logger:log(ngx.ERR, "utils.get_variable() failed : " .. err)
+ return
+ elseif is_loading == "yes" then
+ return
end
- return
- end
- if ok then
- local ok, err = lock:unlock()
- if not ok then
- logger:log(ngx.ERR, "lock:unlock() failed : " .. err)
+
+ -- Instantiate lock
+ local lock = require "resty.lock":new("worker_lock", { timeout = 10 })
+ if not lock then
+ logger:log(ngx.ERR, "lock:new() failed : " .. err)
+ return
end
- return
- end
- logger:log(ngx.INFO, "init_worker phase started")
-
- -- Get plugins order
- local order, err = datastore:get("plugins_order")
- if not order then
- logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
- local ok, err = lock:unlock()
- if not ok then
- logger:log(ngx.ERR, "lock:unlock() failed : " .. err)
+ -- Acquire lock
+ local elapsed, err = lock:lock("ready")
+ if elapsed == nil then
+ logger:log(ngx.ERR, "lock:lock() failed : " .. err)
+ return
end
- return
- end
- order = cjson.decode(order)
- -- Call init_worker() methods
- logger:log(ngx.INFO, "calling init_worker() methods of plugins ...")
- for i, plugin_id in ipairs(order.init_worker) do
- -- Require call
- local plugin_lua, err = helpers.require_plugin(plugin_id)
- if plugin_lua == false then
- logger:log(ngx.ERR, err)
- elseif plugin_lua == nil then
- logger:log(ngx.INFO, err)
- else
- -- Check if plugin has init_worker method
- if plugin_lua.init_worker ~= nil then
- -- New call
- local ok, plugin_obj = helpers.new_plugin(plugin_lua)
- if not ok then
- logger:log(ngx.ERR, plugin_obj)
- else
- local ok, ret = helpers.call_plugin(plugin_obj, "init_worker")
- if not ok then
- logger:log(ngx.ERR, ret)
- elseif not ret.ret then
- logger:log(ngx.ERR, plugin_id .. ":init_worker() call failed : " .. ret.msg)
- else
- logger:log(ngx.INFO, plugin_id .. ":init_worker() call successful : " .. ret.msg)
- end
- end
+ -- Check if work is done
+ local ok, err = datastore:get("misc_ready")
+ if not ok and err ~= "not found" then
+ logger:log(ngx.ERR, "datastore:get() failed : " .. err)
+ local ok, err = lock:unlock()
+ if not ok then
+ logger:log(ngx.ERR, "lock:unlock() failed : " .. err)
+ end
+ return
+ end
+ if ok then
+ local ok, err = lock:unlock()
+ if not ok then
+ logger:log(ngx.ERR, "lock:unlock() failed : " .. err)
+ end
+ return
+ end
+
+ logger:log(ngx.INFO, "init_worker phase started")
+
+ -- Get plugins order
+ local order, err = datastore:get("plugins_order", true)
+ if not order then
+ logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
+ local ok, err = lock:unlock()
+ if not ok then
+ logger:log(ngx.ERR, "lock:unlock() failed : " .. err)
+ end
+ return
+ end
+
+ -- Call init_worker() methods
+ logger:log(ngx.INFO, "calling init_worker() methods of plugins ...")
+ for i, plugin_id in ipairs(order.init_worker) do
+ -- Require call
+ local plugin_lua, err = helpers.require_plugin(plugin_id)
+ if plugin_lua == false then
+ logger:log(ngx.ERR, err)
+ elseif plugin_lua == nil then
+ logger:log(ngx.INFO, err)
else
- logger:log(ngx.INFO, "skipped execution of " .. plugin_id .. " because method init_worker() is not defined")
+ -- Check if plugin has init_worker method
+ if plugin_lua.init_worker ~= nil then
+ -- New call
+ local ok, plugin_obj = helpers.new_plugin(plugin_lua)
+ if not ok then
+ logger:log(ngx.ERR, plugin_obj)
+ else
+ local ok, ret = helpers.call_plugin(plugin_obj, "init_worker")
+ if not ok then
+ logger:log(ngx.ERR, ret)
+ elseif not ret.ret then
+ logger:log(ngx.ERR, plugin_id .. ":init_worker() call failed : " .. ret.msg)
+ else
+ logger:log(ngx.INFO, plugin_id .. ":init_worker() call successful : " .. ret.msg)
+ end
+ end
+ else
+ logger:log(ngx.INFO, "skipped execution of " .. plugin_id .. " because method init_worker() is not defined")
+ end
end
end
+ logger:log(ngx.INFO, "called init_worker() methods of plugins")
+
+ -- End
+ local ok, err = datastore:set("misc_ready", "ok")
+ if not ok then
+ logger:log(ngx.ERR, "datastore:set() failed : " .. err)
+ end
+ local ok, err = lock:unlock()
+ if not ok then
+ logger:log(ngx.ERR, "lock:unlock() failed : " .. err)
+ end
+ logger:log(ngx.INFO, "init phase ended")
+ logger:log(ngx.NOTICE, "BunkerWeb is ready to fool hackers ! đ")
end
- logger:log(ngx.INFO, "called init_worker() methods of plugins")
-
- -- End
- local ok, err = datastore:set("misc_ready", "ok")
- if not ok then
- logger:log(ngx.ERR, "datastore:set() failed : " .. err)
- end
- local ok, err = lock:unlock()
- if not ok then
- logger:log(ngx.ERR, "lock:unlock() failed : " .. err)
- end
- logger:log(ngx.INFO, "init phase ended")
- logger:log(ngx.NOTICE, "BunkerWeb is ready to fool hackers ! đ")
-
-end
-
--- Start timer
-ngx.timer.at(5, ready_work)
+ -- Start timer
+ ngx.timer.at(5, ready_work)
}
diff --git a/src/common/confs/nginx.conf b/src/common/confs/nginx.conf
index f284b030a..7bf691d5b 100644
--- a/src/common/confs/nginx.conf
+++ b/src/common/confs/nginx.conf
@@ -15,7 +15,7 @@ load_module /usr/share/bunkerweb/modules/ngx_http_brotli_static_module.so;
load_module /usr/share/bunkerweb/modules/ngx_stream_lua_module.so;
# PID file
-pid /var/tmp/bunkerweb/nginx.pid;
+pid /var/run/bunkerweb/nginx.pid;
# worker number (default = auto)
worker_processes {{ WORKER_PROCESSES }};
@@ -27,7 +27,7 @@ pcre_jit on;
worker_rlimit_nofile {{ WORKER_RLIMIT_NOFILE }};
# error log level
-error_log /var/log/nginx/error.log {{ LOG_LEVEL }};
+error_log /var/log/bunkerweb/error.log {{ LOG_LEVEL }};
# reason env var
env REASON;
diff --git a/src/common/confs/server-http/access-lua.conf b/src/common/confs/server-http/access-lua.conf
index 945296bbf..8d6edc844 100644
--- a/src/common/confs/server-http/access-lua.conf
+++ b/src/common/confs/server-http/access-lua.conf
@@ -1,124 +1,119 @@
access_by_lua_block {
+ local class = require "middleclass"
+ local clogger = require "bunkerweb.logger"
+ local helpers = require "bunkerweb.helpers"
+ local utils = require "bunkerweb.utils"
+ local cdatastore = require "bunkerweb.datastore"
+ local cclusterstore = require "bunkerweb.clusterstore"
+ local cjson = require "cjson"
-local class = require "middleclass"
-local clogger = require "bunkerweb.logger"
-local helpers = require "bunkerweb.helpers"
-local utils = require "bunkerweb.utils"
-local cdatastore = require "bunkerweb.datastore"
-local cclusterstore = require "bunkerweb.clusterstore"
-local cjson = require "cjson"
-
--- Don't process internal requests
-local logger = clogger:new("ACCESS")
-if ngx.req.is_internal() then
- logger:log(ngx.INFO, "skipped access phase because request is internal")
- return true
-end
-
--- Start access phase
-local datastore = cdatastore:new()
-logger:log(ngx.INFO, "access phase started")
-
--- Fill ctx
-logger:log(ngx.INFO, "filling ngx.ctx ...")
-local ok, ret, errors = helpers.fill_ctx()
-if not ok then
- logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
-elseif errors then
- for i, error in ipairs(errors) do
- logger:log(ngx.ERR, "fill_ctx() error " .. tostring(i) .. " : " .. error)
+ -- Don't process internal requests
+ local logger = clogger:new("ACCESS")
+ if ngx.req.is_internal() then
+ logger:log(ngx.INFO, "skipped access phase because request is internal")
+ return true
end
-end
-logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
--- Process bans as soon as possible
-local banned, reason, ttl = utils.is_banned(ngx.ctx.bw.remote_addr)
-if banned == nil then
- logger:log(ngx.ERR, "can't check if IP " .. ngx.ctx.bw.remote_addr .. " is banned : " .. reason)
-elseif banned then
- logger:log(ngx.WARN, "IP " .. ngx.ctx.bw.remote_addr .. " is banned with reason " .. reason .. " (" .. tostring(ttl) .. "s remaining)")
- return ngx.exit(utils.get_deny_status())
-else
- logger:log(ngx.INFO, "IP " .. ngx.ctx.bw.remote_addr .. " is not banned")
-end
+ -- Start access phase
+ local datastore = cdatastore:new()
+ logger:log(ngx.INFO, "access phase started")
--- Get plugins order
-local order, err = datastore:get("plugins_order")
-if not order then
- logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
- return
-end
-order = cjson.decode(order)
-
--- Call access() methods
-logger:log(ngx.INFO, "calling access() methods of plugins ...")
-local status = nil
-local redirect = nil
-for i, plugin_id in ipairs(order.access) do
- -- Require call
- local plugin_lua, err = helpers.require_plugin(plugin_id)
- if plugin_lua == false then
- logger:log(ngx.ERR, err)
- elseif plugin_lua == nil then
- logger:log(ngx.INFO, err)
- else
- -- Check if plugin has access method
- if plugin_lua.access ~= nil then
- -- New call
- local ok, plugin_obj = helpers.new_plugin(plugin_lua)
- if not ok then
- logger:log(ngx.ERR, plugin_obj)
- else
- local ok, ret = helpers.call_plugin(plugin_obj, "access")
- if not ok then
- logger:log(ngx.ERR, ret)
- elseif not ret.ret then
- logger:log(ngx.ERR, plugin_id .. ":access() call failed : " .. ret.msg)
- else
- logger:log(ngx.INFO, plugin_id .. ":access() call successful : " .. ret.msg)
- end
- if ret.status then
- if ret.status == utils.get_deny_status() then
- ngx.ctx.reason = plugin_id
- logger:log(ngx.WARN, "denied access from " .. plugin_id .. " : " .. ret.msg)
- else
- logger:log(ngx.NOTICE, plugin_id .. " returned status " .. tostring(ret.status) .. " : " .. ret.msg)
- end
- status = ret.status
- break
- elseif ret.redirect then
- logger:log(ngx.NOTICE, plugin_id .. " redirect to " .. ret.redirect .. " : " .. ret.msg)
- redirect = ret.redirect
- break
- end
- end
- else
- logger:log(ngx.INFO, "skipped execution of " .. plugin_id .. " because method access() is not defined")
+ -- Fill ctx
+ logger:log(ngx.INFO, "filling ngx.ctx ...")
+ local ok, ret, errors, ctx = helpers.fill_ctx()
+ if not ok then
+ logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
+ elseif errors then
+ for i, error in ipairs(errors) do
+ logger:log(ngx.ERR, "fill_ctx() error " .. tostring(i) .. " : " .. error)
end
end
-end
-logger:log(ngx.INFO, "called access() methods of plugins")
+ logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
--- Save session if needed
--- local ok, err = utils.save_session()
--- if not ok then
--- logger:log(ngx.ERR, "can't save session : " .. err)
--- else
--- logger:log(ngx.INFO, "session save return : " .. err)
--- end
+ -- Process bans as soon as possible
+ if ctx.bw.is_whitelisted ~= "yes" then
+ local banned, reason, ttl = utils.is_banned(ctx.bw.remote_addr)
+ if banned == nil then
+ logger:log(ngx.ERR, "can't check if IP " .. ctx.bw.remote_addr .. " is banned : " .. reason)
+ elseif banned then
+ logger:log(ngx.WARN,
+ "IP " .. ctx.bw.remote_addr .. " is banned with reason " .. reason .. " (" .. tostring(ttl) .. "s remaining)")
+ return ngx.exit(utils.get_deny_status(ctx))
+ else
+ logger:log(ngx.INFO, "IP " .. ctx.bw.remote_addr .. " is not banned")
+ end
+ end
-logger:log(ngx.INFO, "access phase ended")
+ -- Get plugins order
+ local order, err = datastore:get("plugins_order", true)
+ if not order then
+ logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
+ return
+ end
--- Return status if needed
-if status then
- return ngx.exit(status)
-end
+ -- Call access() methods
+ logger:log(ngx.INFO, "calling access() methods of plugins ...")
+ local status = nil
+ local redirect = nil
+ for i, plugin_id in ipairs(order.access) do
+ -- Require call
+ local plugin_lua, err = helpers.require_plugin(plugin_id)
+ if plugin_lua == false then
+ logger:log(ngx.ERR, err)
+ elseif plugin_lua == nil then
+ logger:log(ngx.INFO, err)
+ else
+ -- Check if plugin has access method
+ if plugin_lua.access ~= nil then
+ -- New call
+ local ok, plugin_obj = helpers.new_plugin(plugin_lua, ctx)
+ if not ok then
+ logger:log(ngx.ERR, plugin_obj)
+ else
+ local ok, ret = helpers.call_plugin(plugin_obj, "access")
+ if not ok then
+ logger:log(ngx.ERR, ret)
+ elseif not ret.ret then
+ logger:log(ngx.ERR, plugin_id .. ":access() call failed : " .. ret.msg)
+ else
+ logger:log(ngx.INFO, plugin_id .. ":access() call successful : " .. ret.msg)
+ end
+ if ret.status then
+ if ret.status == utils.get_deny_status(ctx) then
+ ctx.bw.reason = plugin_id
+ logger:log(ngx.WARN, "denied access from " .. plugin_id .. " : " .. ret.msg)
+ else
+ logger:log(ngx.NOTICE, plugin_id .. " returned status " .. tostring(ret.status) .. " : " .. ret.msg)
+ end
+ status = ret.status
+ break
+ elseif ret.redirect then
+ logger:log(ngx.NOTICE, plugin_id .. " redirect to " .. ret.redirect .. " : " .. ret.msg)
+ redirect = ret.redirect
+ break
+ end
+ end
+ else
+ logger:log(ngx.INFO, "skipped execution of " .. plugin_id .. " because method access() is not defined")
+ end
+ end
+ end
+ logger:log(ngx.INFO, "called access() methods of plugins")
--- Redirect if needed
-if redirect then
- return ngx.redirect(redirect)
-end
+ -- Save ctx
+ ngx.ctx = ctx
-return true
+ logger:log(ngx.INFO, "access phase ended")
-}
\ No newline at end of file
+ -- Return status if needed
+ if status then
+ return ngx.exit(status)
+ end
+
+ -- Redirect if needed
+ if redirect then
+ return ngx.redirect(redirect)
+ end
+
+ return true
+}
diff --git a/src/common/confs/server-http/header-lua.conf b/src/common/confs/server-http/header-lua.conf
index a8bf6ff80..871f499fe 100644
--- a/src/common/confs/server-http/header-lua.conf
+++ b/src/common/confs/server-http/header-lua.conf
@@ -1,69 +1,69 @@
header_filter_by_lua_block {
+ local class = require "middleclass"
+ local clogger = require "bunkerweb.logger"
+ local helpers = require "bunkerweb.helpers"
+ local cdatastore = require "bunkerweb.datastore"
+ local cjson = require "cjson"
-local class = require "middleclass"
-local clogger = require "bunkerweb.logger"
-local helpers = require "bunkerweb.helpers"
-local cdatastore = require "bunkerweb.datastore"
-local cjson = require "cjson"
+ -- Start set phase
+ local logger = clogger:new("HEADER")
+ local datastore = cdatastore:new()
+ logger:log(ngx.INFO, "header phase started")
--- Start set phase
-local logger = clogger:new("HEADER")
-local datastore = cdatastore:new()
-logger:log(ngx.INFO, "header phase started")
-
--- Fill ctx
-logger:log(ngx.INFO, "filling ngx.ctx ...")
-local ok, ret, errors = helpers.fill_ctx()
-if not ok then
- logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
-elseif errors then
- for i, error in ipairs(errors) do
- logger:log(ngx.ERR, "fill_ctx() error " .. tostring(i) .. " : " .. error)
- end
-end
-logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
-
--- Get plugins order
-local order, err = datastore:get("plugins_order")
-if not order then
- logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
- return
-end
-order = cjson.decode(order)
-
--- Call header() methods
-logger:log(ngx.INFO, "calling header() methods of plugins ...")
-for i, plugin_id in ipairs(order.header) do
- -- Require call
- local plugin_lua, err = helpers.require_plugin(plugin_id)
- if plugin_lua == false then
- logger:log(ngx.ERR, err)
- elseif plugin_lua == nil then
- logger:log(ngx.INFO, err)
- else
- -- Check if plugin has header method
- if plugin_lua.header ~= nil then
- -- New call
- local ok, plugin_obj = helpers.new_plugin(plugin_lua)
- if not ok then
- logger:log(ngx.ERR, plugin_obj)
- else
- local ok, ret = helpers.call_plugin(plugin_obj, "header")
- if not ok then
- logger:log(ngx.ERR, ret)
- elseif not ret.ret then
- logger:log(ngx.ERR, plugin_id .. ":header() call failed : " .. ret.msg)
- else
- logger:log(ngx.INFO, plugin_id .. ":header() call successful : " .. ret.msg)
- end
- end
- else
- logger:log(ngx.INFO, "skipped execution of " .. plugin_id .. " because method header() is not defined")
+ -- Fill ctx
+ logger:log(ngx.INFO, "filling ngx.ctx ...")
+ local ok, ret, errors, ctx = helpers.fill_ctx()
+ if not ok then
+ logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
+ elseif errors then
+ for i, error in ipairs(errors) do
+ logger:log(ngx.ERR, "fill_ctx() error " .. tostring(i) .. " : " .. error)
end
end
-end
-logger:log(ngx.INFO, "called header() methods of plugins")
+ logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
-return true
+ -- Get plugins order
+ local order, err = datastore:get("plugins_order", true)
+ if not order then
+ logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
+ return
+ end
-}
\ No newline at end of file
+ -- Call header() methods
+ logger:log(ngx.INFO, "calling header() methods of plugins ...")
+ for i, plugin_id in ipairs(order.header) do
+ -- Require call
+ local plugin_lua, err = helpers.require_plugin(plugin_id)
+ if plugin_lua == false then
+ logger:log(ngx.ERR, err)
+ elseif plugin_lua == nil then
+ logger:log(ngx.INFO, err)
+ else
+ -- Check if plugin has header method
+ if plugin_lua.header ~= nil then
+ -- New call
+ local ok, plugin_obj = helpers.new_plugin(plugin_lua, ctx)
+ if not ok then
+ logger:log(ngx.ERR, plugin_obj)
+ else
+ local ok, ret = helpers.call_plugin(plugin_obj, "header")
+ if not ok then
+ logger:log(ngx.ERR, ret)
+ elseif not ret.ret then
+ logger:log(ngx.ERR, plugin_id .. ":header() call failed : " .. ret.msg)
+ else
+ logger:log(ngx.INFO, plugin_id .. ":header() call successful : " .. ret.msg)
+ end
+ end
+ else
+ logger:log(ngx.INFO, "skipped execution of " .. plugin_id .. " because method header() is not defined")
+ end
+ end
+ end
+ logger:log(ngx.INFO, "called header() methods of plugins")
+
+ -- Save ctx
+ ngx.ctx = ctx
+
+ return true
+}
diff --git a/src/common/confs/server-http/log-lua.conf b/src/common/confs/server-http/log-lua.conf
index bb169996c..29ec7d702 100644
--- a/src/common/confs/server-http/log-lua.conf
+++ b/src/common/confs/server-http/log-lua.conf
@@ -1,74 +1,74 @@
log_by_lua_block {
+ local class = require "middleclass"
+ local clogger = require "bunkerweb.logger"
+ local helpers = require "bunkerweb.helpers"
+ local cdatastore = require "bunkerweb.datastore"
+ local cjson = require "cjson"
-local class = require "middleclass"
-local clogger = require "bunkerweb.logger"
-local helpers = require "bunkerweb.helpers"
-local cdatastore = require "bunkerweb.datastore"
-local cjson = require "cjson"
+ -- Start log phase
+ local logger = clogger:new("LOG")
+ local datastore = cdatastore:new()
+ logger:log(ngx.INFO, "log phase started")
--- Start log phase
-local logger = clogger:new("LOG")
-local datastore = cdatastore:new()
-logger:log(ngx.INFO, "log phase started")
-
--- Fill ctx
-logger:log(ngx.INFO, "filling ngx.ctx ...")
-local ok, ret, errors = helpers.fill_ctx()
-if not ok then
- logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
-elseif errors then
- for i, error in ipairs(errors) do
- logger:log(ngx.ERR, "fill_ctx() error " .. tostring(i) .. " : " .. error)
- end
-end
-logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
-
--- Get plugins order
-local order, err = datastore:get("plugins_order")
-if not order then
- logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
- return
-end
-order = cjson.decode(order)
-
--- Call log() methods
-logger:log(ngx.INFO, "calling log() methods of plugins ...")
-for i, plugin_id in ipairs(order.log) do
- -- Require call
- local plugin_lua, err = helpers.require_plugin(plugin_id)
- if plugin_lua == false then
- logger:log(ngx.ERR, err)
- elseif plugin_lua == nil then
- logger:log(ngx.INFO, err)
- else
- -- Check if plugin has log method
- if plugin_lua.log ~= nil then
- -- New call
- local ok, plugin_obj = helpers.new_plugin(plugin_lua)
- if not ok then
- logger:log(ngx.ERR, plugin_obj)
- else
- local ok, ret = helpers.call_plugin(plugin_obj, "log")
- if not ok then
- logger:log(ngx.ERR, ret)
- elseif not ret.ret then
- logger:log(ngx.ERR, plugin_id .. ":log() call failed : " .. ret.msg)
- else
- logger:log(ngx.INFO, plugin_id .. ":log() call successful : " .. ret.msg)
- end
- end
- else
- logger:log(ngx.INFO, "skipped execution of " .. plugin_id .. " because method log() is not defined")
+ -- Fill ctx
+ logger:log(ngx.INFO, "filling ngx.ctx ...")
+ local ok, ret, errors, ctx = helpers.fill_ctx()
+ if not ok then
+ logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
+ elseif errors then
+ for i, error in ipairs(errors) do
+ logger:log(ngx.ERR, "fill_ctx() error " .. tostring(i) .. " : " .. error)
end
end
-end
-logger:log(ngx.INFO, "called log() methods of plugins")
+ logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
--- Display reason at info level
-if ngx.ctx.reason then
- logger:log(ngx.INFO, "client was denied with reason : " .. ngx.ctx.reason)
-end
+ -- Get plugins order
+ local order, err = datastore:get("plugins_order", true)
+ if not order then
+ logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
+ return
+ end
-logger:log(ngx.INFO, "log phase ended")
+ -- Call log() methods
+ logger:log(ngx.INFO, "calling log() methods of plugins ...")
+ for i, plugin_id in ipairs(order.log) do
+ -- Require call
+ local plugin_lua, err = helpers.require_plugin(plugin_id)
+ if plugin_lua == false then
+ logger:log(ngx.ERR, err)
+ elseif plugin_lua == nil then
+ logger:log(ngx.INFO, err)
+ else
+ -- Check if plugin has log method
+ if plugin_lua.log ~= nil then
+ -- New call
+ local ok, plugin_obj = helpers.new_plugin(plugin_lua, ctx)
+ if not ok then
+ logger:log(ngx.ERR, plugin_obj)
+ else
+ local ok, ret = helpers.call_plugin(plugin_obj, "log")
+ if not ok then
+ logger:log(ngx.ERR, ret)
+ elseif not ret.ret then
+ logger:log(ngx.ERR, plugin_id .. ":log() call failed : " .. ret.msg)
+ else
+ logger:log(ngx.INFO, plugin_id .. ":log() call successful : " .. ret.msg)
+ end
+ end
+ else
+ logger:log(ngx.INFO, "skipped execution of " .. plugin_id .. " because method log() is not defined")
+ end
+ end
+ end
+ logger:log(ngx.INFO, "called log() methods of plugins")
+ -- Display reason at info level
+ if ctx.reason then
+ logger:log(ngx.INFO, "client was denied with reason : " .. ctx.reason)
+ end
+
+ -- Save ctx
+ ngx.ctx = ctx
+
+ logger:log(ngx.INFO, "log phase ended")
}
\ No newline at end of file
diff --git a/src/common/confs/server-http/set-lua.conf b/src/common/confs/server-http/set-lua.conf
index 4262454e5..b09953ec4 100644
--- a/src/common/confs/server-http/set-lua.conf
+++ b/src/common/confs/server-http/set-lua.conf
@@ -1,84 +1,84 @@
set $dummy_set "";
set_by_lua_block $dummy_set {
+ local class = require "middleclass"
+ local clogger = require "bunkerweb.logger"
+ local helpers = require "bunkerweb.helpers"
+ local cdatastore = require "bunkerweb.datastore"
+ local ccachestore = require "bunkerweb.cachestore"
+ local cjson = require "cjson"
-local class = require "middleclass"
-local clogger = require "bunkerweb.logger"
-local helpers = require "bunkerweb.helpers"
-local cdatastore = require "bunkerweb.datastore"
-local ccachestore = require "bunkerweb.cachestore"
-local cjson = require "cjson"
-
--- Don't process internal requests
-local logger = clogger:new("SET")
-if ngx.req.is_internal() then
- logger:log(ngx.INFO, "skipped set phase because request is internal")
- return true
-end
-
--- Start set phase
-local datastore = cdatastore:new()
-logger:log(ngx.INFO, "set phase started")
-
--- Update cachestore only once and before any other code
-local cachestore = ccachestore:new()
-local ok, err = cachestore.cache:update()
-if not ok then
- logger:log(ngx.ERR, "can't update cachestore : " .. err)
-end
-
--- Fill ctx
-logger:log(ngx.INFO, "filling ngx.ctx ...")
-local ok, ret, errors = helpers.fill_ctx()
-if not ok then
- logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
-elseif errors then
- for i, error in ipairs(errors) do
- logger:log(ngx.ERR, "fill_ctx() error " .. tostring(i) .. " : " .. error)
+ -- Don't process internal requests
+ local logger = clogger:new("SET")
+ if ngx.req.is_internal() then
+ logger:log(ngx.INFO, "skipped set phase because request is internal")
+ return true
end
-end
-logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
--- Get plugins order
-local order, err = datastore:get("plugins_order")
-if not order then
- logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
- return
-end
-order = cjson.decode(order)
+ -- Start set phase
+ local datastore = cdatastore:new()
+ logger:log(ngx.INFO, "set phase started")
--- Call set() methods
-logger:log(ngx.INFO, "calling set() methods of plugins ...")
-for i, plugin_id in ipairs(order.set) do
- -- Require call
- local plugin_lua, err = helpers.require_plugin(plugin_id)
- if plugin_lua == false then
- logger:log(ngx.ERR, err)
- elseif plugin_lua == nil then
- logger:log(ngx.INFO, err)
- else
- -- Check if plugin has set method
- if plugin_lua.set ~= nil then
- -- New call
- local ok, plugin_obj = helpers.new_plugin(plugin_lua)
- if not ok then
- logger:log(ngx.ERR, plugin_obj)
- else
- local ok, ret = helpers.call_plugin(plugin_obj, "set")
- if not ok then
- logger:log(ngx.ERR, ret)
- elseif not ret.ret then
- logger:log(ngx.ERR, plugin_id .. ":set() call failed : " .. ret.msg)
- else
- logger:log(ngx.INFO, plugin_id .. ":set() call successful : " .. ret.msg)
- end
- end
- else
- logger:log(ngx.INFO, "skipped execution of " .. plugin_id .. " because method set() is not defined")
+ -- Update cachestore only once and before any other code
+ local cachestore = ccachestore:new()
+ local ok, err = cachestore.cache:update()
+ if not ok then
+ logger:log(ngx.ERR, "can't update cachestore : " .. err)
+ end
+
+ -- Fill ctx
+ logger:log(ngx.INFO, "filling ngx.ctx ...")
+ local ok, ret, errors, ctx = helpers.fill_ctx()
+ if not ok then
+ logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
+ elseif errors then
+ for i, error in ipairs(errors) do
+ logger:log(ngx.ERR, "fill_ctx() error " .. tostring(i) .. " : " .. error)
end
end
-end
-logger:log(ngx.INFO, "called set() methods of plugins")
+ logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
-return true
+ -- Get plugins order
+ local order, err = datastore:get("plugins_order", true)
+ if not order then
+ logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
+ return
+ end
-}
\ No newline at end of file
+ -- Call set() methods
+ logger:log(ngx.INFO, "calling set() methods of plugins ...")
+ for i, plugin_id in ipairs(order.set) do
+ -- Require call
+ local plugin_lua, err = helpers.require_plugin(plugin_id)
+ if plugin_lua == false then
+ logger:log(ngx.ERR, err)
+ elseif plugin_lua == nil then
+ logger:log(ngx.INFO, err)
+ else
+ -- Check if plugin has set method
+ if plugin_lua.set ~= nil then
+ -- New call
+ local ok, plugin_obj = helpers.new_plugin(plugin_lua, ctx)
+ if not ok then
+ logger:log(ngx.ERR, plugin_obj)
+ else
+ local ok, ret = helpers.call_plugin(plugin_obj, "set")
+ if not ok then
+ logger:log(ngx.ERR, ret)
+ elseif not ret.ret then
+ logger:log(ngx.ERR, plugin_id .. ":set() call failed : " .. ret.msg)
+ else
+ logger:log(ngx.INFO, plugin_id .. ":set() call successful : " .. ret.msg)
+ end
+ end
+ else
+ logger:log(ngx.INFO, "skipped execution of " .. plugin_id .. " because method set() is not defined")
+ end
+ end
+ end
+ logger:log(ngx.INFO, "called set() methods of plugins")
+
+ -- Save ctx
+ ngx.ctx = ctx
+
+ return true
+}
diff --git a/src/common/confs/server-stream/log-stream-lua.conf b/src/common/confs/server-stream/log-stream-lua.conf
index ee9da1e46..73d434dc3 100644
--- a/src/common/confs/server-stream/log-stream-lua.conf
+++ b/src/common/confs/server-stream/log-stream-lua.conf
@@ -1,74 +1,74 @@
log_by_lua_block {
+ local class = require "middleclass"
+ local clogger = require "bunkerweb.logger"
+ local helpers = require "bunkerweb.helpers"
+ local cdatastore = require "bunkerweb.datastore"
+ local cjson = require "cjson"
-local class = require "middleclass"
-local clogger = require "bunkerweb.logger"
-local helpers = require "bunkerweb.helpers"
-local cdatastore = require "bunkerweb.datastore"
-local cjson = require "cjson"
+ -- Start log phase
+ local logger = clogger:new("LOG")
+ local datastore = cdatastore:new()
+ logger:log(ngx.INFO, "log phase started")
--- Start log phase
-local logger = clogger:new("LOG")
-local datastore = cdatastore:new()
-logger:log(ngx.INFO, "log phase started")
-
--- Fill ctx
-logger:log(ngx.INFO, "filling ngx.ctx ...")
-local ok, ret, errors = helpers.fill_ctx()
-if not ok then
- logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
-elseif errors then
- for i, error in ipairs(errors) do
- logger:log(ngx.ERR, "fill_ctx() error " .. tostring(i) .. " : " .. error)
- end
-end
-logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
-
--- Get plugins order
-local order, err = datastore:get("plugins_order")
-if not order then
- logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
- return
-end
-order = cjson.decode(order)
-
--- Call log_stream() methods
-logger:log(ngx.INFO, "calling log_stream() methods of plugins ...")
-for i, plugin_id in ipairs(order.log_stream) do
- -- Require call
- local plugin_lua, err = helpers.require_plugin(plugin_id)
- if plugin_lua == false then
- logger:log(ngx.ERR, err)
- elseif plugin_lua == nil then
- logger:log(ngx.INFO, err)
- else
- -- Check if plugin has log_stream method
- if plugin_lua.log_stream ~= nil then
- -- New call
- local ok, plugin_obj = helpers.new_plugin(plugin_lua)
- if not ok then
- logger:log(ngx.ERR, plugin_obj)
- else
- local ok, ret = helpers.call_plugin(plugin_obj, "log_stream")
- if not ok then
- logger:log(ngx.ERR, ret)
- elseif not ret.ret then
- logger:log(ngx.ERR, plugin_id .. ":log_stream() call failed : " .. ret.msg)
- else
- logger:log(ngx.INFO, plugin_id .. ":log_stream() call successful : " .. ret.msg)
- end
- end
- else
- logger:log(ngx.INFO, "skipped execution of " .. plugin_id .. " because method log_stream() is not defined")
+ -- Fill ctx
+ logger:log(ngx.INFO, "filling ngx.ctx ...")
+ local ok, ret, errors, ctx = helpers.fill_ctx()
+ if not ok then
+ logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
+ elseif errors then
+ for i, error in ipairs(errors) do
+ logger:log(ngx.ERR, "fill_ctx() error " .. tostring(i) .. " : " .. error)
end
end
-end
-logger:log(ngx.INFO, "called log_stream() methods of plugins")
+ logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
--- Display reason at info level
-if ngx.ctx.reason then
- logger:log(ngx.INFO, "client was denied with reason : " .. ngx.ctx.reason)
-end
+ -- Get plugins order
+ local order, err = datastore:get("plugins_order", true)
+ if not order then
+ logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
+ return
+ end
-logger:log(ngx.INFO, "log phase ended")
+ -- Call log_stream() methods
+ logger:log(ngx.INFO, "calling log_stream() methods of plugins ...")
+ for i, plugin_id in ipairs(order.log_stream) do
+ -- Require call
+ local plugin_lua, err = helpers.require_plugin(plugin_id)
+ if plugin_lua == false then
+ logger:log(ngx.ERR, err)
+ elseif plugin_lua == nil then
+ logger:log(ngx.INFO, err)
+ else
+ -- Check if plugin has log_stream method
+ if plugin_lua.log_stream ~= nil then
+ -- New call
+ local ok, plugin_obj = helpers.new_plugin(plugin_lua, ctx)
+ if not ok then
+ logger:log(ngx.ERR, plugin_obj)
+ else
+ local ok, ret = helpers.call_plugin(plugin_obj, "log_stream")
+ if not ok then
+ logger:log(ngx.ERR, ret)
+ elseif not ret.ret then
+ logger:log(ngx.ERR, plugin_id .. ":log_stream() call failed : " .. ret.msg)
+ else
+ logger:log(ngx.INFO, plugin_id .. ":log_stream() call successful : " .. ret.msg)
+ end
+ end
+ else
+ logger:log(ngx.INFO, "skipped execution of " .. plugin_id .. " because method log_stream() is not defined")
+ end
+ end
+ end
+ logger:log(ngx.INFO, "called log_stream() methods of plugins")
-}
\ No newline at end of file
+ -- Display reason at info level
+ if ctx.reason then
+ logger:log(ngx.INFO, "client was denied with reason : " .. ctx.reason)
+ end
+
+ -- Save ctx
+ ngx.ctx = ctx
+
+ logger:log(ngx.INFO, "log phase ended")
+}
diff --git a/src/common/confs/server-stream/preread-stream-lua.conf b/src/common/confs/server-stream/preread-stream-lua.conf
index b04bbb0fa..9337845f8 100644
--- a/src/common/confs/server-stream/preread-stream-lua.conf
+++ b/src/common/confs/server-stream/preread-stream-lua.conf
@@ -1,104 +1,104 @@
preread_by_lua_block {
+ ngx.ctx
+ local class = require "middleclass"
+ local clogger = require "bunkerweb.logger"
+ local helpers = require "bunkerweb.helpers"
+ local utils = require "bunkerweb.utils"
+ local cdatastore = require "bunkerweb.datastore"
+ local cclusterstore = require "bunkerweb.clusterstore"
+ local cjson = require "cjson"
-local class = require "middleclass"
-local clogger = require "bunkerweb.logger"
-local helpers = require "bunkerweb.helpers"
-local utils = require "bunkerweb.utils"
-local cdatastore = require "bunkerweb.datastore"
-local cclusterstore = require "bunkerweb.clusterstore"
-local cjson = require "cjson"
+ -- Start preread phase
+ local logger = clogger:new("PREREAD")
+ local datastore = cdatastore:new()
+ logger:log(ngx.INFO, "preread phase started")
--- Start preread phase
-local logger = clogger:new("PREREAD")
-local datastore = cdatastore:new()
-logger:log(ngx.INFO, "preread phase started")
-
--- Fill ctx
-logger:log(ngx.INFO, "filling ngx.ctx ...")
-local ok, ret, errors = helpers.fill_ctx()
-if not ok then
- logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
-elseif errors then
- for i, error in ipairs(errors) do
- logger:log(ngx.ERR, "fill_ctx() error " .. tostring(i) .. " : " .. error)
- end
-end
-logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
-
--- Process bans as soon as possible
-local banned, reason, ttl = utils.is_banned(ngx.ctx.bw.remote_addr)
-if banned == nil then
- logger:log(ngx.ERR, "can't check if IP " .. ngx.ctx.bw.remote_addr .. " is banned : " .. reason)
-elseif banned then
- logger:log(ngx.WARN, "IP " .. ngx.ctx.bw.remote_addr .. " is banned with reason " .. reason .. " (" .. tostring(ttl) .. "s remaining)")
- return ngx.exit(utils.get_deny_status())
-else
- logger:log(ngx.INFO, "IP " .. ngx.ctx.bw.remote_addr .. " is not banned")
-end
-
--- Get plugins order
-local order, err = datastore:get("plugins_order")
-if not order then
- logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
- local ok, err = lock:unlock()
+ -- Fill ctx
+ logger:log(ngx.INFO, "filling ngx.ctx ...")
+ local ok, ret, errors, ctx = helpers.fill_ctx()
if not ok then
- logger:log(ngx.ERR, "lock:unlock() failed : " .. err)
- end
- return
-end
-order = cjson.decode(order)
-
--- Call preread() methods
-logger:log(ngx.INFO, "calling preread() methods of plugins ...")
-local status = nil
-for i, plugin_id in ipairs(order.preread) do
- -- Require call
- local plugin_lua, err = helpers.require_plugin(plugin_id)
- if plugin_lua == false then
- logger:log(ngx.ERR, err)
- elseif plugin_lua == nil then
- logger:log(ngx.INFO, err)
- else
- -- Check if plugin has preread method
- if plugin_lua.preread ~= nil then
- -- New call
- local ok, plugin_obj = helpers.new_plugin(plugin_lua)
- if not ok then
- logger:log(ngx.ERR, plugin_obj)
- else
- local ok, ret = helpers.call_plugin(plugin_obj, "preread")
- if not ok then
- logger:log(ngx.ERR, ret)
- elseif not ret.ret then
- logger:log(ngx.ERR, plugin_id .. ":preread() call failed : " .. ret.msg)
- else
- logger:log(ngx.INFO, plugin_id .. ":preread() call successful : " .. ret.msg)
- end
- if ret.status then
- if ret.status == utils.get_deny_status() then
- ngx.ctx.reason = plugin_id
- logger:log(ngx.WARN, "denied preread from " .. plugin_id .. " : " .. ret.msg)
- else
- logger:log(ngx.NOTICE, plugin_id .. " returned status " .. tostring(ret.status) .. " : " .. ret.msg)
- end
- status = ret.status
- break
- end
- end
- else
- logger:log(ngx.INFO, "skipped execution of " .. plugin_id .. " because method preread() is not defined")
+ logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
+ elseif errors then
+ for i, error in ipairs(errors) do
+ logger:log(ngx.ERR, "fill_ctx() error " .. tostring(i) .. " : " .. error)
end
end
-end
-logger:log(ngx.INFO, "called preread() methods of plugins")
+ logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
-logger:log(ngx.INFO, "preread phase ended")
+ -- Process bans as soon as possible
+ if ctx.bw.is_whitelisted ~= "yes" then
+ local banned, reason, ttl = utils.is_banned(ctx.bw.remote_addr)
+ if banned == nil then
+ logger:log(ngx.ERR, "can't check if IP " .. ctx.bw.remote_addr .. " is banned : " .. reason)
+ elseif banned then
+ logger:log(ngx.WARN,
+ "IP " .. ctx.bw.remote_addr .. " is banned with reason " .. reason .. " (" .. tostring(ttl) .. "s remaining)")
+ return ngx.exit(utils.get_deny_status())
+ else
+ logger:log(ngx.INFO, "IP " .. ctx.bw.remote_addr .. " is not banned")
+ end
+ end
--- Return status if needed
-if status then
- return ngx.exit(status)
-end
+ -- Get plugins order
+ local order, err = datastore:get("plugins_order", true)
+ if not order then
+ logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
+ return
+ end
-return true
+ -- Call preread() methods
+ logger:log(ngx.INFO, "calling preread() methods of plugins ...")
+ local status = nil
+ for i, plugin_id in ipairs(order.preread) do
+ -- Require call
+ local plugin_lua, err = helpers.require_plugin(plugin_id)
+ if plugin_lua == false then
+ logger:log(ngx.ERR, err)
+ elseif plugin_lua == nil then
+ logger:log(ngx.INFO, err)
+ else
+ -- Check if plugin has preread method
+ if plugin_lua.preread ~= nil then
+ -- New call
+ local ok, plugin_obj = helpers.new_plugin(plugin_lua, ctx)
+ if not ok then
+ logger:log(ngx.ERR, plugin_obj)
+ else
+ local ok, ret = helpers.call_plugin(plugin_obj, "preread")
+ if not ok then
+ logger:log(ngx.ERR, ret)
+ elseif not ret.ret then
+ logger:log(ngx.ERR, plugin_id .. ":preread() call failed : " .. ret.msg)
+ else
+ logger:log(ngx.INFO, plugin_id .. ":preread() call successful : " .. ret.msg)
+ end
+ if ret.status then
+ if ret.status == utils.get_deny_status(ctx) then
+ ctx.bw.reason = plugin_id
+ logger:log(ngx.WARN, "denied preread from " .. plugin_id .. " : " .. ret.msg)
+ else
+ logger:log(ngx.NOTICE, plugin_id .. " returned status " .. tostring(ret.status) .. " : " .. ret.msg)
+ end
+ status = ret.status
+ break
+ end
+ end
+ else
+ logger:log(ngx.INFO, "skipped execution of " .. plugin_id .. " because method preread() is not defined")
+ end
+ end
+ end
+ logger:log(ngx.INFO, "called preread() methods of plugins")
-}
\ No newline at end of file
+ -- Save ctx
+ ngx.ctx = ctx
+
+ logger:log(ngx.INFO, "preread phase ended")
+
+ -- Return status if needed
+ if status then
+ return ngx.exit(status)
+ end
+
+ return true
+}
diff --git a/src/common/core/antibot/antibot.lua b/src/common/core/antibot/antibot.lua
index 07c235324..528620e18 100644
--- a/src/common/core/antibot/antibot.lua
+++ b/src/common/core/antibot/antibot.lua
@@ -1,23 +1,87 @@
-local class = require "middleclass"
-local plugin = require "bunkerweb.plugin"
-local utils = require "bunkerweb.utils"
-local datastore = require "bunkerweb.datastore"
-local cjson = require "cjson"
-local captcha = require "antibot.captcha"
-local base64 = require "base64"
-local sha256 = require "resty.sha256"
-local str = require "resty.string"
-local http = require "resty.http"
-local template = nil
+local class = require "middleclass"
+local plugin = require "bunkerweb.plugin"
+local utils = require "bunkerweb.utils"
+local cjson = require "cjson"
+local captcha = require "antibot.captcha"
+local base64 = require "base64"
+local sha256 = require "resty.sha256"
+local str = require "resty.string"
+local http = require "resty.http"
+local template = nil
if ngx.shared.datastore then
template = require "resty.template"
end
local antibot = class("antibot", plugin)
-function antibot:initialize()
+function antibot:initialize(ctx)
-- Call parent initialize
- plugin.initialize(self, "antibot")
+ plugin.initialize(self, "antibot", ctx)
+end
+
+function antibot:header()
+ -- Check if access is needed
+ if self.variables["USE_ANTIBOT"] == "no" then
+ return self:ret(true, "antibot not activated")
+ end
+ -- Check if antibot uri
+ if self.ctx.bw.uri ~= self.variables["ANTIBOT_URI"] then
+ return self:ret(true, "Not antibot uri")
+ end
+
+ -- Get session data
+ local session, err = utils.get_session("antibot", self.ctx)
+ if not session then
+ return self:ret(false, "can't get session : " .. err, ngx.HTTP_INTERNAL_SERVER_ERROR)
+ end
+ self.session = session
+ self.session_data = utils.get_session_data(self.session, true, self.ctx)
+ -- Check if session is valid
+ self:check_session()
+
+ -- Don't go further if client resolved the challenge
+ if self.session_data.resolved then
+ if self.ctx.bw.uri == self.variables["ANTIBOT_URI"] then
+ return self:ret(true, "client already resolved the challenge", nil, self.session_data.original_uri)
+ end
+ return self:ret(true, "client already resolved the challenge")
+ end
+
+ local header = "Content-Security-Policy"
+ if self.variables["CONTENT_SECURITY_POLICY_REPORT_ONLY"] == "yes" then
+ header = header .. "-Report-Only"
+ end
+
+ if self.session_data.type == "recaptcha" then
+ ngx.header[header] =
+ "default-src 'none'; form-action 'self'; script-src 'strict-dynamic' 'nonce-" ..
+ self.session_data.nonce_script ..
+ "' https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/ 'unsafe-inline' http: https:; img-src https://www.gstatic.com/recaptcha/ 'self' data:; frame-src https://www.google.com/recaptcha/ https://recaptcha.google.com/recaptcha/; style-src 'self' 'nonce-" ..
+ self.session_data.nonce_style ..
+ "'; font-src 'self' https://fonts.gstatic.com data:; base-uri 'self';"
+ elseif self.session_data.type == "hcaptcha" then
+ ngx.header[header] =
+ "default-src 'none'; form-action 'self'; script-src 'strict-dynamic' 'nonce-" ..
+ self.session_data.nonce_script ..
+ "' https://hcaptcha.com https://*.hcaptcha.com 'unsafe-inline' http: https:; img-src 'self' data:; frame-src https://hcaptcha.com https://*.hcaptcha.com; style-src 'self' 'nonce-" ..
+ self.session_data.nonce_style ..
+ "' https://hcaptcha.com https://*.hcaptcha.com; connect-src https://hcaptcha.com https://*.hcaptcha.com; font-src 'self' data:; base-uri 'self';"
+ elseif self.session_data.type == "turnstile" then
+ ngx.header[header] =
+ "default-src 'none'; form-action 'self'; script-src 'strict-dynamic' 'nonce-" ..
+ self.session_data.nonce_script ..
+ "' https://challenges.cloudflare.com 'unsafe-inline' http: https:; img-src 'self' data:; frame-src https://challenges.cloudflare.com; style-src 'self' 'nonce-" ..
+ self.session_data.nonce_style ..
+ "'; font-src 'self' data:; base-uri 'self';"
+ else
+ ngx.header[header] =
+ "default-src 'none'; form-action 'self'; script-src 'strict-dynamic' 'nonce-" ..
+ self.session_data.nonce_script ..
+ "' 'unsafe-inline' http: https:; img-src 'self' data:; style-src 'self' 'nonce-" ..
+ self.session_data.nonce_style ..
+ "'; font-src 'self' data:; base-uri 'self';"
+ end
+ return self:ret(true, "Successfully overridden CSP header")
end
function antibot:access()
@@ -27,18 +91,18 @@ function antibot:access()
end
-- Get session data
- local session, err = utils.get_session("antibot")
+ local session, err = utils.get_session("antibot", self.ctx)
if not session then
return self:ret(false, "can't get session : " .. err, ngx.HTTP_INTERNAL_SERVER_ERROR)
end
self.session = session
- self.session_data = utils.get_session_data(self.session)
+ self.session_data = utils.get_session_data(self.session, true, self.ctx)
-- Check if session is valid
self:check_session()
-- Don't go further if client resolved the challenge
if self.session_data.resolved then
- if ngx.ctx.bw.uri == self.variables["ANTIBOT_URI"] then
+ if self.ctx.bw.uri == self.variables["ANTIBOT_URI"] then
return self:ret(true, "client already resolved the challenge", nil, self.session_data.original_uri)
end
return self:ret(true, "client already resolved the challenge")
@@ -52,7 +116,7 @@ function antibot:access()
end
-- Redirect to challenge page
- if ngx.ctx.bw.uri ~= self.variables["ANTIBOT_URI"] then
+ if self.ctx.bw.uri ~= self.variables["ANTIBOT_URI"] then
return self:ret(true, "redirecting client to the challenge uri", nil, self.variables["ANTIBOT_URI"])
end
@@ -62,13 +126,13 @@ function antibot:access()
end
-- Display challenge needed
- if ngx.ctx.bw.request_method == "GET" then
- ngx.ctx.bw.antibot_display_content = true
+ if self.ctx.bw.request_method == "GET" then
+ self.ctx.bw.antibot_display_content = true
return self:ret(true, "displaying challenge to client", ngx.OK)
end
-- Check challenge
- if ngx.ctx.bw.request_method == "POST" then
+ if self.ctx.bw.request_method == "POST" then
local ok, err, redirect = self:check_challenge()
local set_ok, set_err = self:set_session_data()
if not set_ok then
@@ -87,12 +151,12 @@ function antibot:access()
if not ok then
return self:ret(false, "can't save session : " .. err, ngx.HTTP_INTERNAL_SERVER_ERROR)
end
- ngx.ctx.bw.antibot_display_content = true
+ self.ctx.bw.antibot_display_content = true
return self:ret(true, "displaying challenge to client", ngx.OK)
end
-- Method is suspicious, let's deny the request
- return self:ret(true, "unsupported HTTP method for antibot", utils.get_deny_status())
+ return self:ret(true, "unsupported HTTP method for antibot", utils.get_deny_status(self.ctx))
end
function antibot:content()
@@ -102,17 +166,17 @@ function antibot:content()
end
-- Check if display content is needed
- if not ngx.ctx.bw.antibot_display_content then
+ if not self.ctx.bw.antibot_display_content then
return self:ret(true, "display content not needed", nil, "/")
end
-- Get session data
- local session, err = utils.get_session("antibot")
+ local session, err = utils.get_session("antibot", self.ctx)
if not session then
return self:ret(false, "can't get session : " .. err, ngx.HTTP_INTERNAL_SERVER_ERROR)
end
self.session = session
- self.session_data = utils.get_session_data(self.session)
+ self.session_data = utils.get_session_data(self.session, true, self.ctx)
-- Direct access without session
if not self.session_data.prepared then
@@ -155,7 +219,7 @@ end
function antibot:set_session_data()
if self.session_updated then
- local ok, err = utils.set_session_data(self.session, self.session_data)
+ local ok, err = utils.set_session_data(self.session, self.session_data, true, self.ctx)
if not ok then
return false, err
end
@@ -172,16 +236,18 @@ function antibot:prepare_challenge()
self.session_data.time_resolve = ngx.now()
self.session_data.type = self.variables["USE_ANTIBOT"]
self.session_data.resolved = false
- self.session_data.original_uri = ngx.ctx.bw.request_uri
- if ngx.ctx.bw.uri == self.variables["ANTIBOT_URI"] then
+ self.session_data.original_uri = self.ctx.bw.request_uri
+ self.session_data.nonce_script = utils.rand(16)
+ self.session_data.nonce_style = utils.rand(16)
+ if self.ctx.bw.uri == self.variables["ANTIBOT_URI"] then
self.session_data.original_uri = "/"
end
- if self.variables["USE_ANTIBOT"] == "cookie" then
+ if self.session_data.type == "cookie" then
self.session_data.resolved = true
self.session_data.time_valid = ngx.now()
- elseif self.variables["USE_ANTIBOT"] == "javascript" then
+ elseif self.session_data.type == "javascript" then
self.session_data.random = utils.rand(20)
- elseif self.variables["USE_ANTIBOT"] == "captcha" then
+ elseif self.session_data.type == "captcha" then
self.session_data.captcha = utils.rand(6, true)
end
end
@@ -195,16 +261,18 @@ function antibot:display_challenge()
-- Common variables for templates
local template_vars = {
- antibot_uri = self.variables["ANTIBOT_URI"]
+ antibot_uri = self.variables["ANTIBOT_URI"],
+ nonce_script = self.session_data.nonce_script,
+ nonce_style = self.session_data.nonce_style,
}
-- Javascript case
- if self.variables["USE_ANTIBOT"] == "javascript" then
+ if self.session_data.type == "javascript" then
template_vars.random = self.session_data.random
end
-- Captcha case
- if self.variables["USE_ANTIBOT"] == "captcha" then
+ if self.session_data.type == "captcha" then
local chall_captcha = captcha.new()
chall_captcha:font("/usr/share/bunkerweb/core/antibot/files/font.ttf")
chall_captcha:string(self.session_data.captcha)
@@ -213,17 +281,22 @@ function antibot:display_challenge()
end
-- reCAPTCHA case
- if self.variables["USE_ANTIBOT"] == "recaptcha" then
+ if self.session_data.type == "recaptcha" then
template_vars.recaptcha_sitekey = self.variables["ANTIBOT_RECAPTCHA_SITEKEY"]
end
-- hCaptcha case
- if self.variables["USE_ANTIBOT"] == "hcaptcha" then
+ if self.session_data.type == "hcaptcha" then
template_vars.hcaptcha_sitekey = self.variables["ANTIBOT_HCAPTCHA_SITEKEY"]
end
+ -- Turnstile case
+ if self.session_data.type == "turnstile" then
+ template_vars.turnstile_sitekey = self.variables["ANTIBOT_TURNSTILE_SITEKEY"]
+ end
+
-- Render content
- template.render(self.variables["USE_ANTIBOT"] .. ".html", template_vars)
+ template.render(self.session_data.type .. ".html", template_vars)
return true, "displayed challenge"
end
@@ -235,14 +308,12 @@ function antibot:check_challenge()
end
local resolved = false
- local err = ""
- local redirect = nil
self.session_data.prepared = false
self.session_updated = true
-- Javascript case
- if self.variables["USE_ANTIBOT"] == "javascript" then
+ if self.session_data.type == "javascript" then
ngx.req.read_body()
local args, err = ngx.req.get_post_args(1)
if err == "truncated" or not args or not args["challenge"] then
@@ -261,7 +332,7 @@ function antibot:check_challenge()
end
-- Captcha case
- if self.variables["USE_ANTIBOT"] == "captcha" then
+ if self.session_data.type == "captcha" then
ngx.req.read_body()
local args, err = ngx.req.get_post_args(1)
if err == "truncated" or not args or not args["captcha"] then
@@ -276,7 +347,7 @@ function antibot:check_challenge()
end
-- reCAPTCHA case
- if self.variables["USE_ANTIBOT"] == "recaptcha" then
+ if self.session_data.type == "recaptcha" then
ngx.req.read_body()
local args, err = ngx.req.get_post_args(1)
if err == "truncated" or not args or not args["token"] then
@@ -289,8 +360,8 @@ function antibot:check_challenge()
local res, err = httpc:request_uri("https://www.google.com/recaptcha/api/siteverify", {
method = "POST",
body = "secret=" ..
- self.variables["ANTIBOT_RECAPTCHA_SECRET"] ..
- "&response=" .. args["token"] .. "&remoteip=" .. ngx.ctx.bw.remote_addr,
+ self.variables["ANTIBOT_RECAPTCHA_SECRET"] ..
+ "&response=" .. args["token"] .. "&remoteip=" .. self.ctx.bw.remote_addr,
headers = {
["Content-Type"] = "application/x-www-form-urlencoded"
}
@@ -312,7 +383,7 @@ function antibot:check_challenge()
end
-- hCaptcha case
- if self.variables["USE_ANTIBOT"] == "hcaptcha" then
+ if self.session_data.type == "hcaptcha" then
ngx.req.read_body()
local args, err = ngx.req.get_post_args(1)
if err == "truncated" or not args or not args["token"] then
@@ -325,8 +396,8 @@ function antibot:check_challenge()
local res, err = httpc:request_uri("https://hcaptcha.com/siteverify", {
method = "POST",
body = "secret=" ..
- self.variables["ANTIBOT_HCAPTCHA_SECRET"] ..
- "&response=" .. args["token"] .. "&remoteip=" .. ngx.ctx.bw.remote_addr,
+ self.variables["ANTIBOT_HCAPTCHA_SECRET"] ..
+ "&response=" .. args["token"] .. "&remoteip=" .. self.ctx.bw.remote_addr,
headers = {
["Content-Type"] = "application/x-www-form-urlencoded"
}
@@ -347,6 +418,42 @@ function antibot:check_challenge()
return true, "resolved", self.session_data.original_uri
end
+ -- Turnstile case
+ if self.session_data.type == "turnstile" then
+ ngx.req.read_body()
+ local args, err = ngx.req.get_post_args(1)
+ if err == "truncated" or not args or not args["token"] then
+ return nil, "missing challenge arg", nil
+ end
+ local httpc, err = http.new()
+ if not httpc then
+ return nil, "can't instantiate http object : " .. err, nil, nil
+ end
+ local res, err = httpc:request_uri("https://challenges.cloudflare.com/turnstile/v0/siteverify", {
+ method = "POST",
+ body = "secret=" ..
+ self.variables["ANTIBOT_TURNSTILE_SECRET"] ..
+ "&response=" .. args["token"] .. "&remoteip=" .. self.ctx.bw.remote_addr,
+ headers = {
+ ["Content-Type"] = "application/x-www-form-urlencoded"
+ }
+ })
+ httpc:close()
+ if not res then
+ return nil, "can't send request to Turnstile API : " .. err, nil
+ end
+ local ok, tdata = pcall(cjson.decode, res.body)
+ if not ok then
+ return nil, "error while decoding JSON from Turnstile API : " .. data, nil
+ end
+ if not tdata.success then
+ return false, "client failed challenge", nil
+ end
+ self.session_data.resolved = true
+ self.session_data.time_valid = ngx.now()
+ return true, "resolved", self.session_data.original_uri
+ end
+
return nil, "unknown", nil
end
diff --git a/src/common/core/antibot/confs/server-http/antibot.conf b/src/common/core/antibot/confs/server-http/antibot.conf
index bf47d9b84..8480c67ab 100644
--- a/src/common/core/antibot/confs/server-http/antibot.conf
+++ b/src/common/core/antibot/confs/server-http/antibot.conf
@@ -3,17 +3,24 @@ location {{ ANTIBOT_URI }} {
default_type 'text/html';
root /usr/share/bunkerweb/core/antibot/files;
content_by_lua_block {
-
- local cantibot = require "antibot.antibot"
- local clogger = require "bunkerweb.logger"
- local antibot = cantibot:new()
- local logger = clogger:new("ANTIBOT")
- local ret = antibot:content()
+ local logger = require "bunkerweb.logger":new("ANTIBOT")
+ local helpers = require "bunkerweb.helpers"
+ local ok, ret, errors, ctx = helpers.fill_ctx()
+ if not ok then
+ logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
+ elseif errors then
+ for i, error in ipairs(errors) do
+ logger:log(ngx.ERR, "fill_ctx() error " .. tostring(i) .. " : " .. error)
+ end
+ end
+ local antibot = require "antibot.antibot":new(ctx)
+ local ret = antibot:content()
if not ret.ret then
logger:log(ngx.ERR, "antibot:content() failed : " .. ret.msg)
else
logger:log(ngx.INFO, "antibot:content() success : " .. ret.msg)
end
+ ngx.ctx = ctx
}
}
{% endif %}
\ No newline at end of file
diff --git a/src/common/core/antibot/files/captcha.html b/src/common/core/antibot/files/captcha.html
index 0c24172f7..dd28fb010 100644
--- a/src/common/core/antibot/files/captcha.html
+++ b/src/common/core/antibot/files/captcha.html
@@ -1,241 +1,286 @@
-{-raw-}
-
-
-
-
-
-
- Bot Detection
-
-
-
-
-
-