0% found this document useful (0 votes)
1K views263 pages

BunkerWeb Documentation v1.5.8

Uploaded by

Edmar Samortin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1K views263 pages

BunkerWeb Documentation v1.5.8

Uploaded by

Edmar Samortin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 263

BunkerWeb documentation v1.5.

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

4.2.1 HTTP header


4.2.2 Proxy protocol
4.3 Protect UDP/TCP applications
4.4 Custom configurations
4.5 PHP
4.6 IPv6

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

Figure 1: Make your web services secure by default !

BunkerWeb is a next-generation and open-source Web Application Firewall (WAF).

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.

1.2 Why BunkerWeb ?

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.

1.3 Security features


Explore the impressive array of security features offered by BunkerWeb. While not exhaustive, here are some
notable highlights:

HTTPS support with transparent Let's Encrypt automation : 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

BunkerWeb - fooling automated scanners/tools

A demo website protected with BunkerWeb is available at demo.bunkerweb.io. Feel free to visit it and perform some
security tests.

1.5 BunkerWeb Cloud


Don't want to self-host and manage your own BunkerWeb instance(s) ? You might be interested into BunkerWeb
Cloud, our fully managed SaaS offer for BunkerWeb.

Try our BunkerWeb Cloud beta offer for free and get access to :

Fully managed BunkerWeb instance hosted in our cloud

All BunkerWeb features including PRO ones

Monitoring platform including dashboards and alerts

Technical support to assist you in the configuration

You will find more information about BunkerWeb Cloud in the FAQ page of the BunkerWeb panel.

1.6 PRO version


When using BunkerWeb you have the choice of the version you want to use : open-source or PRO.

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 :

Claim your free trial on the BunkerWeb panel

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.

1.7 Professional services


Get the most of BunkerWeb by getting professional services directly from the maintainers of the project. From
technical support to tailored consulting and development, we are here to assist you in the security of your web
services.

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.

1.8 Ecosystem, community and resources


Official websites, tools and resources about BunkerWeb :

Website : get more information, news and articles about BunkerWeb

Panel : dedicated platform to order and manage professional services (e.g. technical support) around BunkerWeb

Documentation : technical documentation of the BunkerWeb solution

Demo : demonstration website of BunkerWeb, don't hesitate to attempt attacks to test the robustness of the
solution

Configurator : user-friendly tool to help you configure BunkerWeb

Threatmap : live cyber attack blocked by BunkerWeb instances all around the world

Community and social networks :

Discord

LinkedIn

Twitter

9 / 263
BunkerWeb documentation v1.5.8

Reddit

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.

The following integrations are officially supported :

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.

Here is a dummy example of a BunkerWeb configuration :

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.

Settings generator tool

To help you tune BunkerWeb, we offer an easy-to-use settings generator tool available at config.bunkerweb.io.

2.3 Multisite mode

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.

Here's a dummy example of a multisite BunkerWeb configuration :

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

2.4 Custom configurations


To address unique challenges and cater to specific use cases, BunkerWeb offers the flexibility of custom
configurations. While the provided settings and external plugins cover a wide range of scenarios, there may be
situations that require additional customization.

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

bw_instances bw_services bw_global_values bw_plugin_pages

hostname varchar[256] id varchar[64] setting_id varchar[256] id int

port int method methods value varchar[8192] plugin_id varchar[64]

server_name varchar[256] is_draft boolean suffix int template_file longblob

method methods template_checksum varchar[128]

actions_file longblob
bw_custom_configs bw_services_settings
actions_checksum varchar[128]
id int service_id varchar[64] bw_settings

service_id varchar[64] setting_id varchar[256] id varchar[256]

type custom_config_types value varchar[8192] name varchar[256] bw_cli_commands

name varchar[256] suffix int plugin_id varchar[64] id int

data longblob method methods context contexes name varchar[64]

checksum varchar[128] default varchar[4096] plugin_id varchar[64]

method methods help varchar[512] file_name varchar[256]


bw_jobs_cache
label varchar[256]
id int
regex varchar[1024]
bw_ui_users job_name varchar[128] bw_plugins
type settings_types
id int service_id varchar[64] id varchar[64]
multiple varchar[128]
username varchar[256] file_name varchar[256] name varchar[128]
order int
password varchar[60] data longblob description varchar[256]

is_two_factor_enabled boolean last_update datetime version varchar[32]

secret_token varchar[32] checksum varchar[128] bw_jobs stream stream_types

method methods name varchar[128] type plugin_types

plugin_id varchar[64] method methods


bw_selects
file_name varchar[256] data longblob
bw_metadata setting_id varchar[256]
every schedules checksum varchar[128]
id int value varchar[256]
reload boolean
is_initialized boolean
success boolean
is_pro boolean
last_run datetime
pro_expire datetime

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

Figure 2: Database Schema

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

3.1 BunkerWeb Cloud

Figure 3: BunkerWeb Cloud

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

Figure 4: Docker integration

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

armv8 (ARM 64-bit)

armv7 (ARM 32-bit)

By accessing these prebuilt images from Docker Hub, you can quickly pull and run BunkerWeb within your Docker
environment, eliminating the need for extensive configuration or setup processes. This streamlined approach allows
you to focus on leveraging the capabilities of BunkerWeb without unnecessary complexities.

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 pull bunkerity/bunkerweb:1.5.8

Docker images are also available on GitHub packages and can be downloaded using the ghcr.io repository
address :

docker pull ghcr.io/bunkerity/bunkerweb:1.5.8

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.

git clone https://github.com/bunkerity/bunkerweb.git && \


cd bunkerweb && \
docker build -t my-bunkerweb -f src/bunkerweb/Dockerfile .

Docker integration key concepts are :

Environment variables to configure BunkerWeb

Scheduler container to store configuration and execute jobs

Networks to expose ports for clients and connect to upstream web services

When integrating BunkerWeb with Docker, there are key concepts to keep in mind, ensuring a smooth and efficient
deployment:

Environment variables: BunkerWeb can be easily configured using environment variables. These variables
allow you to customize various aspects of BunkerWeb's behavior, such as network settings, security options, and
other parameters.

Scheduler container: To effectively manage the configuration and execution of jobs, BunkerWeb utilizes a
dedicated container called the scheduler.

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.

3.2.1 Environment variables

Settings are passed to BunkerWeb using Docker environment variables :

...
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 :

docker pull bunkerity/bunkerweb-scheduler:1.5.8

Alternatively, you can build the Docker image directly from the source (less coffee ☕ needed than BunkerWeb
image) :

21 / 263
BunkerWeb documentation v1.5.8

git clone https://github.com/bunkerity/bunkerweb.git && \


cd bunkerweb && \
docker build -t my-scheduler -f src/scheduler/Dockerfile .

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:

Using local folder for persistent data

The scheduler runs as an unprivileged user with UID 101 and GID 101 inside the container. The reason behind this is
security : in case a vulnerability is exploited, the attacker won't have full root (UID/GID 0) privileges. But there is a
downside : if you use a local folder for the persistent data, you will need to set the correct permissions so the
unprivileged user can write data to it. Something like that should do the trick :

mkdir bw-data && \


chown root:101 bw-data && \
chmod 770 bw-data

Alternatively, if the folder already exists :

chown -R root:101 bw-data && \


chmod -R 770 bw-data

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 :

grep ^$(whoami): /etc/subuid && \


grep ^$(whoami): /etc/subgid

For example, if you have a value of 100000, the mapped UID/GID will be 100100 (100000 + 100) :

mkdir bw-data && \


sudo chgrp 100100 bw-data && \
chmod 770 bw-data

Or if the folder already exists :

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.

Docker API access and security

Due to Docker's limitations in supporting fine-grained authorizations, it's important to be aware of the potential security
risks associated with accessing the API directly. Accessing the Docker API can pose a threat, as an attacker with API
access can potentially obtain root privileges on the host machine. For more detailed information on this topic, we
encourage you to refer to the provided link (here).

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

Docker socket in rootless mode

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

Privileged ports in rootless mode or when using podman

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 :

sudo sysctl net.ipv4.ip_unprivileged_port_start=1

The typical BunkerWeb stack when using the Docker integration contains the following containers :

BunkerWeb

Scheduler

Docker socket proxy

Your services

For defense in depth purposes, we strongly recommend to create at least three different Docker networks :

bw-services : for BunkerWeb and your web services

bw-universe : for BunkerWeb and scheduler

bw-docker : for scheduler and the Docker API proxy

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

3.2.4 Full compose file

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

Figure 5: Linux integration

Supported Linux distributions for BunkerWeb (amd64/x86_64 and arm64/aarch64 architectures) include:

Debian 12 "Bookworm"

Ubuntu 22.04 "Jammy"

Ubuntu 24.04 "Noble"

Fedora 40

Red Hat Enterprise Linux (RHEL) 8.9

Red Hat Enterprise Linux (RHEL) 9.4

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

The first step is to add NGINX official repository :

sudo apt install -y curl gnupg2 ca-certificates lsb-release debian-archive-keyring && \


curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null && \
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/debian `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list

You should now be able to install NGINX 1.26.1 :

sudo apt update && \


sudo apt install -y nginx=1.26.1-2~$(lsb_release -cs)

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.

echo "force-bad-version" | sudo tee -a /etc/dpkg/dpkg.cfg

Optional step : if you want to automatically enable the setup wizard when BunkerWeb is installed, export the
following variable :

export UI_WIZARD=1

And finally install BunkerWeb 1.5.8 :

curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.deb.sh | sudo


bash && \
sudo apt update && \
sudo -E apt install -y bunkerweb=1.5.8

To prevent upgrading NGINX and/or BunkerWeb packages when executing apt upgrade , you can use the following
command :

sudo apt-mark hold nginx bunkerweb

Ubuntu

The first step is to add NGINX official repository :

29 / 263
BunkerWeb documentation v1.5.8

sudo apt install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring && \


curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null && \
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list

You should now be able to install NGINX 1.26.1 :

sudo apt update && \


sudo apt install -y nginx=1.26.1-2~$(lsb_release -cs)

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.

echo "force-bad-version" | sudo tee -a /etc/dpkg/dpkg.cfg

Optional step : if you want to automatically enable the setup wizard when BunkerWeb is installed, export the
following variable :

export UI_WIZARD=1

And finally install BunkerWeb 1.5.8 :

curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.deb.sh | sudo


bash && \
sudo apt update && \
sudo -E apt install -y bunkerweb=1.5.8

To prevent upgrading NGINX and/or BunkerWeb packages when executing apt upgrade , you can use the following
command :

sudo apt-mark hold nginx bunkerweb

Fedora

Fedora Update Testing

If you can't find the NGINX version listed in the stable repository, you can enable the updates-testing repository :

sudo dnf config-manager --set-enabled updates-testing

30 / 263
BunkerWeb documentation v1.5.8

Fedora already provides NGINX 1.26.1 that we support :

sudo dnf install -y nginx-1.26.1

Optional step : if you want to automatically enable the setup wizard when BunkerWeb is installed, export the
following variable :

export UI_WIZARD=1

And finally install BunkerWeb 1.5.8 :

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 :

sudo dnf versionlock add nginx && \


sudo dnf versionlock add bunkerweb

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

You should now be able to install NGINX 1.26.1 :

sudo dnf install nginx-1.26.1

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

And finally install BunkerWeb 1.5.8 :

sudo dnf install -y epel-release && \


curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.rpm.sh | sudo
bash && \
sudo dnf check-update && \
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 :

sudo dnf versionlock add nginx && \


sudo dnf versionlock add bunkerweb

The configuration of BunkerWeb is done by editing the /etc/bunkerweb/variables.env file :

MY_SETTING_1=value1
MY_SETTING_2=value2
...

BunkerWeb is managed using systemctl :

Check BunkerWeb status : systemctl status bunkerweb

Start it if it's stopped : systemctl start bunkerweb

Stop it if it's started : systemctl stop bunkerweb

Reload it to apply new configuration : systemctl reload bunkerweb

And restart it : systemctl restart bunkerweb

3.4 Docker autoconf

32 / 263
BunkerWeb documentation v1.5.8

Figure 6: Docker autoconf integration

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

Database in the bw-docker network

The database container is intentionally not included in the bw-universe network. It is used by the bw-autoconf and
bw-scheduler containers rather than directly by BunkerWeb. Therefore, the database container is part of the bw-
docker network, which enhances security by making external access to the database more challenging. This
deliberate design choice helps safeguard the database and strengthens the overall security perspective of the system.

Using Docker in rootless mode

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

Figure 7: Kubernetes integration

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.

Clustered database backends setup are out-of-the-scope of this documentation.

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

Figure 8: Docker Swarm integration

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.

Clustered database backends setup are out-of-the-scope of this documentation.

Here is the stack boilerplate that you can deploy using docker stack deploy :

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

Swarm mandatory setting

Please note that the SWARM_MODE=yes environment variable is mandatory when using the Swarm integration.

Once the BunkerWeb Swarm stack is set up and running (see autoconf and scheduler logs for more information),
you will be able to deploy web applications in the cluster and use labels to dynamically configure BunkerWeb :

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

3.7 Microsoft Azure

48 / 263
BunkerWeb documentation v1.5.8

Figure 9: Azure integration

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:

Azure CLI in Cloud Shell

Azure ARM Template

Azure portal via the Marketplace

49 / 263
BunkerWeb documentation v1.5.8

Cloud Shell

Create a resource group. Replace value RG_NAME

az group create --name "RG_NAME" --location "LOCATION"

Create a VM with Standard_B2s SKU in the location of the resource group. Replace values RG_NAME , VM_NAME ,
VNET_NAME , SUBNET_NAME

az vm create --resource-group "RG_NAME" --name "VM_NAME" --image


bunkerity:bunkerweb:bunkerweb:latest --accept-term --generate-ssh-keys --vnet-name "VNET_NAME" --
size Standard_B2s --subnet "SUBNET_NAME"

Full command. Replace values RG_NAME , VM_NAME , LOCATION , HOSTNAME , USERNAME , PUBLIC_IP , VNET_NAME ,
SUBNET_NAME , NSG_NAME

az vm create --resource-group "RG_NAME" --name "VM_NAME" --location "LOCATION" --image


bunkerity:bunkerweb:bunkerweb:latest --accept-term --generate-ssh-keys --computer-name "HOSTNAME"
--admin-username "USERNAME" --public-ip-address "PUBLIC_IP" --public-ip-address-allocation Static
--size Standard_B2s --public-ip-sku Standard --os-disk-delete-option Delete --nic-delete-option
Delete --vnet-name "VNET_NAME" --subnet "SUBNET_NAME" --nsg "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.

Deploy the ARM Template:

Marketplace

Login in Azure portal.

Get BunkerWeb from the Create resource menu.

You can also go through the 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.

4.1 Protect HTTP applications


Protecting existing web applications already accessible with the HTTP(S) protocol is the main goal of BunkerWeb : it
will act as a classical reverse proxy with extra security features.

The following settings can be used :

USE_REVERSE_PROXY : enable/disable reverse proxy mode

REVERSE_PROXY_URL : the public path prefix

REVERSE_PROXY_HOST : (internal) address of the proxied web application

You will find more settings about reverse proxy in the settings section of the documentation.

4.1.1 Single application

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 :

python3 -m http.server -b 127.0.0.1

Configuration of BunkerWeb is done by editing the /etc/bunkerweb/variables.env file :

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

Let's check the status of BunkerWeb :

systemctl status bunkerweb

If it's already running, we can reload it :

systemctl reload bunkerweb

Otherwise, we will need to start it :

systemctl start bunkerweb

4.1.2 Multiple applications

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 :

curl -H "Host: app1.example.com" http://ip-or-fqdn-of-server

If you are using HTTPS, you will need to play with SNI :

curl -H "Host: app1.example.com" --resolve example.com:443:ip-of-server https://example.com

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

python3 -m http.server -b 127.0.0.1 8001

Configuration of BunkerWeb is done by editing the /etc/bunkerweb/variables.env file :

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

Let's check the status of BunkerWeb :

systemctl status bunkerweb

If it's already running, we can reload it :

systemctl reload bunkerweb

Otherwise, we will need to start it :

systemctl start bunkerweb

4.2 Behind load balancer or reverse proxy


When BunkerWeb is itself behind a load balancer or a reverse proxy, you need to configure it so it can get the real IP
address of the clients. If you don't, the security features will block the IP address of the load balancer or reverse
proxy instead of the client's one.

BunkerWeb actually supports two methods to retrieve the real IP address of the client :

Using the PROXY protocol

Using a HTTP header like X-Forwarded-For

The following settings can be used :

USE_REAL_IP : enable/disable real IP retrieval

USE_PROXY_PROTOCOL : enable/disable PROXY protocol support

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

4.2.1 HTTP header

We will assume the following regarding the load balancers or reverse proxies (you will need to update the settings
depending on your configuration) :

They use the X-Forwarded-For header to set the real IP

They have IPs in the 1.2.3.0/24 and 100.64.0.0/10 networks

The following settings need to be set :

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

You will need to add the settings to the /etc/bunkerweb/variables.env file :

...
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 :

systemctl restart bunkerweb

4.2.2 Proxy protocol

We will assume the following regarding the load balancers or reverse proxies (you will need to update the settings
depending on your configuration) :

They use the PROXY protocol v1 or v2 to set the real IP

They have IPs in the 1.2.3.0/24 and 100.64.0.0/10 networks

The following settings need to be set :

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

You will need to add the settings to the /etc/bunkerweb/variables.env file :

...
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 :

systemctl restart bunkerweb

4.3 Protect UDP/TCP applications

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

On top of that, the following specific settings are used :

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

LISTEN_STREAM_PORT_SSL=4343 : the listening "ssl/tls" port that BunkerWeb will listen on

USE_UDP=no : listen for and forward UDP packets instead of TCP

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

You will need to add the settings to the /etc/bunkerweb/variables.env file :

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

Let's check the status of BunkerWeb :

systemctl status bunkerweb

If it's already running, we can reload it :

systemctl reload bunkerweb

Otherwise, we will need to start it :

systemctl start bunkerweb

4.4 Custom configurations


To customize and add custom configurations to BunkerWeb, you can take advantage of its NGINX foundation.
Custom NGINX configurations can be added in different NGINX contexts, including configurations for the
ModSecurity Web Application Firewall (WAF), which is a core component of BunkerWeb. More details about
ModSecurity configurations can be found here.

Here are the available types of custom configurations:

http: Configurations at the HTTP level of NGINX.

server-http: Configurations at the HTTP/Server level of NGINX.

default-server-http: Configurations at the Server level of NGINX, specifically for the "default server" when the
supplied client name doesn't match any server name in SERVER_NAME .

modsec-crs: Configurations applied before the OWASP Core Rule Set is loaded.

modsec: Configurations applied after the OWASP Core Rule Set is loaded, or used when the Core Rule Set is
not loaded.

stream: Configurations at the Stream level of NGINX.

server-stream: Configurations at the Stream/Server level of NGINX.

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 specific settings *_CUSTOM_CONF_* as environment variables (recommended)

Writing .conf files to the volume mounted on /data of the scheduler

Using settings

The settings to use must follow the pattern <SITE>_CUSTOM_CONF_<TYPE>_<NAME> :

<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

<NAME> : the name of config without the .conf suffix

Here is a dummy example using a docker-compose file :

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

The first thing to do is to create the folders :

mkdir -p ./bw-data/configs/server-http

You can now write your configurations :

echo "location /hello {


default_type 'text/plain';
content_by_lua_block {
ngx.say('world')
}
}" > ./bw-data/configs/server-http/hello-world.conf

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

chown -R root:101 bw-data && \


chmod -R 770 bw-data

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 specific settings *_CUSTOM_CONF_* as labels (easiest)

Writing .conf files to the volume mounted on /data of the scheduler

Using labels

Limitations 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.

The labels to use must follow the pattern bunkerweb.CUSTOM_CONF_<TYPE>_<NAME> :

<TYPE> : the type of config, accepted values are SERVER_HTTP , MODSEC , MODSEC_CRS and SERVER_STREAM

<NAME> : the name of config without the .conf suffix

Here is a dummy example using a docker-compose file :

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

The first thing to do is to create the folders :

mkdir -p ./bw-data/configs/server-http

You can now write your configurations :

echo "location /hello {


default_type 'text/plain';
content_by_lua_block {
ngx.say('world')
}
}" > ./bw-data/configs/server-http/hello-world.conf

Because the scheduler runs as an unprivileged user with UID and GID 101, you will need to edit the permissions :

chown -R root:101 bw-data && \


chmod -R 770 bw-data

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.

When creating a Config, you will need to add special labels :

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)

Here is the example :

echo "location /hello {


default_type 'text/plain';
content_by_lua_block {
ngx.say('world')
}
}" | docker config create -l bunkerweb.CONFIG_TYPE=server-http my-config -

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.

When creating a ConfigMap, you will need to add special labels :

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)

Here is the example :

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.

Here is an example for server-http/hello-world.conf :

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

chown -R root:nginx /etc/bunkerweb/configs && \


chmod -R 770 /etc/bunkerweb/configs

Let's check the status of BunkerWeb :

systemctl status bunkerweb

If it's already running, we can reload it :

systemctl reload bunkerweb

Otherwise, we will need to start it :

systemctl start bunkerweb

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 :

curl -H "Host: app1.example.com" http://ip-or-fqdn-of-server

If you are using HTTPS, you will need to play with SNI :

curl -H "Host: app1.example.com" --resolve example.com:443:ip-of-server https://example.com

BunkerWeb supports PHP using external or remote PHP-FPM instances. We will assume that you are already
familiar with managing that kind of services.

The following settings can be used :

REMOTE_PHP : Hostname of the remote PHP-FPM instance.

REMOTE_PHP_PATH : Root folder containing files in the remote PHP-FPM instance.

LOCAL_PHP : Path to the local socket file of PHP-FPM instance.

84 / 263
BunkerWeb documentation v1.5.8

LOCAL_PHP_PATH : Root folder containing files in the local PHP-FPM instance.

85 / 263
BunkerWeb documentation v1.5.8

Docker

When using the Docker integration, to support PHP applications, you will need to :

Mount your PHP files into the /var/www/html folder of BunkerWeb

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 :

chown -R 33:101 ./www && \


find ./www -type f -exec chmod 0640 {} \; && \
find ./www -type d -exec chmod 0750 {} \;

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

Multisite mode enabled

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 :

Mount your PHP files into the /var/www/html folder of BunkerWeb

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 :

chown -R 33:101 ./www && \


find ./www -type f -exec chmod 0640 {} \; && \
find ./www -type d -exec chmod 0750 {} \;

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

Multisite mode enabled

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 :

Mount your PHP files into the /var/www/html folder of BunkerWeb

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 :

chown -R 33:101 /shared/www && \


find /shared/www -type f -exec chmod 0640 {} \; && \
find /shared/www -type d -exec chmod 0750 {} \;

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

PHP is not supported for 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
...

Don't forget to restart your PHP-FPM service :

systemctl restart php-fpm

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 :

chown -R www-data:nginx /var/www/html && \


find /var/www/html -type f -exec chmod 0640 {} \; && \
find /var/www/html -type d -exec chmod 0750 {} \;

You can now edit the /etc/bunkerweb/variable.env file :

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

Let's check the status of BunkerWeb :

systemctl status bunkerweb

If it's already running we can reload it :

systemctl reload bunkerweb

Otherwise, we will need to start it :

systemctl start bunkerweb

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 :

systemctl restart docker

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 :

systemctl restart docker

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.

Figure 10: Overview and order of the core security plugins

5.1 HTTP protocol


5.1.1 Deny status code

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.

5.1.2 Default server

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.

5.1.3 Allowed methods

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".

5.1.4 Max sizes

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

5.1.5 Serve files

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.

5.1.6.1 Remove headers

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

5.1.6.2 Keep upstream headers

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

When it comes to cookies security, we can use the following flags :

HttpOnly : disable any access to the cookie from Javascript using document.cookie

SameSite : policy when requests come from third-party websites

Secure : only send cookies on HTTPS request

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.

5.1.6.4 Security headers

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 :

Header Setting Default

Content- CONTENT_SEC object-src 'none'; frame-src 'self'; child-src 'self'; form-action


Security- URITY_POLIC 'self'; frame-ancestors 'self';
Policy Y

Strict- STRICT_TRAN max-age=31536000


Transport- SPORT_SECUR
Security ITY

Referrer- REFERRER_PO strict-origin-when-cross-origin

101 / 263
BunkerWeb documentation v1.5.8

Header Setting Default

Policy LICY

Permissions PERMISSIONS accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(),


-Policy _POLICY 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=()

Feature- FEATURE_POL accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none';


Policy ICY battery 'none'; camera 'none'; display-capture 'none'; document-
domain 'none'; encrypted-media 'none'; execution-while-not-rendered
'none'; execution-while-out-of-viewport 'none'; fullscreen 'none';
'none'; geolocation 'none'; gyroscope 'none'; layout-animation
'none'; legacy-image-formats 'none'; magnetometer 'none'; microphone
'none'; midi 'none'; navigation-override 'none'; payment 'none';
picture-in-picture 'none'; publickey-credentials-get 'none';
speaker-selection 'none'; sync-xhr 'none'; unoptimized-images
'none'; unsized-media 'none'; usb 'none'; screen-wake-lock 'none';
web-share 'none'; xr-spatial-tracking 'none';

X-Frame- X_FRAME_OPT SAMEORIGIN


Options IONS

X-Content- X_CONTENT_T nosniff


Type- YPE_OPTION
Options S

X-XSS- X_XSS_PROTE 1; mode=block


Protection CTION

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

Setting Default Context Multiple Description

USE_CORS no multisite no Use CORS

CORS_ALLOW_O * multisite no Allowed origins to make


RIGIN CORS requests : PCRE
regex or *.

CORS_EXPOSE_ Content-Length,Content- multisite no Value of the Access-


HEADERS Range Control-Expose-
Headers header.

CORS_MAX_AGE 86400 multisite no Value of the Access-


Control-Max-Age
header.

CORS_ALLOW_C no multisite no Send the Access-


REDENTIALS Control-Allow-
Credentials header.

CORS_ALLOW_M GET, POST, OPTIONS multisite no Value of the Access-


ETHODS Control-Allow-Methods
header.

CORS_ALLOW_H DNT,User-Agent,X- multisite no Value of the Access-


EADERS Requested-With,If- Control-Allow-Headers
Modified-Since,Cache- header.
Control,Content-Type,Range

CORS_DENY_RE yes multisite no Deny request and don't


QUEST send it to backend if
Origin is not allowed.

Here is some examples of possible values for CORS_ALLOW_ORIGIN setting :

* will allow all origin

^https://www\.example\.com$ will allow https://www.example.com

^https://.+\.example.com$ will allow any origins when domain ends with .example.com

^https://(www\.example1\.com|www\.example2\.com)$ will allow both https://www.example1.com and


https://www.example2.com

^https?://www\.example\.com$ will allow both https://www.example.com and http://www.example.com

103 / 263
BunkerWeb documentation v1.5.8

5.2 HTTPS / SSL/TLS


Besides the HTTPS / SSL/TLS configuration, the following settings related to HTTPS / SSL/TLS can be set :

Setting Default Description

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.

SSL_PROTOCOLS TLSv1.2 List of supported SSL/TLS protocols when SSL is enabled.


TLSv1.3

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.

5.2.1 Let's Encrypt

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

Here is the list of related settings :

Setting Default Description

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.

5.2.2 Let's Encrypt DNS (PRO)

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

Automatic creation and renewal of Let's Encrypt certificates

Integration with DNS providers for DNS challenges

Generate wildcard certificates

Configuration options for customization and flexibility

Settings of the Let's Encrypt DNS plugin

Setting Default Context Multiple Description

AUTO_LETS_ENCRYPT no multisite no Set to yes to enable automatic


_DNS certificate creation and renewal using
DNS challenges.

LETS_ENCRYPT_DNS_ multisite no Email address for Let's Encrypt

105 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

EMAIL notifications.

USE_LETS_ENCRYPT_ no multisite no Set to yes to use Let's Encrypt


DNS_STAGING staging server.

LETS_ENCRYPT_DNS_ multisite no DNS provider for Let's Encrypt DNS


PROVIDER challenges.

USE_LETS_ENCRYPT_ yes multisite no Set to yes to automatically generate


DNS_WILDCARD wildcard domains in certificates.

LETS_ENCRYPT_DNS_ default multisite no Time in seconds to wait for DNS


PROPAGATION propagation.

LETS_ENCRYPT_DNS_ multisite yes Credential item for Let's Encrypt DNS


CREDENTIAL_ITEM provider that contains required
credentials.

LETS_ENCRYPT_DNS_ no global no Clear old certificates when renewing.


CLEAR_OLD_CERTS

Information and behavior

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.

Available DNS Providers

Provider Description Mandatory Settings Link(s)

cloudflare Cloudflare DNS dns_cloudflare_api_token Documentation


provider

digitalocea DigitalOcean DNS dns_digitalocean_token Documentation


n provider

106 / 263
BunkerWeb documentation v1.5.8

Provider Description Mandatory Settings Link(s)

google Google Cloud DNS project_id , private_key_id , private_key , Documentation


provider client_email , client_email ,
client_x509_cert_url

linode Linode DNS provider dns_linode_key Documentation

ovh OVH DNS provider dns_ovh_application_key , Documentation


dns_ovh_application_secret ,
dns_ovh_consumer_key

rfc2136 RFC 2136 DNS dns_rfc2136_server , dns_rfc2136_name , Documentation


provider dns_rfc2136_secret

route53 Amazon Route 53 aws_access_key_id , aws_secret_access_key Documentation


DNS provider

scaleway Scaleway DNS dns_scaleway_application_token Documentation


provider

5.2.3 Custom certificate

STREAM support

If you want to use your own certificates, here is the list of related settings :

Setting Default Context Multiple Description

USE_CUSTOM_S no multisite no Use custom HTTPS / SSL/TLS certificate.


SL

CUSTOM_SSL_C multisite no Full path of the certificate or bundle file


ERT (must be readable by the scheduler).

CUSTOM_SSL_K multisite no Full path of the key file (must be readable


EY by the scheduler).

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 :

Setting Default Description

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 :

Setting Default Description

USE_MODSECURITY yes When set to yes , ModSecurity will be enabled.

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

ModSecurity and the OWASP Core Rule Set

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 :

3 : The version v3.3.5 of the OWASP Core Rule Set (default)

4 : The version v4.2.0 of the OWASP Core Rule Set

nightly : The latest nightly build of the OWASP Core Rule Set which is updated every day

OWASP Core Rule Set's nightly build

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.

5.3.1 Custom configurations

Tuning ModSecurity and the CRS can be done using custom configurations :

modsec-crs : before the OWASP Core Rule Set is loaded

modsec : after the OWASP Core Rule Set is loaded (also used if CRS is not loaded)

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 :

SecRule REQUEST_FILENAME "/wp-admin/admin-ajax.php" "id:1,ctl:ruleRemoveByTag=attack-


xss,ctl:ruleRemoveByTag=attack-rce"
SecRule REQUEST_FILENAME "/wp-admin/options.php" "id:2,ctl:ruleRemoveByTag=attack-xss"
SecRule REQUEST_FILENAME "^/wp-json/yoast" "id:3,ctl:ruleRemoveById=930120"

5.4 Bad behavior


STREAM support

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 :

Setting Default Description

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.

BAD_BEHAVIOR_THRESHO 10 Maximum number of "suspicious" HTTP status codes


LD within the time period.

BAD_BEHAVIOR_COUNT_T 60 Period of time during which we count "suspicious" HTTP


IME status codes.

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

Javascript : force a client to solve a computation challenge using Javascript

Captcha : force the client to solve a classical captcha (no external dependencies)

110 / 263
BunkerWeb documentation v1.5.8

hCaptcha : force the client to solve a captcha from hCaptcha

reCAPTCHA : force the client to get a minimum score with Google reCAPTCHA

Turnstile : enforce rate limiting and access control for APIs and web applications using various mechanisms with
Coudflare Turnstile

Here is the list of related settings :

Setting Default Context Multiple Description

USE_ANTIBOT no multisite no Activate antibot feature.

ANTIBOT_URI /challeng multisite no Unused URI that clients will be redirected


e to to solve the challenge.

ANTIBOT_RECAP 0.7 multisite no Minimum score required for reCAPTCHA


TCHA_SCORE challenge (Only compatible with
reCAPTCHA v3).

ANTIBOT_RECAP multisite no Sitekey for reCAPTCHA challenge.


TCHA_SITEKEY

ANTIBOT_RECAP multisite no Secret for reCAPTCHA challenge.


TCHA_SECRET

ANTIBOT_HCAPT multisite no Sitekey for hCaptcha challenge.


CHA_SITEKEY

ANTIBOT_HCAPT multisite no Secret for hCaptcha challenge.


CHA_SECRET

ANTIBOT_TURNS multisite no Sitekey for Turnstile challenge.


TILE_SITEKEY

ANTIBOT_TURNS multisite no Secret for Turnstile challenge.


TILE_SECRET

ANTIBOT_TIME_ 60 multisite no Maximum time (in seconds) clients have


RESOLVE to resolve the challenge. Once this time
has passed, a new challenge will be
generated.

ANTIBOT_TIME_ 86400 multisite no Maximum validity time of solved


VALID challenges. Once this time has passed,

111 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

clients will need to resolve a new one.

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.

5.6 Blacklisting, whitelisting and greylisting


The blacklisting security feature is very easy to understand : if a specific criteria is met, the client will be banned. As
for the whitelisting, it's the exact opposite : if a specific criteria is met, the client will be allowed and no additional
security check will be done. Whereas for the greylisting : if a specific criteria is met, the client will be allowed but
additional security checks will be done.

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

You can use the following settings to set up blacklisting :

Setting Default Context Multiple Description

USE_BLACKLI yes multisite no Activate blacklist feature.


ST

BLACKLIST_I multisite no List of IP/network, separated with


P spaces, to block.

BLACKLIST_R yes multisite no Only perform RDNS blacklist


DNS_GLOBAL checks on global IP addresses.

BLACKLIST_R .shodan.io multisite no List of reverse DNS suffixes,


DNS .censys.io separated with spaces, to block.

BLACKLIST_A multisite no List of ASN numbers, separated


SN with spaces, to block.

BLACKLIST_A global no List of URLs, separated with

112 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

SN_URLS spaces, containing ASN to block.

BLACKLIST_U multisite no List of User-Agent (PCRE regex),


SER_AGENT separated with spaces, to block.

BLACKLIST_U multisite no List of URI (PCRE regex),


RI separated with spaces, to block.

BLACKLIST_I https://www.dan.me. global no List of URLs, separated with


P_URLS uk/torlist/?exit spaces, containing bad
IP/network to block. Also
supports file:// URLs and and
auth basic using
http://user:pass@url scheme.

BLACKLIST_R global no List of URLs, separated with


DNS_URLS spaces, containing reverse DNS
suffixes to block. Also supports
file:// URLs and and auth basic
using http://user:pass@url
scheme.

BLACKLIST_A global no List of URLs, separated with


SN_URLS spaces, containing ASN to block.
Also supports file:// URLs and
and auth basic using
http://user:pass@url scheme.

BLACKLIST_U https://raw.githubu global no List of URLs, separated with


SER_AGENT_U sercontent.com/mitc spaces, containing bad User-
RLS hellkrogza/nginx- Agent to block. Also supports
ultimate-bad-bot- file:// URLs and and auth basic
blocker/master/_gen using http://user:pass@url
erator_lists/bad- scheme.
user-agents.list

BLACKLIST_U global no List of URLs, separated with


RI_URLS spaces, containing bad URI to
block. Also supports file:// URLs
and and auth basic using
http://user:pass@url scheme.

113 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

BLACKLIST_I global no List of URLs, separated with


GNORE_IP_UR spaces, containing IP/network to
LS ignore in the blacklist. Also
supports file:// URLs and and
auth basic using
http://user:pass@url scheme.

BLACKLIST_I global no List of URLs, separated with


GNORE_RDNS_ spaces, containing reverse DNS
URLS suffixes to ignore in the blacklist.
Also supports file:// URLs and
and auth basic using
http://user:pass@url scheme.

BLACKLIST_I global no List of URLs, separated with


GNORE_ASN_U spaces, containing ASN to ignore
RLS in the blacklist. Also supports
file:// URLs and and auth basic
using http://user:pass@url
scheme.

BLACKLIST_I global no List of URLs, separated with


GNORE_USER_ spaces, containing User-Agent to
AGENT_URLS ignore in the blacklist. Also
supports file:// URLs and and
auth basic using
http://user:pass@url scheme.

BLACKLIST_I global no List of URLs, separated with


GNORE_URI_U spaces, containing URI to ignore
RLS in the blacklist. Also supports
file:// URLs and and auth basic
using http://user:pass@url
scheme.

When using stream mode, only IP, RDNS and ASN checks will be done.

5.6.2 Greylisting

STREAM support

You can use the following settings to set up greylisting :

114 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

USE_GREYLIS no multisite no Activate greylist feature.


T

GREYLIST_IP multisite no List of IP/network, separated with spaces, to


put into the greylist.

GREYLIST_RDN yes multisite no Only perform RDNS greylist checks on


S_GLOBAL global IP addresses.

GREYLIST_RDN multisite no List of reverse DNS suffixes, separated with


S spaces, to put into the greylist.

GREYLIST_AS multisite no List of ASN numbers, separated with


N spaces, to put into the greylist.

GREYLIST_USE multisite no List of User-Agent (PCRE regex), separated


R_AGENT with spaces, to put into the greylist.

GREYLIST_UR multisite no List of URI (PCRE regex), separated with


I spaces, to put into the greylist.

GREYLIST_IP_ global no List of URLs, separated with spaces,


URLS containing good IP/network to put into the
greylist. Also supports file:// URLs and and
auth basic using http://user:pass@url
scheme.

GREYLIST_RDN global no List of URLs, separated with spaces,


S_URLS containing reverse DNS suffixes to put into
the greylist. Also supports file:// URLs and
and auth basic using http://user:pass@url
scheme.

GREYLIST_ASN global no List of URLs, separated with spaces,


_URLS containing ASN to put into the greylist. Also
supports file:// URLs and and auth basic
using http://user:pass@url scheme.

GREYLIST_USE global no List of URLs, separated with spaces,


R_AGENT_URL containing good User-Agent to put into the
S greylist. Also supports file:// URLs and and

115 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

auth basic using http://user:pass@url


scheme.

GREYLIST_URI global no List of URLs, separated with spaces,


_URLS containing bad URI to put into the greylist.
Also supports file:// URLs and and auth
basic using http://user:pass@url scheme.

When using stream mode, only IP, RDNS and ASN checks will be done.

5.6.3 Whitelisting

STREAM support

You can use the following settings to set up whitelisting :

Setting Default Context Multiple Description

USE_WHITELI yes multisite no Activate whitelist feature.


ST

WHITELIST_I 20.191.45.212 multisite no List of IP/network, separated


P 40.88.21.235 with spaces, to put into the
40.76.173.151 whitelist.
40.76.163.7
20.185.79.47
52.142.26.175
20.185.79.15
52.142.24.149
40.76.162.208
40.76.163.23
40.76.162.191
40.76.162.247
54.208.102.37
107.21.1.8

WHITELIST_R yes multisite no Only perform RDNS whitelist


DNS_GLOBAL checks on global IP
addresses.

WHITELIST_R .google.com multisite no List of reverse DNS suffixes,


DNS .googlebot.com separated with spaces, to

116 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

.yandex.ru .yandex.net whitelist.


.yandex.com
.search.msn.com
.baidu.com .baidu.jp
.crawl.yahoo.net
.fwd.linkedin.com
.twitter.com .twttr.com
.discord.com

WHITELIST_A 32934 multisite no List of ASN numbers,


SN separated with spaces, to
whitelist.

WHITELIST_U multisite no List of User-Agent (PCRE


SER_AGENT regex), separated with spaces,
to whitelist.

WHITELIST_U multisite no List of URI (PCRE regex),


RI separated with spaces, to
whitelist.

WHITELIST_I global no List of URLs, separated with


P_URLS spaces, containing good
IP/network to whitelist. Also
supports file:// URLs and and
auth basic using
http://user:pass@url scheme.

WHITELIST_R global no List of URLs, separated with


DNS_URLS spaces, containing reverse
DNS suffixes to whitelist. Also
supports file:// URLs and and
auth basic using
http://user:pass@url scheme.

WHITELIST_A global no List of URLs, separated with


SN_URLS spaces, containing ASN to
whitelist. Also supports file://
URLs and and auth basic
using http://user:pass@url
scheme.

117 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

WHITELIST_U global no List of URLs, separated with


SER_AGENT_U spaces, containing good User-
RLS Agent to whitelist. Also
supports file:// URLs and and
auth basic using
http://user:pass@url scheme.

WHITELIST_U global no List of URLs, separated with


RI_URLS spaces, containing bad URI to
whitelist. Also supports file://
URLs and and auth basic
using http://user:pass@url
scheme.

When using stream mode, only IP, RDNS and ASN checks will be done.

5.7 Reverse scan


STREAM support

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.

Here is the list of settings related to reverse scan :

Setting Default Description

USE_REVERSE_SCAN no When set to yes , will enable ReverseScan.

REVERSE_SCAN_PORTS 22 80 443 3128 8000 List of suspicious ports to scan.


8080

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.

The setting used to enable or disable BunkerNet is USE_BUNKERNET (default : yes ).

5.8.1 CrowdSec Console integration

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.

Step #1 : create your CrowdSec 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" :

Figure 11: Get your Crowdsec Console enroll key

Step #2 : get your BunkerNet ID

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 .

Get your BunkerNet ID on Docker :

docker exec my-bw-scheduler cat /var/cache/bunkerweb/bunkernet/instance.id

Get your BunkerNet ID on Linux :

cat /var/cache/bunkerweb/bunkernet/instance.id

Step #3 : enroll your instance using the Panel

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

Step #4 : accept new security engine on the 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

Figure 13: Accept enroll into the CrowdSec Console

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.

Figure 14: BunkerWeb data shown in the context column

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.

Here is the list of settings related to DNSBL :

Setting Default Description

USE_DNSBL yes When set to yes , will enable


DNSBL checking.

121 / 263
BunkerWeb documentation v1.5.8

Setting Default Description

DNSBL_LIS bl.blocklist.de problems.dnsbl.sorbs.net List of DNSBL servers to ask.


T sbl.spamhaus.org xbl.spamhaus.org

5.10 Limiting
BunkerWeb supports applying a limit policy to :

Number of connections per IP

Number of requests per IP and URL within a time period

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

The following settings are related to the Limiting connections feature :

Setting Default Description

USE_LIMIT_CONN yes When set to yes , will limit the maximum number of concurrent
connections for a given IP.

LIMIT_CONN_MAX_HTT 10 Maximum number of concurrent connections when using HTTP1


P1 protocol.

LIMIT_CONN_MAX_HTT 100 Maximum number of concurrent streams when using HTTP2 protocol.
P2

LIMIT_CONN_MAX_STR 10 Maximum number of connections per IP when using stream.


EAM

5.10.2 Requests

STREAM support

122 / 263
BunkerWeb documentation v1.5.8

The following settings are related to the Limiting requests feature :

Setting Default Context Multiple Description

USE_LIMIT_R yes multisite no Activate limit requests feature.


EQ

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 :

Deny any access if the country is in a blacklist

Only allow access if the country is in a whitelist (other security checks will still be executed)

Here is the list of related settings :

Setting Default Context Multiple Description

BLACKLIST_CO multisite no Deny access if the country of the client is in


UNTRY the list (ISO 3166-1 alpha-2 format
separated with spaces).

WHITELIST_CO multisite no Deny access if the country of the client is


UNTRY not in the list (ISO 3166-1 alpha-2 format
separated with spaces).

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 :

Setting Default Description

USE_AUTH_BASIC no When set to yes HTTP auth basic will be enabled.

AUTH_BASIC_LOCAT sitewide Location (URL) of the sensitive resource. Use special value
ION sitewide to enable everywhere.

AUTH_BASIC_USER changeme The username required.

AUTH_BASIC_PASSW changeme The password required.


ORD

AUTH_BASIC_TEXT Restricted Text to display in the auth prompt.


area

5.12.2 Auth request

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.

Auth request settings are related to reverse proxy rules.

Setting Default Context Multiple Description

REVERSE_PRO multisite yes Enable authentication using an external


XY_AUTH_REQ provider (value of auth_request directive).
UEST

REVERSE_PRO multisite yes Redirect clients to sign-in URL when using


XY_AUTH_REQ REVERSE_PROXY_AUTH_REQUEST
UEST_SIGNIN (used when auth_request call returned 401).
_URL

124 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

REVERSE_PRO multisite yes List of variables to set from the


XY_AUTH_REQ authentication provider, separated with ;
UEST_SET (values of auth_request_set directives).

5.13 Monitoring and reporting

5.13.1 Monitoring (PRO)

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

Enable collection of various BunkerWeb metrics

Retrieve metrics from the API

Use in combination with other plugins (e.g. Prometheus exporter)

Dedicate UI page to monitor your instance(s)

List of settings

Setting Default Context Multiple Description

USE_MONITORING yes global no Enable monitoring of


BunkerWeb.

MONITORING_METRICS_DIC 10M global no Size of the dict to store


T_SIZE monitoring metrics.

5.13.2 Prometheus exporter (PRO)

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

Prometheus exporter providing internal BunkerWeb metrics

Dedicated and configurable port, listen IP and URL

Whitelist IP/network for maximum security

List of settings

Setting Default Context Multiple Description

USE_PROMETHEUS no global no Enable the Prometheus


_EXPORTER export.

PROMETHEUS_EXP 0.0.0.0 global no Listening IP of the


ORTER_IP Prometheus exporter.

PROMETHEUS_EXP 9113 global no Listening port of the


ORTER_PORT Prometheus exporter.

PROMETHEUS_EXP /metrics global no HTTP URL of the


ORTER_URL Prometheus exporter.

PROMETHEUS_EXP 127.0.0.0/8 global no List of IP/networks allowed


ORTER_ALLOW_IP 10.0.0.0/8 to contact the Prometheus
172.16.0.0/12 exporter endpoint.
192.168.0.0/16

5.13.3 Reporting (PRO)

STREAM support

Monitoring plugin needed

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.

Support for SMTP for email notifications.

Configuration options for customization and flexibility.

List of settings

Setting Default Context Description

USE_REPORTING_SM no global Enable sending the report via email.


TP

USE_REPORTING_WE no global Enable sending the report via webhook.


BHOOK

REPORTING_SCHEDU weekly global The frequency at which reports are sent.


LE

REPORTING_WEBHOO global List of webhook URLs to receive the report in


K_URLS Markdown (separated by spaces).

REPORTING_SMTP_E global List of email addresses to receive the report in HTML


MAILS format (separated by spaces).

REPORTING_SMTP_H global The host server used for SMTP sending.


OST

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

Setting Default Context Description

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.

REPORTING_SMTP_S SSL global Determine whether or not to use a secure connection


SL for SMTP.

REPORTING_SMTP_S BunkerWeb global The subject line of the email.


UBJECT Report

Information and behavior

case USE_REPORTING_SMTP is set to yes , the setting REPORTING_SMTP_EMAILS must be set.

case USE_REPORTING_WEBHOOK is set to yes , the setting REPORTING_WEBHOOK_URLS must be set.

Accepted values for REPORTING_SCHEDULE are daily , weekly and monthly .

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.

5.14 Backup and restore


5.14.1 Backup

STREAM support

5.14.1.1 Automated backup

128 / 263
BunkerWeb documentation v1.5.8

Information for Red Hat Enterprise Linux (RHEL) 8.9 users

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

1. Install the MySQL repository configuration package

sudo dnf install https://dev.mysql.com/get/mysql80-community-release-el8-9.noarch.rpm

2. Enable the MySQL repository

sudo dnf config-manager --enable mysql80-community

3. Install the MySQL client

sudo dnf install mysql-community-client

PostgreSQL

1. Install the PostgreSQL repository configuration package

dnf install "https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-$(uname -m)/pgdg-


redhat-repo-latest.noarch.rpm"

2. Install the PostgreSQL client

dnf install postgresql<version>

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.

Information and behavior

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

Setting Default Context Multiple Description

USE_BACKUP yes global no Enable or disable the backup


feature

BACKUP_DIRECT /var/lib/bunkerweb/ global no The directory where the backup


ORY backups will be stored

BACKUP_SCHEDU daily global no The frequency of the backup


LE

BACKUP_ROTATI 7 global no The number of backups to


ON keep

5.14.1.2 Manual backup

To manually initiate a backup, execute the following command:

Linux

bwcli plugin backup save

Docker

docker exec -it <scheduler_container> bwcli plugin backup save

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

BACKUP_DIRECTORY=/path/to/backup/directory bwcli plugin backup save

Docker

docker exec -it -e BACKUP_DIRECTORY=/path/to/backup/directory <scheduler_container> bwcli plugin


backup save

docker cp <scheduler_container>:/path/to/backup/directory /path/to/backup/directory

130 / 263
BunkerWeb documentation v1.5.8

Specifications for MariaDB/MySQL

In case you are using MariaDB/MySQL, you may encounter the following error when trying to backup your database:

caching_sha2_password could not be loaded: Error loading shared library


/usr/lib/mariadb/plugin/caching_sha2_password.so

To resolve this issue, you can execute the following command to change the authentication plugin to
mysql_native_password :

ALTER USER 'yourusername'@'localhost' IDENTIFIED WITH mysql_native_password BY 'youpassword';

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

5.14.1.3 Manual restore

To manually initiate a restore, execute the following command:

Linux

bwcli plugin backup restore

Docker

docker exec -it <scheduler_container> bwcli plugin backup restore

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

bwcli plugin backup restore /path/to/backup/file

Docker

docker cp /path/to/backup/file <scheduler_container>:/path/to/backup/file

docker exec -it <scheduler_container> bwcli plugin backup restore /path/to/backup/file

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

BACKUP_DIRECTORY=/var/tmp/bunkerweb/backups bwcli plugin backup restore

Docker

docker cp <scheduler_container>:/var/tmp/bunkerweb/backups /var/tmp/bunkerweb/backups

docker exec -it -e BACKUP_DIRECTORY=/var/tmp/bunkerweb/backups <scheduler_container> bwcli plugin


backup restore

5.14.2 Backup S3 (PRO)

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

Information for Red Hat Enterprise Linux (RHEL) 8.9 users

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

1. Install the MySQL repository configuration package

sudo dnf install https://dev.mysql.com/get/mysql80-community-release-el8-9.noarch.rpm

2. Enable the MySQL repository

sudo dnf config-manager --enable mysql80-community

3. Install the MySQL client

sudo dnf install mysql-community-client

PostgreSQL

1. Install the PostgreSQL repository configuration package

dnf install "https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-$(uname -m)/pgdg-


redhat-repo-latest.noarch.rpm"

2. Install the PostgreSQL client

dnf install postgresql<version>

List of features

Automatic data backup to an S3 bucket

Flexible scheduling options: daily, weekly, or monthly

Rotation management for controlling the number of backups to keep

Customizable compression level for backup files

List of settings

133 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Description

USE_BACKUP_S3 no global Enable or disable the S3 backup feature

BACKUP_S3_SCHEDULE daily global The frequency of the backup

BACKUP_S3_ROTATION 7 global The number of backups to keep

BACKUP_S3_ENDPOINT global The S3 endpoint

BACKUP_S3_BUCKET global The S3 bucket

BACKUP_S3_DIR global The S3 directory

BACKUP_S3_REGION global The S3 region

BACKUP_S3_ACCESS_KEY_ID global The S3 access key ID

BACKUP_S3_ACCESS_KEY_SECRET global The S3 access key secret

BACKUP_S3_COMP_LEVEL 6 global The compression level of the backup zip file

5.14.2.1 Manual backup

To manually initiate a backup, execute the following command:

Linux

bwcli plugin backup_s3 save

Docker

docker exec -it <scheduler_container> bwcli plugin backup_s3 save

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

BACKUP_S3_BUCKET=your-bucket-name bwcli plugin backup_s3 save

Docker

docker exec -it -e BACKUP_S3_BUCKET=your-bucket-name <scheduler_container> bwcli plugin backup_s3


save

Specifications for MariaDB/MySQL

In case you are using MariaDB/MySQL, you may encounter the following error when trying to backup your database:

caching_sha2_password could not be loaded: Error loading shared library


/usr/lib/mariadb/plugin/caching_sha2_password.so

To resolve this issue, you can execute the following command to change the authentication plugin to
mysql_native_password :

ALTER USER 'yourusername'@'localhost' IDENTIFIED WITH mysql_native_password BY 'youpassword';

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

5.14.2.2 Manual restore

To manually initiate a restore, execute the following command:

135 / 263
BunkerWeb documentation v1.5.8

Linux

bwcli plugin backup_s3 restore

Docker

docker exec -it <scheduler_container> bwcli plugin backup_s3 restore

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

bwcli plugin backup_s3 restore s3_backup_file.zip

Docker

docker exec -it <scheduler_container> bwcli plugin backup restore s3_backup_file.zip

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

bwcli plugin backup_s3 restore

Docker

docker exec -it <scheduler_container> bwcli plugin backup_s3 restore

5.15 Migration (PRO)


STREAM support

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.

5.15.1 Create a migration file

To manually create a migration file, execute the following command:

Linux

bwcli plugin migration create /path/to/migration/file

Docker

1. Create a migration file:

docker exec -it <scheduler_container> bwcli plugin migration create /path/to/migration/file

2. Copy the migration file to your local machine:

docker cp <scheduler_container>:/path/to/migration/file /path/to/migration/file

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

Specifications for MariaDB/MySQL

In case you are using MariaDB/MySQL, you may encounter the following error when trying to backup your database:

caching_sha2_password could not be loaded: Error loading shared library


/usr/lib/mariadb/plugin/caching_sha2_password.so

To resolve this issue, you can execute the following command to change the authentication plugin to
mysql_native_password :

ALTER USER 'yourusername'@'localhost' IDENTIFIED WITH mysql_native_password BY 'youpassword';

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

5.15.2 Initialize a migration

To manually initialize a migration, execute the following command:

Linux

bwcli plugin migration migrate /path/to/migration/file

Docker

1. Copy the migration file to the container:

docker cp /path/to/migration/file <scheduler_container>:/path/to/migration/file

2. Initialize the migration:

docker exec -it <scheduler_container> bwcli plugin migration migrate /path/to/migration/file

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

Settings generator tool

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.

6.1 Global settings


STREAM support

Setting Default Context Multiple Description

IS_LOADING no global no Internal use : set to yes


when BW is loading.

NGINX_PREFIX /etc/nginx/ global no Where nginx will search


for configurations.

HTTP_PORT 8080 global no HTTP port number which


bunkerweb binds to.

HTTPS_PORT 8443 global no HTTPS port number


which bunkerweb binds
to.

MULTISITE no global no Multi site activation.

SERVER_NAME www.example.com multisite no List of the virtual hosts


served by bunkerweb.

140 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

WORKER_PROCE auto global no Number of worker


SSES processes.

WORKER_RLIMI 2048 global no Maximum number of


T_NOFILE open files for worker
processes.

WORKER_CONNE 1024 global no Maximum number of


CTIONS connections per worker.

LOG_FORMAT $host $remote_addr - global no The format to use for


$remote_user access logs.
[$time_local] "$request"
$status $body_bytes_sent
"$http_referer"
"$http_user_agent"

LOG_LEVEL notice global no The level to use for error


logs.

DNS_RESOLVER 127.0.0.11 global no DNS addresses of


S resolvers to use.

DATASTORE_ME 64m global no Size of the internal


MORY_SIZE datastore.

CACHESTORE_M 64m global no Size of the internal


EMORY_SIZE cachestore.

CACHESTORE_I 16m global no Size of the internal


PC_MEMORY_SI cachestore (ipc).
ZE

CACHESTORE_M 16m global no Size of the internal


ISS_MEMORY_S cachestore (miss).
IZE

CACHESTORE_L 16m global no Size of the internal


OCKS_MEMORY_ cachestore (locks).
SIZE

141 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

USE_API yes global no Activate the API to control


BunkerWeb.

API_HTTP_POR 5000 global no Listen port number for the


T API.

API_LISTEN_I 0.0.0.0 global no Listen IP address for the


P API.

API_SERVER_N bwapi global no Server name (virtual host)


AME for the API.

API_WHITELIS 127.0.0.0/8 global no List of IP/network allowed


T_IP to contact the API.

AUTOCONF_MOD no global no Enable Autoconf Docker


E integration.

SWARM_MODE no global no Enable Docker Swarm


integration.

KUBERNETES_M no global no Enable Kubernetes


ODE integration.

SERVER_TYPE http multisite no Server type : http or


stream.

LISTEN_STREA yes multisite no Enable listening for non-


M ssl (passthrough).

LISTEN_STREA 1337 multisite no Listening port for non-ssl


M_PORT (passthrough).

LISTEN_STREA 4242 multisite no Listening port for ssl


M_PORT_SSL (passthrough).

USE_UDP no multisite no UDP listen instead of


TCP (stream).

USE_IPV6 no global no Enable IPv6 connectivity.

142 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

IS_DRAFT no multisite no Internal use : set to yes


when the service is in
draft mode.

TIMERS_LOG_L debug global no Log level for timers.


EVEL

OVERRIDE_INS global no List of BunkerWeb


TANCES instances separated with
spaces (format : fqdn-or-
ip:5000 fqdn-or-ip:5000)

6.2 Antibot
STREAM support

Bot detection by using a challenge.

Setting Default Context Multiple Description

USE_ANTIBOT no multisite no Activate antibot feature.

ANTIBOT_URI /challeng multisite no Unused URI that clients will be redirected


e to to solve the challenge.

ANTIBOT_TIME_ 60 multisite no Maximum time (in seconds) clients have


RESOLVE to resolve the challenge. Once this time
has passed, a new challenge will be
generated.

ANTIBOT_TIME_ 86400 multisite no Maximum validity time of solved


VALID challenges. Once this time has passed,
clients will need to resolve a new one.

ANTIBOT_RECAP 0.7 multisite no Minimum score required for reCAPTCHA


TCHA_SCORE challenge (Only compatible with
reCAPTCHA v3).

ANTIBOT_RECAP multisite no Sitekey for reCAPTCHA challenge.


TCHA_SITEKEY

143 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

ANTIBOT_RECAP multisite no Secret for reCAPTCHA challenge.


TCHA_SECRET

ANTIBOT_HCAPT multisite no Sitekey for hCaptcha challenge.


CHA_SITEKEY

ANTIBOT_HCAPT multisite no Secret for hCaptcha challenge.


CHA_SECRET

ANTIBOT_TURNS multisite no Sitekey for Turnstile challenge.


TILE_SITEKEY

ANTIBOT_TURNS multisite no Secret for Turnstile challenge.


TILE_SECRET

6.3 Auth basic


STREAM support

Enforce login before accessing a resource or the whole site using HTTP basic auth method.

Setting Default Context Multiple Description

USE_AUTH_BASIC no multisite no Use HTTP basic auth

AUTH_BASIC_LOCAT sitewide multisite no URL of the protected resource or


ION sitewide value.

AUTH_BASIC_USER changeme multisite no Username

AUTH_BASIC_PASSW changeme multisite no Password


ORD

AUTH_BASIC_TEXT Restricted multisite no Text to display


area

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.

Setting Default Context Multiple Description

USE_BACKUP yes global no Enable or disable the backup


feature

BACKUP_SCHEDU daily global no The frequency of the backup


LE (daily, weekly or monthly)

BACKUP_ROTATI 7 global no The number of backups to keep


ON

BACKUP_DIRECT /var/lib/bunkerweb global no The directory where the backup


ORY /backups will be stored

6.5 Backup S3 (PRO)


STREAM support

Automatically backup your data to an S3 bucket

Setting Default Context Multiple Description

USE_BACKUP_S3 no global no Enable or disable the S3 backup


feature

BACKUP_S3_SCHEDULE daily global no The frequency of the backup

BACKUP_S3_ROTATION 7 global no The number of backups to keep

BACKUP_S3_ENDPOINT global no The S3 endpoint

BACKUP_S3_BUCKET global no The S3 bucket

BACKUP_S3_DIR global no The S3 directory

BACKUP_S3_REGION global no The S3 region

145 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

BACKUP_S3_ACCESS_KEY_ global no The S3 access key ID


ID

BACKUP_S3_ACCESS_KEY_ global no The S3 access key secret


SECRET

BACKUP_S3_COMP_LEVEL 6 global no The compression level of the


backup zip file

6.6 Bad behavior


STREAM support

Ban IP generating too much 'bad' HTTP status code in a period of time.

Setting Default Context Multiple Description

USE_BAD_BEHAVI yes multisite no Activate Bad behavior feature.


OR

BAD_BEHAVIOR_S 400 401 403 multisite no List of HTTP status codes


TATUS_CODES 404 405 429 considered as 'bad'.
444

BAD_BEHAVIOR_T 10 multisite no Maximum number of 'bad' HTTP


HRESHOLD status codes within the period of
time before IP is banned.

BAD_BEHAVIOR_C 60 multisite no Period of time (in seconds) during


OUNT_TIME which we count 'bad' HTTP status
codes.

BAD_BEHAVIOR_B 86400 multisite no The duration time (in seconds) of a


AN_TIME ban when the corresponding IP has
reached the threshold.

6.7 Blacklist
STREAM support

146 / 263
BunkerWeb documentation v1.5.8

Deny access based on internal and external IP/network/rDNS/ASN blacklists.

Setting Default Context Multiple Description

USE_BLACKLI yes multisite no Activate blacklist feature.


ST

BLACKLIST_I multisite no List of IP/network, separated with


P spaces, to block.

BLACKLIST_R .shodan.io multisite no List of reverse DNS suffixes,


DNS .censys.io separated with spaces, to block.

BLACKLIST_R yes multisite no Only perform RDNS blacklist


DNS_GLOBAL checks on global IP addresses.

BLACKLIST_A multisite no List of ASN numbers, separated


SN with spaces, to block.

BLACKLIST_U multisite no List of User-Agent (PCRE regex),


SER_AGENT separated with spaces, to block.

BLACKLIST_U multisite no List of URI (PCRE regex),


RI separated with spaces, to block.

BLACKLIST_I multisite no List of IP/network, separated with


GNORE_IP spaces, to ignore in the blacklist.

BLACKLIST_I multisite no List of reverse DNS suffixes,


GNORE_RDNS separated with spaces, to ignore
in the blacklist.

BLACKLIST_I multisite no List of ASN numbers, separated


GNORE_ASN with spaces, to ignore in the
blacklist.

BLACKLIST_I multisite no List of User-Agent (PCRE regex),


GNORE_USER_ separated with spaces, to ignore
AGENT in the blacklist.

BLACKLIST_I multisite no List of URI (PCRE regex),


GNORE_URI separated with spaces, to ignore
in the blacklist.

147 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

BLACKLIST_I https://www.dan.me. global no List of URLs, separated with


P_URLS uk/torlist/?exit spaces, containing bad
IP/network to block. Also
supports file:// URLs and and
auth basic using
http://user:pass@url scheme.

BLACKLIST_R global no List of URLs, separated with


DNS_URLS spaces, containing reverse DNS
suffixes to block. Also supports
file:// URLs and and auth basic
using http://user:pass@url
scheme.

BLACKLIST_A global no List of URLs, separated with


SN_URLS spaces, containing ASN to block.
Also supports file:// URLs and
and auth basic using
http://user:pass@url scheme.

BLACKLIST_U https://raw.githubu global no List of URLs, separated with


SER_AGENT_U sercontent.com/mitc spaces, containing bad User-
RLS hellkrogza/nginx- Agent to block. Also supports
ultimate-bad-bot- file:// URLs and and auth basic
blocker/master/_gen using http://user:pass@url
erator_lists/bad- scheme.
user-agents.list

BLACKLIST_U global no List of URLs, separated with


RI_URLS spaces, containing bad URI to
block. Also supports file:// URLs
and and auth basic using
http://user:pass@url scheme.

BLACKLIST_I global no List of URLs, separated with


GNORE_IP_UR spaces, containing IP/network to
LS ignore in the blacklist. Also
supports file:// URLs and and
auth basic using
http://user:pass@url scheme.

148 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

BLACKLIST_I global no List of URLs, separated with


GNORE_RDNS_ spaces, containing reverse DNS
URLS suffixes to ignore in the blacklist.
Also supports file:// URLs and
and auth basic using
http://user:pass@url scheme.

BLACKLIST_I global no List of URLs, separated with


GNORE_ASN_U spaces, containing ASN to ignore
RLS in the blacklist. Also supports
file:// URLs and and auth basic
using http://user:pass@url
scheme.

BLACKLIST_I global no List of URLs, separated with


GNORE_USER_ spaces, containing User-Agent to
AGENT_URLS ignore in the blacklist. Also
supports file:// URLs and and
auth basic using
http://user:pass@url scheme.

BLACKLIST_I global no List of URLs, separated with


GNORE_URI_U spaces, containing URI to ignore
RLS in the blacklist. Also supports
file:// URLs and and auth basic
using http://user:pass@url
scheme.

6.8 Brotli
STREAM support

Compress HTTP requests with the brotli algorithm.

Setting Default Context Multiple Description

USE_BROTL no multisite no Use brotli


I

149 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

BROTLI_TYP application/atom+xml multisite no List of MIME


ES application/javascript types that will
application/json application/rss+xml be compressed
application/vnd.ms-fontobject with brotli.
application/x-font-opentype
application/x-font-truetype
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

BROTLI_MIN 1000 multisite no Minimum length


_LENGTH for brotli
compression.

BROTLI_COM 6 multisite no The


P_LEVEL compression
level of the
brotli algorithm.

6.9 BunkerNet
STREAM support

Share threat data with other BunkerWeb instances via BunkerNet.

Setting Default Context Multiple Description

USE_BUNKERNET yes multisite no Activate BunkerNet


feature.

BUNKERNET_SERVE https://api.bunkerweb global no Address of the BunkerNet


R .io API.

150 / 263
BunkerWeb documentation v1.5.8

6.10 CORS
STREAM support

Cross-Origin Resource Sharing.

Setting Default Context Multiple Description

USE_CORS no multisite no Use CORS

CORS_ALLOW_ORI * multisite no Allowed origins to make


GIN CORS requests : PCRE
regex or *.

CORS_ALLOW_MET GET, POST, OPTIONS multisite no Value of the Access-


HODS Control-Allow-Methods
header.

CORS_ALLOW_HEA DNT,User-Agent,X- multisite no Value of the Access-


DERS Requested-With,If- Control-Allow-Headers
Modified-Since,Cache- header.
Control,Content-
Type,Range

CORS_ALLOW_CRE no multisite no Send the Access-


DENTIALS Control-Allow-
Credentials header.

CORS_EXPOSE_HE Content-Length,Content- multisite no Value of the Access-


ADERS Range Control-Expose-
Headers header.

CROSS_ORIGIN_O multisite no Value for the Cross-


PENER_POLICY Origin-Opener-Policy
header.

CROSS_ORIGIN_E multisite no Value for the Cross-


MBEDDER_POLIC Origin-Embedder-Policy
Y header.

CROSS_ORIGIN_R multisite no Value for the Cross-


ESOURCE_POLIC Origin-Resource-Policy
Y header.

151 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

CORS_MAX_AGE 86400 multisite no Value of the Access-


Control-Max-Age
header.

CORS_DENY_REQU yes multisite no Deny request and don't


EST send it to backend if
Origin is not allowed.

6.11 Client cache


STREAM support

Manage caching for clients.

Setting Default Context Multiple Description

USE_CLIENT_CA no multisite no Tell client to store locally


CHE static files.

CLIENT_CACHE_ jpg|jpeg|png|bmp|ico|sv global no List of file extensions,


EXTENSIONS g|tif|css|js|otf|ttf|eo separated with pipes that
t|woff|woff2 should be cached.

CLIENT_CACHE_ yes multisite no Send the HTTP ETag


ETAG header for static resources.

CLIENT_CACHE_ public, max- multisite no Value of the Cache-Control


CONTROL age=15552000 HTTP header.

6.12 Country
STREAM support

Deny access based on the country of the client IP.

152 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

BLACKLIST_CO multisite no Deny access if the country of the client is in


UNTRY the list (ISO 3166-1 alpha-2 format
separated with spaces).

WHITELIST_CO multisite no Deny access if the country of the client is


UNTRY not in the list (ISO 3166-1 alpha-2 format
separated with spaces).

6.13 Custom HTTPS certificate


STREAM support

Choose custom certificate for HTTPS.

Setting Default Context Multiple Description

USE_CUSTOM_SSL no multisite no Use custom HTTPS certificate.

CUSTOM_SSL_CER multisite no Full path of the certificate or bundle file


T (must be readable by the scheduler).

CUSTOM_SSL_KEY multisite no Full path of the key file (must be readable


by the scheduler).

CUSTOM_SSL_CER multisite no Certificate data encoded in base64.


T_DATA

CUSTOM_SSL_KEY multisite no Key data encoded in base64.


_DATA

6.14 DB
STREAM support

Integrate easily the Database.

153 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

DATABASE_UR sqlite:////var/ global no The database URI, following the


I lib/bunkerweb/d sqlalchemy format.
b.sqlite3

DATABASE_URI global no The database URI for read-only


_READONLY operations, it can also serve as a
fallback if the main database is down.
Following the sqlalchemy format.

DATABASE_LOG warning global no The level to use for database logs.


_LEVEL

6.15 DNSBL
STREAM support

Deny access based on external DNSBL servers.

Setting Default Context Multiple Description

USE_DNSBL yes multisite no Activate DNSBL


feature.

DNSBL_LIS bl.blocklist.de global no List of DNSBL


T problems.dnsbl.sorbs.net servers.
sbl.spamhaus.org xbl.spamhaus.org

6.16 Errors
STREAM support

Manage default error pages

Setting Default Context Multiple Description

ERRORS multisite no List of HTTP error code and


corresponding error pages,
separated with spaces

154 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

(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.

Setting Default Context Multiple Description

USE_GREYLIS no multisite no Activate greylist feature.


T

GREYLIST_IP multisite no List of IP/network, separated with spaces, to


put into the greylist.

GREYLIST_RDN multisite no List of reverse DNS suffixes, separated with


S spaces, to put into the greylist.

GREYLIST_RDN yes multisite no Only perform RDNS greylist checks on


S_GLOBAL global IP addresses.

GREYLIST_AS multisite no List of ASN numbers, separated with


N spaces, to put into the greylist.

GREYLIST_USE multisite no List of User-Agent (PCRE regex), separated


R_AGENT with spaces, to put into the greylist.

GREYLIST_UR multisite no List of URI (PCRE regex), separated with


I spaces, to put into the greylist.

GREYLIST_IP_ global no List of URLs, separated with spaces,


URLS containing good IP/network to put into the
greylist. Also supports file:// URLs and and

155 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

auth basic using http://user:pass@url


scheme.

GREYLIST_RDN global no List of URLs, separated with spaces,


S_URLS containing reverse DNS suffixes to put into
the greylist. Also supports file:// URLs and
and auth basic using http://user:pass@url
scheme.

GREYLIST_ASN global no List of URLs, separated with spaces,


_URLS containing ASN to put into the greylist. Also
supports file:// URLs and and auth basic
using http://user:pass@url scheme.

GREYLIST_USE global no List of URLs, separated with spaces,


R_AGENT_URL containing good User-Agent to put into the
S greylist. Also supports file:// URLs and and
auth basic using http://user:pass@url
scheme.

GREYLIST_URI global no List of URLs, separated with spaces,


_URLS containing bad URI to put into the greylist.
Also supports file:// URLs and and auth
basic using http://user:pass@url scheme.

6.18 Gzip
STREAM support

Compress HTTP requests with the gzip algorithm.

Setting Default Context Multiple Description

USE_GZIP no multisite no Use gzip

GZIP_TYPE application/atom+xml multisite no List of MIME


S application/javascript types that will
application/json application/rss+xml be compressed
application/vnd.ms-fontobject with gzip.
application/x-font-opentype
application/x-font-truetype

156 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

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

GZIP_MIN_L 1000 multisite no Minimum length


ENGTH for gzip
compression.

GZIP_COMP_ 5 multisite no The


LEVEL compression
level of the gzip
algorithm.

GZIP_PROXI no-cache no-store private expired multisite no Which kind of


ED auth proxied
requests we
should
compress.

6.19 HTML injection


STREAM support

Inject custom HTML code before the tag.

Setting Default Context Multiple Description

INJECT_BODY multisite no The HTML code to inject.

6.20 Headers
STREAM support

Manage HTTP headers sent to clients.

157 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

CUSTOM_HEA multisite yes Custom header to add


DER (HeaderName:
HeaderValue).

REMOVE_HEA Server Expect-CT X- multisite no Headers to remove (Header1


DERS Powered-By X-AspNet- Header2 Header3 ...)
Version X-AspNetMvc-
Version

KEEP_UPSTR Content-Security-Policy multisite no Headers to keep from


EAM_HEADER Permissions-Policy upstream (Header1 Header2
S Feature-Policy X-Frame- Header3 ... or * for all).
Options

STRICT_TRA max-age=31536000 multisite no Value for the Strict-Transport-


NSPORT_SEC Security header.
URITY

COOKIE_FLA * HttpOnly SameSite=Lax multisite yes Cookie flags automatically


GS added to all cookies (value
accepted for
nginx_cookie_flag_module).

COOKIE_AUT yes multisite no Automatically add the Secure


O_SECURE_F flag to all cookies.
LAG

CONTENT_SE object-src 'none'; form- multisite no Value for the Content-


CURITY_POL action 'self'; frame- Security-Policy header.
ICY ancestors 'self';

CONTENT_SE no multisite no Send reports for violations of


CURITY_POL the Content-Security-Policy
ICY_REPORT header instead of blocking
_ONLY them.

REFERRER_P strict-origin-when- multisite no Value for the Referrer-Policy


OLICY cross-origin header.

PERMISSION accelerometer=(), multisite no Value for the Permissions-


S_POLICY ambient-light-sensor=(), Policy header.
autoplay=(), battery=(),

158 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

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=()

FEATURE_PO accelerometer 'none'; multisite no Value for the Feature-Policy


LICY ambient-light-sensor header.
'none'; autoplay 'none';
battery 'none'; camera
'none'; display-capture
'none'; document-domain
'none'; encrypted-media
'none'; execution-while-
not-rendered 'none';
execution-while-out-of-
viewport 'none';
fullscreen 'none';
geolocation 'none';
gyroscope 'none';
layout-animation 'none';
legacy-image-formats
'none'; magnetometer
'none'; microphone
'none'; midi 'none';
navigation-override
'none'; payment 'none';
picture-in-picture

159 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

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

X_FRAME_OP SAMEORIGIN multisite no Value for the X-Frame-


TIONS Options header.

X_CONTENT_ nosniff multisite no Value for the X-Content-


TYPE_OPTIO Type-Options header.
NS

X_XSS_PROT 1; mode=block multisite no Value for the X-XSS-


ECTION Protection header.

6.21 Let's Encrypt


STREAM support

Automatic creation, renewal and configuration of Let's Encrypt certificates.

Setting Default Context Multiple Description

AUTO_LETS_ENC no multisite no Activate automatic Let's Encrypt mode.


RYPT

EMAIL_LETS_EN multisite no Email used for Let's Encrypt notification


CRYPT and in certificate.

USE_LETS_ENCR no multisite no Use the staging environment for Let’s


YPT_STAGING Encrypt certificate generation. Useful when
you are testing your deployments to avoid
being rate limited in the production
environment.

160 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

LETS_ENCRYPT_ no global no Clear old certificates when renewing.


CLEAR_OLD_CER
TS

6.22 Let's Encrypt DNS (PRO)


STREAM support

Automatic creation, renewal and configuration of Let's Encrypt certificates using DNS challenges.

Setting Default Context Multiple Description

AUTO_LETS_ENCR no multisite no Activate automatic Let's Encrypt DNS.


YPT_DNS

LETS_ENCRYPT_D multisite no The email address to use for Let's


NS_EMAIL Encrypt notifications.

USE_LETS_ENCRY no multisite no Use the Let's Encrypt staging


PT_DNS_STAGING environment.

LETS_ENCRYPT_D multisite no The DNS provider to use for DNS


NS_PROVIDER challenges.

USE_LETS_ENCRY yes multisite no Create wildcard certificates for all


PT_DNS_WILDCAR domains using DNS challenges.
D

LETS_ENCRYPT_D default multisite no The time to wait for DNS propagation in


NS_PROPAGATION seconds.

LETS_ENCRYPT_D multisite yes Configuration item that will be added to


NS_CREDENTIAL_ the credentials.ini file for the DNS
ITEM provider (e.g. 'cloudflare_api_token
123456').

LETS_ENCRYPT_D no global no Clear old certificates when renewing.


NS_CLEAR_OLD_C
ERTS

161 / 263
BunkerWeb documentation v1.5.8

6.23 Limit
STREAM support

Limit maximum number of requests and connections.

Setting Default Context Multiple Description

USE_LIMIT_REQ yes multisite no Activate limit requests feature.

LIMIT_REQ_URL / multisite yes URL (PCRE regex) where the limit


request will be applied or special value /
for all requests.

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

USE_LIMIT_CON yes multisite no Activate limit connections feature.


N

LIMIT_CONN_MAX 10 multisite no Maximum number of connections per IP


_HTTP1 when using HTTP/1.X protocol.

LIMIT_CONN_MAX 100 multisite no Maximum number of streams per IP when


_HTTP2 using HTTP/2 protocol.

LIMIT_CONN_MAX 10 multisite no Maximum number of connections per IP


_STREAM when using stream.

6.24 Metrics
STREAM support

Metrics collection and retrieve.

Setting Default Context Multiple Description

USE_METRICS yes multisite no Enable collection and retrieval of


internal metrics.

METRICS_MEMORY_SIZ 16m global no Size of the internal storage for


E metrics.

162 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

METRICS_MAX_BLOCKED 100 global no Maximum number of blocked


_REQUESTS requests to store (per worker).

6.25 Migration (PRO)


STREAM support

Migration of BunkerWeb configuration between instances made easy via the web UI

6.26 Miscellaneous
STREAM support

Miscellaneous settings.

Setting Default Context Multiple Description

DISABLE_DEFA no global no Deny HTTP request if the request vhost is


ULT_SERVER unknown.

DISABLE_DEFA no global no Close SSL/TLS connection if the SNI is


ULT_SERVER_S unknown.
TRICT_SNI

REDIRECT_HTT no multisite no Redirect all HTTP request to HTTPS.


P_TO_HTTPS

AUTO_REDIREC yes multisite no Try to detect if HTTPS is used and


T_HTTP_TO_HT activate HTTP to HTTPS redirection if
TPS that's the case.

ALLOWED_METH GET|POST|HE multisite no Allowed HTTP and WebDAV methods,


ODS AD separated with pipes to be sent by clients.

MAX_CLIENT_S 10m multisite no Maximum body size (0 for infinite).


IZE

SERVE_FILES yes multisite no Serve files from the local folder.

163 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

ROOT_FOLDER multisite no Root folder containing files to serve


(/var/www/html/{server_name} if unset).

SSL_PROTOCOL TLSv1.2 multisite no The supported version of TLS. We


S TLSv1.3 recommend the default value TLSv1.2
TLSv1.3 for compatibility reasons.

HTTP2 yes multisite no Support HTTP2 protocol when HTTPS is


enabled.

HTTP3 no multisite no Support HTTP3 protocol when HTTPS is


enabled.

HTTP3_ALT_SV 443 multisite no HTTP3 alternate service port. This value


C_PORT will be used as part of the Alt-Svc header.

LISTEN_HTTP yes multisite no Respond to (insecure) HTTP requests.

USE_OPEN_FIL no multisite no Enable open file cache feature


E_CACHE

OPEN_FILE_CA max=1000 multisite no Open file cache directive


CHE inactive=20
s

OPEN_FILE_CA yes multisite no Enable open file cache for errors


CHE_ERRORS

OPEN_FILE_CA 2 multisite no Enable open file cache minimum uses


CHE_MIN_USES

OPEN_FILE_CA 30s multisite no Open file cache valid time


CHE_VALID

EXTERNAL_PLU global no List of external plugins URLs (direct


GIN_URLS download to .zip or .tar file) to download
and install (URLs are separated with
space).

164 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

DENY_HTTP_ST 403 global no HTTP status code to send when the


ATUS request is denied (403 or 444). When
using 444, BunkerWeb will close the
connection.

SEND_ANONYMO yes global no Send anonymous report to BunkerWeb


US_REPORT maintainers.

6.27 ModSecurity
STREAM support

Management of the ModSecurity WAF.

Setting Default Context Multiple Description

USE_MODSECURITY yes multisite no Enable ModSecurity WAF.

USE_MODSECURITY_C yes multisite no Enable OWASP Core Rule Set.


RS

MODSECURITY_CRS_V 3 multisite no Version of the OWASP Core Rule Set


ERSION to use with ModSecurity (3, 4 or
nightly).

MODSECURITY_SEC_A RelevantOn multisite no SecAuditEngine directive of


UDIT_ENGINE ly ModSecurity.

MODSECURITY_SEC_R On multisite no SecRuleEngine directive of


ULE_ENGINE ModSecurity.

MODSECURITY_SEC_A ABCFHZ multisite no SecAuditLogParts directive of


UDIT_LOG_PARTS ModSecurity.

6.28 Monitoring (PRO)


STREAM support

BunkerWeb monitoring pro system. This plugin is a prerequisite for some other plugins.

165 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

USE_MONITORING yes global no Enable monitoring of BunkerWeb.

MONITORING_METRIC 10M global no Size of the dict to store monitoring


S_DICT_SIZE metrics.

MONITORING_IGNORE global no List of URLs to ignore when


_URLS monitoring separated with spaces
(e.g. /health)

6.29 PHP
STREAM support

Manage local or remote PHP-FPM.

Setting Default Context Multiple Description

REMOTE_PHP multisite no Hostname of the remote PHP-FPM


instance.

REMOTE_PHP_PA multisite no Root folder containing files in the remote


TH PHP-FPM instance.

LOCAL_PHP multisite no Path to the PHP-FPM socket file.

LOCAL_PHP_PAT multisite no Root folder containing files in the local


H PHP-FPM instance.

6.30 Pro
STREAM support

Pro settings for the Pro version of BunkerWeb.

Setting Default Context Multiple Description

PRO_LICENSE_KE global no The License Key for the Pro version of


Y BunkerWeb.

166 / 263
BunkerWeb documentation v1.5.8

6.31 Prometheus exporter (PRO)


STREAM support

Prometheus exporter for BunkerWeb internal metrics.

Setting Default Context Multiple Description

USE_PROMETHEUS no global no Enable the Prometheus


_EXPORTER export.

PROMETHEUS_EXP 0.0.0.0 global no Listening IP of the


ORTER_IP Prometheus exporter.

PROMETHEUS_EXP 9113 global no Listening port of the


ORTER_PORT Prometheus exporter.

PROMETHEUS_EXP /metrics global no HTTP URL of the


ORTER_URL Prometheus exporter.

PROMETHEUS_EXP 127.0.0.0/8 global no List of IP/networks allowed


ORTER_ALLOW_IP 10.0.0.0/8 to contact the Prometheus
172.16.0.0/12 exporter endpoint.
192.168.0.0/16

6.32 Real IP
STREAM support

Get real IP of clients when BunkerWeb is behind a reverse proxy / load balancer.

Setting Default Context Multiple Description

USE_REAL_I no multisite no Retrieve the real IP of client.


P

USE_PROXY_P no multisite no Enable PROXY protocol communication.


ROTOCOL

REAL_IP_FRO 192.168.0.0/1 multisite no List of trusted IPs / networks, separated


M 6 with spaces, where proxied requests
come from.

167 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

172.16.0.0/12
10.0.0.0/8

REAL_IP_HEA X-Forwarded- multisite no HTTP header containing the real IP or


DER For special value proxy_protocol for PROXY
protocol.

REAL_IP_REC yes multisite no Perform a recursive search in the header


URSIVE container IP address.

REAL_IP_FRO global no List of URLs containing trusted IPs /


M_URLS networks, separated with spaces, where
proxied requests come from. Also
supports file:// URLs and and auth basic
using http://user:pass@url scheme.

6.33 Redirect
STREAM support

Manage HTTP redirects.

Setting Default Context Multiple Description

REDIRECT_TO multisite no Redirect a whole site to another one.

REDIRECT_TO_REQUES no multisite no Append the requested URI to the


T_URI redirect address.

REDIRECT_TO_STATUS 301 multisite no Status code to send to client when


_CODE redirecting.

6.34 Redis
STREAM support

Redis server configuration when using BunkerWeb in cluster mode.

168 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

USE_REDIS no global no Activate Redis.

REDIS_HOST global no Redis server IP or hostname.

REDIS_PORT 6379 global no Redis server port.

REDIS_DATABASE 0 global no Redis database number.

REDIS_SSL no global no Use SSL/TLS connection with Redis


server.

REDIS_SSL_VERIFY no global no Verify the certificate of Redis server.

REDIS_TIMEOUT 1000 global no Redis server timeout (in ms) for


connect, read and write.

REDIS_USERNAME global no Redis username used in AUTH


command.

REDIS_PASSWORD global no Redis password used in AUTH


command.

REDIS_SENTINEL_H global no Redis sentinel hosts with format host:


OSTS [port] separated with spaces.

REDIS_SENTINEL_U global no Redis sentinel username.


SERNAME

REDIS_SENTINEL_P global no Redis sentinel password.


ASSWORD

REDIS_SENTINEL_M global no Redis sentinel master name.


ASTER

REDIS_KEEPALIVE_ 30000 global no Max idle time (in ms) before closing
IDLE redis connection in the pool.

REDIS_KEEPALIVE_ 10 global no Max number of redis connection(s)


POOL kept in the pool.

169 / 263
BunkerWeb documentation v1.5.8

6.35 Reporting (PRO)


STREAM support

Regular reporting of important data from BunkerWeb (global, attacks, bans, requests, reasons, AS...). Monitoring pro
plugin needed to work.

Setting Default Context Multiple Description

USE_REPORTING_ no global no Enable sending the report via email.


SMTP

USE_REPORTING_ no global no Enable sending the report via webhook.


WEBHOOK

REPORTING_SCHE weekly global no The frequency at which reports are sent.


DULE

REPORTING_WEBH global no List of webhook URLs to receive the


OOK_URLS report in Markdown (separated by
spaces).

REPORTING_SMTP global no List of email addresses to receive the


_EMAILS report in HTML format (separated by
spaces).

REPORTING_SMTP global no The host server used for SMTP sending.


_HOST

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

REPORTING_SMTP global no The email address used as the sender.


_FROM_EMAIL Note that 2FA must be disabled for this
email address.

REPORTING_SMTP global no The user authentication value for


_FROM_USER sending via the from email address.

REPORTING_SMTP global no The password authentication value for


_FROM_PASSWOR sending via the from email address.

170 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

REPORTING_SMTP SSL global no Determine whether or not to use a


_SSL secure connection for SMTP.

REPORTING_SMTP BunkerWeb global no The subject line of the email.


_SUBJECT Report

6.36 Reverse proxy


STREAM support

Manage reverse proxy configurations.

Setting Default Context Multiple Description

USE_REVERSE no multisite no Activate reverse proxy mode.


_PROXY

REVERSE_PRO yes multisite no Intercept and rewrite errors.


XY_INTERCEP
T_ERRORS

REVERSE_PRO multisite no Override Host header sent to upstream


XY_CUSTOM_H server.
OST

REVERSE_PRO multisite yes Full URL of the proxied resource


XY_HOST (proxy_pass).

REVERSE_PRO / multisite yes Location URL that will be proxied.


XY_URL

REVERSE_PRO no multisite yes Enable websocket on the proxied resource.


XY_WS

REVERSE_PRO multisite yes List of HTTP headers to send to proxied


XY_HEADERS resource separated with semicolons (values
for proxy_set_header directive).

171 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

REVERSE_PRO multisite yes List of HTTP headers to send to client


XY_HEADERS_ separated with semicolons (values for
CLIENT add_header directive).

REVERSE_PRO yes multisite yes Enable or disable buffering of responses


XY_BUFFERIN from proxied resource.
G

REVERSE_PRO no multisite yes Enable or disable keepalive connections


XY_KEEPALIV with the proxied resource.
E

REVERSE_PRO multisite yes Enable authentication using an external


XY_AUTH_REQ provider (value of auth_request directive).
UEST

REVERSE_PRO multisite yes Redirect clients to sign-in URL when using


XY_AUTH_REQ REVERSE_PROXY_AUTH_REQUEST
UEST_SIGNIN (used when auth_request call returned
_URL 401).

REVERSE_PRO multisite yes List of variables to set from the


XY_AUTH_REQ authentication provider, separated with
UEST_SET semicolons (values of auth_request_set
directives).

REVERSE_PRO 60s multisite yes Timeout when connecting to the proxied


XY_CONNECT_ resource.
TIMEOUT

REVERSE_PRO 60s multisite yes Timeout when reading from the proxied
XY_READ_TIM resource.
EOUT

REVERSE_PRO 60s multisite yes Timeout when sending to the proxied


XY_SEND_TIM resource.
EOUT

REVERSE_PRO multisite yes Additional configuration to include in the


XY_INCLUDE location block, separated with spaces.
S

172 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

USE_PROXY_C no multisite no Enable or disable caching of the proxied


ACHE resources.

PROXY_CACHE 1:2 global no Hierarchy levels of the cache.


_PATH_LEVEL
S

PROXY_CACHE 10m global no Maximum size of cached metadata when


_PATH_ZONE_ caching proxied resources.
SIZE

PROXY_CACHE max_size=10 global no Additional parameters to add to the


_PATH_PARAM 0m proxy_cache directive.
S

PROXY_CACHE GET HEAD multisite no HTTP methods that should trigger a cache
_METHODS operation.

PROXY_CACHE 2 multisite no The minimum number of requests before a


_MIN_USES response is cached.

PROXY_CACHE $scheme$hos multisite no The key used to uniquely identify a cached


_KEY t$request_u response.
ri

PROXY_CACHE 200=24h multisite no Define the caching time depending on the


_VALID 301=1h HTTP status code (list of status=time),
302=24h separated with spaces.

PROXY_NO_CA $http_pragm multisite no Conditions to disable caching of responses.


CHE a
$http_autho
rization

PROXY_CACHE 0 multisite no Conditions to bypass caching of responses.


_BYPASS

6.37 Reverse scan


STREAM support

173 / 263
BunkerWeb documentation v1.5.8

Scan clients ports to detect proxies or servers.

Setting Default Context Multiple Description

USE_REVERSE_SC no multisite no Enable scanning of clients ports


AN and deny access if one is opened.

REVERSE_SCAN_P 22 80 443 3128 multisite no List of port to scan when using


ORTS 8000 8080 reverse scan feature.

REVERSE_SCAN_T 500 multisite no Specify the maximum timeout (in


IMEOUT ms) when scanning a port.

6.38 Self-signed certificate


STREAM support

Generate self-signed certificate.

Setting Default Context Multiple Description

GENERATE_SELF_SIGN no multisite no Generate and use self-


ED_SSL signed certificate.

SELF_SIGNED_SSL_EX 365 multisite no Self-signed certificate expiry


PIRY in days.

SELF_SIGNED_SSL_SU /CN=www.example. multisite no Self-signed certificate


BJ com/ subject.

6.39 Sessions
STREAM support

Management of session used by other plugins.

Setting Default Context Multiple Description

SESSIONS_SECRET random global no Secret used to encrypt sessions


variables for storing data related to

174 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

challenges.

SESSIONS_NAME random global no Name of the cookie given to clients.

SESSIONS_IDLING_ 1800 global no Maximum time (in seconds) of inactivity


TIMEOUT before the session is invalidated.

SESSIONS_ROLLING 3600 global no Maximum time (in seconds) before a


_TIMEOUT session must be renewed.

SESSIONS_ABSOLUT 86400 global no Maximum time (in seconds) before a


E_TIMEOUT session is destroyed.

SESSIONS_CHECK_I yes global no Destroy session if IP address is


P different than original one.

SESSIONS_CHECK_U yes global no Destroy session if User-Agent is


SER_AGENT different than original one.

6.40 UI
STREAM support

Integrate easily the BunkerWeb UI.

Setting Default Context Multiple Description

USE_UI no multisite no Use UI

UI_HOST global no Address of the web UI used for initial setup

6.41 Whitelist
STREAM support

Allow access based on internal and external IP/network/rDNS/ASN whitelists.

175 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

USE_WHITELI yes multisite no Activate whitelist feature.


ST

WHITELIST_I 20.191.45.212 multisite no List of IP/network, separated


P 40.88.21.235 with spaces, to put into the
40.76.173.151 whitelist.
40.76.163.7
20.185.79.47
52.142.26.175
20.185.79.15
52.142.24.149
40.76.162.208
40.76.163.23
40.76.162.191
40.76.162.247

WHITELIST_R .google.com multisite no List of reverse DNS suffixes,


DNS .googlebot.com separated with spaces, to
.yandex.ru .yandex.net whitelist.
.yandex.com
.search.msn.com
.baidu.com .baidu.jp
.crawl.yahoo.net
.fwd.linkedin.com
.twitter.com
.twttr.com
.discord.com

WHITELIST_R yes multisite no Only perform RDNS whitelist


DNS_GLOBAL checks on global IP addresses.

WHITELIST_A 32934 multisite no List of ASN numbers,


SN separated with spaces, to
whitelist.

WHITELIST_U multisite no List of User-Agent (PCRE


SER_AGENT regex), separated with spaces,
to whitelist.

WHITELIST_U multisite no List of URI (PCRE regex),


RI separated with spaces, to
whitelist.

176 / 263
BunkerWeb documentation v1.5.8

Setting Default Context Multiple Description

WHITELIST_I global no List of URLs, separated with


P_URLS spaces, containing good
IP/network to whitelist. Also
supports file:// URLs and and
auth basic using
http://user:pass@url scheme.

WHITELIST_R global no List of URLs, separated with


DNS_URLS spaces, containing reverse
DNS suffixes to whitelist. Also
supports file:// URLs and and
auth basic using
http://user:pass@url scheme.

WHITELIST_A global no List of URLs, separated with


SN_URLS spaces, containing ASN to
whitelist. Also supports file://
URLs and and auth basic using
http://user:pass@url scheme.

WHITELIST_U global no List of URLs, separated with


SER_AGENT_U spaces, containing good User-
RLS Agent to whitelist. Also
supports file:// URLs and and
auth basic using
http://user:pass@url scheme.

WHITELIST_U global no List of URLs, separated with


RI_URLS spaces, containing bad URI to
whitelist. Also supports file://
URLs and and auth basic using
http://user:pass@url scheme.

177 / 263
BunkerWeb documentation v1.5.8

7 Web UI

7.1 Overview

BunkerWeb - user interface demo

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 settings for your web applications

Add, edit and delete custom configurations for NGINX and ModSecurity

Install and uninstall external plugins

Explore the cached files

Monitor jobs execution

View the logs and search pattern

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)

Put the web UI under a "hard to guess" URI

Do not open the web UI on the Internet without any further restrictions

Apply settings listed in the security tuning section of the documentation

Please note that using HTTPS in front the web UI is mandatory since version 1.5.8 of BunkerWeb.

Multisite mode

The usage of the web UI implies enabling the multisite mode.

7.4 Setup wizard

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

Figure 15: Account section of the setup wizard

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

Figure 16: Settings section of the setup wizard

Configure the following settings :

UI Host : internal http endpoint of your web UI

UI URL : the public path where your web UI will be accessible

Server name : the public server name where your web UI will be accessible

Auto let's encrypt : enable/disable HTTPS using automated let's encrypt

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 .

Accessing the setup wizard

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 .

Accessing the setup wizard

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 .

Accessing the setup wizard

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 .

Accessing the setup wizard

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

Accessing the setup wizard

You can access the setup wizard by browsing the https://your-ip-address/setup URI of your server.

7.5 Account management


You can access the account management page by clicking on manage account inside the sidebar menu :

195 / 263
BunkerWeb documentation v1.5.8

Figure 17: Account page access from menu

7.5.1 Upgrade to PRO

What is BunkerWeb PRO ?

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.

Figure 18: Upgrade to PRO from the web UI

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

Figure 19: PRO license information

7.5.2 Username / Password

Overriding admin credentials from environment variables

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 )

ADMIN_USERNAME : username to access the web UI

ADMIN_PASSWORD : password to access the web UI

The web UI will use these variables to authenticate you.

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

Figure 20: Username / Password forms

7.5.3 Two-Factor Authentication

Lost secret key

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

Enter the current TOTP code in the 2FA input

Enter your current password

198 / 263
BunkerWeb documentation v1.5.8

Secret key refresh

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.

Once enabled, 2FA authentication can be disabled at the same place.

Figure 21: TOTP enable / disable forms

After a successful login/password combination, you will be prompted to enter your TOTP code :

199 / 263
BunkerWeb documentation v1.5.8

Figure 22: Additional TOTP page

7.6 Advanced installation

200 / 263
BunkerWeb documentation v1.5.8

Docker

The web UI can be deployed using a dedicated container which is available on Docker Hub :

docker pull bunkerity/bunkerweb-ui

Alternatively, you can also build it yourself :

git clone https://github.com/bunkerity/bunkerweb.git && \


cd bunkerweb && \
docker build -t my-bunkerweb-ui -f src/ui/Dockerfile .

The following environment variables are used to configure the web UI container :

ADMIN_USERNAME : username to access the web UI

ADMIN_PASSWORD : password to access the web UI

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

stronger password for the database


- DOCKER_HOST=tcp://bw-docker:2375
- ADMIN_USERNAME=changeme
- ADMIN_PASSWORD=changeme # Remember to set a stronger password for the changeme user
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 # 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 :

docker pull bunkerity/bunkerweb-ui

Alternatively, you can also build it yourself :

git clone https://github.com/bunkerity/bunkerweb.git && \


cd bunkerweb && \
docker build -t my-bunkerweb-ui -f src/ui/Dockerfile .

The following environment variables are used to configure the web UI container :

ADMIN_USERNAME : username to access the web UI

ADMIN_PASSWORD : password to access the web UI

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 :

docker pull bunkerity/bunkerweb-ui

Alternatively, you can also build it yourself :

206 / 263
BunkerWeb documentation v1.5.8

git clone https://github.com/bunkerity/bunkerweb.git && \


cd bunkerweb && \
docker build -t my-bunkerweb-ui -f src/ui/Dockerfile .

The following environment variables are used to configure the web UI container :

ADMIN_USERNAME : username to access the web UI

ADMIN_PASSWORD : password to access the web UI

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 :

ADMIN_USERNAME : username to access the web UI

ADMIN_PASSWORD : password to access the web UI

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 :

systemctl enable bunkerweb-ui

A dedicated environment file located at /etc/bunkerweb/ui.env is used to configure the web UI :

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 :

systemctl restart bunkerweb-ui

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.

Here is the /etc/bunkerweb/variables.env boilerplate you can use :

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

Don't forget to reload the bunkerweb service :

systemctl reload bunkerweb

217 / 263
BunkerWeb documentation v1.5.8

8 Upgrading

8.1 Upgrade from 1.5.X

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

1. Backup the database:

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

1.5.7 and later

219 / 263
BunkerWeb documentation v1.5.8

Docker

docker exec -it -e BACKUP_DIRECTORY=/path/to/backup/directory <scheduler_container> bwcli


plugin backup save

docker cp <scheduler_container>:/path/to/backup/directory /path/to/backup/directory

Linux

Information for Red Hat Enterprise Linux (RHEL) 8.9 users

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

a. Install the MySQL repository configuration package

sudo dnf install https://dev.mysql.com/get/mysql80-community-release-el8-9.noarch.rpm

b. Enable the MySQL repository

sudo dnf config-manager --enable mysql80-community

c. Install the MySQL client

sudo dnf install mysql-community-client

PostgreSQL

a. Install the PostgreSQL repository configuration package

dnf install "https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-$(uname -m)/pgdg-


redhat-repo-latest.noarch.rpm"

b. Install the PostgreSQL client

dnf install postgresql<version>

BACKUP_DIRECTORY=/path/to/backup/directory bwcli plugin backup save

220 / 263
BunkerWeb documentation v1.5.8

1.5.6 and earlier

SQLite

Docker

We first need to install the sqlite package in the container.

docker exec -u 0 -it <scheduler_container> apk add sqlite

Then, backup the database.

docker exec -it <scheduler_container> sqlite3 /var/lib/bunkerweb/db.sqlite3 ".dump" >


/path/to/backup/directory/backup.sql

Linux

sqlite3 /var/lib/bunkerweb/db.sqlite3 ".dump" > /path/to/backup/directory/backup.sql

MySQL/MariaDB

Docker

docker exec -it <database_container> mysqldump -u <username> -p <database_name> >


/path/to/backup/directory/backup.sql

Linux

mysqldump -u <username> -p <database_name> > /path/to/backup/directory/backup.sql

PostgreSQL

Docker

docker exec -it <database_container> pg_dump -U <username> -d <database_name> >


/path/to/backup/directory/backup.sql

Linux

pg_dump -U <username> -d <database_name> > /path/to/backup/directory/backup.sql

2. Upgrade BunkerWeb:

Upgrade BunkerWeb to the latest version.

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

b. Restart the containers: Restart the containers to apply the changes.

docker compose down


docker compose up -d

Linux

a. Stop the services:

systemctl stop bunkerweb


systemctl stop bunkerweb-ui

b. Update BunkerWeb:

222 / 263
BunkerWeb documentation v1.5.8

Debian/Ubuntu

First, if you have previously hold the BunkerWeb package, unhold it :

You can print a list of packages on hold with apt-mark showhold

sudo apt-mark unhold bunkerweb

Them, you can update BunkerWeb package :

sudo apt install -y bunkerweb=1.5.8

To prevent upgrading BunkerWeb package when executing apt upgrade , you can use the following
command :

sudo apt-mark hold bunkerweb

More details in the integration Linux page.

Fedora/RedHat

First, if you have previously hold the BunkerWeb package, unhold it :

You can print a list of packages on hold with dnf versionlock list

sudo dnf versionlock delete package bunkerweb

Them, you can update BunkerWeb package :

sudo dnf install -y bunkerweb-1.5.8

To prevent upgrading BunkerWeb package when executing dnf upgrade , you can use the following
command :

sudo dnf versionlock add bunkerweb

More details in the integration Linux page.

3. Check the logs: Check the logs of the scheduler service to ensure that the migration was successful.

Docker

docker compose logs <scheduler_container>

Linux

journalctl -u bunkerweb --no-pager

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.

Get support and more information :

Order professional support

Create an issue on GitHub

Join the BunkerWeb Discord server

224 / 263
BunkerWeb documentation v1.5.8

Docker

1. Restore the backup.

225 / 263
BunkerWeb documentation v1.5.8

SQLite

a. Stop the Stack.

docker compose down

b. Remove the existing database file.

docker exec -u 0 -i <scheduler_container> rm -f /var/lib/bunkerweb/db.sqlite3

c. Restore the backup.

docker exec -i -T <scheduler_container> sqlite3 /var/lib/bunkerweb/db.sqlite3 <


/path/to/backup/directory/backup.sql

d. Fix permissions.

docker exec -u 0 -i <scheduler_container> chown root:nginx /var/lib/bunkerweb/db.sqlite3


docker exec -u 0 -i <scheduler_container> chmod 770 /var/lib/bunkerweb/db.sqlite3

MySQL/MariaDB

a. Stop the Stack.

docker compose down

b. Restore the backup.

docker exec -e MYSQL_PWD=<your_password> -i -T <database_container> mysql -u <username>


<database_name> < /path/to/backup/directory/backup.sql

PostgreSQL

a. Stop the Stack.

docker compose down

b. Remove the existing database.

docker exec -i <database_container> dropdb -U <username> --force <database_name>

c. Recreate the database.

docker exec -i <database_container> createdb -U <username> <database_name>

226 / 263
BunkerWeb documentation v1.5.8

d. Restore the backup.

docker exec -i -T <database_container> psql -U <username> -d <database_name> <


/path/to/backup/directory/backup.sql

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

3. Start the containers.

docker compose up -d

Linux

1. Stop the services.

systemctl stop bunkerweb bunkerweb-ui

2. Restore the backup.

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

mysql -u <username> -p <database_name> < /path/to/backup/directory/backup.sql

PostgreSQL

a. Remove the existing database.

dropdb -U <username> --force <database_name>

b. Recreate the database.

createdb -U <username> <database_name>

c. Restore the backup.

psql -U <username> -d <database_name> < /path/to/backup/directory/backup.sql

3. Downgrade BunkerWeb.

Downgrade BunkerWeb to the previous version by following the same steps as when upgrading BunkerWeb
in the integration Linux page

8.2 Upgrade from 1.4.X

Read this if you were a 1.4.X user

A lot of things changed since the 1.4.X releases. Container-based integrations stacks contain more services but, trust
us, fundamental principles of BunkerWeb are still there. You will find ready to use boilerplates for various integrations in
the misc/integrations 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.

You will find more information about the scheduler here.

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 :

Backup of the current configuration

Usage with multiple services (scheduler, web UI, ...)

Upgrade to a new BunkerWeb version

Please note that we actually support, SQLite, MySQL, MariaDB and PostgreSQL as backends.

You will find more information about the database here.

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.

We actually support Redis as a backend for the shared data store.

See the list of redis settings and the corresponding documentation of your integration for more information.

8.2.4 Default values and new settings

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

docker logs mybunker

Here is the docker-compose equivalent (replace mybunker with the name of the services declared in the docker-
compose.yml file) :

docker-compose logs mybunker

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

docker logs mybunker


docker logs myautoconf

Here is the docker-compose equivalent (replace mybunker and myautoconf with the name of the services declared
in the docker-compose.yml file) :

docker-compose logs mybunker


docker-compose logs myautoconf

Swarm

231 / 263
BunkerWeb documentation v1.5.8

List services

To list the services, you can use the following command :

docker service ls

You can use the docker service logs command (replace mybunker and myautoconf with the name of your
services) :

docker service logs mybunker


docker service logs myautoconf

Kubernetes

List pods

To list the pods, you can use the following command :

kubectl get pods

You can use the kubectl logs command (replace mybunker and myautoconf with the name of your pods) :

kubectl logs mybunker


kubectl logs myautoconf

Linux

For errors related to BunkerWeb services (e.g. not starting), you can use journalctl :

journalctl -u bunkerweb --no-pager

Common logs are located inside the /var/log/bunkerweb directory :

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.3 Disable security checks


For debugging purposes, you may need to temporarily disable the security checks made by BunkerWeb. One quick
way of doing it is by adding everyone in the whitelist (e.g. WHITELIST_IP=0.0.0.0/0 ).

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"

As we can see, there are 3 different logs :

1. Rule 930120 matched

2. Rule 932160 matched

3. Access denied (rule 949110)

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.5 Bad Behavior


A common false-positive case is when the client is banned because of the "bad behavior" feature which means that
too many suspicious HTTP status codes were generated within a time period (more info here). You should start by
reviewing the settings and then edit them according to your web application(s) like removing a suspicious HTTP
code, decreasing the count time, increasing the threshold, ...

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

docker exec mybunker bwcli unban 1.2.3.4

Here is the docker-compose equivalent (replace mybunker with the name of the services declared in the docker-
compose.yml file) :

docker-compose exec mybunker bwcli unban 1.2.3.4

Docker autoconf

You can use the docker exec command (replace myautoconf with the name of your container) :

docker exec myautoconf bwcli unban 1.2.3.4

Here is the docker-compose equivalent (replace myautoconf with the name of the services declared in the docker-
compose.yml file) :

docker-compose exec myautoconf bwcli unban 1.2.3.4

Swarm

You can use the docker exec command (replace myautoconf with the name of your service) :

docker exec $(docker ps -q -f name=myautoconf) bwcli unban 1.2.3.4

Kubernetes

You can use the kubectl exec command (replace myautoconf with the name of your pod) :

kubectl exec myautoconf bwcli unban 1.2.3.4

Linux

You can use the bwcli command (as root) :

sudo bwcli unban 1.2.3.4

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 :

Healthcheck / status bot

Callback like IPN or webhook

Social media crawler

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

Install SQLite (Debian/Ubuntu) :

sudo apt install sqlite3

Install SQLite (Fedora/RedHat) :

sudo dnf install sqlite

Docker

Get a shell into your scheduler container :

Docker arguments

the -u 0 option is to run the command as root (mandatory)

the -it options are to run the command interactively (mandatory)

<bunkerweb_scheduler_container> : the name or ID of your scheduler container

docker exec -u 0 -it <bunkerweb_scheduler_container> bash

Install SQLite :

apk add sqlite

Access your database :

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

You should see something like this :

238 / 263
BunkerWeb documentation v1.5.8

SQLite version <VER> <DATE>


Enter ".help" for usage hints.
sqlite>

MariaDB / MySQL

MariaDB / MySQL only

The following steps are only valid for MariaDB / MySQL databases. If you are using another database, please refer to
the documentation of your database.

Credentials and database name

You will need to use the same credentials and database named used in the DATABASE_URI setting.

Linux

Access your local database :

mysql -u <user> -p <database>

Then enter your password of the database user and you should be able to access your database.

Docker

Access your database container :

Docker arguments

the -u 0 option is to run the command as root (mandatory)

the -it options are to run the command interactively (mandatory)

<bunkerweb_db_container> : the name or ID of your database container

<user> : the database user

<database> : the database name

docker exec -u 0 -it <bunkerweb_db_container> mysql -u <user> -p <database>

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

The schema of the bw_ui_users table is the following :

id INTEGER PRIMARY KEY AUTOINCREMENT


username VARCHAR(256) NOT NULL UNIQUE
password VARCHAR(60) NOT NULL
is_two_factor_enabled BOOLEAN NOT NULL DEFAULT 0
secret_token VARCHAR(32) DEFAULT NULL
method ("manual" or "ui") NOT NULL DEFAULT 'manual'

240 / 263
BunkerWeb documentation v1.5.8

Retrieve username

Execute the following command to extract data from the bw_ui_users table :

SELECT * FROM bw_ui_users;

You should see something like this :

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.

Install the Python bcrypt library :

pip install bcrypt

Generate your hash (replace mypassword with your own password) :

python -c 'from bcrypt import hashpw, gensalt ; print(hashpw("mypassword".encode("utf-8"),


gensalt(rounds=13)).decode())'

You can update your username / password executing this command :

UPDATE bw_ui_users SET username = <username>, password = <password_hash> WHERE id = 1;

If you check again your bw_ui_users table following this command :

SELECT * FROM bw_ui_users;

You should see something like this :

1|<username>|<password_hash>|0||(manual or ui)

You should now be able to use the new credentials to log into the web UI.

Disable 2FA authentication

You can deactivate 2FA by executing this command :

UPDATE bw_ui_users SET is_two_factor_enabled = 0, secret_token = NULL WHERE id = 1;

If you check again your bw_ui_users table by following this command :

241 / 263
BunkerWeb documentation v1.5.8

SELECT * FROM bw_ui_users;

You should see something like this :

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

It may not be possible to upload a plugin from the UI in certain situations:

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.

10.1 Official plugins


Here is the list of "official" plugins that we maintain (see the bunkerweb-plugins repository for more information) :

Name Version Description Link

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

CrowdSec 1.5 CrowdSec bouncer for BunkerWeb. bunkerweb-


plugins/crowdsec

Discord 1.5 Send security notifications to a Discord channel using bunkerweb-


a Webhook. plugins/discord

Slack 1.5 Send security notifications to a Slack channel using a bunkerweb-


Webhook. plugins/slack

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.

WebHook 1.5 Send security notifications to a custom HTTP endpoint bunkerweb-


using a Webhook. plugins/webhook

10.2 How to use a plugin


10.2.1 Automatic

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.

The first thing to do is to create the plugins folder :

mkdir -p ./bw-data/plugins

Then, you can drop the plugins of your choice into that folder :

git clone https://github.com/bunkerity/bunkerweb-plugins && \


cp -rp ./bunkerweb-plugins/* ./bw-data/plugins

Using local folder for persistent data

The scheduler runs as an unprivileged user with UID 101 and GID 101 inside the container. The reason behind this is
security : in case a vulnerability is exploited, the attacker won't have full root (UID/GID 0) privileges. But there is a
downside : if you use a local folder for the persistent data, you will need to set the correct permissions so the
unprivileged user can write data to it. Something like that should do the trick :

mkdir bw-data && \


chown root:101 bw-data && \
chmod 770 bw-data

Alternatively, if the folder already exists :

chown -R root:101 bw-data && \


chmod -R 770 bw-data

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 :

grep ^$(whoami): /etc/subuid && \


grep ^$(whoami): /etc/subgid

For example, if you have a value of 100000, the mapped UID/GID will be 100100 (100000 + 100) :

mkdir bw-data && \


sudo chgrp 100100 bw-data && \
chmod 770 bw-data

Or if the folder already exists :

sudo chgrp -R 100100 bw-data && \


chmod -R 770 bw-data

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.

The first thing to do is to create the plugins folder :

mkdir -p ./bw-data/plugins

Then, you can drop the plugins of your choice into that folder :

git clone https://github.com/bunkerity/bunkerweb-plugins && \


cp -rp ./bunkerweb-plugins/* ./bw-data/plugins

Because the scheduler runs as an unprivileged user with UID and GID 101, you will need to edit the permissions :

chown -R 101:101 ./bw-data

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.

The first thing to do is to create the plugins folder :

mkdir -p /shared/bw-plugins

Then, you can drop the plugins of your choice into that folder :

git clone https://github.com/bunkerity/bunkerweb-plugins && \


cp -rp ./bunkerweb-plugins/* /shared/bw-plugins

Because the scheduler runs as an unprivileged user with UID and GID 101, you will need to edit the permissions :

chown -R 101:101 /shared/bw-plugins

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 :

git clone https://github.com/bunkerity/bunkerweb-plugins && \


cp -rp ./bunkerweb-plugins/* /etc/bunkerweb/plugins && \
chown -R nginx:nginx /etc/bunkerweb/plugins

10.3 Writing a plugin

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

What a plugin structure looks like :

plugin /
confs / conf_type / conf_name.conf
ui / actions.py
template.html
jobs / my-job.py
plugin.lua
plugin.json

conf_name.conf : add custom NGINX configurations (as jinja2 templates)

actions.py : script to execute on flask server, this script is running on flask context, you have access to lib and
utils like jinja2 , requests , etc...

template.html : custom plugin page you can access from ui

jobs py file : custom python files executed as jobs by the scheduler

plugin.lua : code to execute on NGINX using NGINX LUA module

plugin.json : metadata, settings and jobs for your settings

10.3.2 Getting started

The first step is to create a folder that will contain the plugin :

mkdir myplugin && \


cd myplugin

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

Here are the details of the fields :

Field Mandatory Type Description

id yes string Internal ID for the plugin : must be unique among other plugins
(including "core" ones) and contain only lowercase chars.

name yes string Name of your plugin.

descriptio yes string Description of your plugin.


n

version yes string Version of your plugin.

stream yes string Information about stream support : no , yes or partial .

settings yes dict List of the settings of your plugin.

jobs no list List of the jobs of your plugin.

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

Field Mandatory Type Description

context yes string Context of the setting : multisite or global .

default yes string The default value of the setting.

help yes string Help text about the plugin (shown in web UI).

id yes string Internal ID used by the web UI for HTML elements.

label yes string Label shown by the 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 .

multiple no string Unique ID to group multiple settings with numbers as suffix.

select no list List of possible string values when type is select .

Each job has the following fields :

Field Mandatory Type Description

name yes string Name of the job.

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

10.3.5.1 Main script

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

local class = require "middleclass"


local plugin = require "bunkerweb.plugin"
local utils = require "bunkerweb.utils"

local myplugin = class("myplugin", plugin)

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 :

Function Context Description Return value

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

Function Context Description Return value

prepare any data that will be used by your ret (boolean) : true if
plugin. no error or else false

msg (string) : success


or error message

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

msg (string) : success


or error message

access access_by_lua Called on each request received by the ret ,


server. The typical use case is to do the msg , status , redirect
security checks here and deny the request if
ret (boolean) : true if
needed.
no error or else false

msg (string) : success


or error message

status (number) :
interrupt current
process and return
HTTP status

redirect (URL) : if set


will redirect to given
URL

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

msg (string) : success


or error message

254 / 263
BunkerWeb documentation v1.5.8

Function Context Description Return value

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

msg (string) : success


or error message

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

msg (string) : success


or error message

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 :

local mylibrary = require "myplugin.mylibrary"

...

mylibrary.dummy()

...

10.3.5.3 Helpers

255 / 263
BunkerWeb documentation v1.5.8

Some helpers modules provide common helpful helpers :

self.variables : allows to access and store plugins' attributes

self.logger : print logs

bunkerweb.utils : various useful functions

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)

To access the functions, you first need to require the modules :

local utils = require "bunkerweb.utils"


local datastore = require "bunkerweb.datastore"
local clustestore = require "bunkerweb.clustertore"

Retrieve a setting value :

local myvar = self.variables["DUMMY_SETTING"]


if not myvar then
self.logger:log(ngx.ERR, "can't retrieve setting DUMMY_SETTING")
else
self.logger:log(ngx.NOTICE, "DUMMY_SETTING = " .. value)
end

Store something in the local cache :

local ok, err = self.datastore:set("plugin_myplugin_something", "somevalue")


if not ok then
self.logger:log(ngx.ERR, "can't save plugin_myplugin_something into datastore : " .. err)
else
self.logger:log(ngx.NOTICE, "successfully saved plugin_myplugin_something into datastore")
end

Check if an IP address is global :

local ret, err = utils.ip_is_global(ngx.ctx.bw.remote_addr)


if ret == nil then
self.logger:log(ngx.ERR, "error while checking if IP " .. ngx.ctx.bw.remote_addr .. " is
global or not : " .. err)
elseif not ret then
self.logger:log(ngx.NOTICE, "IP " .. ngx.ctx.bw.remote_addr .. " is not global")
else
self.logger:log(ngx.NOTICE, "IP " .. ngx.ctx.bw.remote_addr .. " is global")
end

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.

10.3.7 Plugin page

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 :

template.html that will be accessible with a GET /plugins/<plugin_id>.

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.

10.3.7.2 Basic example

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 :

<p>request args : {{ request.args.get() }}.</p>

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 :

<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />

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

You have two functions by default in actions.py :

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>

BunkerWeb will send you this type of response :

return jsonify({"status": "ok|ko", "code" : XXX, "data": <pre_render_data>}), 200

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

BunkerWeb will send you this type of response :

return jsonify({"message": "ok", "data": <plugin_id_data>}), 200

What you can access from action.py

Here are the arguments that are passed and access on action.py functions:

function(app=app, args=request.args.to_dict() or request.json or None)

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

Retrieve form submitted data

from flask import request

def myplugin(**kwargs) :
my_form_value = request.form["my_form_input"]
return my_form_value

258 / 263
BunkerWeb documentation v1.5.8

Access app config

action.py

from flask import request

def pre_render(**kwargs) :
config = kwargs['app'].config["CONFIG"].get_config(methods=False)
return config

template

<!-- metadata + config -->


<div>{{ pre_render }}</div>

259 / 263
BunkerWeb documentation v1.5.8

11 Professional services

11.1 Why should I get professional services ?


Since BunkerWeb is a free (as in freedom) software, you've the right to use it freely as long as you respect the
AGPLv3 license.

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.

11.2 Which professional services do you offer ?


We offer technical support around the BunkerWeb solution. By using this service, we will assist you on the technical
issues (installation, configuration, false positive, ...).

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 :

Consulting : a dedicated expert will give you advices on your project

Development : if you need specific features in BunkerWeb, we can do it for you

11.3 How can I get more information ?


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.

260 / 263
BunkerWeb documentation v1.5.8

12 About

12.1 Who maintains BunkerWeb ?


BunkerWeb is maintained by Bunkerity, a French 🇫🇷 company specialized in Cybersecurity 🛡️.
12.2 Do you have a professional version ?
Yes, we do offer a professional version of BunkerWeb called "BunkerWeb PRO".

Here are the main benefits of BunkerWeb PRO :

Unlock all features of BunkerWeb

Pay per protected services

Respond to professional needs

Free trial with no credit card

Best effort support included

You can go the BunkerWeb panel to get more information and claim your free trial.

12.3 Do you offer professional services ?


Yes, we offer professional services related to BunkerWeb.

You can get in touch with us about any of the following :

Consulting

Support

Custom development

Partnership

We have a dedicated panel to centralize all professional requests.

You can also contact use at [email protected] if you are interested.

12.4 Where to get community support ?


To get free community support, you can use the following media :

The #help channel of BunkerWeb in the Discord server

The help category of GitHub discussions

261 / 263
BunkerWeb documentation v1.5.8

The /r/BunkerWeb subreddit

The Server Fault and Super User forums

Please don't use GitHub issues to ask for help, use it only for bug reports and feature requests.

12.5 How can I contribute ?


Here is a non-exhaustive list of what you can do :

Join the Discord server, /r/BunkerWeb subreddit and GitHub discussions to talk about the project and help others

Follow us on LinkedIn, Twitter and GitHub

Report bugs and propose new features using issues

Contribute to the code using pull requests

Write an awesome plugin

Talk about BunkerWeb to your friends/colleagues, on social media, on your blog, ...

12.6 How to report security issue ?


Please contact us at [email protected] using the following PGP key :

262 / 263
BunkerWeb documentation v1.5.8

-----BEGIN PGP PUBLIC KEY BLOCK-----

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

You might also like