BunkerWeb Documentation v1.5.8
BunkerWeb Documentation v1.5.8
Table of Contents
1 Introduction
1.1 Overview
1.2 Why BunkerWeb ?
1.3 Security features
1.4 Demo
1.5 BunkerWeb Cloud
1.6 PRO version
1.7 Professional services
1.8 Ecosystem, community and resources
2 Concepts
2.1 Integrations
2.2 Settings
2.3 Multisite mode
2.4 Custom configurations
2.5 Database
2.6 Scheduler
3 Integrations
3.1 BunkerWeb Cloud
3.2 Docker
3.2.1 Environment variables
3.2.2 Scheduler
3.2.3 Networks
3.2.4 Full compose file
3.3 Linux
3.4 Docker autoconf
3.5 Kubernetes
3.6 Swarm
3.7 Microsoft Azure
4 Quickstart guide
4.1 Protect HTTP applications
4.1.1 Single application
4.1.2 Multiple applications
4.2 Behind load balancer or reverse proxy
1 / 263
BunkerWeb documentation v1.5.8
5 Security tuning
5.1 HTTP protocol
5.1.1 Deny status code
5.1.2 Default server
5.1.3 Allowed methods
5.1.4 Max sizes
5.1.5 Serve files
5.1.6 Headers
5.2 HTTPS / SSL/TLS
5.2.1 Let's Encrypt
5.2.2 Let's Encrypt DNS
5.2.3 Custom certificate
5.2.4 Self-signed
5.3 ModSecurity
5.3.1 Custom configurations
5.4 Bad behavior
5.5 Antibot
5.6 Blacklisting, whitelisting and greylisting
5.6.1 Blacklisting
5.6.2 Greylisting
5.6.3 Whitelisting
5.7 Reverse scan
5.8 BunkerNet
5.8.1 CrowdSec Console integration
5.9 DNSBL
5.10 Limiting
5.10.1 Connections
5.10.2 Requests
5.11 Country
5.12 Authentication
5.12.1 Auth basic
5.12.2 Auth request
5.13 Monitoring and reporting
2 / 263
BunkerWeb documentation v1.5.8
5.13.1 Monitoring
5.13.2 Prometheus exporter
5.13.3 Reporting
5.14 Backup and restore
5.14.1 Backup
5.14.2 Backup S3
5.15 Migration
5.15.1 Create a migration file
5.15.2 Initialize a migration
6 Settings
6.1 Global settings
6.2 Antibot
6.3 Auth basic
6.4 Backup
6.5 Backup S3
6.6 Bad behavior
6.7 Blacklist
6.8 Brotli
6.9 BunkerNet
6.10 CORS
6.11 Client cache
6.12 Country
6.13 Custom HTTPS certificate
6.14 DB
6.15 DNSBL
6.16 Errors
6.17 Greylist
6.18 Gzip
6.19 HTML injection
6.20 Headers
6.21 Let's Encrypt
6.22 Let's Encrypt DNS
6.23 Limit
6.24 Metrics
6.25 Migration
6.26 Miscellaneous
6.27 ModSecurity
6.28 Monitoring
6.29 PHP
3 / 263
BunkerWeb documentation v1.5.8
6.30 Pro
6.31 Prometheus exporter
6.32 Real IP
6.33 Redirect
6.34 Redis
6.35 Reporting
6.36 Reverse proxy
6.37 Reverse scan
6.38 Self-signed certificate
6.39 Sessions
6.40 UI
6.41 Whitelist
7 Web UI
7.1 Overview
7.2 Features
7.3 Prerequisites
7.4 Setup wizard
7.5 Account management
7.5.1 Upgrade to PRO
7.5.2 Username / Password
7.5.3 Two-Factor Authentication
7.6 Advanced installation
8 Upgrading
8.1 Upgrade from 1.5.X
8.1.1 Procedure
8.1.2 Rollback
8.2 Upgrade from 1.4.X
8.2.1 Scheduler
8.2.2 Database
8.2.3 Redis
8.2.4 Default values and new settings
9 Troubleshooting
9.1 Logs
9.2 Permissions
9.3 Disable security checks
9.4 ModSecurity
9.5 Bad Behavior
9.6 IP unban
4 / 263
BunkerWeb documentation v1.5.8
9.7 Whitelisting
9.8 Timezone
9.9 Web UI
10 Plugins
10.1 Official plugins
10.2 How to use a plugin
10.2.1 Automatic
10.2.2 Manual
10.3 Writing a plugin
10.3.1 Structure
10.3.2 Getting started
10.3.3 Metadata
10.3.4 Configurations
10.3.5 LUA
10.3.6 Jobs
10.3.7 Plugin page
11 Professional services
11.1 Why should I get professional services ?
11.2 Which professional services do you offer ?
11.3 How can I get more information ?
12 About
12.1 Who maintains BunkerWeb ?
12.2 Do you have a professional version ?
12.3 Do you offer professional services ?
12.4 Where to get community support ?
12.5 How can I contribute ?
12.6 How to report security issue ?
5 / 263
BunkerWeb documentation v1.5.8
1 Introduction
1.1 Overview
Being a full-featured web server (based on NGINX under the hood), it will protect your web services to make them
"secure by default". BunkerWeb integrates seamlessly into your existing environments (Linux, Docker, Swarm,
Kubernetes, …) and is fully configurable (don't panic, there is an awesome 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 as part of the core but can be easily extended with additional ones
thanks to a plugin system.
Easy integration into existing environments : Seamlessly integrate BunkerWeb into various environments
such as Linux, Docker, Swarm, Kubernetes and more. Enjoy a smooth transition and hassle-free implementation.
6 / 263
BunkerWeb documentation v1.5.8
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, embracing the principles of
freedom and openness. Enjoy the freedom to use, modify, and distribute the software, backed by a supportive
community.
Professional services : Get technical support, tailored consulting and custom development directly from the
maintainers of BunkerWeb. Visit the BunkerWeb Panel for more information.
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.
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.
7 / 263
BunkerWeb documentation v1.5.8
To delve deeper into the core security features, we invite you to explore the security tuning section of the
documentation. Discover how BunkerWeb empowers you to fine-tune and optimize security measures according to
your specific needs.
1.4 Demo
A demo website protected with BunkerWeb is available at demo.bunkerweb.io. Feel free to visit it and perform some
security tests.
Try our BunkerWeb Cloud beta offer for free and get access to :
You will find more information about BunkerWeb Cloud in the FAQ page of the BunkerWeb panel.
8 / 263
BunkerWeb documentation v1.5.8
Whether it's enhanced security, an enriched user experience, or technical monitoring, the BunkerWeb PRO version
will allow you to fully benefit from BunkerWeb and respond to your professional needs.
Be it in the documentation or the user interface, the PRO features are annotated with a crown to distinguish
them from those integrated into the open-source version.
You can upgrade from the open-source version to the PRO one easily and at any time you want. The process is
pretty straightforward :
Once connected to the client area, copy your PRO license key
Paste your private key into BunkerWeb using the web UI or specific setting
Do not hesitate to visit the BunkerWeb panel or contact us if you have any question regarding the PRO version.
You will find more information by visiting the BunkerWeb Panel, our dedicated platform for professional services.
Don't hesitate to contact us if you have any question, we will be more than happy to respond to your needs.
Panel : dedicated platform to order and manage professional services (e.g. technical support) around BunkerWeb
Demo : demonstration website of BunkerWeb, don't hesitate to attempt attacks to test the robustness of the
solution
Threatmap : live cyber attack blocked by BunkerWeb instances all around the world
Discord
9 / 263
BunkerWeb documentation v1.5.8
10 / 263
BunkerWeb documentation v1.5.8
2 Concepts
2.1 Integrations
The first concept is the integration of BunkerWeb into the target environment. We prefer to use the word "integration"
instead of "installation" because one of the goals of BunkerWeb is to integrate seamlessly into existing
environments.
Docker
Linux
Docker autoconf
Kubernetes
Swarm
11 / 263
BunkerWeb documentation v1.5.8
If you think that a new integration should be supported, do not hesitate to open a new issue on the GitHub repository.
Going further
The technical details of all BunkerWeb integrations are available in the integrations section of the documentation.
2.2 Settings
Pro settings
Some plugins are reserved for the pro version. Find out more about the pro version here.
Once BunkerWeb is integrated into your environment, you will need to configure it to serve and protect your web
applications.
The configuration of BunkerWeb is done by using what we call the "settings" or "variables". Each setting is identified
by a name such as AUTO_LETS_ENCRYPT or USE_ANTIBOT . You can assign values to the settings to configure
BunkerWeb.
SERVER_NAME=www.example.com
AUTO_LETS_ENCRYPT=yes
USE_ANTIBOT=captcha
REFERRER_POLICY=no-referrer
USE_MODSECURITY=no
USE_GZIP=yes
USE_BROTLI=no
Going further
The complete list of available settings with descriptions and possible values is available in the settings section of the
documentation.
To help you tune BunkerWeb, we offer an easy-to-use settings generator tool available at config.bunkerweb.io.
12 / 263
BunkerWeb documentation v1.5.8
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). These
virtual hosts enable the serving of multiple web applications from a single instance or cluster.
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.
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 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 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.
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.
MULTISITE=yes
SERVER_NAME=app1.example.com app2.example.com app3.example.com
AUTO_LETS_ENCRYPT=yes
USE_GZIP=yes
USE_BROTLI=yes
app1.example.com_USE_ANTIBOT=javascript
app1.example.com_USE_MODSECURITY=no
app2.example.com_USE_ANTIBOT=cookie
app2.example.com_WHITELIST_COUNTRY=FR
app3.example.com_USE_BAD_BEHAVIOR=no
Going further
You will find concrete examples of multisite mode in the quickstart guide of the documentation and the examples
directory of the repository.
13 / 263
BunkerWeb documentation v1.5.8
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 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 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.
Going further
You will find concrete examples of custom configurations in the quickstart guide of the documentation and the
examples directory of the repository.
2.5 Database
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 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.
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.
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.
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.
14 / 263
BunkerWeb documentation v1.5.8
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.
15 / 263
BunkerWeb documentation v1.5.8
actions_file longblob
bw_custom_configs bw_services_settings
actions_checksum varchar[128]
id int service_id varchar[64] bw_settings
pro_status pro_status_enum
pro_services int
pro_overlapped boolean
last_pro_check datetime
first_config_saved boolean
autoconf_loaded boolean
scheduler_first_start boolean
custom_configs_changed boolean
external_plugins_changed boolean
pro_plugins_changed boolean
config_changed boolean
instances_changed boolean
integration integrations
version varchar
2.6 Scheduler
16 / 263
BunkerWeb documentation v1.5.8
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 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.
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.
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.
17 / 263
BunkerWeb documentation v1.5.8
3 Integrations
Beta phase
BunkerWeb Cloud offer is in beta phase. We are actively getting feedbacks from our precious beta tester to improve the
offer.
BunkerWeb Cloud is the easiest way to get started with BunkerWeb. It offers you a fully managed BunkerWeb
service with no hassle. Think of a like a BunkerWeb-as-a-Service !
You will find more information about BunkerWeb Cloud beta here and you can apply for free in the BunkerWeb
panel.
3.2 Docker
18 / 263
BunkerWeb documentation v1.5.8
Utilizing BunkerWeb as a Docker container offers a convenient and straightforward approach for testing and utilizing
the solution, particularly if you are already familiar with Docker technology.
To facilitate your Docker deployment, we provide readily available prebuilt images on Docker Hub, supporting
multiple architectures. These prebuilt images are optimized and prepared for use on the following architectures:
x64 (64-bit)
x86
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.
19 / 263
BunkerWeb documentation v1.5.8
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.
Docker images are also available on GitHub packages and can be downloaded using the ghcr.io repository
address :
Alternatively, if you prefer a more hands-on approach, you have the option to build the Docker image directly from
the source. 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.
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.
20 / 263
BunkerWeb documentation v1.5.8
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.
Database backend
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 folder of the repository for more information.
...
services:
mybunker:
image: bunkerity/bunkerweb:1.5.8
labels:
- "bunkerweb.INSTANCE=yes"
environment:
- MY_SETTING=value
- ANOTHER_SETTING=another value
...
Please note that the bunkerweb.INSTANCE is mandatory to make sure the scheduler can detect BunkerWeb
instance(s).
Full list
For the complete list of environment variables, see the settings section of the documentation.
3.2.2 Scheduler
The scheduler is executed in its own container which is also available on Docker Hub :
Alternatively, you can build the Docker image directly from the source (less coffee ☕ needed than BunkerWeb
image) :
21 / 263
BunkerWeb documentation v1.5.8
A volume is needed to store the SQLite database that will be used by the scheduler :
...
services:
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
volumes:
- bw-data:/data
...
volumes:
bw-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 :
If you are using Docker in rootless mode or podman, UIDs and GIDs in the container will be mapped to different ones in
the host. You will first need to check your initial subuid and subgid :
For example, if you have a value of 100000, the mapped UID/GID will be 100100 (100000 + 100) :
shell
sudo chgrp -R 100100 bw-data && \
chmod -R 770 bw-data
22 / 263
BunkerWeb documentation v1.5.8
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.
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).
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.
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 :
...
services:
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
env:
- DOCKER_HOST=tcp://bw-docker:2375
...
bw-docker:
image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- CONTAINERS=1
- LOG_LEVEL=warning
...
If you are using Docker in rootless mode, 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 .
3.2.3 Networks
By default, BunkerWeb container is listening (inside the container) on 8080/tcp for HTTP and 8443/tcp for HTTPS.
23 / 263
BunkerWeb documentation v1.5.8
If you are using Docker in rootless mode and want to redirect privileged ports (< 1024) like 80 and 443 to BunkerWeb,
please refer to the prerequisites here.
If you are using podman you can lower the minimum number for unprivileged ports :
The typical BunkerWeb stack when using the Docker integration contains the following containers :
BunkerWeb
Scheduler
Your services
For defense in depth purposes, we strongly recommend to create at least three different Docker networks :
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:
24 / 263
BunkerWeb documentation v1.5.8
...
services:
mybunker:
image: bunkerity/bunkerweb:1.5.8
ports:
- 80:8080
- 443:8443
networks:
- bw-services
- bw-universe
...
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
networks:
- bw-universe
- bw-docker
...
bw-docker:
image: tecnativa/docker-socket-proxy:nightly
networks:
- bw-docker
...
networks:
bw-universe:
name: bw-universe
ipam:
driver: default
config:
- subnet: 10.20.30.0/24
bw-services:
name: bw-services
bw-docker:
name: bw-docker
25 / 263
BunkerWeb documentation v1.5.8
version: "3.5"
services:
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
ports:
- 80:8080
- 443:8443
labels:
- "bunkerweb.INSTANCE=yes"
environment:
- SERVER_NAME=www.example.com
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
networks:
- bw-universe
- bw-services
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
depends_on:
- bunkerweb
- bw-docker
volumes:
- bw-data:/data
environment:
- DOCKER_HOST=tcp://bw-docker:2375
networks:
- bw-universe
- bw-docker
bw-docker:
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
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe
ipam:
driver: default
config:
- subnet: 10.20.30.0/24
bw-services:
name: bw-services
bw-docker:
name: bw-docker
3.3 Linux
26 / 263
BunkerWeb documentation v1.5.8
Supported Linux distributions for BunkerWeb (amd64/x86_64 and arm64/aarch64 architectures) include:
Debian 12 "Bookworm"
Fedora 40
Please ensure that you have NGINX 1.26.1 installed before installing BunkerWeb. For all distributions, except
Fedora, it is mandatory to use prebuilt packages from the official NGINX repository. 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.
27 / 263
BunkerWeb documentation v1.5.8
To simplify the installation process, Linux package repositories for BunkerWeb are available on PackageCloud. 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 instructions if you prefer.
28 / 263
BunkerWeb documentation v1.5.8
Debian
Testing/dev version
If you use the testing or dev version, you will need to add the force-bad-version directive to your
/etc/dpkg/dpkg.cfg file before installing BunkerWeb.
Optional step : if you want to automatically enable the setup wizard when BunkerWeb is installed, export the
following variable :
export UI_WIZARD=1
To prevent upgrading NGINX and/or BunkerWeb packages when executing apt upgrade , you can use the following
command :
Ubuntu
29 / 263
BunkerWeb documentation v1.5.8
Testing/dev version
If you use the testing or dev version, you will need to add the force-bad-version directive to your
/etc/dpkg/dpkg.cfg file before installing BunkerWeb.
Optional step : if you want to automatically enable the setup wizard when BunkerWeb is installed, export the
following variable :
export UI_WIZARD=1
To prevent upgrading NGINX and/or BunkerWeb packages when executing apt upgrade , you can use the following
command :
Fedora
If you can't find the NGINX version listed in the stable repository, you can enable the updates-testing repository :
30 / 263
BunkerWeb documentation v1.5.8
Optional step : if you want to automatically enable the setup wizard when BunkerWeb is installed, export the
following variable :
export UI_WIZARD=1
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 -E dnf install -y bunkerweb-1.5.8
To prevent upgrading NGINX and/or BunkerWeb packages when executing dnf upgrade , you can use the following
command :
RedHat
The first step is to add NGINX official repository. Create the following file at /etc/yum.repos.d/nginx.repo :
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
31 / 263
BunkerWeb documentation v1.5.8
Optional step : if you want to automatically enable the setup wizard when BunkerWeb is installed, export the
following variable :
export UI_WIZARD=1
To prevent upgrading NGINX and/or BunkerWeb packages when executing dnf upgrade , you can use the following
command :
MY_SETTING_1=value1
MY_SETTING_2=value2
...
32 / 263
BunkerWeb documentation v1.5.8
Docker integration
The Docker autoconf integration is an "evolution" of the Docker one. Please read the Docker integration section first if
needed.
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.
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.
33 / 263
BunkerWeb documentation v1.5.8
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.
Multisite mode
The Docker autoconf integration implies the use of multisite mode. Please refer to the multisite section of the
documentation for more information.
Database backend
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 folder of the repository for more information.
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.
34 / 263
BunkerWeb documentation v1.5.8
version: "3.5"
services:
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
ports:
- 80:8080
- 443:8443
labels:
- "bunkerweb.INSTANCE=yes"
environment:
- SERVER_NAME=
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db
- AUTOCONF_MODE=yes
- MULTISITE=yes
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
networks:
- bw-universe
- bw-services
bw-autoconf:
image: bunkerity/bunkerweb-autoconf:1.5.8
depends_on:
- bunkerweb
- bw-docker
environment:
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db
- AUTOCONF_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
networks:
- bw-universe
- bw-docker
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
depends_on:
- bunkerweb
- bw-docker
environment:
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db
- DOCKER_HOST=tcp://bw-docker:2375
- AUTOCONF_MODE=yes
networks:
- bw-universe
- bw-docker
bw-docker:
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-db:
image: mariadb:10.10
35 / 263
BunkerWeb documentation v1.5.8
environment:
- MYSQL_RANDOM_ROOT_PASSWORD=yes
- MYSQL_DATABASE=db
- MYSQL_USER=bunkerweb
- MYSQL_PASSWORD=changeme
volumes:
- bw-data:/var/lib/mysql
networks:
- bw-docker
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe
ipam:
driver: default
config:
- subnet: 10.20.30.0/24
bw-services:
name: bw-services
bw-docker:
name: bw-docker
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.
If you are using Docker in rootless mode, 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 .
Once the stack is set up, you will be able to create the web application container and add the settings as labels
using the "bunkerweb." prefix in order to automatically set up BunkerWeb :
36 / 263
BunkerWeb documentation v1.5.8
version: "3.5"
services:
myapp:
image: mywebapp:4.2
networks:
bw-services:
aliases:
- myapp
labels:
- "bunkerweb.MY_SETTING_1=value1"
- "bunkerweb.MY_SETTING_2=value2"
networks:
bw-services:
external: true
name: bw-services
3.5 Kubernetes
37 / 263
BunkerWeb documentation v1.5.8
To automate the configuration of BunkerWeb instances in a Kubernetes environment, the autoconf service serves as
an Ingress controller. It configures the BunkerWeb instances based on Ingress resources and also monitors other
Kubernetes objects, such as ConfigMap, for custom configurations.
For an optimal setup, it is recommended to define BunkerWeb as a DaemonSet, which ensures that a pod is
created on all nodes, while the autoconf and scheduler are defined as single replicated Deployment.
Given the presence of multiple BunkerWeb instances, it is necessary to establish a shared data store implemented
as a Redis 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.
Database backend
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 folder of the repository for more information.
Please ensure that both the scheduler and autoconf services have access to the Kubernetes API. It is recommended
to utilize RBAC authorization for this purpose.
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.
To assist you, here is a YAML boilerplate that can serve as a foundation for your configuration:
38 / 263
BunkerWeb documentation v1.5.8
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cr-bunkerweb
rules:
- apiGroups: [""]
resources: ["services", "pods", "configmaps", "secrets"]
verbs: ["get", "watch", "list"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "watch", "list"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa-bunkerweb
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: crb-bunkerweb
subjects:
- kind: ServiceAccount
name: sa-bunkerweb
namespace: default
apiGroup: ""
roleRef:
kind: ClusterRole
name: cr-bunkerweb
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: bunkerweb
spec:
selector:
matchLabels:
app: bunkerweb
template:
metadata:
labels:
app: bunkerweb
# mandatory annotation
annotations:
bunkerweb.io/INSTANCE: "yes"
spec:
containers:
# using bunkerweb as name is mandatory
- name: bunkerweb
image: bunkerity/bunkerweb:1.5.8
imagePullPolicy: Always
securityContext:
runAsUser: 101
runAsGroup: 101
allowPrivilegeEscalation: false
capabilities:
drop:
39 / 263
BunkerWeb documentation v1.5.8
- ALL
ports:
- containerPort: 8080
hostPort: 80
- containerPort: 8443
hostPort: 443
env:
- name: KUBERNETES_MODE
value: "yes"
# replace with your DNS resolvers
# e.g. : kube-dns.kube-system.svc.cluster.local
- name: DNS_RESOLVERS
value: "coredns.kube-system.svc.cluster.local"
- name: USE_API
value: "yes"
# 10.0.0.0/8 is the cluster internal subnet
- name: API_WHITELIST_IP
value: "127.0.0.0/8 10.0.0.0/8"
- name: SERVER_NAME
value: ""
- name: MULTISITE
value: "yes"
- name: USE_REDIS
value: "yes"
- name: REDIS_HOST
value: "svc-bunkerweb-redis.default.svc.cluster.local"
livenessProbe:
exec:
command:
- /usr/share/bunkerweb/helpers/healthcheck.sh
initialDelaySeconds: 30
periodSeconds: 5
timeoutSeconds: 1
failureThreshold: 3
readinessProbe:
exec:
command:
- /usr/share/bunkerweb/helpers/healthcheck.sh
initialDelaySeconds: 30
periodSeconds: 1
timeoutSeconds: 1
failureThreshold: 3
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bunkerweb-controller
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: bunkerweb-controller
template:
metadata:
labels:
app: bunkerweb-controller
spec:
40 / 263
BunkerWeb documentation v1.5.8
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-controller
image: bunkerity/bunkerweb-autoconf:1.5.8
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
value: "yes"
- name: "DATABASE_URI"
value: "mariadb+pymysql://bunkerweb:changeme@svc-bunkerweb-db:3306/db"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bunkerweb-scheduler
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: bunkerweb-scheduler
template:
metadata:
labels:
app: bunkerweb-scheduler
spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-scheduler
image: bunkerity/bunkerweb-scheduler:1.5.8
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
value: "yes"
- name: "DATABASE_URI"
value: "mariadb+pymysql://bunkerweb:changeme@svc-bunkerweb-db:3306/db"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bunkerweb-redis
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: bunkerweb-redis
template:
metadata:
labels:
app: bunkerweb-redis
spec:
containers:
- name: bunkerweb-redis
image: redis:7-alpine
imagePullPolicy: Always
---
41 / 263
BunkerWeb documentation v1.5.8
apiVersion: apps/v1
kind: Deployment
metadata:
name: bunkerweb-db
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: bunkerweb-db
template:
metadata:
labels:
app: bunkerweb-db
spec:
containers:
- name: bunkerweb-db
image: mariadb:10.10
imagePullPolicy: Always
env:
- name: MYSQL_RANDOM_ROOT_PASSWORD
value: "yes"
- name: "MYSQL_DATABASE"
value: "db"
- name: "MYSQL_USER"
value: "bunkerweb"
- name: "MYSQL_PASSWORD"
value: "changeme"
volumeMounts:
- mountPath: "/var/lib/mysql"
name: vol-db
volumes:
- name: vol-db
persistentVolumeClaim:
claimName: pvc-bunkerweb
---
apiVersion: v1
kind: Service
metadata:
name: svc-bunkerweb
spec:
clusterIP: None
selector:
app: bunkerweb
---
apiVersion: v1
kind: Service
metadata:
name: svc-bunkerweb-db
spec:
type: ClusterIP
selector:
app: bunkerweb-db
ports:
- name: sql
protocol: TCP
port: 3306
targetPort: 3306
42 / 263
BunkerWeb documentation v1.5.8
---
apiVersion: v1
kind: Service
metadata:
name: svc-bunkerweb-redis
spec:
type: ClusterIP
selector:
app: bunkerweb-redis
ports:
- name: redis
protocol: TCP
port: 6379
targetPort: 6379
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-bunkerweb
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
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.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
bunkerweb.io/MY_SETTING: "value"
bunkerweb.io/www.example.com_MY_SETTING: "value"
spec:
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svc-my-app
port:
number: 8000
...
43 / 263
BunkerWeb documentation v1.5.8
3.6 Swarm
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 first if needed.
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, for
custom configurations.
Similar to the Docker autoconf integration, configuration for web services is defined using labels that start with the
bunkerweb prefix.
44 / 263
BunkerWeb documentation v1.5.8
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 multiple instances of BunkerWeb are running, a shared data store implemented as a Redis 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.
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.
Database backend
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 folder of the repository for more information.
Here is the stack boilerplate that you can deploy using docker stack deploy :
45 / 263
BunkerWeb documentation v1.5.8
version: "3.5"
services:
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
ports:
- published: 80
target: 8080
mode: host
protocol: tcp
- published: 443
target: 8443
mode: host
protocol: tcp
environment:
- SERVER_NAME=
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db # Remember to set a
stronger password for the database
- SWARM_MODE=yes
- MULTISITE=yes
- USE_REDIS=yes
- REDIS_HOST=bw-redis
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
networks:
- bw-universe
- bw-services
deploy:
mode: global
placement:
constraints:
- "node.role == worker"
labels:
- "bunkerweb.INSTANCE=yes"
bw-autoconf:
image: bunkerity/bunkerweb-autoconf:1.5.8
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db # Remember to set a
stronger password for the database
networks:
- bw-universe
- bw-docker
deploy:
placement:
constraints:
- "node.role == worker"
bw-docker:
image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONFIGS=1
- CONTAINERS=1
- SERVICES=1
- SWARM=1
46 / 263
BunkerWeb documentation v1.5.8
- TASKS=1
- LOG_LEVEL=warning
networks:
- bw-docker
deploy:
placement:
constraints:
- "node.role == manager"
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db
networks:
- bw-universe
- bw-docker
deploy:
placement:
constraints:
- "node.role == worker"
bw-db:
image: mariadb:10.10
environment:
- MYSQL_RANDOM_ROOT_PASSWORD=yes
- MYSQL_DATABASE=db
- MYSQL_USER=bunkerweb
- MYSQL_PASSWORD=changeme
volumes:
- bw-data:/var/lib/mysql
networks:
- bw-docker
deploy:
placement:
constraints:
- "node.role == worker"
bw-redis:
image: redis:7-alpine
networks:
- bw-universe
deploy:
placement:
constraints:
- "node.role == worker"
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe
driver: overlay
attachable: true
ipam:
config:
- subnet: 10.20.30.0/24
47 / 263
BunkerWeb documentation v1.5.8
bw-services:
name: bw-services
driver: overlay
attachable: true
bw-docker:
name: bw-docker
driver: overlay
attachable: true
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 :
version: "3.5"
services:
myapp:
image: mywebapp:4.2
networks:
- bw-services
deploy:
placement:
constraints:
- "node.role==worker"
labels:
- "bunkerweb.MY_SETTING_1=value1"
- "bunkerweb.MY_SETTING_2=value2"
networks:
bw-services:
external: true
name: bw-services
48 / 263
BunkerWeb documentation v1.5.8
Recommended VM size
Please be aware while you choose the SKU of the VM. You must select a SKU compatible with Gen2 VM and we
recommend starting at B2s or Ds2 series for optimal use.
You can easily deploy BunkerWeb on your Azure subscription in several ways:
49 / 263
BunkerWeb documentation v1.5.8
Cloud Shell
Create a VM with Standard_B2s SKU in the location of the resource group. Replace values RG_NAME , VM_NAME ,
VNET_NAME , SUBNET_NAME
Full command. Replace values RG_NAME , VM_NAME , LOCATION , HOSTNAME , USERNAME , PUBLIC_IP , VNET_NAME ,
SUBNET_NAME , NSG_NAME
ARM Template
Permissions requirement
To deploy a ARM template, you need write access on the resources you're deploying and access to all operations on
the Microsoft.Resources/deployments resource type. To deploy a virtual machine, you need
Microsoft.Compute/virtualMachines/write and Microsoft.Resources/deployments/* permissions. The what-if operation
has the same permission requirements.
Marketplace
You can access the setup wizard by browsing the https://your-ip-address/setup URI of your virtual machine.
50 / 263
BunkerWeb documentation v1.5.8
4 Quickstart guide
Prerequisites
We assume that you're already familiar with the core concepts and you have followed the integrations instructions for
your environment.
Going further
To demonstrate the use of BunkerWeb, we will deploy a dummy "Hello World" web application as an example. See the
examples folder of the repository to get real-world examples.
You will find more settings about reverse proxy in the settings section of the documentation.
51 / 263
BunkerWeb documentation v1.5.8
Docker
When using Docker integration, the easiest way of protecting an existing application is to add the web service in the
bw-services network :
52 / 263
BunkerWeb documentation v1.5.8
version: "3.5"
services:
myapp:
image: nginxdemos/nginx-hello
networks:
- bw-services
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
ports:
- 80:8080
- 443:8443
labels:
- "bunkerweb.INSTANCE=yes"
environment:
- SERVER_NAME=www.example.com
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
- USE_REVERSE_PROXY=yes
- REVERSE_PROXY_URL=/
- REVERSE_PROXY_HOST=http://myapp:8080
networks:
- bw-universe
- bw-services
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
depends_on:
- bunkerweb
- bw-docker
volumes:
- bw-data:/data
environment:
- DOCKER_HOST=tcp://bw-docker:2375
networks:
- bw-universe
- bw-docker
bw-docker:
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
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe
ipam:
driver: default
config:
53 / 263
BunkerWeb documentation v1.5.8
- subnet: 10.20.30.0/24
bw-services:
name: bw-services
bw-docker:
name: bw-docker
Docker autoconf
We will assume that you already have the Docker autoconf integration stack running on your machine and
connected to a network called bw-services so you can connect your existing application and configure BunkerWeb
with labels :
version: '3.5'
services:
myapp:
image: nginxdemos/nginx-hello
networks:
bw-services:
aliases:
- myapp
labels:
- "bunkerweb.SERVER_NAME=www.example.com"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- "bunkerweb.REVERSE_PROXY_URL=/"
- "bunkerweb.REVERSE_PROXY_HOST=http://myapp:8080"
networks:
bw-services:
external: true
name: bw-services
Swarm
We will assume that you already have the Swarm integration stack running on your cluster and connected to a
network called bw-services so you can connect your existing application and configure BunkerWeb with labels :
54 / 263
BunkerWeb documentation v1.5.8
version: "3"
services:
myapp:
image: nginxdemos/nginx-hello
networks:
bw-services:
aliases:
- myapp
deploy:
placement:
constraints:
- "node.role==worker"
labels:
- "bunkerweb.SERVER_NAME=www.example.com"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- "bunkerweb.REVERSE_PROXY_URL=/"
- "bunkerweb.REVERSE_PROXY_HOST=http://myapp:8080"
networks:
bw-services:
external: true
name: bw-services
Kubernetes
We will assume that you already have the Kubernetes integration stack running on your cluster.
Let's assume that you have a typical Deployment with a Service to access the web application from within the cluster
:
55 / 263
BunkerWeb documentation v1.5.8
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
labels:
app: app
spec:
replicas: 1
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: nginxdemos/nginx-hello
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: svc-app
spec:
selector:
app: app
ports:
- protocol: TCP
port: 80
targetPort: 8080
Here is the corresponding Ingress definition to serve and protect the web application :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
annotations:
bunkerweb.io/DUMMY_SETTING: "value"
spec:
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svc-app
port:
number: 80
56 / 263
BunkerWeb documentation v1.5.8
Linux
We will assume that you already have the Linux integration stack running on your machine.
The following command will run a basic HTTP server on the port 8000 and deliver the files in the current directory :
HTTP_PORT=80
HTTPS_PORT=443
DNS_RESOLVERS=9.9.9.9 8.8.8.8 8.8.4.4
API_LISTEN_IP=127.0.0.1
SERVER_NAME=www.example.com
USE_REVERSE_PROXY=yes
REVERSE_PROXY_URL=/
REVERSE_PROXY_HOST=http://127.0.0.1:8000
Testing
To perform quick tests when multisite mode is enabled (and if you don't have the proper DNS entries set up for the
domains) you can use curl with the HTTP Host header of your choice :
If you are using HTTPS, you will need to play with SNI :
57 / 263
BunkerWeb documentation v1.5.8
Docker
When using Docker integration, the easiest way of protecting an existing application is to add the web service in the
bw-services network :
58 / 263
BunkerWeb documentation v1.5.8
version: "3.5"
services:
myapp1:
image: nginxdemos/nginx-hello
networks:
- bw-services
myapp2:
image: nginxdemos/nginx-hello
networks:
- bw-services
myapp3:
image: nginxdemos/nginx-hello
networks:
- bw-services
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
ports:
- 80:8080
- 443:8443
labels:
- "bunkerweb.INSTANCE=yes"
environment:
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
- MULTISITE=yes
- SERVER_NAME=app1.example.com app2.example.com app3.example.com
- USE_REVERSE_PROXY=yes # Will be applied to all server config
- REVERSE_PROXY_URL=/ # Will be applied to all server config
- app1.example.com_REVERSE_PROXY_HOST=http://myapp1:8080
- app2.example.com_REVERSE_PROXY_HOST=http://myapp2:8080
- app3.example.com_REVERSE_PROXY_HOST=http://myapp3:8080
networks:
- bw-universe
- bw-services
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
depends_on:
- bunkerweb
- bw-docker
volumes:
- bw-data:/data
environment:
- DOCKER_HOST=tcp://bw-docker:2375
networks:
- bw-universe
- bw-docker
bw-docker:
image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
- LOG_LEVEL=warning
59 / 263
BunkerWeb documentation v1.5.8
networks:
- bw-docker
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe
ipam:
driver: default
config:
- subnet: 10.20.30.0/24
bw-services:
name: bw-services
bw-docker:
name: bw-docker
Docker autoconf
We will assume that you already have the Docker autoconf integration stack running on your machine and
connected to a network called bw-services so you can connect your existing application and configure BunkerWeb
with labels :
60 / 263
BunkerWeb documentation v1.5.8
version: '3.5'
services:
myapp1:
image: nginxdemos/nginx-hello
networks:
bw-services:
aliases:
- myapp1
labels:
- "bunkerweb.SERVER_NAME=app1.example.com"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- "bunkerweb.REVERSE_PROXY_URL=/"
- "bunkerweb.REVERSE_PROXY_HOST=http://myapp1:8080"
myapp2:
image: nginxdemos/nginx-hello
networks:
bw-services:
aliases:
- myapp1
labels:
- "bunkerweb.SERVER_NAME=app2.example.com"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- "bunkerweb.REVERSE_PROXY_URL=/"
- "bunkerweb.REVERSE_PROXY_HOST=http://myapp2:8080"
myapp3:
image: nginxdemos/nginx-hello
networks:
bw-services:
aliases:
- myapp3
labels:
- "bunkerweb.SERVER_NAME=app3.example.com"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- "bunkerweb.REVERSE_PROXY_URL=/"
- "bunkerweb.REVERSE_PROXY_HOST=http://myapp3:8080"
networks:
bw-services:
external: true
name: bw-services
Swarm
We will assume that you already have the Swarm integration stack running on your cluster and connected to a
network called bw-services so you can connect your existing application and configure BunkerWeb with labels :
61 / 263
BunkerWeb documentation v1.5.8
version: "3"
services:
myapp1:
image: nginxdemos/nginx-hello
networks:
bw-services:
aliases:
- myapp1
deploy:
placement:
constraints:
- "node.role==worker"
labels:
- "bunkerweb.SERVER_NAME=app1.example.com"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- "bunkerweb.REVERSE_PROXY_URL=/"
- "bunkerweb.REVERSE_PROXY_HOST=http://myapp1:8080"
myapp2:
image: nginxdemos/nginx-hello
networks:
bw-services:
aliases:
- myapp2
deploy:
placement:
constraints:
- "node.role==worker"
labels:
- "bunkerweb.SERVER_NAME=app2.example.com"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- "bunkerweb.REVERSE_PROXY_URL=/"
- "bunkerweb.REVERSE_PROXY_HOST=http://myapp2:8080"
myapp3:
image: nginxdemos/nginx-hello
networks:
bw-services:
aliases:
- myapp3
deploy:
placement:
constraints:
- "node.role==worker"
labels:
- "bunkerweb.SERVER_NAME=app3.example.com"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- "bunkerweb.REVERSE_PROXY_URL=/"
- "bunkerweb.REVERSE_PROXY_HOST=http://myapp3:8080"
networks:
bw-services:
external: true
name: bw-services
Kubernetes
62 / 263
BunkerWeb documentation v1.5.8
We will assume that you already have the Kubernetes integration stack running on your cluster.
Let's assume that you have typical Deployments with a Service to access the web applications from within the
cluster :
apiVersion: apps/v1
kind: Deployment
metadata:
name: app1
labels:
app: app1
spec:
replicas: 1
selector:
matchLabels:
app: app1
template:
metadata:
labels:
app: app1
spec:
containers:
- name: app1
image: nginxdemos/nginx-hello
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: svc-app1
spec:
selector:
app: app1
ports:
- protocol: TCP
port: 80
targetPort: 8080
Here is the corresponding Ingress definition to serve and protect the web applications :
63 / 263
BunkerWeb documentation v1.5.8
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
annotations:
bunkerweb.io/DUMMY_SETTING: "value"
bunkerweb.io/app1.example.com_DUMMY_SETTING: "value"
spec:
rules:
- host: app1.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svc-app1
port:
number: 80
- host: app2.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svc-app2
port:
number: 80
- host: app3.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svc-app3
port:
number: 80
Linux
We will assume that you already have the Linux integration stack running on your machine.
The following command will run a basic HTTP server on the port 8001 and deliver the files in the current directory
(repeat it and change the port if you want to test BunkerWeb) :
64 / 263
BunkerWeb documentation v1.5.8
HTTP_PORT=80
HTTPS_PORT=443
DNS_RESOLVERS=9.9.9.9 8.8.8.8 8.8.4.4
API_LISTEN_IP=127.0.0.1
MULTISITE=yes
SERVER_NAME=app1.example.com app2.example.com app3.example.com
USE_REVERSE_PROXY=yes
REVERSE_PROXY_URL=/
app1.example.com_REVERSE_PROXY_HOST=http://127.0.0.1:8001
app2.example.com_REVERSE_PROXY_HOST=http://127.0.0.1:8002
app3.example.com_REVERSE_PROXY_HOST=http://127.0.0.1:8003
BunkerWeb actually supports two methods to retrieve the real IP address of the client :
REAL_IP_FROM : list of trusted IP/network address allowed to send us the "real IP"
REAL_IP_HEADER : the HTTP header containing the real IP or special value proxy_protocol when using PROXY
protocol
You will find more settings about real IP in the settings section of the documentation.
65 / 263
BunkerWeb documentation v1.5.8
We will assume the following regarding the load balancers or reverse proxies (you will need to update the settings
depending on your configuration) :
USE_REAL_IP=yes
REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16
REAL_IP_HEADER=X-Forwarded-For
66 / 263
BunkerWeb documentation v1.5.8
Docker
When starting the BunkerWeb container, you will need to add the settings :
mybunker:
image: bunkerity/bunkerweb:1.5.8
...
environment:
- USE_REAL_IP=yes
- REAL_IP_FROM=1.2.3.0/24 100.64.0.0/10
- REAL_IP_HEADER=X-Forwarded-For
...
Docker autoconf
Before running the Docker autoconf integration stack, you will need to add the settings for the BunkerWeb container
:
mybunker:
image: bunkerity/bunkerweb:1.5.8
...
environment:
- USE_REAL_IP=yes
- REAL_IP_FROM=1.2.3.0/24 100.64.0.0/10
- REAL_IP_HEADER=X-Forwarded-For
...
Swarm
Before running the Swarm integration stack, you will need to add the settings for the BunkerWeb service :
mybunker:
image: bunkerity/bunkerweb:1.5.8
...
environment:
- USE_REAL_IP=yes
- REAL_IP_FROM=1.2.3.0/24 100.64.0.0/10
- REAL_IP_HEADER=X-Forwarded-For
...
Kubernetes
You will need to add the settings to the environment variables of the BunkerWeb containers (doing it using the
ingress is not supported because you will get into trouble when using things like Let's Encrypt) :
67 / 263
BunkerWeb documentation v1.5.8
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: bunkerweb
spec:
...
spec:
containers:
- name: bunkerweb
...
env:
- name: USE_REAL_IP
value: "yes"
- name: REAL_IP_FROM
value: "1.2.3.0/24 100.64.0.0/10"
- name: REAL_IP_HEADER
value: "X-Forwarded-For"
...
Linux
...
USE_REAL_IP=yes
REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16
REAL_IP_HEADER=X-Forwarded-For
...
Please note that it's recommended to issue a restart instead of reload when configuring settings related to proxy
protocols :
We will assume the following regarding the load balancers or reverse proxies (you will need to update the settings
depending on your configuration) :
USE_REAL_IP=yes
USE_PROXY_PROTOCOL=yes
REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16
REAL_IP_HEADER=proxy_protocol
68 / 263
BunkerWeb documentation v1.5.8
Docker
When starting the BunkerWeb container, you will need to add the settings :
mybunker:
image: bunkerity/bunkerweb:1.5.8
...
environment:
- USE_REAL_IP=yes
- USE_PROXY_PROTOCOL=yes
- REAL_IP_FROM=1.2.3.0/24 100.64.0.0/10
- REAL_IP_HEADER=proxy_protocol
...
Docker autoconf
Before running the Docker autoconf integration stack, you will need to add the settings for the BunkerWeb container
:
mybunker:
image: bunkerity/bunkerweb:1.5.8
...
environment:
- USE_REAL_IP=yes
- USE_PROXY_PROTOCOL=yes
- REAL_IP_FROM=1.2.3.0/24 100.64.0.0/10
- REAL_IP_HEADER=proxy_protocol
...
Swarm
Before running the Swarm integration stack, you will need to add the settings for the BunkerWeb service :
mybunker:
image: bunkerity/bunkerweb:1.5.8
...
environment:
- USE_REAL_IP=yes
- USE_PROXY_PROTOCOL=yes
- REAL_IP_FROM=1.2.3.0/24 100.64.0.0/10
- REAL_IP_HEADER=proxy_protocol
...
Kubernetes
You will need to add the settings to the environment variables of the BunkerWeb containers (doing it using the
ingress is not supported because you will get into trouble when using things like Let's Encrypt) :
69 / 263
BunkerWeb documentation v1.5.8
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: bunkerweb
spec:
...
spec:
containers:
- name: bunkerweb
...
env:
- name: USE_REAL_IP
value: "yes"
- name: USE_PROXY_PROTOCOL
value: "yes"
- name: REAL_IP_FROM
value: "1.2.3.0/24 100.64.0.0/10"
- name: REAL_IP_HEADER
value: "proxy_protocol"
...
Linux
...
USE_REAL_IP=yes
USE_PROXY_PROTOCOL=yes
REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16
REAL_IP_HEADER=proxy_protocol
...
Please note that it's recommended to issue a restart instead of reload when configuring settings related to proxy
protocols :
Feature is in beta
This feature is not production-ready. Feel free to test it and report us any bug using issues in the GitHub repository.
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 of NGINX.
70 / 263
BunkerWeb documentation v1.5.8
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 and settings sections of the documentation.
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).
SERVER_TYPE=stream : activate stream mode (generic UDP/TCP) instead of http one (which is the default)
LISTEN_STREAM_PORT=4242 : the listening "plain" (without SSL/TLS) port that BunkerWeb will listen on
For complete list of settings regarding stream mode, please refer to the settings section of the documentation.
71 / 263
BunkerWeb documentation v1.5.8
Docker
When using Docker integration, the easiest way of protecting existing network applications is to add the services in
the bw-services network :
72 / 263
BunkerWeb documentation v1.5.8
version: "3.5"
services:
myapp1:
image: istio/tcp-echo-server:1.2
command: [ "9000", "app1" ]
networks:
- bw-services
myapp2:
image: istio/tcp-echo-server:1.2
command: [ "9000", "app2" ]
networks:
- bw-services
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
ports:
- 80:8080 # Keep it if you want to use Let's Encrypt automation
- 10000:10000 # app1
- 20000:20000 # app2
labels:
- "bunkerweb.INSTANCE=yes"
environment:
- SERVER_NAME=app1.example.com app2.example.com
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
- MULTISITE=yes
- USE_REVERSE_PROXY=yes # Will be applied to all services
- SERVER_TYPE=stream # Will be applied to all services
- app1.example.com_REVERSE_PROXY_HOST=myapp1:9000
- app1.example.com_LISTEN_STREAM_PORT=10000
- app2.example.com_REVERSE_PROXY_HOST=myapp2:9000
- app2.example.com_LISTEN_STREAM_PORT=20000
networks:
- bw-universe
- bw-services
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
depends_on:
- bunkerweb
- bw-docker
volumes:
- bw-data:/data
environment:
- DOCKER_HOST=tcp://bw-docker:2375
networks:
- bw-universe
- bw-docker
bw-docker:
image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
- LOG_LEVEL=warning
73 / 263
BunkerWeb documentation v1.5.8
networks:
- bw-docker
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe
ipam:
driver: default
config:
- subnet: 10.20.30.0/24
bw-services:
name: bw-services
bw-docker:
name: bw-docker
Docker autoconf
Before running the Docker autoconf integration stack on your machine, you will need to edit the ports :
version: "3.5"
services:
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
ports:
- 80:8080 # Keep it if you want to use Let's Encrypt automation
- 10000:10000 # app1
- 20000:20000 # app2
...
Once the stack is running, you can connect your existing applications to the bw-services network and configure
BunkerWeb with labels :
74 / 263
BunkerWeb documentation v1.5.8
version: '3.5'
services:
myapp1:
image: istio/tcp-echo-server:1.2
command: [ "9000", "app1" ]
networks:
bw-services:
aliases:
- myapp1
labels:
- "bunkerweb.SERVER_NAME=app1.example.com"
- "bunkerweb.SERVER_KIND=stream"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- "bunkerweb.REVERSE_PROXY_HOST=myapp1:9000"
- "bunkerweb.LISTEN_STREAM_PORT=10000"
myapp2:
image: istio/tcp-echo-server:1.2
command: [ "9000", "app2" ]
networks:
bw-services:
aliases:
- myapp2
labels:
- "bunkerweb.SERVER_NAME=app2.example.com"
- "bunkerweb.SERVER_KIND=stream"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- "bunkerweb.REVERSE_PROXY_HOST=myapp2:9000"
- "bunkerweb.LISTEN_STREAM_PORT=20000"
networks:
bw-services:
external: true
name: bw-services
Swarm
Before running the Swarm integration stack on your machine, you will need to edit the ports :
75 / 263
BunkerWeb documentation v1.5.8
version: "3.5"
services:
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
ports:
# Keep it if you want to use Let's Encrypt automation
- published: 80
target: 8080
mode: host
protocol: tcp
# app1
- published: 10000
target: 10000
mode: host
protocol: tcp
# app2
- published: 10000
target: 10000
mode: host
protocol: tcp
...
Once the stack is running, you can connect your existing applications to the bw-services network and configure
BunkerWeb with labels :
76 / 263
BunkerWeb documentation v1.5.8
version: '3.5'
services:
myapp1:
image: istio/tcp-echo-server:1.2
command: [ "9000", "app1" ]
networks:
- bw-services
deploy:
placement:
constraints:
- "node.role==worker"
labels:
- "bunkerweb.SERVER_NAME=app1.example.com"
- "bunkerweb.SERVER_KIND=stream"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- "bunkerweb.REVERSE_PROXY_HOST=myapp1:9000"
- "bunkerweb.LISTEN_STREAM_PORT=10000"
myapp2:
image: istio/tcp-echo-server:1.2
command: [ "9000", "app2" ]
networks:
- bw-services
deploy:
placement:
constraints:
- "node.role==worker"
labels:
- "bunkerweb.SERVER_NAME=app2.example.com"
- "bunkerweb.SERVER_KIND=stream"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- "bunkerweb.REVERSE_PROXY_HOST=myapp2:9000"
- "bunkerweb.LISTEN_STREAM_PORT=20000"
networks:
bw-services:
external: true
name: bw-services
Kubernetes
Protection TCP/UDP applications using the stream feature is not yet supported when using the Kubernetes
integration.
Linux
77 / 263
BunkerWeb documentation v1.5.8
...
SERVER_NAME=app1.example.com app2.example.com
MULTISITE=yes
USE_REVERSE_PROXY=yes
SERVER_TYPE=stream
app1.example.com_REVERSE_PROXY_HOST=myapp1.domain.or.ip:9000
app1.example.com_LISTEN_STREAM_PORT=10000
app2.example.com_REVERSE_PROXY_HOST=myapp2.domain.or.ip:9000
app2.example.com_LISTEN_STREAM_PORT=20000
...
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.
Custom configurations can be applied globally or specifically for a particular server, depending on the applicable
context and whether the multisite mode is enabled.
78 / 263
BunkerWeb documentation v1.5.8
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 in Docker Swarm or
ConfigMap in Kubernetes. These options offer simpler approaches for managing and applying configurations.
79 / 263
BunkerWeb documentation v1.5.8
Docker
When using the Docker integration, you have two choices for the addition of custom configurations :
Using settings
<SITE> : optional primary server name if multisite mode is enabled and the config must be applied to a specific
service
<TYPE> : the type of config, accepted values are HTTP , DEFAULT_SERVER_HTTP , SERVER_HTTP , MODSEC ,
MODSEC_CRS , STREAM and SERVER_STREAM
...
mybunker:
image: bunkerity/bunkerweb:1.5.8
environment:
- |
CUSTOM_CONF_SERVER_HTTP_hello-world=
location /hello {
default_type 'text/plain';
content_by_lua_block {
ngx.say('world')
}
}
...
Using files
mkdir -p ./bw-data/configs/server-http
Because the scheduler runs as an unprivileged user with UID and GID 101, you will need to edit the permissions :
80 / 263
BunkerWeb documentation v1.5.8
When starting the scheduler container, you will need to mount the folder on /data :
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
volumes:
- ./bw-data:/data
...
Docker autoconf
When using the Docker autoconf integration, you have two choices for adding custom configurations :
Using labels
When using labels with the Docker autoconf integration, you can only apply custom configurations for the
corresponding web service. Applying http, default-server-http, stream or any global configurations (like server-http
or server-stream for all services) is not possible : you will need to mount files for that purpose.
<TYPE> : the type of config, accepted values are SERVER_HTTP , MODSEC , MODSEC_CRS and SERVER_STREAM
myapp:
image: nginxdemos/nginx-hello
labels:
- |
bunkerweb.CUSTOM_CONF_SERVER_HTTP_hello-world=
location /hello {
default_type 'text/plain';
content_by_lua_block {
ngx.say('world')
}
}
...
Using files
81 / 263
BunkerWeb documentation v1.5.8
mkdir -p ./bw-data/configs/server-http
Because the scheduler runs as an unprivileged user with UID and GID 101, you will need to edit the permissions :
When starting the scheduler container, you will need to mount the folder on /data :
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
volumes:
- ./bw-data:/data
...
Swarm
When using the Swarm integration, custom configurations are managed using Docker Configs.
To keep it simple, you don't even need to attach the Config to a service : the autoconf service is listening for Config
events and will update the custom configurations when needed.
bunkerweb.CONFIG_TYPE : must be set to a valid custom configuration type (http, server-http, default-server-
http, modsec, modsec-crs, stream or server-stream)
bunkerweb.CONFIG_SITE : set to a server name to apply configuration to that specific server (optional, will be
applied globally if unset)
82 / 263
BunkerWeb documentation v1.5.8
There is no update mechanism : the alternative is to remove an existing config using docker config rm and then
recreate it.
Kubernetes
When using the Kubernetes integration, custom configurations are managed using ConfigMap.
To keep it simple, you don't even need to use the ConfigMap with a Pod (e.g. as environment variable or volume) :
the autoconf Pod is listening for ConfigMap events and will update the custom configurations when needed.
bunkerweb.io/CONFIG_TYPE : must be set to a valid custom configuration type (http, server-http, default-server-
http, modsec, modsec-crs, stream or server-stream)
bunkerweb.io/CONFIG_SITE : set to a server name to apply configuration to that specific server (optional, will be
applied globally if unset)
apiVersion: v1
kind: ConfigMap
metadata:
name: cfg-bunkerweb-all-server-http
annotations:
bunkerweb.io/CONFIG_TYPE: "server-http"
data:
myconf: |
location /hello {
default_type 'text/plain';
content_by_lua_block {
ngx.say('world')
}
}
Linux
When using the Linux integration, custom configurations must be written to the /etc/bunkerweb/configs folder.
location /hello {
default_type 'text/plain';
content_by_lua_block {
ngx.say('world')
}
}
Because BunkerWeb runs as an unprivileged user (nginx:nginx), you will need to edit the permissions :
83 / 263
BunkerWeb documentation v1.5.8
4.5 PHP
Support is in beta
At the moment, PHP support with BunkerWeb is still in beta and we recommend you use a reverse-proxy architecture if
you can. By the way, PHP is not supported at all for some integrations like Kubernetes.
Testing
To perform quick tests when multisite mode is enabled (and if you don't have the proper DNS entries set up for the
domains) you can use curl with the HTTP Host header of your choice :
If you are using HTTPS, you will need to play with SNI :
BunkerWeb supports PHP using external or remote PHP-FPM instances. We will assume that you are already
familiar with managing that kind of services.
84 / 263
BunkerWeb documentation v1.5.8
85 / 263
BunkerWeb documentation v1.5.8
Docker
When using the Docker integration, to support PHP applications, you will need to :
Set up a PHP-FPM container for your application and mount the folder containing PHP files
Use the specific settings REMOTE_PHP and REMOTE_PHP_PATH as environment variables when starting BunkerWeb
If you enable the multisite mode, you will need to create separate directories for each of your applications. Each
subdirectory should be named using the first value of SERVER_NAME . Here is a dummy example :
www
├── app1.example.com
│ └── index.php
├── app2.example.com
│ └── index.php
└── app3.example.com
└── index.php
3 directories, 3 files
We will assume that your PHP apps are located into a folder named www . Please note that you will need to fix the
permissions so BunkerWeb (UID/GID 101) can at least read files and list folders and PHP-FPM (UID/GID 33 if you
use the php:fpm image) is the owner of the files and folders :
You can now run BunkerWeb, configure it for your PHP application and also run the PHP apps :
86 / 263
BunkerWeb documentation v1.5.8
version: "3.5"
services:
myapp1:
image: php:fpm
volumes:
- ./www/app1.example.com:/app
networks:
- bw-services
myapp2:
image: php:fpm
volumes:
- ./www/app2.example.com:/app
networks:
- bw-services
myapp3:
image: php:fpm
volumes:
- ./www/app3.example.com:/app
networks:
- bw-services
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
volumes:
- ./www:/var/www/html
ports:
- 80:8080
- 443:8443
labels:
- "bunkerweb.INSTANCE=yes"
environment:
- SERVER_NAME=app1.example.com app2.example.com
- MULTISITE=yes
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
- app1.example.com_REMOTE_PHP=myapp1
- app1.example.com_REMOTE_PHP_PATH=/app
- app2.example.com_REMOTE_PHP=myapp2
- app2.example.com_REMOTE_PHP_PATH=/app
- app3.example.com_REMOTE_PHP=myapp3
- app3.example.com_REMOTE_PHP_PATH=/app
networks:
- bw-universe
- bw-services
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
depends_on:
- bunkerweb
- bw-docker
volumes:
- bw-data:/data
environment:
- DOCKER_HOST=tcp://bw-docker:2375
networks:
87 / 263
BunkerWeb documentation v1.5.8
- bw-universe
- bw-docker
bw-docker:
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
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe
ipam:
driver: default
config:
- subnet: 10.20.30.0/24
bw-services:
name: bw-services
bw-docker:
name: bw-docker
Docker autoconf
The Docker autoconf integration integration implies the use of multisite mode : protecting one PHP application is the
same as protecting multiple ones.
When using the Docker autoconf integration, to support PHP applications, you will need to :
Set up a PHP-FPM containers for your applications and mount the folder containing PHP apps
Use the specific settings REMOTE_PHP and REMOTE_PHP_PATH as labels for your PHP-FPM container
Since the Docker autoconf implies using the multisite mode, you will need to create separate directories for each of
your applications. Each subdirectory should be named using the first value of SERVER_NAME . Here is a dummy
example :
88 / 263
BunkerWeb documentation v1.5.8
www
├── app1.example.com
│ └── index.php
├── app2.example.com
│ └── index.php
└── app3.example.com
└── index.php
3 directories, 3 files
Once the folders are created, copy your files and fix the permissions so BunkerWeb (UID/GID 101) can at least read
files and list folders and PHP-FPM (UID/GID 33 if you use the php:fpm image) is the owner of the files and folders :
When you start the BunkerWeb autoconf stack, mount the www folder into /var/www/html for the BunkerWeb
container :
89 / 263
BunkerWeb documentation v1.5.8
version: '3.5'
services:
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
volumes:
- ./www:/var/www/html
labels:
- "bunkerweb.INSTANCE=yes"
environment:
- MULTISITE=yes
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db # Remember to set a
stronger password for the database
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
networks:
- bw-universe
- bw-services
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
depends_on:
- bunkerweb
- bw-docker
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
networks:
- bw-universe
- bw-docker
bw-docker:
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-db:
image: mariadb:10.10
environment:
- MYSQL_RANDOM_ROOT_PASSWORD=yes
- MYSQL_DATABASE=db
- MYSQL_USER=bunkerweb
- MYSQL_PASSWORD=changeme # Remember to set a stronger password for the database
volumes:
- bw-data:/var/lib/mysql
networks:
- bw-docker
volumes:
bw-data:
networks:
bw-universe:
90 / 263
BunkerWeb documentation v1.5.8
name: bw-universe
ipam:
driver: default
config:
- subnet: 10.20.30.0/24
bw-services:
name: bw-services
bw-docker:
name: bw-docker
You can now create your PHP-FPM containers, mount the correct subfolders and use labels to configure BunkerWeb
:
91 / 263
BunkerWeb documentation v1.5.8
version: '3.5'
services:
myapp1:
image: php:fpm
volumes:
- ./www/app1.example.com:/app
networks:
bw-services:
aliases:
- myapp1
labels:
- "bunkerweb.SERVER_NAME=app1.example.com"
- "bunkerweb.REMOTE_PHP=myapp1"
- "bunkerweb.REMOTE_PHP_PATH=/app"
myapp2:
image: php:fpm
volumes:
- ./www/app2.example.com:/app
networks:
bw-services:
aliases:
- myapp2
labels:
- "bunkerweb.SERVER_NAME=app2.example.com"
- "bunkerweb.REMOTE_PHP=myapp2"
- "bunkerweb.REMOTE_PHP_PATH=/app"
myapp3:
image: php:fpm
volumes:
- ./www/app3.example.com:/app
networks:
bw-services:
aliases:
- myapp3
labels:
- "bunkerweb.SERVER_NAME=app3.example.com"
- "bunkerweb.REMOTE_PHP=myapp3"
- "bunkerweb.REMOTE_PHP_PATH=/app"
networks:
bw-services:
external: true
name: bw-services
Swarm
The Swarm integration integration implies the use of multisite mode : protecting one PHP application is the same as
protecting multiple ones.
92 / 263
BunkerWeb documentation v1.5.8
Shared volume
Using PHP with the Docker Swarm integration needs a shared volume between all BunkerWeb and PHP-FPM
instances which is not covered in this documentation.
When using the Docker autoconf integration, to support PHP applications, you will need to :
Set up a PHP-FPM containers for your applications and mount the folder containing PHP apps
Use the specific settings REMOTE_PHP and REMOTE_PHP_PATH as labels for your PHP-FPM container
Since the Swarm integration implies using the multisite mode, you will need to create separate directories for each of
your applications. Each subdirectory should be named using the first value of SERVER_NAME . Here is a dummy
example :
www
├── app1.example.com
│ └── index.php
├── app2.example.com
│ └── index.php
└── app3.example.com
└── index.php
3 directories, 3 files
As an example, we will consider that you have a shared folder mounted on your worker nodes on the /shared
endpoint.
Once the folders are created, copy your files and fix the permissions so BunkerWeb (UID/GID 101) can at least read
files and list folders and PHP-FPM (UID/GID 33 if you use the php:fpm image) is the owner of the files and folders :
When you start the BunkerWeb stack, mount the /shared/www folder into /var/www/html for the BunkerWeb
container :
version: "3.5"
services:
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
volumes:
- /shared/www:/var/www/html
...
You can now create your PHP-FPM services, mount the correct subfolders and use labels to configure BunkerWeb :
93 / 263
BunkerWeb documentation v1.5.8
version: '3.5'
services:
myapp1:
image: php:fpm
volumes:
- ./www/app1.example.com:/app
networks:
bw-services:
aliases:
- myapp1
deploy:
placement:
constraints:
- "node.role==worker"
labels:
- "bunkerweb.SERVER_NAME=app1.example.com"
- "bunkerweb.REMOTE_PHP=myapp1"
- "bunkerweb.REMOTE_PHP_PATH=/app"
myapp2:
image: php:fpm
volumes:
- ./www/app2.example.com:/app
networks:
bw-services:
aliases:
- myapp2
deploy:
placement:
constraints:
- "node.role==worker"
labels:
- "bunkerweb.SERVER_NAME=app2.example.com"
- "bunkerweb.REMOTE_PHP=myapp2"
- "bunkerweb.REMOTE_PHP_PATH=/app"
myapp3:
image: php:fpm
volumes:
- ./www/app3.example.com:/app
networks:
bw-services:
aliases:
- myapp3
deploy:
placement:
constraints:
- "node.role==worker"
labels:
- "bunkerweb.SERVER_NAME=app3.example.com"
- "bunkerweb.REMOTE_PHP=myapp3"
- "bunkerweb.REMOTE_PHP_PATH=/app"
networks:
bw-services:
external: true
name: bw-services
94 / 263
BunkerWeb documentation v1.5.8
Kubernetes
Kubernetes integration allows configuration through Ingress and the BunkerWeb controller only supports HTTP
applications at the moment.
Linux
We will assume that you already have the Linux integration stack running on your machine.
By default, BunkerWeb will search for web files inside the /var/www/html folder. You can use it to store your PHP
applications. Please note that you will need to configure your PHP-FPM service to get or set the user/group of the
running processes and the UNIX socket file used to communicate with BunkerWeb.
First of all, you will need to make sure that your PHP-FPM instance can access the files inside the /var/www/html
folder and also that BunkerWeb can access the UNIX socket file in order to communicate with PHP-FPM. We
recommend to set a different user like www-data for the PHP-FPM service and to give the nginx group access to the
UNIX socket file. Here is corresponding PHP-FPM configuration :
...
[www]
user = www-data
group = www-data
listen = /run/php/php-fpm.sock
listen.owner = www-data
listen.group = nginx
listen.mode = 0660
...
If you enable the multisite mode, you will need to create separate directories for each of your applications. Each
subdirectory should be named using the first value of SERVER_NAME . Here is a dummy example :
/var/www/html
├── app1.example.com
│ └── index.php
├── app2.example.com
│ └── index.php
└── app3.example.com
└── index.php
3 directories, 3 files
95 / 263
BunkerWeb documentation v1.5.8
Please note that you will need to fix the permissions so BunkerWeb (group nginx ) can at least read files and list
folders and PHP-FPM (user www-data but it might be different depending on your system) is the owner of the files
and folders :
HTTP_PORT=80
HTTPS_PORT=443
DNS_RESOLVERS=9.9.9.9 8.8.8.8 8.8.4.4
API_LISTEN_IP=127.0.0.1
MULTISITE=yes
SERVER_NAME=app1.example.com app2.example.com app3.example.com
app1.example.com_LOCAL_PHP=/run/php/php-fpm.sock
app1.example.com_LOCAL_PHP_PATH=/var/www/html/app1.example.com
app2.example.com_LOCAL_PHP=/run/php/php-fpm.sock
app2.example.com_LOCAL_PHP_PATH=/var/www/html/app2.example.com
app3.example.com_LOCAL_PHP=/run/php/php-fpm.sock
app3.example.com_LOCAL_PHP_PATH=/var/www/html/app3.example.com
4.6 IPv6
Feature is in beta
This feature is not production-ready. Feel free to test it and report us any bug using issues in the GitHub repository.
By default, BunkerWeb will only listen on IPv4 addresses and won't use IPv6 for network communications. If you
want to enable IPv6 support, you need to set USE_IPV6=yes . Please note that IPv6 configuration of your network
and environment is out-of-the-scope of this documentation.
96 / 263
BunkerWeb documentation v1.5.8
Docker
First of all, you will need to configure your Docker daemon to enable IPv6 support for containers and use ip6tables if
needed. Here is sample configuration for your /etc/docker/daemon.json file :
{
"experimental": true,
"ipv6": true,
"ip6tables": true,
"fixed-cidr-v6": "fd00:dead:beef::/48"
}
You can now restart the Docker service to apply the changes :
Once Docker is setup to support IPv6 you can add the USE_IPV6 setting and configure the bw-services for IPv6 :
version: '3.5'
services:
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
environment:
- USE_IPv6=yes
...
networks:
bw-services:
name: bw-services
enable_ipv6: true
ipam:
config:
- subnet: fd00:13:37::/48
gateway: fd00:13:37::1
...
Docker autoconf
First of all, you will need to configure your Docker daemon to enable IPv6 support for containers and use ip6tables if
needed. Here is sample configuration for your /etc/docker/daemon.json file :
{
"experimental": true,
"ipv6": true,
"ip6tables": true,
"fixed-cidr-v6": "fd00:dead:beef::/48"
}
97 / 263
BunkerWeb documentation v1.5.8
You can now restart the Docker service to apply the changes :
Once Docker is setup to support IPv6 you can add the USE_IPV6 setting and configure the IPv6 for the bw-
services network :
version: '3.5'
services:
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
environment:
- USE_IPv6=yes
...
networks:
bw-services:
name: bw-services
enable_ipv6: true
ipam:
config:
- subnet: fd00:13:37::/48
gateway: fd00:13:37::1
...
98 / 263
BunkerWeb documentation v1.5.8
5 Security tuning
BunkerWeb offers many security features that you can configure with settings. Even if the default values of settings
ensure a minimal "security by default", we strongly recommend you tune them. By doing so you will be able to
ensure the security level of your choice but also manage false positives.
Other settings
This section only focuses on security tuning, see the settings section of the documentation for other settings.
STREAM support
The first thing to define is the kind of action to do when a client access is denied. You can control the action with the
DENY_HTTP_STATUS setting which allows the following values :
403 : send a "classical" Forbidden HTTP status code (a web page or custom content will be displayed)
444 : close the connection (no web page or custom content will be displayed)
The default value is 403 and we suggest you set it to 444 only if you already fixed a lot of false positive, you are
familiar with BunkerWeb and want a higher level of security.
When using stream mode, value is ignored and always set to 444 with effect of closing the connection.
99 / 263
BunkerWeb documentation v1.5.8
STREAM support
In the HTTP protocol, the Host header is used to determine which server the client wants to send the request to.
That header is facultative and may be missing from the request or can be set as an unknown value. This is a
common case, a lot of bots are scanning the Internet and are trying to exploit services or simply doing some
fingerprinting.
You can disable any request containing undefined or unknown Host value by setting DISABLE_DEFAULT_SERVER to
yes (default : no ). Please note that clients won't even receive a response, the TCP connection will be closed (using
the special 444 status code of NGINX).
If you want to close SSL/TLS connection if Server Name Indication (SNI) is undefined or unknown, you can set
DISABLE_DEFAULT_SERVER_STRICT_SNI to yes (default : no ). On the one hand, you can block attackers as soon as
possible at SSL/TLS level but, in the other hand, you may have issues if your BunkerWeb instance is behind a
reverse proxy configured to send HTTPS requests without SNI.
STREAM support
You can control the allowed HTTP methods by listing them (separated with "|") in the ALLOWED_METHODS setting
(default : GET|POST|HEAD ). Clients sending a method which is not listed will get a "405 - Method Not Allowed".
STREAM support
You can control the maximum body size with the MAX_CLIENT_SIZE setting (default : 10m ). See here for accepted
values. You can use the special value 0 to allow a body of infinite size (not recommended).
STREAM support
To disable serving files from the www folder, you can set SERVE_FILES to no (default : yes ). The value no is
recommended if you use BunkerWeb as a reverse proxy.
5.1.6 Headers
STREAM support
Headers are very important when it comes to HTTP security. While some of them might be too verbose, others'
verbosity will need to be increased, especially on the client-side.
STREAM support
100 / 263
BunkerWeb documentation v1.5.8
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 ).
STREAM support
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.
5.1.6.3 Cookies
STREAM support
HttpOnly : disable any access to the cookie from Javascript using document.cookie
Cookie flags can be overridden with values of your choice by using the COOKIE_FLAGS setting (default : * HttpOnly
SameSite=Lax ). See here for accepted values.
The Secure flag can be automatically added if HTTPS is used by using the COOKIE_AUTO_SECURE_FLAG setting
(default : yes ). The value no is not recommended unless you know what you're doing.
STREAM support
Various security headers are available and most of them can be set using BunkerWeb settings. Here is the list of
headers, the corresponding setting and default value :
101 / 263
BunkerWeb documentation v1.5.8
Policy LICY
5.1.6.5 CORS
STREAM support
Cross-Origin Resource Sharing lets you manage how your service can be contacted from different origins. Please
note that you will have to allow the OPTIONS HTTP method using the ALLOWED_METHODS if you want to enable it
(more info here). Here is the list of settings related to CORS :
102 / 263
BunkerWeb documentation v1.5.8
^https://.+\.example.com$ will allow any origins when domain ends with .example.com
103 / 263
BunkerWeb documentation v1.5.8
REDIRECT_HTTP_TO_HT no When set to yes , will redirect every HTTP request to HTTPS even
TPS if BunkerWeb is not configured with HTTPS.
AUTO_REDIRECT_HTTP_ yes When set to yes , will redirect every HTTP request to HTTPS only if
TO_HTTPS BunkerWeb is configured with HTTPS.
HTTP2 yes When set to yes , will enable HTTP2 protocol support when using
HTTPS.
HTTP3 no When set to yes , will enable HTTP3 protocol support when using
HTTPS.
HTTP3_ALT_SVC_PORT 443 HTTP3 alternate service port. This value will be used as part of the
Alt-Svc header.
LISTEN_HTTP yes When set to no , BunkerWeb will not listen for HTTP requests.
Useful if you want HTTPS only for example.
About HTTP3
HTTP/3 is the next version of the HTTP protocol. It is based on Google's QUIC protocol which is a transport layer
protocol that provides security and reliability features. HTTP/3 is designed to improve the performance of websites and
web applications.
Remember that NGINX's support for HTTP/3 is still experimental and may not be suitable for all use cases.
STREAM support
BunkerWeb comes with automatic Let's Encrypt certificate generation and renewal. This is the easiest way of getting
HTTPS / SSL/TLS working out of the box for public-facing web applications. Please note that you will need to set up
proper DNS A record(s) for each of your domains pointing to your public IP(s) where BunkerWeb is accessible.
104 / 263
BunkerWeb documentation v1.5.8
AUTO_LETS_ENCRY no When set to yes , HTTPS / SSL/TLS will be enabled with automatic
PT certificate generation and renewal from Let's Encrypt.
EMAIL_LETS_ENCR contact@{FIRST Email to use when generating certificates. Let's Encrypt will send
YPT _SERVER} notifications to that email like certificate expiration.
USE_LETS_ENCRYP no When set to yes , the staging server of Let's Encrypt will be used
T_STAGING instead of the production one. Useful when doing tests to avoid being
"blocked" due to limits.
Full Let's Encrypt automation is fully working with stream mode as long as you open the 80/tcp port from the
outside. Please note that you will need to use the LISTEN_STREAM_PORT_SSL setting in order to choose your listening
SSL/TLS port.
STREAM support
The Let's Encrypt DNS plugin facilitates the automatic creation, renewal, and configuration of Let's Encrypt
certificates using DNS challenges.
This plugin offers seamless integration with various DNS providers for streamlined certificate management.
List of features
105 / 263
BunkerWeb documentation v1.5.8
EMAIL notifications.
The LETS_ENCRYPT_DNS_CREDENTIAL_ITEM setting is a multiple setting and can be used to set multiple items for the
DNS provider. The items will be saved as a cache file and Certbot will read the credentials from it.
If no LETS_ENCRYPT_DNS_PROPAGATION setting is set, the provider's default propagation time will be used.
106 / 263
BunkerWeb documentation v1.5.8
STREAM support
If you want to use your own certificates, here is the list of related settings :
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.
107 / 263
BunkerWeb documentation v1.5.8
When using stream mode, you will need to use the LISTEN_STREAM_PORT_SSL setting in order to choose your
listening SSL/TLS port.
5.2.4 Self-signed
STREAM support
If you want to quickly test HTTPS / SSL/TLS for staging/dev environment you can configure BunkerWeb to generate
self-signed certificates, here is the list of related settings :
GENERATE_SELF_SI no When set to yes , HTTPS / SSL/TLS will be enabled with automatic
GNED_SSL self-signed certificate generation and renewal from Let's Encrypt.
SELF_SIGNED_SSL_ 365 Number of days for the certificate expiration (-days value used with
EXPIRY openssl).
SELF_SIGNED_SSL_ /CN=www.exampl Certificate subject to use (-subj value used with openssl).
SUBJ e.com/
When using stream mode, you will need to use the LISTEN_STREAM_PORT_SSL setting in order to choose your
listening SSL/TLS port.
5.3 ModSecurity
STREAM support
ModSecurity is integrated and enabled by default alongside the OWASP Core Rule Set within BunkerWeb. Here is
the list of related settings :
USE_MODSECURITY_CR yes When set to yes and USE_MODSECURITY is also set to yes , the
S OWASP Core Rule Set will be loaded.
MODSECURITY_CRS_VE 3 Version of the OWASP Core Rule Set to use with ModSecurity (3, 4 or
RSION nightly).
108 / 263
BunkerWeb documentation v1.5.8
We strongly recommend keeping both ModSecurity and the OWASP Core Rule Set enabled. The only downsides
are the false positives that may occur. But they can be fixed with some efforts and the CRS team maintains a list of
exclusions for common applications (e.g., WordPress, Nextcloud, Drupal, Cpanel, ...).
You can choose between the following versions of the OWASP Core Rule Set :
nightly : The latest nightly build of the OWASP Core Rule Set which is updated every day
The nightly build of the OWASP Core Rule Set is updated every day and contains the latest rules. It is recommended to
use it in a staging environment before using it in production.
Tuning ModSecurity and the CRS can be done using custom configurations :
modsec : after the OWASP Core Rule Set is loaded (also used if CRS is not loaded)
For example, you can add a custom configuration with type modsec-crs to add CRS exclusions :
SecAction \
"id:900130,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.crs_exclusions_wordpress=1"
You can also add a custom configuration with type modsec to update loaded CRS rules :
109 / 263
BunkerWeb documentation v1.5.8
When attackers search for and/or exploit vulnerabilities they might generate some "suspicious" HTTP status codes
that a "regular" user won’t generate within a period of time. If we detect that kind of behavior we can ban the
offending IP address and force the attacker to come up with a new one.
That kind of security measure is implemented and enabled by default in BunkerWeb and is called "Bad behavior".
Here is the list of the related settings :
USE_BAD_BEHAVIOR yes When set to yes , the Bad behavior feature will be
enabled.
BAD_BEHAVIOR_STATUS_ 400 401 403 404 405 List of HTTP status codes considered as "suspicious".
CODES 429 444
BAD_BEHAVIOR_BAN_TIM 86400 The duration time (in seconds) of a ban when a client
E reached the threshold.
In other words, with the default values, if a client generates more than 10 status codes from the list 400 401 403
404 405 429 444 within 60 seconds their IP address will be banned for 86400 seconds.
When using stream mode, only the 444 status code will count as "bad".
5.5 Antibot
STREAM support
Attackers will certainly use automated tools to exploit/find some vulnerabilities in your web applications. One
countermeasure is to challenge the users to detect if they look like a bot. If the challenge is solved, we consider the
client as "legitimate" and they can access the web application.
That kind of security is implemented but not enabled by default in BunkerWeb and is called "Antibot". Here is the list
of supported challenges :
Cookie : send a cookie to the client, we expect to get the cookie back on other requests
Captcha : force the client to solve a classical captcha (no external dependencies)
110 / 263
BunkerWeb documentation v1.5.8
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
111 / 263
BunkerWeb documentation v1.5.8
Please note that antibot feature is using a cookie to maintain a session with clients. If you are using BunkerWeb in a
clustered environment, you will need to set the SESSIONS_SECRET and SESSIONS_NAME settings to another value
than the default one (which is random ). You will find more info about sessions here.
You can configure blacklisting, whitelisting and greylisting at the same time. If that's the case, note that whitelisting is
executed before blacklisting and greylisting : even if a criteria is true for all of them, the client will be whitelisted.
5.6.1 Blacklisting
STREAM support
112 / 263
BunkerWeb documentation v1.5.8
113 / 263
BunkerWeb documentation v1.5.8
When using stream mode, only IP, RDNS and ASN checks will be done.
5.6.2 Greylisting
STREAM support
114 / 263
BunkerWeb documentation v1.5.8
115 / 263
BunkerWeb documentation v1.5.8
When using stream mode, only IP, RDNS and ASN checks will be done.
5.6.3 Whitelisting
STREAM support
116 / 263
BunkerWeb documentation v1.5.8
117 / 263
BunkerWeb documentation v1.5.8
When using stream mode, only IP, RDNS and ASN checks will be done.
Reverse scan is a feature designed to detect open ports by establishing TCP connections with clients' IP addresses.
Consider adding this feature if you want to detect possible open proxies or connections from servers.
We provide a list of suspicious ports by default but it can be modified to fit your needs. Be mindful, adding too many
ports to the list can significantly slow down clients' connections due to the network checks. If a listed port is open, the
client's access will be denied.
Please be aware, this feature is new and further improvements will be added soon.
REVERSE_SCAN_TIMEOU 500 Specify the maximum timeout (in ms) when scanning a
T port.
118 / 263
BunkerWeb documentation v1.5.8
5.8 BunkerNet
STREAM support
BunkerNet is a crowdsourced database of malicious requests shared between all BunkerWeb instances over the
world.
If you enable BunkerNet, malicious requests will be sent to a remote server and will be analyzed by our systems. By
doing so, we can extract malicious data from everyone's reports and give back the results to each BunkerWeb
instances participating into BunkerNet.
Besides the enhanced security, enabling BunkerNet will let you benefit from extra features such as the integration
with CrowdSec Console.
If you don't already know about it, CrowdSec is an open-source cybersecurity solution leveraging crowdsourced
intelligence to mitigate cyber threats. Think of it like Waze but applied to cybersecurity : when a specific server is
attacked, other systems around the globe will be informed and protected from the same attackers. You will find more
information on their website here.
Thanks to a partnership with CrowdSec, you can enroll your BunkerWeb instances to your CrowdSec Console. In
other words, the attacks blocked by BunkerWeb will be visible the same way it does for attacks blocked by
CrowdSec Security Engines.
Please note that CrowdSec doesn't need to be installed at all (even if we recommend you to try it with the CrowdSec
plugin for BunkerWeb to enhance the security of your web services) and you can still enroll your Security Engines
into the same Console account.
Go to the CrowdSec Console and register your account if you don't already have one. Once it's done, write down
your enroll key by going to "Security Engines", then "Engines" and click on "Add Security Engine" :
119 / 263
BunkerWeb documentation v1.5.8
Activating the BunkerNet feature (which is the case by default) is mandatory if you want to enroll your BunkerWeb
instance(s) into your CrowdSec console. You can do it by setting USE_BUNKERNET to yes .
cat /var/cache/bunkerweb/bunkernet/instance.id
Once you have noted your BunkerNet ID and CrowdSec Console enroll key, you can order the free product
"BunkerNet / CrowdSec" on the Panel. Please note that you will need to create an account if you don't already have
one.
You can now select the "BunkerNet / CrowdSec" service and fill out the form by pasting your BunkerNet ID and
CrowdSec Console enroll key :
Figure 12: Enroll your BunkerWeb instance into the CrowdSec Console
Last but not least, you need to go back to your CrowdSec Console and accept the new Security Engine :
120 / 263
BunkerWeb documentation v1.5.8
Congratulations, your BunkerWeb instance is now enrolled into your CrowdSec Console !
Pro tip : when viewing your alerts, click on "columns" and tick the "context" checkbox to get access to BunkerWeb
specific data.
5.9 DNSBL
STREAM support
DNSBL or "DNS BlackList" is an external list of malicious IPs that you query using the DNS protocol. Automatic
querying of that kind of blacklist is supported by BunkerWeb. If a remote DNSBL server of your choice says that the
IP address of the client is in the blacklist, it will be banned.
121 / 263
BunkerWeb documentation v1.5.8
5.10 Limiting
BunkerWeb supports applying a limit policy to :
Please note that it should not be considered as an effective solution against DoS or DDoS but rather as an anti-
bruteforce measure or rate limit policy for API.
In both cases (connections or requests) if the limit is reached, the client will receive the HTTP status "429 - Too Many
Requests".
5.10.1 Connections
STREAM support
USE_LIMIT_CONN yes When set to yes , will limit the maximum number of concurrent
connections for a given IP.
LIMIT_CONN_MAX_HTT 100 Maximum number of concurrent streams when using HTTP2 protocol.
P2
5.10.2 Requests
STREAM support
122 / 263
BunkerWeb documentation v1.5.8
LIMIT_REQ_U / multisite yes URL (PCRE regex) where the limit request
RL will be applied or special value / for all
requests.
LIMIT_REQ_R 2r/s multisite yes Rate to apply to the URL (s for second, m for
ATE minute, h for hour and d for day).
Please note that you can add different rates for different URLs by adding a number as a suffix to the settings for
example : LIMIT_REQ_URL_1=^/url1$ , LIMIT_REQ_RATE_1=5r/d , LIMIT_REQ_URL_2=^/url2/subdir/.*$ ,
LIMIT_REQ_RATE_2=1r/m , ...
Another important thing to note is that LIMIT_REQ_URL values are PCRE regex.
5.11 Country
STREAM support
The country security feature allows you to apply policy based on the country of the IP address of clients :
Only allow access if the country is in a whitelist (other security checks will still be executed)
Using both country blacklist and whitelist at the same time makes no sense. If you do, please note that only the
whitelist will be executed.
123 / 263
BunkerWeb documentation v1.5.8
5.12 Authentication
5.12.1 Auth basic
STREAM support
You can quickly protect sensitive resources like the admin area for example, by requiring HTTP basic authentication.
Here is the list of related settings :
AUTH_BASIC_LOCAT sitewide Location (URL) of the sensitive resource. Use special value
ION sitewide to enable everywhere.
You can deploy complex authentication (e.g. SSO), by using the auth request settings (see here for more information
on the feature). Please note that you will find Authelia and Authentik examples in the repository.
124 / 263
BunkerWeb documentation v1.5.8
STREAM support
The monitoring plugin lets you collect and retrieve metrics about BunkerWeb. By enabling it, your instance(s) will
start collecting various data related to attacks, requests and performance. You can then retrieve them by calling the
/monitoring API endpoint on regular basis or by using other plugins like the Prometheus exporter one.
List of features
List of settings
STREAM support
The Prometheus exporter plugin adds a Prometheus exporter on your BunkerWeb instance(s). When enabled, you
can configure your Prometheus instance(s) to scrape a specific endpoint on Bunkerweb and gather internal metrics.
We also provide a Grafana dashboard that you can import into your own instance and connect to your own
Prometheus datasource.
125 / 263
BunkerWeb documentation v1.5.8
Please note that the use of Prometheus exporter plugin requires to enable the Monitoring plugin
( USE_MONITORING=yes )
List of features
List of settings
STREAM support
This plugins requires the Monitoring Pro plugin to be installed and enabled with the USE_MONITORING setting set to
yes .
126 / 263
BunkerWeb documentation v1.5.8
The Reporting plugin provides a comprehensive solution for regular reporting of important data from BunkerWeb,
including global statistics, attacks, bans, requests, reasons, and AS information. It offers a wide range of features,
including automatic report creation, customization options, and seamless integration with monitoring pro plugin. With
the Reporting plugin, you can easily generate and manage reports to monitor the performance and security of your
application.
List of features
Regular reporting of important data from BunkerWeb, including global statistics, attacks, bans, requests, reasons,
and AS information.
Integration with Monitoring Pro plugin for seamless integration and enhanced reporting capabilities.
Support for webhooks (classic, Discord, and Slack) for real-time notifications.
List of settings
REPORTING_SMTP_P 465 global The port used for SMTP. Please note that there are
ORT different standards depending on the type of
connection (SSL = 465, TLS = 587).
REPORTING_SMTP_F global The email address used as the sender. Note that 2FA
ROM_EMAIL must be disabled for this email address.
127 / 263
BunkerWeb documentation v1.5.8
REPORTING_SMTP_F global The user authentication value for sending via the from
ROM_USER email address.
REPORTING_SMTP_F global The password authentication value for sending via the
ROM_PASSWORD from email address.
case no REPORTING_SMTP_FROM_USER and REPORTING_SMTP_FROM_PASSWORD are set, the plugin will try to send the
email without authentication.
case REPORTING_SMTP_FROM_USER isn't set but REPORTING_SMTP_FROM_PASSWORD is set, the plugin will use the
REPORTING_SMTP_FROM_EMAIL as the username.
case the job fails, the plugin will retry sending the report in the next execution.
STREAM support
128 / 263
BunkerWeb documentation v1.5.8
If you are using RHEL 8.9 and plan on using an external database, you will need to install the mysql-community-
client package to ensure the mysqldump command is available. You can install the package by executing the
following commands:
MySQL/MariaDB
PostgreSQL
Data is invaluable, especially in digital environments where it's susceptible to loss due to various factors such as
hardware failures, software errors, or human mistakes. To mitigate such risks and ensure the safety and availability
of your important files, it's crucial to establish a robust backup system. This section outlines the backup functionality
provided by BunkerWeb, allowing you to securely store your data in a custom location through regular backups.
The importance of backups cannot be overstated. They serve as a safety net against data loss scenarios, providing a
means to restore your system to a previous state in case of unexpected events. Regular backups not only safeguard
your data but also offer peace of mind, knowing that you have a reliable mechanism in place to recover from any
mishaps.
129 / 263
BunkerWeb documentation v1.5.8
Linux
Docker
This command will create a backup of your database and store it in the backup directory specified in the
BACKUP_DIRECTORY setting.
You can also specify a custom directory for the backup by providing the BACKUP_DIRECTORY environment variable
when executing the command:
Linux
Docker
130 / 263
BunkerWeb documentation v1.5.8
In case you are using MariaDB/MySQL, you may encounter the following error when trying to backup your database:
To resolve this issue, you can execute the following command to change the authentication plugin to
mysql_native_password :
If you're using the Docker integration, you can add the following command to the docker-compose.yml file to
automatically change the authentication plugin:
MariaDB
bw-db:
image: mariadb:<version>
command: --default-authentication-plugin=mysql_native_password
...
MySQL
bw-db:
image: mysql:<version>
command: --default-authentication-plugin=mysql_native_password
...
Linux
Docker
This command will create a temporary backup of your database in /var/tmp/bunkerweb/backups and restore your
database to the latest backup available in the backup directory specified in the BACKUP_DIRECTORY setting.
You can also specify a custom backup file for the restore by providing the path to it as an argument when executing
the command:
131 / 263
BunkerWeb documentation v1.5.8
Linux
Docker
In case of failure
Don't worry if the restore fails, you can always restore your database to the previous state by executing the command
again but with the BACKUP_DIRECTORY setting set to /var/tmp/bunkerweb/backups :
Linux
Docker
STREAM support
The Backup S3 tool seamlessly automates data protection, similar to the community backup plugin. However, it
stands out by securely storing backups directly in an S3 bucket.
By activating this feature, you're proactively safeguarding your data's integrity. Storing backups remotely shields
crucial information from threats like hardware failures, cyberattacks, or natural disasters. This ensures both
security and availability, enabling swift recovery during unexpected events, preserving operational continuity,
and ensuring peace of mind.
132 / 263
BunkerWeb documentation v1.5.8
If you are using RHEL 8.9 and plan on using an external database, you will need to install the mysql-community-
client package to ensure the mysqldump command is available. You can install the package by executing the
following commands:
MySQL/MariaDB
PostgreSQL
List of features
List of settings
133 / 263
BunkerWeb documentation v1.5.8
Linux
Docker
This command will create a backup of your database and store it in the S3 bucket specified in the
BACKUP_S3_BUCKET setting.
You can also specify a custom S3 bucket for the backup by providing the BACKUP_S3_BUCKET environment variable
when executing the command:
134 / 263
BunkerWeb documentation v1.5.8
Linux
Docker
In case you are using MariaDB/MySQL, you may encounter the following error when trying to backup your database:
To resolve this issue, you can execute the following command to change the authentication plugin to
mysql_native_password :
If you're using the Docker integration, you can add the following command to the docker-compose.yml file to
automatically change the authentication plugin:
MariaDB
bw-db:
image: mariadb:<version>
command: --default-authentication-plugin=mysql_native_password
...
MySQL
bw-db:
image: mysql:<version>
command: --default-authentication-plugin=mysql_native_password
...
135 / 263
BunkerWeb documentation v1.5.8
Linux
Docker
This command will create a temporary backup of your database in the S3 bucket specified in the BACKUP_S3_BUCKET
setting and restore your database to the latest backup available in the bucket.
You can also specify a custom backup file for the restore by providing the path to it as an argument when executing
the command:
Linux
Docker
In case of failure
Don't worry if the restore fails, you can always restore your database to the previous state by executing the command
again as a backup is created before the restore:
Linux
Docker
The Migration plugin revolutionizes BunkerWeb configuration transfers between instances with its user-friendly
web interface, simplifying the entire migration journey. Whether you're upgrading systems, scaling infrastructure, or
transitioning environments, this tool empowers you to effortlessly transfer settings, preferences, and data with
unmatched ease and confidence. Say goodbye to cumbersome manual processes and hello to a seamless, hassle-
free migration experience.
136 / 263
BunkerWeb documentation v1.5.8
List of features
Effortless Migration: Easily transfer BunkerWeb configurations between instances without the complexities of
manual procedures.
Intuitive Web Interface: Navigate through the migration process effortlessly with a user-friendly web interface
designed for intuitive operation.
Cross-Database Compatibility: Enjoy seamless migration across various database platforms, including SQLite,
MySQL, MariaDB, and PostgreSQL, ensuring compatibility with your preferred database environment.
Linux
Docker
This command will create a backup of your database and store it in the backup directory specified in the command.
137 / 263
BunkerWeb documentation v1.5.8
In case you are using MariaDB/MySQL, you may encounter the following error when trying to backup your database:
To resolve this issue, you can execute the following command to change the authentication plugin to
mysql_native_password :
If you're using the Docker integration, you can add the following command to the docker-compose.yml file to
automatically change the authentication plugin:
MariaDB
bw-db:
image: mariadb:<version>
command: --default-authentication-plugin=mysql_native_password
...
MySQL
bw-db:
image: mysql:<version>
command: --default-authentication-plugin=mysql_native_password
...
Linux
Docker
138 / 263
BunkerWeb documentation v1.5.8
This command seamlessly migrates your BunkerWeb data to precisely match the configuration outlined in the
migration file.
139 / 263
BunkerWeb documentation v1.5.8
6 Settings
To help you tune BunkerWeb, we have made an easy-to-use settings generator tool available at config.bunkerweb.io.
This section contains the full list of settings supported by BunkerWeb. If you are not yet familiar with BunkerWeb,
you should first read the concepts section of the documentation. Please follow the instructions for your own
integration on how to apply the settings.
As a general rule when multisite mode is enabled, if you want to apply settings with multisite context to a specific
server, you will need to add the primary (first) server name as a prefix like www.example.com_USE_ANTIBOT=captcha
or myapp.example.com_USE_GZIP=yes for example.
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.
140 / 263
BunkerWeb documentation v1.5.8
141 / 263
BunkerWeb documentation v1.5.8
142 / 263
BunkerWeb documentation v1.5.8
6.2 Antibot
STREAM support
143 / 263
BunkerWeb documentation v1.5.8
Enforce login before accessing a resource or the whole site using HTTP basic auth method.
6.4 Backup
144 / 263
BunkerWeb documentation v1.5.8
STREAM support
Backup your data to a custom location. Ensure the safety and availability of your important files by creating regular
backups.
145 / 263
BunkerWeb documentation v1.5.8
Ban IP generating too much 'bad' HTTP status code in a period of time.
6.7 Blacklist
STREAM support
146 / 263
BunkerWeb documentation v1.5.8
147 / 263
BunkerWeb documentation v1.5.8
148 / 263
BunkerWeb documentation v1.5.8
6.8 Brotli
STREAM support
149 / 263
BunkerWeb documentation v1.5.8
6.9 BunkerNet
STREAM support
150 / 263
BunkerWeb documentation v1.5.8
6.10 CORS
STREAM support
151 / 263
BunkerWeb documentation v1.5.8
6.12 Country
STREAM support
152 / 263
BunkerWeb documentation v1.5.8
6.14 DB
STREAM support
153 / 263
BunkerWeb documentation v1.5.8
6.15 DNSBL
STREAM support
6.16 Errors
STREAM support
154 / 263
BunkerWeb documentation v1.5.8
(404=/my404.html
403=/errors/403.html ...).
INTERCEPTED_ 400 401 403 404 multisite no List of HTTP error code intercepted
ERROR_CODES 405 413 429 500 by BunkerWeb
501 502 503 504
6.17 Greylist
STREAM support
Allow access while keeping security features based on internal and external IP/network/rDNS/ASN greylists.
155 / 263
BunkerWeb documentation v1.5.8
6.18 Gzip
STREAM support
156 / 263
BunkerWeb documentation v1.5.8
application/x-font-ttf
application/x-javascript
application/xhtml+xml
application/xml font/eot
font/opentype font/otf font/truetype
image/svg+xml
image/vnd.microsoft.icon image/x-
icon image/x-win-bitmap text/css
text/javascript text/plain text/xml
6.20 Headers
STREAM support
157 / 263
BunkerWeb documentation v1.5.8
158 / 263
BunkerWeb documentation v1.5.8
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=()
159 / 263
BunkerWeb documentation v1.5.8
'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';
160 / 263
BunkerWeb documentation v1.5.8
Automatic creation, renewal and configuration of Let's Encrypt certificates using DNS challenges.
161 / 263
BunkerWeb documentation v1.5.8
6.23 Limit
STREAM support
LIMIT_REQ_RAT 2r/s multisite yes Rate to apply to the URL (s for second, m
E for minute, h for hour and d for day).
6.24 Metrics
STREAM support
162 / 263
BunkerWeb documentation v1.5.8
Migration of BunkerWeb configuration between instances made easy via the web UI
6.26 Miscellaneous
STREAM support
Miscellaneous settings.
163 / 263
BunkerWeb documentation v1.5.8
164 / 263
BunkerWeb documentation v1.5.8
6.27 ModSecurity
STREAM support
BunkerWeb monitoring pro system. This plugin is a prerequisite for some other plugins.
165 / 263
BunkerWeb documentation v1.5.8
6.29 PHP
STREAM support
6.30 Pro
STREAM support
166 / 263
BunkerWeb documentation v1.5.8
6.32 Real IP
STREAM support
Get real IP of clients when BunkerWeb is behind a reverse proxy / load balancer.
167 / 263
BunkerWeb documentation v1.5.8
172.16.0.0/12
10.0.0.0/8
6.33 Redirect
STREAM support
6.34 Redis
STREAM support
168 / 263
BunkerWeb documentation v1.5.8
REDIS_KEEPALIVE_ 30000 global no Max idle time (in ms) before closing
IDLE redis connection in the pool.
169 / 263
BunkerWeb documentation v1.5.8
Regular reporting of important data from BunkerWeb (global, attacks, bans, requests, reasons, AS...). Monitoring pro
plugin needed to work.
REPORTING_SMTP 465 global no The port used for SMTP. Please note
_PORT that there are different standards
depending on the type of connection
(SSL = 465, TLS = 587).
170 / 263
BunkerWeb documentation v1.5.8
171 / 263
BunkerWeb documentation v1.5.8
REVERSE_PRO 60s multisite yes Timeout when reading from the proxied
XY_READ_TIM resource.
EOUT
172 / 263
BunkerWeb documentation v1.5.8
PROXY_CACHE GET HEAD multisite no HTTP methods that should trigger a cache
_METHODS operation.
173 / 263
BunkerWeb documentation v1.5.8
6.39 Sessions
STREAM support
174 / 263
BunkerWeb documentation v1.5.8
challenges.
6.40 UI
STREAM support
6.41 Whitelist
STREAM support
175 / 263
BunkerWeb documentation v1.5.8
176 / 263
BunkerWeb documentation v1.5.8
177 / 263
BunkerWeb documentation v1.5.8
7 Web UI
7.1 Overview
The "Web UI" is a web application that helps you manage your BunkerWeb instance using a user-friendly interface
instead of the command-line one.
7.2 Features
Start, stop, restart and reload your BunkerWeb instance
Add, edit and delete custom configurations for NGINX and ModSecurity
7.3 Prerequisites
Because the web UI is a web application, the recommended installation procedure is to use BunkerWeb in front of it
as a reverse proxy.
178 / 263
BunkerWeb documentation v1.5.8
Security considerations
The security of the web UI is really important. If someone manages to gain access to the application, not only he will be
able to edit your configurations but he could execute some code in the context of BunkerWeb (with a custom
configuration containing LUA code for example). We highly recommend you to follow minimal security best practices
like :
Choose a strong password for the login (at least 8 chars with 1 lower case letter, 1 upper case letter, 1 digit and
1 special char is required)
Do not open the web UI on the Internet without any further restrictions
Please note that using HTTPS in front the web UI is mandatory since version 1.5.8 of BunkerWeb.
Multisite mode
Wizard
The setup wizard is a feature that helps you to configure and install the web UI using a user-friendly interface. You
will need to set the UI_HOST setting ( http://hostname-of-web-ui:7000 ) and browse the /setup URI of your server
to access the setup wizard.
179 / 263
BunkerWeb documentation v1.5.8
Choose your administrator username and password. Please note that password must have at least 8 chars with 1
lower case letter, 1 upper case letter, 1 digit and 1 special char.
180 / 263
BunkerWeb documentation v1.5.8
Server name : the public server name where your web UI will be accessible
Please note that your server name must have a valid DNS entry pointing to your BunkerWeb instance (or load
balancer if you use Swarm/Kubernetes). You can check the DNS validity by clicking the Check button.
Review your final BunkerWeb UI URL and then click on the Setup button. Once the setup is finished, you will be
redirected to your web UI login page.
181 / 263
BunkerWeb documentation v1.5.8
Docker
If you want to use the setup wizard, you will need to set the UI_HOST setting to the HTTP endpoint of your web UI
container. For example, if your web UI container is named bw-ui and is listening on the 7000 port, you will need to
set the UI_HOST setting to http://bw-ui:7000 .
You can access the setup wizard by browsing the https://your-ip-address-or-fqdn/setup URI of your server.
Here is the docker-compose boilerplate that you can use (don't forget to edit the changeme data) :
182 / 263
BunkerWeb documentation v1.5.8
version: "3.5"
services:
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
ports:
- 80:8080
- 443:8443
labels:
- "bunkerweb.INSTANCE=yes"
environment:
- SERVER_NAME=
- MULTISITE=yes
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
- UI_HOST=http://bw-ui:7000 # Change it if needed
networks:
- bw-universe
- bw-services
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
depends_on:
- bunkerweb
- bw-docker
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
networks:
- bw-universe
- bw-docker
bw-docker:
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.8
depends_on:
- bw-docker
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
networks:
- bw-universe
- bw-docker
bw-db:
image: mariadb:10.10
environment:
- MYSQL_RANDOM_ROOT_PASSWORD=yes
183 / 263
BunkerWeb documentation v1.5.8
- MYSQL_DATABASE=db
- MYSQL_USER=bunkerweb
- MYSQL_PASSWORD=changeme # Remember to set a stronger password for the database
volumes:
- bw-data:/var/lib/mysql
networks:
- bw-docker
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe
ipam:
driver: default
config:
- subnet: 10.20.30.0/24
bw-services:
name: bw-services
bw-docker:
name: bw-docker
Docker autoconf
If you want to use the setup wizard, you will need to set the UI_HOST setting to the HTTP endpoint of your web UI
container. For example, if your web UI container is named bw-ui and is listening on the 7000 port, you will need to
set the UI_HOST setting to http://bw-ui:7000 .
You can access the setup wizard by browsing the https://your-ip-address-or-fqdn/setup URI of your server.
Here is the docker-compose boilerplate that you can use (don't forget to edit the changeme data) :
184 / 263
BunkerWeb documentation v1.5.8
version: "3.5"
services:
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
ports:
- 80:8080
- 443:8443
labels:
- "bunkerweb.INSTANCE=yes"
environment:
- SERVER_NAME=
- AUTOCONF_MODE=yes
- MULTISITE=yes
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
- UI_HOST=http://bw-ui:7000 # Change it if needed
networks:
- bw-universe
- bw-services
bw-autoconf:
image: bunkerity/bunkerweb-autoconf:1.5.8
depends_on:
- bunkerweb
- bw-docker
environment:
- AUTOCONF_MODE=yes
- 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
networks:
- bw-universe
- bw-docker
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
depends_on:
- bunkerweb
- bw-docker
environment:
- AUTOCONF_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db # Remember to set a
stronger password for the database
networks:
- bw-universe
- bw-docker
bw-docker:
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
185 / 263
BunkerWeb documentation v1.5.8
bw-db:
image: mariadb:10.10
environment:
- MYSQL_RANDOM_ROOT_PASSWORD=yes
- MYSQL_DATABASE=db
- MYSQL_USER=bunkerweb
- MYSQL_PASSWORD=changeme # Remember to set a stronger password for the database
volumes:
- bw-data:/var/lib/mysql
networks:
- bw-docker
bw-ui:
image: bunkerity/bunkerweb-ui:1.5.8
networks:
bw-docker:
bw-universe:
aliases:
- bw-ui
environment:
- AUTOCONF_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db # Remember to set a
stronger password for the database
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe
ipam:
driver: default
config:
- subnet: 10.20.30.0/24
bw-services:
name: bw-services
bw-docker:
name: bw-docker
Swarm
If you want to use the setup wizard, you will need to set the UI_HOST setting to the HTTP endpoint of your web UI
container. For example, if your web UI container is named bw-ui and is listening on the 7000 port, you will need to
set the UI_HOST setting to http://bw-ui:7000 .
You can access the setup wizard by browsing the https://your-ip-address-or-fqdn/setup URI of your server.
Here is the stack boilerplate that you can use (don't forget to edit the changeme data) :
186 / 263
BunkerWeb documentation v1.5.8
version: "3.5"
services:
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
ports:
- published: 80
target: 8080
mode: host
protocol: tcp
- published: 443
target: 8443
mode: host
protocol: tcp
environment:
- SERVER_NAME=
- SWARM_MODE=yes
- MULTISITE=yes
- USE_REDIS=yes
- REDIS_HOST=bw-redis
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
- UI_HOST=http://bw-ui:7000 # Change it if needed
networks:
- bw-universe
- bw-services
deploy:
mode: global
placement:
constraints:
- "node.role == worker"
labels:
- "bunkerweb.INSTANCE=yes"
bw-autoconf:
image: bunkerity/bunkerweb-autoconf:1.5.8
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db # Remember to set a
stronger password for the database
networks:
- bw-universe
- bw-docker
bw-docker:
image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONFIGS=1
- CONTAINERS=1
- SERVICES=1
- SWARM=1
- TASKS=1
- LOG_LEVEL=warning
networks:
- bw-docker
deploy:
187 / 263
BunkerWeb documentation v1.5.8
placement:
constraints:
- "node.role == manager"
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db # Remember to set a
stronger password for the database
networks:
- bw-universe
- bw-docker
bw-db:
image: mariadb:10.10
environment:
- MYSQL_RANDOM_ROOT_PASSWORD=yes
- MYSQL_DATABASE=db
- MYSQL_USER=bunkerweb
- MYSQL_PASSWORD=changeme
volumes:
- bw-data:/var/lib/mysql
networks:
- bw-docker
bw-redis:
image: redis:7-alpine
networks:
- bw-universe
bw-ui:
image: bunkerity/bunkerweb-ui:1.5.8
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db # Remember to set a
stronger password for the database
networks:
- bw-universe
- bw-docker
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe
driver: overlay
attachable: true
ipam:
config:
- subnet: 10.20.30.0/24
bw-services:
name: bw-services
driver: overlay
attachable: true
bw-docker:
188 / 263
BunkerWeb documentation v1.5.8
name: bw-docker
driver: overlay
attachable: true
Kubernetes
If you want to use the setup wizard, you will need to set the UI_HOST setting to the HTTP endpoint of your web UI
SERVICE. For example, if your web UI service is named svc-bunkerweb-ui and is listening on the 7000 port, you
will need to set the UI_HOST setting to http://svc-bunkerweb-ui:7000 .
You can access the setup wizard by browsing the https://your-ip-address-or-fqdn/setup URI of your server.
Here is the yaml boilerplate that you can use (don't forget to edit the changeme data) :
189 / 263
BunkerWeb documentation v1.5.8
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cr-bunkerweb
rules:
- apiGroups: [""]
resources: ["services", "pods", "configmaps", "secrets"]
verbs: ["get", "watch", "list"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "watch", "list"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa-bunkerweb
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: crb-bunkerweb
subjects:
- kind: ServiceAccount
name: sa-bunkerweb
namespace: default
apiGroup: ""
roleRef:
kind: ClusterRole
name: cr-bunkerweb
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: bunkerweb
spec:
selector:
matchLabels:
app: bunkerweb
template:
metadata:
labels:
app: bunkerweb
# mandatory annotation
annotations:
bunkerweb.io/INSTANCE: "yes"
spec:
containers:
# using bunkerweb as name is mandatory
- name: bunkerweb
image: bunkerity/bunkerweb:1.5.8
imagePullPolicy: Always
securityContext:
runAsUser: 101
runAsGroup: 101
allowPrivilegeEscalation: false
capabilities:
drop:
190 / 263
BunkerWeb documentation v1.5.8
- ALL
ports:
- containerPort: 8080
hostPort: 80
- containerPort: 8443
hostPort: 443
env:
- name: KUBERNETES_MODE
value: "yes"
# replace with your DNS resolvers
# e.g. : kube-dns.kube-system.svc.cluster.local
- name: DNS_RESOLVERS
value: "coredns.kube-system.svc.cluster.local"
- name: USE_API
value: "yes"
# 10.0.0.0/8 is the cluster internal subnet
- name: API_WHITELIST_IP
value: "127.0.0.0/8 10.0.0.0/8"
- name: SERVER_NAME
value: ""
- name: MULTISITE
value: "yes"
- name: USE_REDIS
value: "yes"
- name: REDIS_HOST
value: "svc-bunkerweb-redis.default.svc.cluster.local"
# Change it if needed
- name: UI_HOST
value: "http://svc-bunkerweb-ui:7000"
livenessProbe:
exec:
command:
- /usr/share/bunkerweb/helpers/healthcheck.sh
initialDelaySeconds: 30
periodSeconds: 5
timeoutSeconds: 1
failureThreshold: 3
readinessProbe:
exec:
command:
- /usr/share/bunkerweb/helpers/healthcheck.sh
initialDelaySeconds: 30
periodSeconds: 1
timeoutSeconds: 1
failureThreshold: 3
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bunkerweb-controller
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: bunkerweb-controller
template:
metadata:
191 / 263
BunkerWeb documentation v1.5.8
labels:
app: bunkerweb-controller
spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-controller
image: bunkerity/bunkerweb-autoconf:1.5.8
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
value: "yes"
- name: "DATABASE_URI"
value: "mariadb+pymysql://bunkerweb:changeme@svc-bunkerweb-db:3306/db"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bunkerweb-scheduler
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: bunkerweb-scheduler
template:
metadata:
labels:
app: bunkerweb-scheduler
spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-scheduler
image: bunkerity/bunkerweb-scheduler:1.5.8
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
value: "yes"
- name: "DATABASE_URI"
value: "mariadb+pymysql://bunkerweb:changeme@svc-bunkerweb-db:3306/db"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bunkerweb-redis
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: bunkerweb-redis
template:
metadata:
labels:
app: bunkerweb-redis
spec:
containers:
- name: bunkerweb-redis
192 / 263
BunkerWeb documentation v1.5.8
image: redis:7-alpine
imagePullPolicy: Always
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bunkerweb-db
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: bunkerweb-db
template:
metadata:
labels:
app: bunkerweb-db
spec:
containers:
- name: bunkerweb-db
image: mariadb:10.10
imagePullPolicy: Always
env:
- name: MYSQL_RANDOM_ROOT_PASSWORD
value: "yes"
- name: "MYSQL_DATABASE"
value: "db"
- name: "MYSQL_USER"
value: "bunkerweb"
- name: "MYSQL_PASSWORD"
value: "changeme"
volumeMounts:
- mountPath: "/var/lib/mysql"
name: vol-db
volumes:
- name: vol-db
persistentVolumeClaim:
claimName: pvc-bunkerweb
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bunkerweb-ui
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: bunkerweb-ui
template:
metadata:
labels:
app: bunkerweb-ui
spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-ui
193 / 263
BunkerWeb documentation v1.5.8
image: bunkerity/bunkerweb-ui:1.5.8
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
value: "YES"
- name: "DATABASE_URI"
value: "mariadb+pymysql://bunkerweb:testor@svc-bunkerweb-db:3306/db"
---
apiVersion: v1
kind: Service
metadata:
name: svc-bunkerweb
spec:
clusterIP: None
selector:
app: bunkerweb
---
apiVersion: v1
kind: Service
metadata:
name: svc-bunkerweb-db
spec:
type: ClusterIP
selector:
app: bunkerweb-db
ports:
- name: sql
protocol: TCP
port: 3306
targetPort: 3306
---
apiVersion: v1
kind: Service
metadata:
name: svc-bunkerweb-redis
spec:
type: ClusterIP
selector:
app: bunkerweb-redis
ports:
- name: redis
protocol: TCP
port: 6379
targetPort: 6379
---
apiVersion: v1
kind: Service
metadata:
name: svc-bunkerweb-ui
spec:
type: ClusterIP
selector:
app: bunkerweb-ui
ports:
- name: http
protocol: TCP
port: 7000
targetPort: 7000
---
194 / 263
BunkerWeb documentation v1.5.8
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-bunkerweb
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
volumeName: pv-bunkerweb
Linux
If you want to use the setup wizard, you will need to run the following command export UI_WIZARD=1 before
installing BunkerWeb as described in integrations section of the documentation (this is an optional step).
You can access the setup wizard by browsing the https://your-ip-address/setup URI of your server.
195 / 263
BunkerWeb documentation v1.5.8
BunkerWeb PRO is an enhanced version of BunkerWeb open-source. Whether it's enhanced security, an enriched user
experience, or technical monitoring, the BunkerWeb PRO version will allow you to fully benefit from BunkerWeb and
respond to your professional needs. Do not hesitate to visit the BunkerWeb panel or contact us if you have any
question regarding the PRO version.
Once you have your PRO license key from the BunkerWeb panel, you can paste it into the PRO section of the
account management page.
Upgrade time
The PRO version is downloaded in the background by the scheduler, it may take some time to upgrade.
When your BunkerWeb instance has upgraded to the PRO version, you will see your license expiration date and the
maximum number of services you can protect.
196 / 263
BunkerWeb documentation v1.5.8
If you want to override the admin credentials from environment variables, you can set the following variables :
OVERRIDE_ADMIN_CREDS : set it to yes to enable the override even if the admin credentials are already set (default is
no )
Lost password/username
In case you forgot your UI credentials, you can reset them from the CLI following the steps described in the
troubleshooting section.
You can update your username or password by filling the dedicated forms. For security reason, you need to enter
your current password even if you are connected.
Please note that when your username or password is updated, you will be logout from the web UI to log in again.
197 / 263
BunkerWeb documentation v1.5.8
In case you lost your secret key, you can disable 2FA from the CLI following the steps described in the troubleshooting
section.
You can power-up your login security by adding Two-Factor Authentication (2FA) to your account. By doing so, an
extra code will be needed in addition to your password.
The web UI uses Time based One Time Password (TOTP) as 2FA implementation : using a secret key, the
algorithm will generate one time passwords only valid for a short period of time.
Any TOTP client such as Google Authenticator, Authy, FreeOTP, ... can be used to store the secret key and generate
the codes. Please note that once TOTP is enabled, you won't be able to retrieve it from the web UI.
The following steps are needed to enable the TOTP feature from the web UI :
Copy the secret key or use the QR code on your authenticator app
198 / 263
BunkerWeb documentation v1.5.8
A new secret key is generated each time you visit the page or submit the form. In case something went wrong (e.g. :
expired TOTP code), you will need to copy the new secret key to your authenticator app until 2FA is successfully
enabled.
After a successful login/password combination, you will be prompted to enter your TOTP code :
199 / 263
BunkerWeb documentation v1.5.8
200 / 263
BunkerWeb documentation v1.5.8
Docker
The web UI can be deployed using a dedicated container which is available on Docker Hub :
The following environment variables are used to configure the web UI container :
OVERRIDE_ADMIN_CREDS : force override the admin credentials even if we already have a user in the database
(default = no )
Accessing the web UI through BunkerWeb is a classical reverse proxy setup. 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.
Database backend
If you want another Database backend than MariaDB please refer to the docker-compose files in the misc/integrations
folder of the repository.
Here is the docker-compose boilerplate that you can use (don't forget to edit the changeme data) :
201 / 263
BunkerWeb documentation v1.5.8
version: "3.5"
services:
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
ports:
- 80:8080
- 443:8443
labels:
- "bunkerweb.INSTANCE=yes"
environment:
- SERVER_NAME=www.example.com
- MULTISITE=yes
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db # Remember to set a
stronger password for the database
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
- DISABLE_DEFAULT_SERVER=yes
- USE_CLIENT_CACHE=yes
- 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_HOST=http://bw-ui:7000
- www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
- www.example.com_MAX_CLIENT_SIZE=50m
networks:
- bw-universe
- bw-services
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
depends_on:
- bunkerweb
- bw-docker
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
networks:
- bw-universe
- bw-docker
bw-docker:
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.8
depends_on:
- bw-docker
environment:
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db # Remember to set a
202 / 263
BunkerWeb documentation v1.5.8
bw-db:
image: mariadb:10.10
environment:
- MYSQL_RANDOM_ROOT_PASSWORD=yes
- MYSQL_DATABASE=db
- MYSQL_USER=bunkerweb
- MYSQL_PASSWORD=changeme # Remember to set a stronger password for the database
volumes:
- bw-data:/var/lib/mysql
networks:
- bw-docker
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe
ipam:
driver: default
config:
- subnet: 10.20.30.0/24
bw-services:
name: bw-services
bw-docker:
name: bw-docker
Docker autoconf
The web UI can be deployed using a dedicated container which is available on Docker Hub :
The following environment variables are used to configure the web UI container :
OVERRIDE_ADMIN_CREDS : force override the admin credentials even if we already have a user in the database
(default = no )
203 / 263
BunkerWeb documentation v1.5.8
Accessing the web UI through BunkerWeb is a classical reverse proxy setup. 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.
Database backend
If you want another Database backend than MariaDB please refer to the docker-compose files in the misc/integrations
folder of the repository.
Here is the docker-compose boilerplate that you can use (don't forget to edit the changeme data) :
204 / 263
BunkerWeb documentation v1.5.8
version: "3.5"
services:
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
ports:
- 80:8080
- 443:8443
labels:
- "bunkerweb.INSTANCE=yes"
environment:
- SERVER_NAME=
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db
- AUTOCONF_MODE=yes
- MULTISITE=yes
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
networks:
- bw-universe
- bw-services
bw-autoconf:
image: bunkerity/bunkerweb-autoconf:1.5.8
depends_on:
- bunkerweb
- bw-docker
environment:
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db
- AUTOCONF_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
networks:
- bw-universe
- bw-docker
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
depends_on:
- bunkerweb
- bw-docker
environment:
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db
- DOCKER_HOST=tcp://bw-docker:2375
- AUTOCONF_MODE=yes
networks:
- bw-universe
- bw-docker
bw-docker:
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-db:
image: mariadb:10.10
205 / 263
BunkerWeb documentation v1.5.8
environment:
- MYSQL_RANDOM_ROOT_PASSWORD=yes
- MYSQL_DATABASE=db
- MYSQL_USER=bunkerweb
- MYSQL_PASSWORD=changeme
volumes:
- bw-data:/var/lib/mysql
networks:
- bw-docker
bw-ui:
image: bunkerity/bunkerweb-ui:1.5.8
networks:
bw-docker:
bw-universe:
aliases:
- bw-ui
environment:
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db
- DOCKER_HOST=tcp://bw-docker:2375
- AUTOCONF_MODE=yes
- ADMIN_USERNAME=admin
- ADMIN_PASSWORD=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_HOST=http://bw-ui:7000"
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
- "bunkerweb.MAX_CLIENT_SIZE=50m"
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe
ipam:
driver: default
config:
- subnet: 10.20.30.0/24
bw-services:
name: bw-services
bw-docker:
name: bw-docker
Swarm
The web UI can be deployed using a dedicated container which is available on Docker Hub :
206 / 263
BunkerWeb documentation v1.5.8
The following environment variables are used to configure the web UI container :
OVERRIDE_ADMIN_CREDS : force override the admin credentials even if we already have a user in the database
(default = no )
Accessing the web UI through BunkerWeb is a classical reverse proxy setup. 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.
Database backend
If you want another Database backend than MariaDB please refer to the stack files in the misc/integrations folder of the
repository.
Here is the stack boilerplate that you can use (don't forget to edit the changeme data) :
207 / 263
BunkerWeb documentation v1.5.8
version: "3.5"
services:
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
ports:
- published: 80
target: 8080
mode: host
protocol: tcp
- published: 443
target: 8443
mode: host
protocol: tcp
environment:
- SERVER_NAME=
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db
- SWARM_MODE=yes
- MULTISITE=yes
- USE_REDIS=yes
- REDIS_HOST=bw-redis
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
networks:
- bw-universe
- bw-services
deploy:
mode: global
placement:
constraints:
- "node.role == worker"
labels:
- "bunkerweb.INSTANCE=yes"
bw-autoconf:
image: bunkerity/bunkerweb-autoconf:1.5.8
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db
networks:
- bw-universe
- bw-docker
bw-docker:
image: tecnativa/docker-socket-proxy:nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONFIGS=1
- CONTAINERS=1
- SERVICES=1
- SWARM=1
- TASKS=1
- LOG_LEVEL=warning
networks:
- bw-docker
deploy:
placement:
208 / 263
BunkerWeb documentation v1.5.8
constraints:
- "node.role == manager"
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
environment:
- SWARM_MODE=yes
- DOCKER_HOST=tcp://bw-docker:2375
- DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db
networks:
- bw-universe
- bw-docker
bw-db:
image: mariadb:10.10
environment:
- MYSQL_RANDOM_ROOT_PASSWORD=yes
- MYSQL_DATABASE=db
- MYSQL_USER=bunkerweb
- MYSQL_PASSWORD=changeme
volumes:
- bw-data:/var/lib/mysql
networks:
- bw-docker
bw-redis:
image: redis:7-alpine
networks:
- bw-universe
bw-ui:
image: bunkerity/bunkerweb-ui:1.5.8
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
- SWARM_MODE=yes
- ADMIN_USERNAME=changeme
- ADMIN_PASSWORD=changeme # Remember to set a stronger password for the changeme user
networks:
- bw-universe
- bw-docker
deploy:
labels:
- "bunkerweb.SERVER_NAME=www.example.com"
- "bunkerweb.USE_UI=yes"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- "bunkerweb.REVERSE_PROXY_URL=/changeme"
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
- "bunkerweb.REVERSE_PROXY_INTERCEPT_ERRORS=no"
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
- "bunkerweb.MAX_CLIENT_SIZE=50m"
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe
driver: overlay
209 / 263
BunkerWeb documentation v1.5.8
attachable: true
ipam:
config:
- subnet: 10.20.30.0/24
bw-services:
name: bw-services
driver: overlay
attachable: true
bw-docker:
name: bw-docker
driver: overlay
attachable: true
Kubernetes
The web UI can be deployed using a dedicated container which is available on Docker Hub as a standard
Deployment.
The following environment variables are used to configure the web UI container :
OVERRIDE_ADMIN_CREDS : force override the admin credentials even if we already have a user in the database
(default = no )
Accessing the web UI through BunkerWeb is a classical reverse proxy setup. 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.
Database backend
If you want another Database backend than MariaDB please refer to the yaml files in the misc/integrations folder of the
repository.
Here is the yaml boilerplate that you can use (don't forget to edit the changeme data) :
210 / 263
BunkerWeb documentation v1.5.8
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cr-bunkerweb
rules:
- apiGroups: [""]
resources: ["services", "pods", "configmaps", "secrets"]
verbs: ["get", "watch", "list"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "watch", "list"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa-bunkerweb
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: crb-bunkerweb
subjects:
- kind: ServiceAccount
name: sa-bunkerweb
namespace: default
apiGroup: ""
roleRef:
kind: ClusterRole
name: cr-bunkerweb
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: bunkerweb
spec:
selector:
matchLabels:
app: bunkerweb
template:
metadata:
labels:
app: bunkerweb
# mandatory annotation
annotations:
bunkerweb.io/INSTANCE: "yes"
spec:
containers:
# using bunkerweb as name is mandatory
- name: bunkerweb
image: bunkerity/bunkerweb:1.5.8
imagePullPolicy: Always
securityContext:
runAsUser: 101
runAsGroup: 101
allowPrivilegeEscalation: false
capabilities:
drop:
211 / 263
BunkerWeb documentation v1.5.8
- ALL
ports:
- containerPort: 8080
hostPort: 80
- containerPort: 8443
hostPort: 443
env:
- name: KUBERNETES_MODE
value: "yes"
# replace with your DNS resolvers
# e.g. : kube-dns.kube-system.svc.cluster.local
- name: DNS_RESOLVERS
value: "coredns.kube-system.svc.cluster.local"
- name: USE_API
value: "yes"
# 10.0.0.0/8 is the cluster internal subnet
- name: API_WHITELIST_IP
value: "127.0.0.0/8 10.0.0.0/8"
- name: SERVER_NAME
value: ""
- name: MULTISITE
value: "yes"
- name: USE_REDIS
value: "yes"
- name: REDIS_HOST
value: "svc-bunkerweb-redis.default.svc.cluster.local"
livenessProbe:
exec:
command:
- /usr/share/bunkerweb/helpers/healthcheck.sh
initialDelaySeconds: 30
periodSeconds: 5
timeoutSeconds: 1
failureThreshold: 3
readinessProbe:
exec:
command:
- /usr/share/bunkerweb/helpers/healthcheck.sh
initialDelaySeconds: 30
periodSeconds: 1
timeoutSeconds: 1
failureThreshold: 3
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bunkerweb-controller
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: bunkerweb-controller
template:
metadata:
labels:
app: bunkerweb-controller
spec:
212 / 263
BunkerWeb documentation v1.5.8
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-controller
image: bunkerity/bunkerweb-autoconf:1.5.8
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
value: "yes"
- name: "DATABASE_URI"
value: "mariadb+pymysql://bunkerweb:changeme@svc-bunkerweb-db:3306/db"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bunkerweb-scheduler
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: bunkerweb-scheduler
template:
metadata:
labels:
app: bunkerweb-scheduler
spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-scheduler
image: bunkerity/bunkerweb-scheduler:1.5.8
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
value: "yes"
- name: "DATABASE_URI"
value: "mariadb+pymysql://bunkerweb:changeme@svc-bunkerweb-db:3306/db"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bunkerweb-redis
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: bunkerweb-redis
template:
metadata:
labels:
app: bunkerweb-redis
spec:
containers:
- name: bunkerweb-redis
image: redis:7-alpine
imagePullPolicy: Always
---
213 / 263
BunkerWeb documentation v1.5.8
apiVersion: apps/v1
kind: Deployment
metadata:
name: bunkerweb-db
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: bunkerweb-db
template:
metadata:
labels:
app: bunkerweb-db
spec:
containers:
- name: bunkerweb-db
image: mariadb:10.10
imagePullPolicy: Always
env:
- name: MYSQL_RANDOM_ROOT_PASSWORD
value: "yes"
- name: "MYSQL_DATABASE"
value: "db"
- name: "MYSQL_USER"
value: "bunkerweb"
- name: "MYSQL_PASSWORD"
value: "changeme"
volumeMounts:
- mountPath: "/var/lib/mysql"
name: vol-db
volumes:
- name: vol-db
persistentVolumeClaim:
claimName: pvc-bunkerweb
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bunkerweb-ui
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: bunkerweb-ui
template:
metadata:
labels:
app: bunkerweb-ui
spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-ui
image: bunkerity/bunkerweb-ui:1.5.8
imagePullPolicy: Always
env:
214 / 263
BunkerWeb documentation v1.5.8
- name: ADMIN_USERNAME
value: "changeme"
- name: "ADMIN_PASSWORD"
value: "changeme"
- name: KUBERNETES_MODE
value: "YES"
- name: "DATABASE_URI"
value: "mariadb+pymysql://bunkerweb:testor@svc-bunkerweb-db:3306/db"
---
apiVersion: v1
kind: Service
metadata:
name: svc-bunkerweb
spec:
clusterIP: None
selector:
app: bunkerweb
---
apiVersion: v1
kind: Service
metadata:
name: svc-bunkerweb-db
spec:
type: ClusterIP
selector:
app: bunkerweb-db
ports:
- name: sql
protocol: TCP
port: 3306
targetPort: 3306
---
apiVersion: v1
kind: Service
metadata:
name: svc-bunkerweb-redis
spec:
type: ClusterIP
selector:
app: bunkerweb-redis
ports:
- name: redis
protocol: TCP
port: 6379
targetPort: 6379
---
apiVersion: v1
kind: Service
metadata:
name: svc-bunkerweb-ui
spec:
type: ClusterIP
selector:
app: bunkerweb-ui
ports:
- name: http
protocol: TCP
port: 7000
targetPort: 7000
215 / 263
BunkerWeb documentation v1.5.8
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-bunkerweb
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
volumeName: pv-bunkerweb
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
annotations:
bunkerweb.io/www.example.com_USE_UI: "yes"
bunkerweb.io/www.example.com_INTERCEPTED_ERROR_CODES: '400 404 405 413 429 500 501 502 503
504'
bunkerweb.io/www.example.com_MAX_CLIENT_SIZE: '50m'
spec:
rules:
- host: www.example.com
http:
paths:
- path: /changeme
pathType: Prefix
backend:
service:
name: svc-bunkerweb-ui
port:
number: 7000
Linux
The installation of the web UI using the Linux integration is pretty straightforward because it is installed with
BunkerWeb.
The web UI comes as systemd service named bunkerweb-ui which is not enabled by default. If you want to start
the web UI when on startup you can run the following command :
ADMIN_USERNAME=changeme
ADMIN_PASSWORD=changeme
OVERRIDE_ADMIN_CREDS=no
Each time you edit the /etc/bunkerweb/ui.env file, you will need to restart the service :
216 / 263
BunkerWeb documentation v1.5.8
Accessing the web UI through BunkerWeb is a classical reverse proxy setup. Please note that the web UI is listening
on the 7000 port and only on the loopback interface.
HTTP_PORT=80
HTTPS_PORT=443
DNS_RESOLVERS=9.9.9.9 8.8.8.8 8.8.4.4
API_LISTEN_IP=127.0.0.1
SERVER_NAME=www.example.com
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_HOST=http://127.0.0.1:7000
www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
www.example.com_MAX_CLIENT_SIZE=50m
217 / 263
BunkerWeb documentation v1.5.8
8 Upgrading
Read me first
We often add new features and settings to BunkerWeb. We recommend you read the settings sections of the
documentation or the GitHub releases to see what's new.
8.1.1 Procedure
Before proceeding with the database upgrade, ensure to perform a complete backup of the current state of
the database.
Use appropriate tools to backup the entire database, including data, schemas, and configurations.
218 / 263
BunkerWeb documentation v1.5.8
219 / 263
BunkerWeb documentation v1.5.8
Docker
Linux
If you are using RHEL 8.9 and plan on using an external database, you will need to install the mysql-community-
client package to ensure the mysqldump command is available. You can install the package by executing the
following commands:
MySQL/MariaDB
PostgreSQL
220 / 263
BunkerWeb documentation v1.5.8
SQLite
Docker
Linux
MySQL/MariaDB
Docker
Linux
PostgreSQL
Docker
Linux
2. Upgrade BunkerWeb:
221 / 263
BunkerWeb documentation v1.5.8
Docker
a. Update the Docker Compose file: Update the Docker Compose file to use the new version of the
BunkerWeb image.
services:
bunkerweb:
image: bunkerity/bunkerweb:1.5.8
...
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
...
bw-autoconf:
image: bunkerity/bunkerweb-autoconf:1.5.8
...
bw-ui:
image: bunkerity/bunkerweb-ui:1.5.8
...
Linux
b. Update BunkerWeb:
222 / 263
BunkerWeb documentation v1.5.8
Debian/Ubuntu
To prevent upgrading BunkerWeb package when executing apt upgrade , you can use the following
command :
Fedora/RedHat
You can print a list of packages on hold with dnf versionlock list
To prevent upgrading BunkerWeb package when executing dnf upgrade , you can use the following
command :
3. Check the logs: Check the logs of the scheduler service to ensure that the migration was successful.
Docker
Linux
223 / 263
BunkerWeb documentation v1.5.8
4. Verify the database: Verify that the database upgrade was successful by checking the data and configurations
in the new database container.
8.1.2 Rollback
In case of issues
If you encounter any issues during the upgrade, you can rollback to the previous version of the database by restoring
the backup taken in step 1.
224 / 263
BunkerWeb documentation v1.5.8
Docker
225 / 263
BunkerWeb documentation v1.5.8
SQLite
d. Fix permissions.
MySQL/MariaDB
PostgreSQL
226 / 263
BunkerWeb documentation v1.5.8
2. Downgrade BunkerWeb.
services:
bunkerweb:
image: bunkerity/bunkerweb:<old_version>
...
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:<old_version>
...
bw-autoconf:
image: bunkerity/bunkerweb-autoconf:<old_version>
...
bw-ui:
image: bunkerity/bunkerweb-ui:<old_version>
...
docker compose up -d
Linux
227 / 263
BunkerWeb documentation v1.5.8
SQLite
sudo rm -f /var/lib/bunkerweb/db.sqlite3
sudo sqlite3 /var/lib/bunkerweb/db.sqlite3 < /path/to/backup/directory/backup.sql
sudo chown root:nginx /var/lib/bunkerweb/db.sqlite3
sudo chmod 770 /var/lib/bunkerweb/db.sqlite3
MySQL/MariaDB
PostgreSQL
3. Downgrade BunkerWeb.
Downgrade BunkerWeb to the previous version by following the same steps as when upgrading BunkerWeb
in the integration Linux page
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 folder of the repository.
8.2.1 Scheduler
Back to the 1.4.X releases, jobs (like Let's Encrypt certificate generation/renewal or blacklists download) were
executed in the same container as BunkerWeb. For the purpose of separation of concerns, we decided to create
a separate service which is now responsible for managing jobs.
228 / 263
BunkerWeb documentation v1.5.8
Called Scheduler, this service also generates the final configuration used by BunkerWeb and acts as an
intermediary between autoconf and BunkerWeb. In other words, the scheduler is the brain of the BunkerWeb 1.5.X
stack.
8.2.2 Database
BunkerWeb configuration is no more stored in a plain file (located at /etc/nginx/variables.env if you didn't
know it). That's it, we now support a fully-featured database as a backend to store settings, cache, custom
configs, ... 🥳
Using a real database offers many advantages :
Please note that we actually support, SQLite, MySQL, MariaDB and PostgreSQL as backends.
8.2.3 Redis
When BunkerWeb 1.4.X was used in cluster mode (Swarm or Kubernetes integrations), data were not shared
among the nodes. For example, if an attacker was banned via the "bad behavior" feature on a specific node, he
could still connect to the other nodes.
Security is not the only reason to have a shared data store for clustered integrations, caching is also another one.
We can now store results of time-consuming operations like (reverse) dns lookups so they are available for other
nodes.
See the list of redis settings and the corresponding documentation of your integration for more information.
The default value of some settings have changed and we have added many other settings, we recommend you read
the security tuning and settings sections of the documentation.
229 / 263
BunkerWeb documentation v1.5.8
9 Troubleshooting
BunkerWeb Panel
If you are unable to resolve your problems, you can contact us directly via our panel. This centralises all requests
relating to the BunkerWeb solution.
9.1 Logs
When troubleshooting, logs are your best friends. We try our best to provide user-friendly logs to help you
understand what's happening.
Please note that you can set LOG_LEVEL setting to info (default : notice ) to increase the verbosity of BunkerWeb.
Here is how you can access the logs, depending on your integration :
230 / 263
BunkerWeb documentation v1.5.8
Docker
List containers
To list the running containers, you can use the following command :
docker ps
You can use the docker logs command (replace mybunker with the name of your container) :
Here is the docker-compose equivalent (replace mybunker with the name of the services declared in the docker-
compose.yml file) :
Docker autoconf
List containers
To list the running containers, you can use the following command :
docker ps
You can use the docker logs command (replace mybunker and myautoconf with the name of your containers) :
Here is the docker-compose equivalent (replace mybunker and myautoconf with the name of the services declared
in the docker-compose.yml file) :
Swarm
231 / 263
BunkerWeb documentation v1.5.8
List services
docker service ls
You can use the docker service logs command (replace mybunker and myautoconf with the name of your
services) :
Kubernetes
List pods
You can use the kubectl logs command (replace mybunker and myautoconf with the name of your pods) :
Linux
For errors related to BunkerWeb services (e.g. not starting), you can use journalctl :
cat /var/log/bunkerweb/error.log
cat /var/log/bunkerweb/access.log
9.2 Permissions
232 / 263
BunkerWeb documentation v1.5.8
Don't forget that BunkerWeb runs as an unprivileged user for obvious security reasons. Double-check the
permissions of files and folders used by BunkerWeb, especially if you use custom configurations (more info here).
You will need to set at least RW rights on files and RWX on folders.
9.4 ModSecurity
The default BunkerWeb configuration of ModSecurity is to load the Core Rule Set in anomaly scoring mode with a
paranoia level (PL) of 1 :
Each matched rule will increase an anomaly score (so many rules can match a single request)
PL1 includes rules with fewer chances of false positives (but less security than PL4)
the default threshold for anomaly score is 5 for requests and 4 for responses
Let's take the following logs as an example of ModSecurity detection using default configuration (formatted for better
readability) :
233 / 263
BunkerWeb documentation v1.5.8
2022/04/26 12:01:10 [warn] 85#85: *11 ModSecurity: Warning. Matched "Operator `PmFromFile' with
parameter `lfi-os-files.data' against variable `ARGS:id' (Value: `/etc/passwd' )
[file "/usr/share/bunkerweb/core/modsecurity/files/coreruleset/rules/REQUEST-930-APPLICATION-
ATTACK-LFI.conf"]
[line "78"]
[id "930120"]
[rev ""]
[msg "OS File Access Attempt"]
[data "Matched Data: etc/passwd found within ARGS:id: /etc/passwd"]
[severity "2"]
[ver "OWASP_CRS/3.3.2"]
[maturity "0"]
[accuracy "0"]
[tag "application-multi"]
[tag "language-multi"]
[tag "platform-multi"]
[tag "attack-lfi"]
[tag "paranoia-level/1"]
[tag "OWASP_CRS"]
[tag "capec/1000/255/153/126"]
[tag "PCI/6.5.4"]
[hostname "172.17.0.2"]
[uri "/"]
[unique_id "165097447014.179282"]
[ref "o1,10v9,11t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,t:lowercase"],
client: 172.17.0.1, server: localhost, request: "GET /?id=/etc/passwd HTTP/1.1", host:
"localhost"
2022/04/26 12:01:10 [warn] 85#85: *11 ModSecurity: Warning. Matched "Operator `PmFromFile' with
parameter `unix-shell.data' against variable `ARGS:id' (Value: `/etc/passwd' )
[file "/usr/share/bunkerweb/core/modsecurity/files/coreruleset/rules/REQUEST-932-APPLICATION-
ATTACK-RCE.conf"]
[line "480"]
[id "932160"]
[rev ""]
[msg "Remote Command Execution: Unix Shell Code Found"]
[data "Matched Data: etc/passwd found within ARGS:id: /etc/passwd"]
[severity "2"]
[ver "OWASP_CRS/3.3.2"]
[maturity "0"]
[accuracy "0"]
[tag "application-multi"]
[tag "language-shell"]
[tag "platform-unix"]
[tag "attack-rce"]
[tag "paranoia-level/1"]
[tag "OWASP_CRS"]
[tag "capec/1000/152/248/88"]
[tag "PCI/6.5.2"]
[hostname "172.17.0.2"]
[uri "/"]
[unique_id "165097447014.179282"]
[ref "o1,10v9,11t:urlDecodeUni,t:cmdLine,t:normalizePath,t:lowercase"],
client: 172.17.0.1, server: localhost, request: "GET /?id=/etc/passwd HTTP/1.1", host:
"localhost"
2022/04/26 12:01:10 [error] 85#85: *11 [client 172.17.0.1] ModSecurity: Access denied with code
403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE'
(Value: `10' )
[file "/usr/share/bunkerweb/core/modsecurity/files/coreruleset/rules/REQUEST-949-BLOCKING-
234 / 263
BunkerWeb documentation v1.5.8
EVALUATION.conf"]
[line "80"]
[id "949110"]
[rev ""]
[msg "Inbound Anomaly Score Exceeded (Total Score: 10)"]
[data ""]
[severity "2"]
[ver "OWASP_CRS/3.3.2"]
[maturity "0"]
[accuracy "0"]
[tag "application-multi"]
[tag "language-multi"]
[tag "platform-multi"]
[tag "attack-generic"]
[hostname "172.17.0.2"]
[uri "/"]
[unique_id "165097447014.179282"]
[ref ""],
client: 172.17.0.1, server: localhost, request: "GET /?id=/etc/passwd HTTP/1.1", host:
"localhost"
One important thing to understand is that rule 949110 is not a "real" one : it's the one that will deny the request
because the anomaly threshold is reached (which is 10 in this example). You should never remove the 949110 rule !
If it's a false-positive, you should then focus on both 930120 and 932160 rules. ModSecurity and/or CRS tuning is
out of the scope of this documentation but don't forget that you can apply custom configurations before and after the
CRS is loaded (more info here).
9.6 IP unban
You can manually unban an IP which can be useful when doing some tests but it needs the setting USE_API set to
yes (which is not the default) so you can contact the internal API of BunkerWeb (replace 1.2.3.4 with the IP
address to unban) :
235 / 263
BunkerWeb documentation v1.5.8
Docker
You can use the docker exec command (replace mybunker with the name of your container) :
Here is the docker-compose equivalent (replace mybunker with the name of the services declared in the docker-
compose.yml file) :
Docker autoconf
You can use the docker exec command (replace myautoconf with the name of your container) :
Here is the docker-compose equivalent (replace myautoconf with the name of the services declared in the docker-
compose.yml file) :
Swarm
You can use the docker exec command (replace myautoconf with the name of your service) :
Kubernetes
You can use the kubectl exec command (replace myautoconf with the name of your pod) :
Linux
9.7 Whitelisting
236 / 263
BunkerWeb documentation v1.5.8
If you have bots that need to access your website, the recommended way to avoid any false positive is to whitelist
them using the whitelisting feature. We don't recommend using the WHITELIST_URI* or WHITELIST_USER_AGENT*
settings unless they are set to secret and unpredictable values. Common use cases are :
9.8 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 identifiers here.
9.9 Web UI
In case you lost your UI credentials or have 2FA issues, you can connect to the database to retrieve access.
Access database
237 / 263
BunkerWeb documentation v1.5.8
SQLite
Linux
Docker
Docker arguments
Install SQLite :
Database path
We assume that you are using the default database path. If you are using a custom path, you will need to adapt the
command.
sqlite3 /var/lib/bunkerweb/db.sqlite3
238 / 263
BunkerWeb documentation v1.5.8
MariaDB / MySQL
The following steps are only valid for MariaDB / MySQL databases. If you are using another database, please refer to
the documentation of your database.
You will need to use the same credentials and database named used in the DATABASE_URI setting.
Linux
Then enter your password of the database user and you should be able to access your database.
Docker
Docker arguments
Then enter your password of the database user and you should be able to access your database.
239 / 263
BunkerWeb documentation v1.5.8
Troubleshooting actions
Table schema
240 / 263
BunkerWeb documentation v1.5.8
Retrieve username
Execute the following command to extract data from the bw_ui_users table :
1|<username>|<password_hash>|1|<secret_totp_token>|(manual or ui)
Update password
You first need to hash the new password using the bcrypt algorithm.
1|<username>|<password_hash>|0||(manual or ui)
You should now be able to use the new credentials to log into the web UI.
241 / 263
BunkerWeb documentation v1.5.8
1|<username>|<password_hash>|0||(manual or ui)
You should now be able to log into the web UI only using your username and password.
Upload plugin
Missing package to manage compressed files on your integration, in which case you will need to add the
necessary packages
Safari browser : the 'safe mode' may prevent you from being able to add a plugin. You will need to make the
necessary changes on your machine
242 / 263
BunkerWeb documentation v1.5.8
10 Plugins
BunkerWeb comes with a plugin system making it possible to easily add new features. Once a plugin is installed,
you can manage it using additional settings defined by the plugin.
ClamAV 1.5 Automatically scans uploaded files with the ClamAV bunkerweb-
antivirus engine and denies the request when a file is plugins/clamav
detected as malicious.
Coraza 1.5 Inspect requests using a the Coraza WAF (alternative bunkerweb-
of ModSecurity). plugins/coraza
VirusTotal 1.5 Automatically scans uploaded files with the VirusTotal bunkerweb-
API and denies the request when a file is detected as plugins/virustotal
malicious.
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).
243 / 263
BunkerWeb documentation v1.5.8
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.5.zip
10.2.2 Manual
The first step is to install the plugin by putting the plugin files inside the corresponding plugins data folder, the
procedure depends on your integration :
244 / 263
BunkerWeb documentation v1.5.8
Docker
When using the Docker integration, plugins must be written to the volume mounted on /data/plugins into the
scheduler container.
mkdir -p ./bw-data/plugins
Then, you can drop the plugins of your choice into that folder :
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 :
If you are using Docker in rootless mode or podman, UIDs and GIDs in the container will be mapped to different ones in
the host. You will first need to check your initial subuid and subgid :
For example, if you have a value of 100000, the mapped UID/GID will be 100100 (100000 + 100) :
245 / 263
BunkerWeb documentation v1.5.8
Then you can mount the volume when starting your Docker stack :
version: '3.5'
services:
...
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
volumes:
- ./bw-data:/data
...
Docker autoconf
When using the Docker autoconf integration, plugins must be written to the volume mounted on /data/plugins into
the scheduler container.
mkdir -p ./bw-data/plugins
Then, you can drop the plugins of your choice into that folder :
Because the scheduler runs as an unprivileged user with UID and GID 101, you will need to edit the permissions :
Then you can mount the volume when starting your Docker stack :
version: '3.5'
services:
...
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
volumes:
- ./bw-data:/data
...
Swarm
When using the Swarm integration, plugins must be written to the volume mounted on /data/plugins into the
scheduler container.
246 / 263
BunkerWeb documentation v1.5.8
Swarm volume
Configuring a Swarm volume that will persist when the scheduler service is running on different nodes is not covered is
in this documentation. We will assume that you have a shared folder mounted on /shared across all nodes.
mkdir -p /shared/bw-plugins
Then, you can drop the plugins of your choice into that folder :
Because the scheduler runs as an unprivileged user with UID and GID 101, you will need to edit the permissions :
Then you can mount the volume when starting your Swarm stack :
version: '3.5'
services:
...
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.5.8
volumes:
- /shared/bw-plugins:/data/plugins
...
Kubernetes
When using the Kubernetes integration, plugins must be written to the volume mounted on /data/plugins into the
scheduler container.
The fist thing to do is to declare a PersistentVolumeClaim that will contain our plugins data :
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-bunkerweb-plugins
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
You can now add the volume mount and an init containers to automatically provision the volume :
247 / 263
BunkerWeb documentation v1.5.8
apiVersion: apps/v1
kind: Deployment
metadata:
name: bunkerweb-scheduler
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: bunkerweb-scheduler
template:
metadata:
labels:
app: bunkerweb-scheduler
spec:
serviceAccountName: sa-bunkerweb
containers:
- name: bunkerweb-scheduler
image: bunkerity/bunkerweb-scheduler:1.5.8
imagePullPolicy: Always
env:
- name: KUBERNETES_MODE
value: "yes"
- name: "DATABASE_URI"
value: "mariadb+pymysql://bunkerweb:changeme@svc-bunkerweb-db:3306/db"
volumeMounts:
- mountPath: "/data/plugins"
name: vol-plugins
initContainers:
- name: bunkerweb-scheduler-init
image: alpine/git
command: ["/bin/sh", "-c"]
args: ["git clone https://github.com/bunkerity/bunkerweb-plugins /data/plugins && chown
-R 101:101 /data/plugins"]
volumeMounts:
- mountPath: "/data/plugins"
name: vol-plugins
volumes:
- name: vol-plugins
persistentVolumeClaim:
claimName: pvc-bunkerweb-plugins
Linux
When using the Linux integration, plugins must be written to the /etc/bunkerweb/plugins folder :
248 / 263
BunkerWeb documentation v1.5.8
10.3.1 Structure
Existing plugins
If the documentation is not enough, you can have a look at the existing source code of official plugins and the core
plugins (already included in BunkerWeb but they are plugins, technically speaking).
plugin /
confs / conf_type / conf_name.conf
ui / actions.py
template.html
jobs / my-job.py
plugin.lua
plugin.json
actions.py : script to execute on flask server, this script is running on flask context, you have access to lib and
utils like jinja2 , requests , etc...
The first step is to create a folder that will contain the plugin :
10.3.3 Metadata
A file named plugin.json and written at the root of the plugin folder must contain metadata about the plugin. Here is
an example :
249 / 263
BunkerWeb documentation v1.5.8
{
"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"
}
]
}
id yes string Internal ID for the plugin : must be unique among other plugins
(including "core" ones) and contain only lowercase chars.
Each setting has the following fields (the key is the ID of the settings used in a configuration) :
250 / 263
BunkerWeb documentation v1.5.8
help yes string Help text about the plugin (shown in web UI).
regex yes string The regex used to validate the value provided by the user.
type yes string The type of the field : text , check , select or password .
file yes string Name of the file inside the jobs folder.
every yes string Job scheduling frequency : minute , hour , day , week or once
(no frequency, only once before (re)generating the
configuration).
10.3.4 Configurations
You can add custom NGINX configurations by adding a folder named confs with content similar to the custom
configurations. Each subfolder inside the confs will contain jinja2 templates that will be generated and loaded at the
corresponding context ( http , server-http , default-server-http , stream , server-stream , modsec and
modsec-crs ).
Here is an example for a configuration template file inside the confs/server-http folder named example.conf :
251 / 263
BunkerWeb documentation v1.5.8
location /setting {
default_type 'text/plain';
content_by_lua_block {
ngx.say('{{ DUMMY_SETTING }}')
}
}
{{ DUMMY_SETTING }} will be replaced by the value of the DUMMY_SETTING chosen by the user of the plugin.
10.3.5 LUA
Under the hood, BunkerWeb is using the NGINX LUA module to execute code within NGINX. Plugins that need to
execute code must provide a lua file at the root directory of the plugin folder using the id value of plugin.json as its
name. Here is an example named myplugin.lua :
252 / 263
BunkerWeb documentation v1.5.8
function myplugin:initialize(ctx)
plugin.initialize(self, "myplugin", ctx)
self.dummy = "dummy"
end
function myplugin:init()
self.logger:log(ngx.NOTICE, "init called")
return self:ret(true, "success")
end
function myplugin:set()
self.logger:log(ngx.NOTICE, "set called")
return self:ret(true, "success")
end
function myplugin:access()
self.logger:log(ngx.NOTICE, "access called")
return self:ret(true, "success")
end
function myplugin:log()
self.logger:log(ngx.NOTICE, "log called")
return self:ret(true, "success")
end
function myplugin:log_default()
self.logger:log(ngx.NOTICE, "log_default called")
return self:ret(true, "success")
end
function myplugin:preread()
self.logger:log(ngx.NOTICE, "preread called")
return self:ret(true, "success")
end
function myplugin:log_stream()
self.logger:log(ngx.NOTICE, "log_stream called")
return self:ret(true, "success")
end
return myplugin
The declared functions are automatically called during specific contexts. Here are the details of each function :
init init_by_lua Called when NGINX just started or received a ret , msg
reload order. the typical use case is to
253 / 263
BunkerWeb documentation v1.5.8
prepare any data that will be used by your ret (boolean) : true if
plugin. no error or else false
set set_by_lua Called before each request received by the ret , msg
server.The typical use case is for computing
ret (boolean) : true if
before access phase.
no error or else false
status (number) :
interrupt current
process and return
HTTP status
log log_by_lua Called when a request has finished (and ret , msg
before it gets logged to the access logs). The
ret (boolean) : true if
typical use case is to make stats or compute
no error or else false
counters for example.
msg (string) : success
or error message
log_defaul log_by_lua Same as log but only called on the default ret , msg
t server.
ret (boolean) : true if
no error or else false
254 / 263
BunkerWeb documentation v1.5.8
preread preread_by_lua Similar to the access function but for stream ret , msg , status
mode.
ret (boolean) : true if
no error or else false
status (number) :
interrupt current
process and return
status
log_strea log_by_lua Similar to the log function but for stream ret , msg
m mode.
ret (boolean) : true if
no error or else false
10.3.5.2 Libraries
All directives from NGINX LUA module and are available and NGINX stream LUA module. On top of that, you can
use the LUA libraries included within BunkerWeb : see this script for the complete list.
If you need additional libraries, you can put them in the root folder of the plugin and access them by prefixing them
with your plugin ID. Here is an example file named mylibrary.lua :
local _M = {}
_M.dummy = function ()
return "dummy"
end
return _M
And here is how you can use it from the myplugin.lua file :
...
mylibrary.dummy()
...
10.3.5.3 Helpers
255 / 263
BunkerWeb documentation v1.5.8
bunkerweb.datastore : access the global shared data on one instance (key/value store)
bunkerweb.clusterstore : access a Redis data store shared between BunkerWeb instances (key/value store)
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 of the
repository.
256 / 263
BunkerWeb documentation v1.5.8
10.3.6 Jobs
BunkerWeb uses an internal job scheduler for periodic tasks like renewing certificates with certbot, downloading
blacklists, downloading MMDB files, ... You can add tasks of your choice by putting them inside a subfolder named
jobs and listing them in the plugin.json metadata file. Don't forget to add the execution permissions for everyone to
avoid any problems when a user is cloning and installing your plugin.
Everything related to the web UI is located inside the subfolder ui as we seen in the previous structure section..
10.3.7.1 Prerequisites
When you want to create a plugin page, you need two files :
actions.py where you can add some scripting and logic with a POST /plugins/<plugin_id>. Notice that this file
need a function with the same name as the plugin to work. This file is needed even if the function is empty.
Jinja 2 template
The template.html file is a Jinja2 template, please refer to the Jinja2 documentation if needed.
We can put aside the actions.py file and start only using the template on a GET situation. The template can
access app context and libs, so you can use Jinja, request or flask utils.
For example, you can get the request arguments in your template like this :
10.3.7.3 Actions.py
CSRF Token
Please note that every form submission is protected via a CSRF token, you will need to include the following snippet
into your forms :
You can power-up your plugin page with additional scripting with the actions.py file when sending a POST
/plugins/<plugin_id>.
257 / 263
BunkerWeb documentation v1.5.8
pre_render function
This allows you to retrieve data when you GET the template, and to use the data with the pre_render variable
available in Jinja to display content more dynamically.
def pre_render(**kwargs)
return <pre_render_data>
<plugin_id> function
This allows you to retrieve data when you make a POST from the template endpoint, which must be used in AJAX.
def myplugin(**kwargs)
return <plugin_id_data>
Here are the arguments that are passed and access on action.py functions:
Python libraries
In addition, you can use Python libraries that are already available like : Flask , Flask-Login , Flask-WTF ,
beautifulsoup4 , docker , Jinja2 , python-magic and requests . To see the full list, you can have a look at the Web
UI requirements.txt. If you need external libraries, you can install them inside the ui folder of your plugin and then use
the classical import directive.
Some examples
def myplugin(**kwargs) :
my_form_value = request.form["my_form_input"]
return my_form_value
258 / 263
BunkerWeb documentation v1.5.8
action.py
def pre_render(**kwargs) :
config = kwargs['app'].config["CONFIG"].get_config(methods=False)
return config
template
259 / 263
BunkerWeb documentation v1.5.8
11 Professional services
You can also upgrade BunkerWeb to the PRO version at any time. By doing so, you will get an enhanced experience
to assist you in the security of your web services. Our goal is to help you focus on your business needs. The PRO
version is updated regularly and we try our best to gather feedbacks from enterprises to include the needed features.
But dedicating time to a specific technology may not be easy depending on your business priorities. Not mentioning
that cybersecurity is complex domain where being both judge and jury is not recommended.
Getting professional services in addition to the open-source or PRO version is the ideal solution to cover your
business needs. You can focus on your top priorities and rely on a trusted partner when it comes to web security.
Please note that professional services are directly offered by Bunkerity, the company maintaining the BunkerWeb
project, through our BunkerWeb Panel online platform.
According to your needs you have the choice between "one time" and subscriptions offers.
One important thing to note is that the support service is based on "credit" system where you pay for a number of
support hours dedicated for you. Time passed on your requests will be deducted to your credit. In other words, you
only pay for real time dedicated to your needs.
In addition to the support service, we also offer custom services around the BunkerWeb solution to meet your
specific needs :
Don't hesitate to contact us if you have any question, we will be more than happy to respond to your needs.
260 / 263
BunkerWeb documentation v1.5.8
12 About
You can go the BunkerWeb panel to get more information and claim your free trial.
Consulting
Support
Custom development
Partnership
261 / 263
BunkerWeb documentation v1.5.8
Please don't use GitHub issues to ask for help, use it only for bug reports and feature requests.
Join the Discord server, /r/BunkerWeb subreddit and GitHub discussions to talk about the project and help others
Talk about BunkerWeb to your friends/colleagues, on social media, on your blog, ...
262 / 263
BunkerWeb documentation v1.5.8
mQINBGCEMiMBEACtXJBDbF86qjC/Q1cfmJfYcYrbk6eE5czknG294XObC97wAgDf
/MbX6bnti4kDRpflGDqQtwOXudcEzledTD4bdDUKvZwqPoYQGa24uCuUxSINTLXr
RuoMaKfpvs7trsFXp5iYUqf4Org2aaJE7Tk/9sOvxgdqsT22jEgCZXTRU1qG494U
u6XRQN8hKlw6aa6njjX9vUk6Jpl46/kwwO9mpXBZX6iFKYnBlUWs2k8d6D6cO5aZ
KLoYyz5v3Gw2hHSqj4qbVQPTIT7qrrcfd8nblYK7Dh3IM+vQq7a7lB0AudIyBNPd
rsypi9ZYgwI3lv/rmQnDc32Ua5cLvTvgg/XoaNK9ogc3kei1+hXODEgRA/zvSKqq
20i/1Y0OnIGv89LOI6urWpOgDAhQUV5xvANll2lm3Bkmy29UOzNadUc/yImxrM06
HwX82ju6PFAqOaxMW6SEE71ylGOSlikAGNcmmc5Ihd1J/VRZA4PBiQ31gQxFRpUC
3NTw2QNAD1kjni5PuQD10Q1Ognvb6uJh/MtqsoX6r1t+Oly9MblFSuyqFkqNO3F0
QAJqprhJlQ3YOcJdJ1EZR7qs0xJm5h+lw0Z/UINqkwiZUW3PCO8BKxfq6sfdwM8L
5hPhyUzy2gIJ0J/4NGYEBH1ojoYODGU8OCSmyjSTY9SoVMeWDfqYP4ZTvQARAQAB
tCVidW5rZXJpdHktcGdwIDxjb250YWN0QGJ1bmtlcml0eS5jb20+iQJUBBMBCAA+
FiEEw78SjkcVxXCq7hStPYCAbxJgKnwFAmCEMiMCGwMFCQPCIP0FCwkIBwIGFQoJ
CAsCBBYCAwECHgECF4AACgkQPYCAbxJgKnzvYhAAnNqGB6ce2eZzwk1EiNlNaXaA
hFWLq/s/J1IOAP+0V5jKJxA6zTX01HyIfIIHQy6nrxxEXzYsIUHdJ+HBPCNswCqn
2d/aDkkfoEUc1bUD0c2bXfoSCsAeIoK+eOf6iSr4IENVoIUYFQTUKFNu+Y7eDL0I
J8Xadg53G+fkK9LE6TeYpBs3hDT4w7vlDfIwWa1NC9HoLzSmZ2fqZ7SnihLGsLmp
98VqDrDjhRPzrz5/tVYgvPCQQU5ED/TayCCYvrGpw9gP8qmEOabIUz0ppGwEfQVs
Wycilm1/Js/qjdbxUFMipBIzDu7bI3kMLmENhI+16Xtub9dUrvkW2SdDngYhtWj8
IzVOe6N/XDuiRGpaYFpEuXbrnDFexe1ygZwnVHt3fukPfa7W8mhMs2kY1ishIA0O
WElKO1Q6N0ZWEad0PwM8NCDjaDUNWQC36ZF/MS+ipHWx9joPUjImY2AXDjN+L+Si
ABQIe4Fo6Jx6S6Bi8YvPq8idYZvaWFJjBvmaPjxdUMPbIsMRiEjvlrhvqhLuVBpE
lGA+M4UJGw5yBl+yiiLDuws/Fppv9HwNqw6Uq1m1XaW859Om1GGBKYfphyn+fHjR
7ftOuT7Ss4zioXT4mscOZgkfzDAqgpZiHjYhe7tLUu7iD6UEsZmey/gRV0hCxng3
N7yaRrBu0+3sIQV4jYC5Ag0EYIQyIwEQALSurJGOx7At5mRFjvhXd4/JHuBZZOSI
M45LSJ+mKYnAGmwsL0AneZMIf6Yc0Vcn32oqlIXN5aB8jIt91pChLre8tl/lFZZP
xY3WIEBJhZF0FIUqSQLjg4HD0S70REii7Om1kgtZueid8V6T5F1JDcO2mDoh8oc9
h9nRQ1Ld6dblEuwBzbFkI1K6OUk1+ec7+mQc7orHdBVgelmqwG7fGZnPiN3XfklF
dnwSkFIX/qkAsKQmmx1VSzaGFoPLajf4wrkzZdA3iEafsHyvdEFlezZCZ7TsoHBh
tNg1Psg6MbBVgiMfHyRHSEBJZ7r5Awj2MpFUFMOd1IPcor1I254mx0VYfCvof4Km
Ri1F/86kHc23A77pd4HFYZWiZjaWhh12L+wz5fDL5/sSFXVGSCtSWIKx6FjysZ+v
szk3lItHoomZhA7M+FjU/cOjq9hae9uwZeU39DQk0/npln2RcHitoqgUIzII5woO
S3SlMSc910tHf40D2cBr1iFKC0jQICjkDexB9CtNx/N25SJmLfiimYtk6/NHlPq4
HXdq6ZfLZ7xQmuGcyWv4f0pwA2CK3twISpsIxIKe456WYTDtQu9d1s987dvmw6F/
qURC6m2WPGroHb8COQTKzbshjpGUmLpyR3FXki4wNXeI1KaQLL7NpZmK6yJlWviO
1sCjh4m7VS+zABEBAAGJAjwEGAEIACYWIQTDvxKORxXFcKruFK09gIBvEmAqfAUC
YIQyIwIbDAUJA8Ig/QAKCRA9gIBvEmAqfP2WEACqmXEhu4ARl2yT9bay0+W3F1q1
MrLQkcVOau2ihXx3PhYsXRUoEFj72VDAar41WIlHsPJfB14WtSlYcX2XdjHLHMpC
dL2eGhqIcHzFChR0vGjtvm2wae/rJTChWf8WXiHrRnRcfFFfhpCvkNi43fQeH4yp
cel2a35WV+IRbnkCkaly2NG3XO0t83Siok8Ku+OJGPatUMxJmaEVQeeXVPDzVRva
rtvyd9Sclkd9QDPBLZyWHC1vsPKGRJpi5uDZjGxhaFRkimw/SYtFHj7AUrMKAIHB
GfEcwC3Eq4rF0FeCOPfBd2vwGGrRflx76jK9rj288ta9Oq6u6ev8PCVzt0E7jrSf
AX88vfVRcxihNfj/9i5xmY596jpgbvNA2aJX2hAO3Q8pD6AunVXPUyc3RlFHt7jC
tL+9Xv7Qwjz7OToWqj+9cM6T+6oZLxYNVPT72Z/KOFW+mzGb87qjcsDMb/hu2fNq
tSWyZk2AAgHQyG1y8vCQQzsDnUDM6NIPwYG5XMP+11WAsPk5fP1ksixpUqIWgjhY
M22YUsjLeaRtgSmhAGIkbBgecs1EHSZZ6sf2lB8gSom1wW0UCBPSifP0DwYFizS5
SOk62kZ0lqEctwgKDe3MNQnPxt9+tU9L1pIkyXgXihcOLiCMl434K0djJXxIbiX0
JvbFAfI3qteepvnjBQ==
=g1tf
-----END PGP PUBLIC KEY BLOCK-----
263 / 263