diff --git a/1.4/about/index.html b/1.4/about/index.html index 3f4f9ab..b13161c 100644 --- a/1.4/about/index.html +++ b/1.4/about/index.html @@ -654,14 +654,14 @@ documentation for the current version.
  • 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
  • +
  • Write an awesome plugin
  • Talk about BunkerWeb to your friends/colleagues, on social media, on your blog, ...
  • How to report security issue ?

    Please contact us at security@bunkerity.com using the following PGP key :

    -
    -----BEGIN PGP PUBLIC KEY BLOCK-----
    -
    -mQINBGCEMiMBEACtXJBDbF86qjC/Q1cfmJfYcYrbk6eE5czknG294XObC97wAgDf
    +

    ```conf +-----BEGIN PGP PUBLIC KEY BLOCK-----

    +

    mQINBGCEMiMBEACtXJBDbF86qjC/Q1cfmJfYcYrbk6eE5czknG294XObC97wAgDf /MbX6bnti4kDRpflGDqQtwOXudcEzledTD4bdDUKvZwqPoYQGa24uCuUxSINTLXr RuoMaKfpvs7trsFXp5iYUqf4Org2aaJE7Tk/9sOvxgdqsT22jEgCZXTRU1qG494U u6XRQN8hKlw6aa6njjX9vUk6Jpl46/kwwO9mpXBZX6iFKYnBlUWs2k8d6D6cO5aZ @@ -711,7 +711,7 @@ SOk62kZ0lqEctwgKDe3MNQnPxt9+tU9L1pIkyXgXihcOLiCMl434K0djJXxIbiX0 JvbFAfI3qteepvnjBQ== =g1tf -----END PGP PUBLIC KEY BLOCK----- -

    +```

    diff --git a/1.4/concepts/index.html b/1.4/concepts/index.html index 569afbd..8d2ff4b 100644 --- a/1.4/concepts/index.html +++ b/1.4/concepts/index.html @@ -627,32 +627,32 @@ documentation for the current version.

    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 :

    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.

    +

    The technical details of all BunkerWeb integrations are available in the integrations section of the documentation.

    Settings

    Once BunkerWeb is integrated into your environment, you will need to configure it to serve and protect your web applications.

    Configuration of BunkerWeb is done using what we called the "settings" or "variables". Each setting is identified by a name like AUTO_LETS_ENCRYPT or USE_ANTIBOT for example. You can assign values to the settings to configure BunkerWeb.

    Here is a dummy example of a BunkerWeb configuration :

    -
    SERVER_NAME=www.example.com
    +

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

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

    +

    The complete list of available settings with descriptions and possible values is available in the settings section of the documentation.

    Settings generator tool

    @@ -665,7 +665,8 @@ USE_BROTLI=no

    The multisite mode is controlled by the MULTISITE setting which can be set to yes (enabled) or no (disabled, which is the default).

    Each setting has a context which defines "where" it can be applied. If the context is global then the setting can't be set per server (or "per site", "per app") but only to the whole configuration. Otherwise, if the context is multisite, the setting can be set globally and per server. Defining a multisite setting to a specific server is done by adding the server name as a prefix of the setting name like app1.example.com_AUTO_LETS_ENCRYPT or app2.example.com_USE_ANTIBOT for example. When a multisite setting is defined globally (without any server prefix), all the servers will inherit that setting (but can still be overriden if we set the same setting with the server name prefix).

    Here is a dummy example of a multisite BunkerWeb configuration :

    -
    MULTISITE=yes
    +

    conf +MULTISITE=yes SERVER_NAME=app1.example.com app2.example.com app3.example.com AUTO_LETS_ENCRYPT=yes USE_GZIP=yes @@ -674,19 +675,18 @@ 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 -

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

    +

    You will find concrete examples of multisite mode in the quickstart guide of the documentation and the examples directory of the repository.

    Custom configurations

    -

    Because meeting all the use cases only using the settings is not an option (even with external plugins), you can use custom configurations to solve your specific challenges.

    +

    Because meeting all the use cases only using the settings is not an option (even with external plugins), you can use custom configurations to solve your specific challenges.

    Under the hood, BunkerWeb uses the notorious NGINX web server, that's why you can leverage its configuration system for your specific needs. Custom NGINX configurations can be included in different contexts like HTTP or server (all servers and/or specific server block).

    Another core component of BunkerWeb is the ModSecurity Web Application Firewall : you can also use custom configurations to fix some false positives or add custom rules for example.

    Going further

    -

    You will find concrete examples of custom configurations in the quickstart guide of the documentation and the examples directory of the repository.

    +

    You will find concrete examples of custom configurations in the quickstart guide of the documentation and the examples directory of the repository.

    diff --git a/1.4/index.html b/1.4/index.html index fcc8d58..421b7d5 100644 --- a/1.4/index.html +++ b/1.4/index.html @@ -627,8 +627,8 @@ documentation for the current version.
    Make your web services secure by default !

    BunkerWeb is a web server based on the notorious NGINX and focused on security.

    -

    It integrates into existing environments (Linux, Docker, Swarm, Kubernetes, …) to make your web services "secure by default" without any hassle. The security best practices are automatically applied for you while keeping control of every setting to meet your use case.

    -

    BunkerWeb contains primary security features as part of the core but can be easily extended with additional ones thanks to a plugin system.

    +

    It integrates into existing environments (Linux, Docker, Swarm, Kubernetes, …) to make your web services "secure by default" without any hassle. The security best practices are automatically applied for you while keeping control of every setting to meet your use case.

    +

    BunkerWeb contains primary security features as part of the core but can be easily extended with additional ones thanks to a plugin system.

    Why BunkerWeb ?

    -

    Please note that you will need to install NGINX 1.20.2 before BunkerWeb. The installation is not covered in this documentation but you need to use prebuilt packages from the NGINX official repository as described here. If you are on Fedora, you can use the prebuilt packages from the Fedora repository.

    -

    Repositories of Linux packages for BunkerWeb are available on PackageCloud, they provide a bash script to automatically add and trust the repository (but you can also follow the manual installation instructions if you prefer) :

    +

    Please note that you will need to install NGINX 1.20.2 before BunkerWeb. For all distros, except Fedora, using prebuilt packages from official NGINX repository is mandatory. Compiling NGINX from source or using packages from different repositories won't work with the official supported way of installing BunkerWeb on Linux.

    +

    Repositories of Linux packages for BunkerWeb are available on PackageCloud, they provide a bash script to automatically add and trust the repository (but you can also follow the manual installation instructions if you prefer).

    -
    curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.deb.sh | sudo bash && \
    -apt update && \
    -apt install -y bunkerweb
    -
    +

    The first step is to add NGINX official repository : +shell +sudo apt install 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.20.2 : +shell +sudo apt update && \ +sudo apt install nginx=1.20.2-1~bullseye

    +

    And finally install BunkerWeb 1.4.0 : +shell +curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.deb.sh | sudo bash && \ +apt update && \ +apt install -y bunkerweb=1.4.0

    -
    curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.deb.sh | sudo bash && \
    -apt update && \
    -apt install -y bunkerweb
    -
    +

    The first step is to add NGINX official repository : +shell +sudo apt install 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.20.2 : +shell +sudo apt update && \ +sudo apt install nginx=1.20.2-1~jammy

    +

    And finally install BunkerWeb 1.4.0 : +shell +curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.deb.sh | sudo bash && \ +apt update && \ +apt install -y bunkerweb=1.4.0

    -
    curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.rpm.sh | sudo bash && \
    -dnf check-update && \
    -dnf install -y bunkerweb
    -
    +

    Fedora already provides NGINX 1.20.2 that we support : +shell +sudo dnf install nginx-1.20.2

    +

    shell +curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.rpm.sh | sudo bash && \ +dnf check-update && \ +dnf install -y bunkerweb-1.4.0

    -
    dnf install -y epel-release && \
    -curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.rpm.sh | sudo bash && \
    -dnf check-update && \
    -dnf install -y bunkerweb
    -
    +

    The first step is to add NGINX official repository, create the following file at /etc/yum.repos.d/nginx.repo : +conf +[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

    +

    You should now be able to install NGINX 1.20.2 : +shell +sudo dnf install nginx-1.20.2

    +

    And finally install BunkerWeb 1.4.0 : +shell +dnf install -y epel-release && \ +curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.rpm.sh | sudo bash && \ +dnf check-update && \ +dnf install -y bunkerweb-1.4.0

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

    -
    MY_SETTING_1=value1
    +

    conf +MY_SETTING_1=value1 MY_SETTING_2=value2 -... -

    +...

    BunkerWeb is managed using systemctl :

    Volumes

    -

    When using container-based integrations like Docker, Docker autoconf, Swarm or Kubernetes, volumes for storing data like certificates, cache or custom configurations has changed. We now have a single "bw-data" volume which contains everything and should be easier to manage than bunkerized.

    +

    When using container-based integrations like Docker, Docker autoconf, Swarm or Kubernetes, volumes for storing data like certificates, cache or custom configurations has changed. We now have a single "bw-data" volume which contains everything and should be easier to manage than bunkerized.

    Removed features

    We decided to drop the following features :

    Replaced BLOCK_, WHITELIST_ and BLACKLIST_* settings

    -

    The blocking mechanisms has been completely redesigned. We have detected that a lot of false positives came from the default blacklists hardcoded into bunkerized. That's why we decided to give the users the choice of their blacklists (and also whitelists) for IP address, reverse DNS, user-agent, URI and ASN, see the Blacklisting and whitelisting section of the security tuning.

    +

    The blocking mechanisms has been completely redesigned. We have detected that a lot of false positives came from the default blacklists hardcoded into bunkerized. That's why we decided to give the users the choice of their blacklists (and also whitelists) for IP address, reverse DNS, user-agent, URI and ASN, see the Blacklisting and whitelisting section of the security tuning.

    Changed WHITELIST_USER_AGENT setting behavior

    The new behavior of the WHITELIST_USER_AGENT setting is to disable completely security checks if the User-Agent value of a client match any of the patterns. In bunkerized it was used to ignore specific User-Agent values when BLOCK_USER_AGENT was set to yes to avoid false positives. You can choose the blacklist of your choice to avoid FP (see previous section).

    Changed PROXY_REAL_IP_* settings

    -

    To avoid any confusion between reverse proxy and real IP, we decided to renamed the PROXY_REAL_IP_* settings, you will find more information on the subject here.

    +

    To avoid any confusion between reverse proxy and real IP, we decided to renamed the PROXY_REAL_IP_* settings, you will find more information on the subject here.

    Default values and new settings

    -

    The default value of settings may have changed and we have added many other settings, we recommend you to read the security tuning and settings sections of the documentation.

    +

    The default value of settings may have changed and we have added many other settings, we recommend you to read the security tuning and settings sections of the documentation.

    diff --git a/1.4/plugins/index.html b/1.4/plugins/index.html index dfcaebe..70a63e3 100644 --- a/1.4/plugins/index.html +++ b/1.4/plugins/index.html @@ -712,69 +712,69 @@ documentation for the current version.
    -

    When using the Docker integration, plugins must be written to the volume mounted on /data.

    +

    When using the Docker integration, plugins must be written to the volume mounted on /data.

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

    mkdir -p ./bw-data/plugins
    -

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

    +shell +git clone https://github.com/bunkerity/bunkerweb-plugins && \ +cp -rp ./bunkerweb-plugins/* ./bw-data/plugins

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

    +shell +chown -R root:101 bw-data && \ +chmod -R 770 bw-data

    When starting the BunkerWeb container, you will need to mount the folder on /data : -

    docker run \
    +shell
    +docker run \
            ...
    -       -v "${PWD}/bw-data:/data" \
    +       -v "${PWD}/bw-data:/data" \
            ...
    -       bunkerity/bunkerweb:1.4.0
    -

    + bunkerity/bunkerweb:1.4.0

    Here is the docker-compose equivalent : -

    mybunker:
    -  image: bunkerity/bunkerweb:1.4.0
    -  volumes:
    -    - ./bw-data:/data
    -  ...
    -

    +yaml +mybunker: + image: bunkerity/bunkerweb:1.4.0 + volumes: + - ./bw-data:/data + ...

    -

    When using the Docker autoconf integration, plugins must be written to the volume mounted on /data.

    +

    When using the Docker autoconf integration, plugins must be written to the volume mounted on /data.

    The easiest way to do it is by starting the Docker autoconf stack with a folder mounted on /data (instead of a named volume). Once the stack is started, you can copy the plugins of your choice to the plugins folder from your host : -

    git clone https://github.com/bunkerity/bunkerweb-plugins && \
    -cp -rp ./bunkerweb-plugins/* ./bw-data/plugins
    -

    +shell +git clone https://github.com/bunkerity/bunkerweb-plugins && \ +cp -rp ./bunkerweb-plugins/* ./bw-data/plugins

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

    +shell +chown -R root:101 bw-data && \ +chmod -R 770 bw-data

    -

    When using the Swarm integration, the easiest way of installing plugins is by using docker exec and downloading the plugins from the container.

    +

    When using the Swarm integration, the easiest way of installing plugins is by using docker exec and downloading the plugins from the container.

    Execute a shell inside the autoconf container (use docker ps to get the name) : -

    docker exec -it myautoconf /bin/bash
    -

    +shell +docker exec -it myautoconf /bin/bash

    Once you have a shell inside the container, you can drop the plugins of your choice inside the /data/plugins folder : -

    git clone https://github.com/bunkerity/bunkerweb-plugins && \
    -cp -rp ./bunkerweb-plugins/* /data/plugins
    -

    +shell +git clone https://github.com/bunkerity/bunkerweb-plugins && \ +cp -rp ./bunkerweb-plugins/* /data/plugins

    -

    When using the Kubernetes integration, the easiest way of installing plugins is by using kubectl exec and downloading the plugins from the container.

    +

    When using the Kubernetes integration, the easiest way of installing plugins is by using kubectl exec and downloading the plugins from the container.

    Execute a shell inside the autoconf container (use kubectl get pods to get the name) : -

    kubectl exec -it myautoconf -- /bin/bash
    -

    +shell +kubectl exec -it myautoconf -- /bin/bash

    Once you have a shell inside the container, you can drop the plugins of your choice inside the /data/plugins folder : -

    git clone https://github.com/bunkerity/bunkerweb-plugins && \
    -cp -rp ./bunkerweb-plugins/* /data/plugins
    -

    +shell +git clone https://github.com/bunkerity/bunkerweb-plugins && \ +cp -rp ./bunkerweb-plugins/* /data/plugins

    -

    When using the Linux integration, plugins must be written to the /opt/bunkerweb/plugins folder : -

    git clone https://github.com/bunkerity/bunkerweb-plugins && \
    -cp -rp ./bunkerweb-plugins/* /data/plugins
    -

    +

    When using the Linux integration, plugins must be written to the /opt/bunkerweb/plugins folder : +shell +git clone https://github.com/bunkerity/bunkerweb-plugins && \ +cp -rp ./bunkerweb-plugins/* /data/plugins

    @@ -785,37 +785,37 @@ cp -rp ./bunkerweb-plugins/* /data/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).

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

    -
    mkdir myplugin && \
    -cd myplugin
    -
    +

    shell +mkdir myplugin && \ +cd myplugin

    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 :

    -
    {
    -    "id": "myplugin",
    -    "order": 42,
    -    "name": "My Plugin",
    -    "description": "Just an example plugin.",
    -    "version": "1.0",
    -    "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"
    -        }
    -    ]
    -}
    -
    +

    json +{ + "id": "myplugin", + "order": 42, + "name": "My Plugin", + "description": "Just an example plugin.", + "version": "1.0", + "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 :

    @@ -970,49 +970,44 @@ cp -rp ./bunkerweb-plugins/* /data/plugins

    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 and default-server-http).

    +

    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 and default-server-http).

    Here is an example for a configuration template file inside the confs/server-http folder named example.conf :

    -
    location /setting {
    -    default_type 'text/plain';
    +

    conf +location /setting { + default_type 'text/plain'; content_by_lua_block { - ngx.say('{{ DUMMY_SETTING }}') + ngx.say('{{ DUMMY_SETTING }}') } -} -

    +}

    {{ DUMMY_SETTING }} will be replaced by the value of the DUMMY_SETTING chosen by the user of the plugin.

    LUA

    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 :

    -
    local _M        = {}
    -_M.__index      = _M
    -
    -local utils     = require "utils"
    -local datastore = require "datastore"
    -local logger    = require "logger"
    -
    -function _M.new()
    -    local self = setmetatable({}, _M)
    -    self.dummy = "dummy"
    -    return self, nil
    -end
    -
    -function _M:init()
    -    logger.log(ngx.NOTICE, "MYPLUGIN", "init called")
    -    return true, "success"
    -end
    -
    -function _M:access()
    -    logger.log(ngx.NOTICE, "MYPLUGIN", "access called")
    -    return true, "success", nil, nil
    -end
    -
    -function _M:log()
    -    logger.log(ngx.NOTICE, "MYPLUGIN", "log called")
    -    return true, "success"
    -end
    -
    -return _M
    -
    +

    ```lua +local _M = {} +_M.__index = _M

    +

    local utils = require "utils" +local datastore = require "datastore" +local logger = require "logger"

    +

    function _M.new() + local self = setmetatable({}, _M) + self.dummy = "dummy" + return self, nil +end

    +

    function _M:init() + logger.log(ngx.NOTICE, "MYPLUGIN", "init called") + return true, "success" +end

    +

    function _M:access() + logger.log(ngx.NOTICE, "MYPLUGIN", "access called") + return true, "success", nil, nil +end

    +

    function _M:log() + logger.log(ngx.NOTICE, "MYPLUGIN", "log called") + return true, "success" +end

    +

    return _M +```

    The 3 functions init, access, and log are automatically called during specific contexts. Here are the details of each function :

    @@ -1047,23 +1042,20 @@ cp -rp ./bunkerweb-plugins/* /data/plugins

    Libraries

    All directives from NGINX LUA module are available. 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
    -
    +

    ```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()
    -
    -...
    -
    +

    ```lua +local mylibrary = require "myplugin.mylibrary"

    +

    ...

    +

    mylibrary.dummy()

    +

    ... +```

    Helpers

    Some helpers modules provide common helpful functions :

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

    -
    ...
    -
    -local utils     = require "utils"
    -local datastore = require "datastore"
    -local logger    = require "logger"
    -
    -...
    -
    +

    ```lua +...

    +

    local utils = require "utils" +local datastore = require "datastore" +local logger = require "logger"

    +

    ... +```

    Retrieve a setting value :

    -
    local value, err = utils:get_variable("DUMMY_SETTING")
    -if not value then
    -    logger.log(ngx.ERR, "MYPLUGIN", "can't retrieve setting DUMMY_SETTING : " .. err)
    -else
    -    logger.log(ngx.NOTICE, "MYPLUGIN", "DUMMY_SETTING = " .. value)
    -end
    -
    +

    lua +local value, err = utils:get_variable("DUMMY_SETTING") +if not value then + logger.log(ngx.ERR, "MYPLUGIN", "can't retrieve setting DUMMY_SETTING : " .. err) +else + logger.log(ngx.NOTICE, "MYPLUGIN", "DUMMY_SETTING = " .. value) +end

    Store something in the cache :

    -
    local ok, err = datastore:set("plugin_myplugin_something", "somevalue")
    -if not value then
    -    logger.log(ngx.ERR, "MYPLUGIN", "can't save plugin_myplugin_something into datastore : " .. err)
    -else
    -    logger.log(ngx.NOTICE, "MYPLUGIN", "successfully saved plugin_myplugin_something into datastore into datastore")
    -end
    -
    +

    lua +local ok, err = datastore:set("plugin_myplugin_something", "somevalue") +if not value then + logger.log(ngx.ERR, "MYPLUGIN", "can't save plugin_myplugin_something into datastore : " .. err) +else + logger.log(ngx.NOTICE, "MYPLUGIN", "successfully saved plugin_myplugin_something into datastore into datastore") +end

    Check if an IP address is global :

    -
    local ret, err = utils.ip_is_global(ngx.var.remote_addr)
    -if ret == nil then
    -    logger.log(ngx.ERR, "MYPLUGIN", "error while checking if IP " .. ngx.var.remote_addr .. " is global or not : " .. err)
    -elseif not ret then
    -    logger.log(ngx.NOTICE, "MYPLUGIN", "IP " .. ngx.var.remote_addr .. " is not global")
    -else
    -    logger.log(ngx.NOTICE, "MYPLUGIN", "IP " .. ngx.var.remote_addr .. " is global")
    -end
    -
    +

    lua +local ret, err = utils.ip_is_global(ngx.var.remote_addr) +if ret == nil then + logger.log(ngx.ERR, "MYPLUGIN", "error while checking if IP " .. ngx.var.remote_addr .. " is global or not : " .. err) +elseif not ret then + logger.log(ngx.NOTICE, "MYPLUGIN", "IP " .. ngx.var.remote_addr .. " is not global") +else + logger.log(ngx.NOTICE, "MYPLUGIN", "IP " .. ngx.var.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.

    diff --git a/1.4/quickstart-guide/index.html b/1.4/quickstart-guide/index.html index c7a82c6..26c527f 100644 --- a/1.4/quickstart-guide/index.html +++ b/1.4/quickstart-guide/index.html @@ -655,7 +655,7 @@ documentation for the current version.

    Quickstart guide

    Prerequisites

    -

    We assume that you're already familiar with the core concepts and you have followed the integrations instructions for your environment.

    +

    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.

    @@ -669,225 +669,218 @@ documentation for the current version.
  • 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.

    +

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

    Single application

    When using Docker integration, the easiest way of protecting an existing application is to create a network so BunkerWeb can send requests using the container name.

    Create the Docker network if it's not already created : -

    docker network create bw-net
    -

    +shell +docker network create bw-net

    Then instantiate your app : -

    docker run -d \
    -       --name myapp \
    -       --network bw-net \
    -       nginxdemos/hello:plain-text
    -

    +shell +docker run -d \ + --name myapp \ + --network bw-net \ + nginxdemos/hello:plain-text

    Create the BunkerWeb volume if it's not already created : -

    docker volume create bw-data
    -

    +shell +docker volume create bw-data

    You can now run BunkerWeb and configure it for your app : -

    docker run -d \
    -       --name mybunker \
    -       --network bw-net \
    -       -p 80:8080 \
    -       -p 443:8443 \
    -       -v bw-data:/data \
    -       -e SERVER_NAME=www.example.com \
    -       -e USE_REVERSE_PROXY=yes \
    -       -e REVERSE_PROXY_URL=/ \
    -       -e REVERSE_PROXY_HOST=http://myapp \
    -       bunkerity/bunkerweb:1.4.0
    -

    +shell +docker run -d \ + --name mybunker \ + --network bw-net \ + -p 80:8080 \ + -p 443:8443 \ + -v bw-data:/data \ + -e SERVER_NAME=www.example.com \ + -e USE_REVERSE_PROXY=yes \ + -e REVERSE_PROXY_URL=/ \ + -e REVERSE_PROXY_HOST=http://myapp \ + bunkerity/bunkerweb:1.4.0

    Here is the docker-compose equivalent : -

    version: '3'
    -
    -services:
    -
    -  mybunker:
    -    image: bunkerity/bunkerweb:1.4.0
    -    ports:
    -      - 80:8080
    -      - 443:8443
    -    volumes:
    -      - bw-data:/data
    -    environment:
    -      - USE_REVERSE_PROXY=yes
    -      - REVERSE_PROXY_URL=/
    -      - REVERSE_PROXY_HOST=http://myapp
    -    networks:
    -      - bw-net
    -
    -  myapp:
    -    image: nginxdemos/hello:plain-text
    -    networks:
    -      - bw-net
    -
    -volumes:
    -  bw-data:
    -
    -networks:
    -  bw-net:
    -    name: bw-net
    -

    +```yaml +version: '3'

    +

    services:

    +

    mybunker: + image: bunkerity/bunkerweb:1.4.0 + ports: + - 80:8080 + - 443:8443 + volumes: + - bw-data:/data + environment: + - USE_REVERSE_PROXY=yes + - REVERSE_PROXY_URL=/ + - REVERSE_PROXY_HOST=http://myapp + networks: + - bw-net

    +

    myapp: + image: nginxdemos/hello:plain-text + networks: + - bw-net

    +

    volumes: + bw-data:

    +

    networks: + bw-net: + name: bw-net +```

    -

    We will assume that you already have the Docker autoconf integration stack running on your machine and connected to a network called bw-services.

    +

    We will assume that you already have the Docker autoconf integration stack running on your machine and connected to a network called bw-services.

    You can instantiate your container and pass the settings as labels : -

    docker run -d \
    -       --name myapp \
    -       --network bw-services \
    -       -l bunkerweb.SERVER_NAME=www.example.com \
    -       -l bunkerweb.USE_REVERSE_PROXY=yes \
    -       -l bunkerweb.USE_REVERSE_URL=/ \
    -       -l bunkerweb.REVERSE_PROXY_HOST=http://myapp \
    -       nginxdemos/hello:plain-text
    -

    +shell +docker run -d \ + --name myapp \ + --network bw-services \ + -l bunkerweb.SERVER_NAME=www.example.com \ + -l bunkerweb.USE_REVERSE_PROXY=yes \ + -l bunkerweb.USE_REVERSE_URL=/ \ + -l bunkerweb.REVERSE_PROXY_HOST=http://myapp \ + nginxdemos/hello:plain-text

    Here is the docker-compose equivalent : -

    version: '3'
    -
    -services:
    -
    -  myapp:
    -    image: nginxdemos/hello:plain-text
    -    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"
    -
    -networks:
    -  bw-services:
    -    external:
    -      name: bw-services
    -

    +```yaml +version: '3'

    +

    services:

    +

    myapp: + image: nginxdemos/hello:plain-text + 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"

    +

    networks: + bw-services: + external: + name: bw-services +```

    -

    We will assume that you already have the Swarm integration stack running on your cluster.

    +

    We will assume that you already have the Swarm integration stack running on your cluster.

    You can instantiate your service and pass the settings as labels : -

    docker service \
    -   create \
    -   --name myapp \
    -   --network bw-services \
    -   -l bunkerweb.SERVER_NAME=www.example.com \
    -   -l bunkerweb.USE_REVERSE_PROXY=yes \
    -   -l bunkerweb.REVERSE_PROXY_HOST=http://myapp \
    -   -l bunkerweb.REVERSE_PROXY_URL=/ \
    -   nginxdemos/hello:plain-text
    -

    +shell +docker service \ + create \ + --name myapp \ + --network bw-services \ + -l bunkerweb.SERVER_NAME=www.example.com \ + -l bunkerweb.USE_REVERSE_PROXY=yes \ + -l bunkerweb.REVERSE_PROXY_HOST=http://myapp \ + -l bunkerweb.REVERSE_PROXY_URL=/ \ + nginxdemos/hello:plain-text

    Here is the docker-compose equivalent (using docker stack deploy) : -

    version: "3"
    -
    -services:
    -
    -  myapp:
    -    image: nginxdemos/hello:plain-text
    -    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"
    -
    -networks:
    -  bw-services:
    -    external:
    -      name: bw-services
    -

    +```yaml +version: "3"

    +

    services:

    +

    myapp: + image: nginxdemos/hello:plain-text + 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"

    +

    networks: + bw-services: + external: + name: bw-services +```

    -

    We will assume that you already have the Kubernetes integration stack running on your cluster.

    +

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

    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/hello:plain-text
    -        ports:
    -        - containerPort: 80
    ----
    -apiVersion: v1
    -kind: Service
    -metadata:
    -  name: svc-app
    -spec:
    -  selector:
    -    app: app
    -  ports:
    -    - protocol: TCP
    -      port: 80
    -      targetPort: 80
    -

    +```yaml +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/hello:plain-text + ports: + - containerPort: 80

    +
    +

    apiVersion: v1 +kind: Service +metadata: + name: svc-app +spec: + selector: + app: app + ports: + - protocol: TCP + port: 80 + targetPort: 80 +```

    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/AUTOCONF: "yes"
    -spec:
    -  rules:
    -  - host: www.example.com
    -    http:
    -      paths:
    -      - path: /
    -        pathType: Prefix
    -        backend:
    -          service:
    -            name: svc-app
    -            port:
    -              number: 80
    -

    +yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ingress + annotations: + bunkerweb.io/AUTOCONF: "yes" +spec: + rules: + - host: www.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: svc-app + port: + number: 80

    -

    We will assume that you already have the Linux integration stack running on your machine.

    +

    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
    -

    +shell +python3 -m http.server -b 127.0.0.1

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

    SERVER_NAME=www.example.com
    +conf
    +SERVER_NAME=www.example.com
     HTTP_PORT=80
     HTTPS_PORT=443
     DNS_RESOLVERS=8.8.8.8 8.8.4.4
     USE_REVERSE_PROXY=yes
     REVERSE_PROXY_URL=/
    -REVERSE_PROXY_HOST=http://127.0.0.1:8000
    -

    +REVERSE_PROXY_HOST=http://127.0.0.1:8000

    Let's check the status of BunkerWeb : -

    systemctl status bunkerweb
    -

    +shell +systemctl status bunkerweb

    If it's already running we can just reload it : -

    systemctl reload bunkerweb
    -

    +shell +systemctl reload bunkerweb

    Otherwise, we will need to start it : -

    systemctl start bunkerweb
    -

    +shell +systemctl start bunkerweb

    @@ -902,508 +895,494 @@ REVERSE_PROXY_HOST=http://127.0.0.1:8000

    When using Docker integration, the easiest way of protecting multiple existing applications is to create a network so BunkerWeb can send requests using the container names.

    Create the Docker network if it's not already created : -

    docker network create bw-net
    -

    +shell +docker network create bw-net

    Then instantiate your apps :

    -
    docker run -d \
    -       --name myapp1 \
    -       --network bw-net \
    -       nginxdemos/hello:plain-text
    -
    +

    shell +docker run -d \ + --name myapp1 \ + --network bw-net \ + nginxdemos/hello:plain-text

    -
    docker run -d \
    -       --name myapp2 \
    -       --network bw-net \
    -       nginxdemos/hello:plain-text
    -
    +

    shell +docker run -d \ + --name myapp2 \ + --network bw-net \ + nginxdemos/hello:plain-text

    -
    docker run -d \
    -       --name myapp3 \
    -       --network bw-net \
    -       nginxdemos/hello:plain-text
    -
    +

    shell +docker run -d \ + --name myapp3 \ + --network bw-net \ + nginxdemos/hello:plain-text

    Create the BunkerWeb volume if it's not already created : -

    docker volume create bw-data
    -

    +shell +docker volume create bw-data

    You can now run BunkerWeb and configure it for your apps : -

    docker run -d \
    -       --name mybunker \
    -       --network bw-net \
    -       -p 80:8080 \
    -       -p 443:8443 \
    -       -v bw-data:/data \
    -       -e MULTISITE=yes
    -       -e "SERVER_NAME=app1.example.com app2.example.com app3.example.com" \
    -       -e USE_REVERSE_PROXY=yes \
    -       -e REVERSE_PROXY_URL=/ \
    -       -e app1.example.com_REVERSE_PROXY_HOST=http://myapp1 \
    -       -e app2.example.com_REVERSE_PROXY_HOST=http://myapp2 \
    -       -e app3.example.com_REVERSE_PROXY_HOST=http://myapp3 \
    -       bunkerity/bunkerweb:1.4.0
    -

    +shell +docker run -d \ + --name mybunker \ + --network bw-net \ + -p 80:8080 \ + -p 443:8443 \ + -v bw-data:/data \ + -e MULTISITE=yes + -e "SERVER_NAME=app1.example.com app2.example.com app3.example.com" \ + -e USE_REVERSE_PROXY=yes \ + -e REVERSE_PROXY_URL=/ \ + -e app1.example.com_REVERSE_PROXY_HOST=http://myapp1 \ + -e app2.example.com_REVERSE_PROXY_HOST=http://myapp2 \ + -e app3.example.com_REVERSE_PROXY_HOST=http://myapp3 \ + bunkerity/bunkerweb:1.4.0

    Here is the docker-compose equivalent : -

    version: '3'
    -
    -services:
    -
    -  mybunker:
    -    image: bunkerity/bunkerweb:1.4.0
    -    ports:
    -      - 80:8080
    -      - 443:8443
    -    volumes:
    -      - bw-data:/data
    -    environment:
    -      - 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://myapp1
    -      - app2.example.com_REVERSE_PROXY_HOST=http://myapp2
    -      - app3.example.com_REVERSE_PROXY_HOST=http://myapp3
    -    networks:
    -      - bw-net
    -
    -  myapp1:
    -    image: nginxdemos/hello:plain-text
    -    networks:
    -      - bw-net
    -
    -  myapp2:
    -    image: nginxdemos/hello:plain-text
    -    networks:
    -      - bw-net
    -
    -  myapp3:
    -    image: nginxdemos/hello:plain-text
    -    networks:
    -      - bw-net
    -
    -volumes:
    -  bw-data:
    -
    -networks:
    -  bw-net:
    -    name: bw-net
    -

    +```yaml +version: '3'

    +

    services:

    +

    mybunker: + image: bunkerity/bunkerweb:1.4.0 + ports: + - 80:8080 + - 443:8443 + volumes: + - bw-data:/data + environment: + - 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://myapp1 + - app2.example.com_REVERSE_PROXY_HOST=http://myapp2 + - app3.example.com_REVERSE_PROXY_HOST=http://myapp3 + networks: + - bw-net

    +

    myapp1: + image: nginxdemos/hello:plain-text + networks: + - bw-net

    +

    myapp2: + image: nginxdemos/hello:plain-text + networks: + - bw-net

    +

    myapp3: + image: nginxdemos/hello:plain-text + networks: + - bw-net

    +

    volumes: + bw-data:

    +

    networks: + bw-net: + name: bw-net +```

    -

    We will assume that you already have the Docker autoconf integration stack running on your machine and connected to a network called bw-services.

    +

    We will assume that you already have the Docker autoconf integration stack running on your machine and connected to a network called bw-services.

    You can instantiate your containers and pass the settings as labels :

    -
    docker run -d \
    -   --name myapp1 \
    -   --network bw-services \
    -   -l bunkerweb.SERVER_NAME=app1.example.com \
    -   -l bunkerweb.USE_REVERSE_PROXY=yes \
    -   -l bunkerweb.USE_REVERSE_URL=/ \
    -   -l bunkerweb.REVERSE_PROXY_HOST=http://myapp1 \
    -   nginxdemos/hello:plain-text
    -
    +

    shell +docker run -d \ + --name myapp1 \ + --network bw-services \ + -l bunkerweb.SERVER_NAME=app1.example.com \ + -l bunkerweb.USE_REVERSE_PROXY=yes \ + -l bunkerweb.USE_REVERSE_URL=/ \ + -l bunkerweb.REVERSE_PROXY_HOST=http://myapp1 \ + nginxdemos/hello:plain-text

    Here is the docker-compose equivalent : -

    version: '3'
    -
    -services:
    -
    -  myapp1:
    -    image: nginxdemos/hello:plain-text
    -    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"
    -
    -networks:
    -  bw-services:
    -    external:
    -      name: bw-services
    -

    +```yaml +version: '3'

    +

    services:

    +

    myapp1: + image: nginxdemos/hello:plain-text + 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"

    +

    networks: + bw-services: + external: + name: bw-services +```

    -
    docker run -d \
    -   --name myapp2 \
    -   --network bw-services \
    -   -l bunkerweb.SERVER_NAME=app2.example.com \
    -   -l bunkerweb.USE_REVERSE_PROXY=yes \
    -   -l bunkerweb.USE_REVERSE_URL=/ \
    -   -l bunkerweb.REVERSE_PROXY_HOST=http://myapp2 \
    -   nginxdemos/hello:plain-text
    -
    +

    shell +docker run -d \ + --name myapp2 \ + --network bw-services \ + -l bunkerweb.SERVER_NAME=app2.example.com \ + -l bunkerweb.USE_REVERSE_PROXY=yes \ + -l bunkerweb.USE_REVERSE_URL=/ \ + -l bunkerweb.REVERSE_PROXY_HOST=http://myapp2 \ + nginxdemos/hello:plain-text

    Here is the docker-compose equivalent : -

    version: '3'
    -
    -services:
    -
    -  myapp2:
    -    image: nginxdemos/hello:plain-text
    -    networks:
    -      bw-services:
    -        aliases:
    -          - myapp2
    -    labels:
    -      - "bunkerweb.SERVER_NAME=app2.example.com"
    -      - "bunkerweb.USE_REVERSE_PROXY=yes"
    -      - "bunkerweb.REVERSE_PROXY_URL=/"
    -      - "bunkerweb.REVERSE_PROXY_HOST=http://myapp2"
    -
    -networks:
    -  bw-services:
    -    external:
    -      name: bw-services
    -

    +```yaml +version: '3'

    +

    services:

    +

    myapp2: + image: nginxdemos/hello:plain-text + networks: + bw-services: + aliases: + - myapp2 + labels: + - "bunkerweb.SERVER_NAME=app2.example.com" + - "bunkerweb.USE_REVERSE_PROXY=yes" + - "bunkerweb.REVERSE_PROXY_URL=/" + - "bunkerweb.REVERSE_PROXY_HOST=http://myapp2"

    +

    networks: + bw-services: + external: + name: bw-services +```

    -
    docker run -d \
    -   --name myapp3 \
    -   --network bw-services \
    -   -l bunkerweb.SERVER_NAME=app3.example.com \
    -   -l bunkerweb.USE_REVERSE_PROXY=yes \
    -   -l bunkerweb.USE_REVERSE_URL=/ \
    -   -l bunkerweb.REVERSE_PROXY_HOST=http://myapp3 \
    -   nginxdemos/hello:plain-text
    -
    +

    shell +docker run -d \ + --name myapp3 \ + --network bw-services \ + -l bunkerweb.SERVER_NAME=app3.example.com \ + -l bunkerweb.USE_REVERSE_PROXY=yes \ + -l bunkerweb.USE_REVERSE_URL=/ \ + -l bunkerweb.REVERSE_PROXY_HOST=http://myapp3 \ + nginxdemos/hello:plain-text

    Here is the docker-compose equivalent : -

    version: '3'
    -
    -services:
    -
    -  myapp3:
    -    image: nginxdemos/hello:plain-text
    -    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"
    -
    -networks:
    -  bw-services:
    -    external:
    -      name: bw-services
    -

    +```yaml +version: '3'

    +

    services:

    +

    myapp3: + image: nginxdemos/hello:plain-text + 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"

    +

    networks: + bw-services: + external: + name: bw-services +```

    -

    We will assume that you already have the Swarm integration stack running on your cluster.

    +

    We will assume that you already have the Swarm integration stack running on your cluster.

    You can instantiate your services and pass the settings as labels :

    -
    docker service \
    -   create \
    -   --name myapp1 \
    -   --network bw-services \
    -   -l bunkerweb.SERVER_NAME=app1.example.com \
    -   -l bunkerweb.USE_REVERSE_PROXY=yes \
    -   -l bunkerweb.REVERSE_PROXY_HOST=http://myapp1 \
    -   -l bunkerweb.REVERSE_PROXY_URL=/ \
    -   nginxdemos/hello:plain-text
    -
    +

    shell +docker service \ + create \ + --name myapp1 \ + --network bw-services \ + -l bunkerweb.SERVER_NAME=app1.example.com \ + -l bunkerweb.USE_REVERSE_PROXY=yes \ + -l bunkerweb.REVERSE_PROXY_HOST=http://myapp1 \ + -l bunkerweb.REVERSE_PROXY_URL=/ \ + nginxdemos/hello:plain-text

    Here is the docker-compose equivalent (using docker stack deploy) : -

    version: "3"
    -
    -services:
    -
    -  myapp1:
    -    image: nginxdemos/hello:plain-text
    -    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"
    -
    -networks:
    -  bw-services:
    -    external:
    -      name: bw-services
    -

    +```yaml +version: "3"

    +

    services:

    +

    myapp1: + image: nginxdemos/hello:plain-text + 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"

    +

    networks: + bw-services: + external: + name: bw-services +```

    -
    docker service \
    -   create \
    -   --name myapp2 \
    -   --network bw-services \
    -   -l bunkerweb.SERVER_NAME=app2.example.com \
    -   -l bunkerweb.USE_REVERSE_PROXY=yes \
    -   -l bunkerweb.REVERSE_PROXY_HOST=http://myapp2 \
    -   -l bunkerweb.REVERSE_PROXY_URL=/ \
    -   nginxdemos/hello:plain-text
    -
    +

    shell +docker service \ + create \ + --name myapp2 \ + --network bw-services \ + -l bunkerweb.SERVER_NAME=app2.example.com \ + -l bunkerweb.USE_REVERSE_PROXY=yes \ + -l bunkerweb.REVERSE_PROXY_HOST=http://myapp2 \ + -l bunkerweb.REVERSE_PROXY_URL=/ \ + nginxdemos/hello:plain-text

    Here is the docker-compose equivalent (using docker stack deploy) : -

    version: "3"
    -
    -services:
    -
    -  myapp2:
    -    image: nginxdemos/hello:plain-text
    -    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"
    -
    -networks:
    -  bw-services:
    -    external:
    -      name: bw-services
    -

    +```yaml +version: "3"

    +

    services:

    +

    myapp2: + image: nginxdemos/hello:plain-text + 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"

    +

    networks: + bw-services: + external: + name: bw-services +```

    -
    docker service \
    -   create \
    -   --name myapp3 \
    -   --network bw-services \
    -   -l bunkerweb.SERVER_NAME=app3.example.com \
    -   -l bunkerweb.USE_REVERSE_PROXY=yes \
    -   -l bunkerweb.REVERSE_PROXY_HOST=http://myapp3 \
    -   -l bunkerweb.REVERSE_PROXY_URL=/ \
    -   nginxdemos/hello:plain-text
    -
    +

    shell +docker service \ + create \ + --name myapp3 \ + --network bw-services \ + -l bunkerweb.SERVER_NAME=app3.example.com \ + -l bunkerweb.USE_REVERSE_PROXY=yes \ + -l bunkerweb.REVERSE_PROXY_HOST=http://myapp3 \ + -l bunkerweb.REVERSE_PROXY_URL=/ \ + nginxdemos/hello:plain-text

    Here is the docker-compose equivalent (using docker stack deploy) : -

    version: "3"
    -
    -services:
    -
    -  myapp3:
    -    image: nginxdemos/hello:plain-text
    -    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"
    -
    -networks:
    -  bw-services:
    -    external:
    -      name: bw-services
    -

    +```yaml +version: "3"

    +

    services:

    +

    myapp3: + image: nginxdemos/hello:plain-text + 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"

    +

    networks: + bw-services: + external: + name: bw-services +```

    -

    We will assume that you already have the Kubernetes integration stack running on your cluster.

    +

    We will assume that you already have the Kubernetes integration stack running on your cluster.

    Let's also assume that you have some typical Deployments with Services 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/hello:plain-text
    -        ports:
    -        - containerPort: 80
    ----
    -apiVersion: v1
    -kind: Service
    -metadata:
    -  name: svc-app1
    -spec:
    -  selector:
    -    app: app1
    -  ports:
    -    - protocol: TCP
    -      port: 80
    -      targetPort: 80
    -
    +

    ```yaml +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/hello:plain-text + ports: + - containerPort: 80

    +
    +

    apiVersion: v1 +kind: Service +metadata: + name: svc-app1 +spec: + selector: + app: app1 + ports: + - protocol: TCP + port: 80 + targetPort: 80 +```

    -
    apiVersion: apps/v1
    -kind: Deployment
    -metadata:
    -  name: app2
    -  labels:
    -    app: app2
    -spec:
    -  replicas: 1
    -  selector:
    -    matchLabels:
    -      app: app2
    -  template:
    -    metadata:
    -      labels:
    -        app: app2
    -    spec:
    -      containers:
    -      - name: app2
    -        image: nginxdemos/hello:plain-text
    -        ports:
    -        - containerPort: 80
    ----
    -apiVersion: v1
    -kind: Service
    -metadata:
    -  name: svc-app2
    -spec:
    -  selector:
    -    app: app2
    -  ports:
    -    - protocol: TCP
    -      port: 80
    -      targetPort: 80
    -
    +

    ```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: app2 + labels: + app: app2 +spec: + replicas: 1 + selector: + matchLabels: + app: app2 + template: + metadata: + labels: + app: app2 + spec: + containers: + - name: app2 + image: nginxdemos/hello:plain-text + ports: + - containerPort: 80

    +
    +

    apiVersion: v1 +kind: Service +metadata: + name: svc-app2 +spec: + selector: + app: app2 + ports: + - protocol: TCP + port: 80 + targetPort: 80 +```

    -
    apiVersion: apps/v1
    -kind: Deployment
    -metadata:
    -  name: app3
    -  labels:
    -    app: app3
    -spec:
    -  replicas: 1
    -  selector:
    -    matchLabels:
    -      app: app3
    -  template:
    -    metadata:
    -      labels:
    -        app: app3
    -    spec:
    -      containers:
    -      - name: app1
    -        image: nginxdemos/hello:plain-text
    -        ports:
    -        - containerPort: 80
    ----
    -apiVersion: v1
    -kind: Service
    -metadata:
    -  name: svc-app3
    -spec:
    -  selector:
    -    app: app3
    -  ports:
    -    - protocol: TCP
    -      port: 80
    -      targetPort: 80
    -
    +

    ```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: app3 + labels: + app: app3 +spec: + replicas: 1 + selector: + matchLabels: + app: app3 + template: + metadata: + labels: + app: app3 + spec: + containers: + - name: app1 + image: nginxdemos/hello:plain-text + ports: + - containerPort: 80

    +
    +

    apiVersion: v1 +kind: Service +metadata: + name: svc-app3 +spec: + selector: + app: app3 + ports: + - protocol: TCP + port: 80 + targetPort: 80 +```

    Here is the corresponding Ingress definition to serve and protect the web applications : -

    apiVersion: networking.k8s.io/v1
    -kind: Ingress
    -metadata:
    -  name: ingress
    -  annotations:
    -    bunkerweb.io/AUTOCONF: "yes"
    -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
    -

    +yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ingress + annotations: + bunkerweb.io/AUTOCONF: "yes" +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

    -

    We will assume that you already have the Linux integration stack running on your machine.

    +

    We will assume that you already have the Linux integration stack running on your machine.

    Let's assume that you have some web applications running on the same machine as BunkerWeb :

    The following command will run a basic HTTP server on the port 8001 and deliver the files in the current directory : -

    python3 -m http.server -b 127.0.0.1 8001
    -

    +shell +python3 -m http.server -b 127.0.0.1 8001

    The following command will run a basic HTTP server on the port 8002 and deliver the files in the current directory : -

    python3 -m http.server -b 127.0.0.1 8002
    -

    +shell +python3 -m http.server -b 127.0.0.1 8002

    The following command will run a basic HTTP server on the port 8003 and deliver the files in the current directory : -

    python3 -m http.server -b 127.0.0.1 8003
    -

    +shell +python3 -m http.server -b 127.0.0.1 8003

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

    SERVER_NAME=app1.example.com app2.example.com app3.example.com
    +conf
    +SERVER_NAME=app1.example.com app2.example.com app3.example.com
     HTTP_PORT=80
     HTTPS_PORT=443
     DNS_RESOLVERS=8.8.8.8 8.8.4.4
    @@ -1411,17 +1390,16 @@ 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
    -

    +app3.example.com_REVERSE_PROXY_HOST=http://127.0.0.1:8003

    Let's check the status of BunkerWeb : -

    systemctl status bunkerweb
    -

    +shell +systemctl status bunkerweb

    If it's already running we can just reload it : -

    systemctl reload bunkerweb
    -

    +shell +systemctl reload bunkerweb

    Otherwise, we will need to start it : -

    systemctl start bunkerweb
    -

    +shell +systemctl start bunkerweb

    @@ -1439,7 +1417,7 @@ app3.example.com_REVERSE_PROXY_HOST=http://127.0.0.1:8003
  • 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.

    +

    You will find more settings about real IP in the settings section of the documentation.

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

    The following settings need to be set :

    -
    USE_REAL_IP=yes
    +

    conf +USE_REAL_IP=yes REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16 -REAL_IP_HEADER=X-Forwarded-For -

    +REAL_IP_HEADER=X-Forwarded-For

    When starting the BunkerWeb container, you will need to add the settings : -

    docker run \
    +shell
    +docker run \
            ...
    -       -e USE_REAL_IP=yes \
    -       -e "REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16" \
    -       -e REAL_IP_HEADER=X-Forwarded-For \
    +       -e USE_REAL_IP=yes \
    +       -e "REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16" \
    +       -e REAL_IP_HEADER=X-Forwarded-For \
            ...
    -       bunkerity/bunkerweb:1.4.0
    -

    + bunkerity/bunkerweb:1.4.0

    Here is the docker-compose equivalent : -

    mybunker:
    -  image: bunkerity/bunkerweb:1.4.0
    -  ...
    -  environment:
    -    - USE_REAL_IP=yes
    -    - REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16
    -    - REAL_IP_HEADER=X-Forwarded-For
    -  ...
    -

    +yaml +mybunker: + image: bunkerity/bunkerweb:1.4.0 + ... + environment: + - USE_REAL_IP=yes + - REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16 + - REAL_IP_HEADER=X-Forwarded-For + ...

    -

    Before running the Docker autoconf integration stack, you will need to add the settings for the BunkerWeb container : -

    docker run \
    +

    Before running the Docker autoconf integration stack, you will need to add the settings for the BunkerWeb container : +shell +docker run \ ... - -e USE_REAL_IP=yes \ - -e "REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16" \ - -e REAL_IP_HEADER=X-Forwarded-For \ + -e USE_REAL_IP=yes \ + -e "REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16" \ + -e REAL_IP_HEADER=X-Forwarded-For \ ... - bunkerity/bunkerweb:1.4.0 -

    + bunkerity/bunkerweb:1.4.0

    Here is the docker-compose equivalent : -

    mybunker:
    -  image: bunkerity/bunkerweb:1.4.0
    -  ...
    -  environment:
    -    - USE_REAL_IP=yes
    -    - REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16
    -    - REAL_IP_HEADER=X-Forwarded-For
    -  ...
    -

    +yaml +mybunker: + image: bunkerity/bunkerweb:1.4.0 + ... + environment: + - USE_REAL_IP=yes + - REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16 + - REAL_IP_HEADER=X-Forwarded-For + ...

    -

    Before running the Swarm integration stack, you will need to add the settings for the BunkerWeb service : -

    docker service create \
    +

    Before running the Swarm integration stack, you will need to add the settings for the BunkerWeb service : +shell +docker service create \ ... - -e USE_REAL_IP=yes \ - -e "REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16" \ - -e REAL_IP_HEADER=X-Forwarded-For \ + -e USE_REAL_IP=yes \ + -e "REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16" \ + -e REAL_IP_HEADER=X-Forwarded-For \ ... - bunkerity/bunkerweb:1.4.0 -

    + bunkerity/bunkerweb:1.4.0

    Here is the docker-compose equivalent (using docker stack deploy) : -

    mybunker:
    -  image: bunkerity/bunkerweb:1.4.0
    -  ...
    -  environment:
    -    - USE_REAL_IP=yes
    -    - REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16
    -    - REAL_IP_HEADER=X-Forwarded-For
    -  ...
    -

    +yaml +mybunker: + image: bunkerity/bunkerweb:1.4.0 + ... + environment: + - USE_REAL_IP=yes + - REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16 + - REAL_IP_HEADER=X-Forwarded-For + ...

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

    apiVersion: apps/v1
    -kind: DaemonSet
    -metadata:
    -  name: bunkerweb
    -spec:
    -  selector:
    -    matchLabels:
    -      app: bunkerweb
    -  template:
    -    spec:
    -      containers:
    -      - name: bunkerweb
    -        image: bunkerity/bunkerweb:1.4.0
    -        ...
    -        env:
    -        - name: USE_REAL_IP
    -          value: "yes"
    -        - name: REAL_IP_HEADER
    -          value: "X-Forwarded-For"
    -        - name: REAL_IP_FROM
    -          value: "1.2.3.0/24 100.64.0.0/16"
    -...
    -

    +yaml +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: bunkerweb +spec: + selector: + matchLabels: + app: bunkerweb + template: + spec: + containers: + - name: bunkerweb + image: bunkerity/bunkerweb:1.4.0 + ... + env: + - name: USE_REAL_IP + value: "yes" + - name: REAL_IP_HEADER + value: "X-Forwarded-For" + - name: REAL_IP_FROM + value: "1.2.3.0/24 100.64.0.0/16" +...

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

    ...
    +conf
    +...
     USE_REAL_IP=yes
     REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16
     REAL_IP_HEADER=X-Forwarded-For
    -...
    -

    +...

    Don't forget to reload the bunkerweb service once it's done.

    @@ -1561,125 +1539,125 @@ REAL_IP_HEADER=X-Forwarded-For
  • They have IPs in the 1.2.3.0/24 and 100.64.0.0/16 networks
  • The following settings need to be set :

    -
    USE_REAL_IP=yes
    +

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

    +REAL_IP_HEADER=proxy_protocol

    When starting the BunkerWeb container, you will need to add the settings : -

    docker run \
    +shell
    +docker run \
            ...
    -       -e USE_REAL_IP=yes \
    -       -e USE_PROXY_PROTOCOL=yes \
    -       -e "REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16" \
    -       -e REAL_IP_HEADER=proxy_protocol \
    +       -e USE_REAL_IP=yes \
    +       -e USE_PROXY_PROTOCOL=yes \
    +       -e "REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16" \
    +       -e REAL_IP_HEADER=proxy_protocol \
            ...
    -       bunkerity/bunkerweb:1.4.0
    -

    + bunkerity/bunkerweb:1.4.0

    Here is the docker-compose equivalent : -

    mybunker:
    -  image: bunkerity/bunkerweb:1.4.0
    -  ...
    -  environment:
    -    - 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
    -  ...
    -

    +yaml +mybunker: + image: bunkerity/bunkerweb:1.4.0 + ... + environment: + - 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 + ...

    -

    Before running the Docker autoconf integration stack, you will need to add the settings for the BunkerWeb container : -

    docker run \
    +

    Before running the Docker autoconf integration stack, you will need to add the settings for the BunkerWeb container : +shell +docker run \ ... - -e USE_REAL_IP=yes \ - -e USE_PROXY_PROTOCOL=yes \ - -e "REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16" \ - -e REAL_IP_HEADER=proxy_protocol \ + -e USE_REAL_IP=yes \ + -e USE_PROXY_PROTOCOL=yes \ + -e "REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16" \ + -e REAL_IP_HEADER=proxy_protocol \ ... - bunkerity/bunkerweb:1.4.0 -

    + bunkerity/bunkerweb:1.4.0

    Here is the docker-compose equivalent : -

    mybunker:
    -  image: bunkerity/bunkerweb:1.4.0
    -  ...
    -  environment:
    -    - 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
    -  ...
    -

    +yaml +mybunker: + image: bunkerity/bunkerweb:1.4.0 + ... + environment: + - 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 + ...

    -

    Before running the Swarm integration stack, you will need to add the settings for the BunkerWeb service : -

    docker service create \
    +

    Before running the Swarm integration stack, you will need to add the settings for the BunkerWeb service : +shell +docker service create \ ... - -e USE_REAL_IP=yes \ - -e USE_PROXY_PROTOCOL=yes \ - -e "REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16" \ - -e REAL_IP_HEADER=proxy_protocol \ + -e USE_REAL_IP=yes \ + -e USE_PROXY_PROTOCOL=yes \ + -e "REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16" \ + -e REAL_IP_HEADER=proxy_protocol \ ... - bunkerity/bunkerweb:1.4.0 -

    + bunkerity/bunkerweb:1.4.0

    Here is the docker-compose equivalent (using docker stack deploy) : -

    mybunker:
    -  image: bunkerity/bunkerweb:1.4.0
    -  ...
    -  environment:
    -    - 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
    -  ...
    -

    +yaml +mybunker: + image: bunkerity/bunkerweb:1.4.0 + ... + environment: + - 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 + ...

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

    apiVersion: apps/v1
    -kind: DaemonSet
    -metadata:
    -  name: bunkerweb
    -spec:
    -  selector:
    -    matchLabels:
    -      app: bunkerweb
    -  template:
    -    spec:
    -      containers:
    -      - name: bunkerweb
    -        image: bunkerity/bunkerweb:1.4.0
    -        ...
    -        env:
    -        - name: USE_REAL_IP
    -          value: "yes"
    -        - name: USE_PROXY_PROTOCOL
    -          value: "yes"
    -        - name: REAL_IP_HEADER
    -          value: "proxy_protocol"
    -        - name: REAL_IP_FROM
    -          value: "1.2.3.0/24 100.64.0.0/16"
    -...
    -

    +yaml +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: bunkerweb +spec: + selector: + matchLabels: + app: bunkerweb + template: + spec: + containers: + - name: bunkerweb + image: bunkerity/bunkerweb:1.4.0 + ... + env: + - name: USE_REAL_IP + value: "yes" + - name: USE_PROXY_PROTOCOL + value: "yes" + - name: REAL_IP_HEADER + value: "proxy_protocol" + - name: REAL_IP_FROM + value: "1.2.3.0/24 100.64.0.0/16" +...

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

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

    +...

    Don't forget to reload the bunkerweb service once it's done.

    Custom configurations

    -

    Because BunkerWeb is based on the NGINX web server, you can add custom NGINX configurations in different NGINX contexts. You can also apply custom configurations for the ModSecurity WAF which is a core component of BunkerWeb (more info here). Here is the list of custom configurations types :

    +

    Because BunkerWeb is based on the NGINX web server, you can add custom NGINX configurations in different NGINX contexts. You can also apply custom configurations for the ModSecurity WAF which is a core component of BunkerWeb (more info here). Here is the list of custom configurations types :

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

    -

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

    +

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

    For example, you can add a custom configuration with type modsec-crs to add CRS exclusions :

    -
    SecAction \
    - "id:900130,\
    +

    conf +SecAction \ + "id:900130,\ phase:1,\ nolog,\ pass,\ t:none,\ - setvar:tx.crs_exclusions_wordpress=1" -

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

    conf +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"

    Bad behavior

    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 :

    diff --git a/1.4/settings/index.html b/1.4/settings/index.html index f93ebd1..1fab3a1 100644 --- a/1.4/settings/index.html +++ b/1.4/settings/index.html @@ -791,7 +791,7 @@ documentation for the current version.

    Settings generator tool

    To help you tuning 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 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.

    +

    This section contains the full list of settings supported by BunkerWeb. If you are not 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.

    Global settings

    diff --git a/1.4/sitemap.xml b/1.4/sitemap.xml index 8bbc665..6f1c79a 100644 --- a/1.4/sitemap.xml +++ b/1.4/sitemap.xml @@ -2,57 +2,57 @@ https://docs.bunkerweb.io/1.4/ - 2022-06-03 + 2022-06-06 daily https://docs.bunkerweb.io/1.4/about/ - 2022-06-03 + 2022-06-06 daily https://docs.bunkerweb.io/1.4/concepts/ - 2022-06-03 + 2022-06-06 daily https://docs.bunkerweb.io/1.4/integrations/ - 2022-06-03 + 2022-06-06 daily https://docs.bunkerweb.io/1.4/migrating/ - 2022-06-03 + 2022-06-06 daily https://docs.bunkerweb.io/1.4/plugins/ - 2022-06-03 + 2022-06-06 daily https://docs.bunkerweb.io/1.4/quickstart-guide/ - 2022-06-03 + 2022-06-06 daily https://docs.bunkerweb.io/1.4/security-tuning/ - 2022-06-03 + 2022-06-06 daily https://docs.bunkerweb.io/1.4/settings/ - 2022-06-03 + 2022-06-06 daily https://docs.bunkerweb.io/1.4/troubleshooting/ - 2022-06-03 + 2022-06-06 daily https://docs.bunkerweb.io/1.4/web-ui/ - 2022-06-03 + 2022-06-06 daily \ No newline at end of file diff --git a/1.4/sitemap.xml.gz b/1.4/sitemap.xml.gz index 1377dd7..ae77d01 100644 Binary files a/1.4/sitemap.xml.gz and b/1.4/sitemap.xml.gz differ diff --git a/1.4/troubleshooting/index.html b/1.4/troubleshooting/index.html index a2413b6..fbeb2d1 100644 --- a/1.4/troubleshooting/index.html +++ b/1.4/troubleshooting/index.html @@ -644,66 +644,66 @@ documentation for the current version.

    List containers

    To list the running containers you can use the following command : -

    docker ps
    -

    +shell +docker ps

    You can use the docker logs command (replace mybunker with the name of your container) : -

    docker logs mybunker
    -

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

    +shell +docker-compose logs mybunker

    List containers

    To list the running containers you can use the following command : -

    docker ps
    -

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

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

    +shell +docker-compose logs mybunker +docker-compose logs myautoconf

    List services

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

    docker service ls
    -

    +shell +docker service ls

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

    docker service logs mybunker
    -docker service logs myautoconf
    -

    +shell +docker service logs mybunker +docker service logs myautoconf

    List pods

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

    kubectl get pods
    -

    +shell +kubectl get pods

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

    kubectl logs mybunker
    -kubectl logs myautoconf
    -

    +shell +kubectl logs mybunker +kubectl logs myautoconf

    The logs are located inside the /var/log/nginx directory. There is two files : -

    cat /var/log/nginx/error.log
    -cat /var/log/nginx/access.log
    -

    +shell +cat /var/log/nginx/error.log +cat /var/log/nginx/access.log

    Permissions

    -

    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.

    +

    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.

    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 :

    Let's take the following logs as an example of ModSecurity detection using default configuration (formatted for better readability) :

    -
    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 "/opt/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 "/opt/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 "/opt/bunkerweb/core/modsecurity/files/coreruleset/rules/REQUEST-949-BLOCKING-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"
    -
    +

    log +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 "/opt/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 "/opt/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 "/opt/bunkerweb/core/modsecurity/files/coreruleset/rules/REQUEST-949-BLOCKING-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. @@ -788,48 +788,48 @@ cat /var/log/nginx/access.log
    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).

    +

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

    Bad Behavior

    -

    A common false-positive case is that 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 edit them according to your web application(s) like removing a suspicious HTTP code, decreasing the count time, increasing the threshold, ...

    +

    A common false-positive case is that 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 edit them according to your web application(s) like removing a suspicious HTTP code, decreasing the count time, increasing the threshold, ...

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

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

    docker exec mybunker bwcli unban 1.2.3.4
    -

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

    +shell +docker-compose exec mybunker bwcli unban 1.2.3.4

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

    docker exec mybunker bwcli unban 1.2.3.4
    -

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

    +shell +docker-compose exec mybunker bwcli unban 1.2.3.4

    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
    -

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

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

    kubectl exec myautoconf bwcli unban 1.2.3.4
    -

    +shell +kubectl exec myautoconf bwcli unban 1.2.3.4

    You can use the bwcli command : -

    bwcli unban 1.2.3.4
    -

    +shell +bwcli unban 1.2.3.4

    Whitelisting

    -

    If you have bots that need to access your website, the recommended way to avoid any false positive is to whitelist it 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 :

    +

    If you have bots that need to access your website, the recommended way to avoid any false positive is to whitelist it 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 :

    Multisite mode

    -

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

    +

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

    UI specific env variables

    @@ -658,36 +658,36 @@ documentation for the current version.
    -

    When using the Docker integration, we recommend you to connect the BunkerWeb and web UI using a dedicated network and use another dedicated network for the communications between BunkerWeb and your web applications. The web UI can be deployed using a dedicated container based on the bunkerweb-ui image.

    +

    When using the Docker integration, we recommend you to connect the BunkerWeb and web UI using a dedicated network and use another dedicated network for the communications between BunkerWeb and your web applications. The web UI can be deployed using a dedicated container based on the bunkerweb-ui image.

    Let's start by creating the networks (replace 10.20.30.0/24 with an unused network of your choice) : -

    docker network create --subnet 10.20.30.0/24 bw-ui && \
    -docker network create bw-services
    -

    +shell +docker network create --subnet 10.20.30.0/24 bw-ui && \ +docker network create bw-services

    You will also need two volumes, one for the BunkerWeb data and another one to share the configuration files between the web UI and BunkerWeb : -

    docker volume create bw-data && \
    -docker volume create bw-confs
    -

    +shell +docker volume create bw-data && \ +docker volume create bw-confs

    You can now create the BunkerWeb container with specific settings and volumes related to the web UI, please note the special bunkerweb.UI label which is mandatory : -

    docker run -d \
    +shell
    +docker run -d \
        --name mybunker
    -   --network bw-services \
    -   -p 80:8080 \
    -   -p 443:8443 \
    -   -v bw-data:/data \
    -   -v bw-confs:/etc/nginx \
    -   -e SERVER_NAME=bwadm.example.com \
    -   -e MULTISITE=yes \
    -   -e "API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24" \
    -   -e bwadm.example.com_USE_UI=yes \
    -   -e bwadm.example.com_USE_REVERSE_PROXY=yes \
    -   -e bwadm.example.com_REVERSE_PROXY_URL=/changeme \
    -   -e bwadm.example.com_REVERSE_PROXY_HOST=http://myui:7000 \
    -   -e "bwadm.example.com_REVERSE_PROXY_HEADER=X-Script-Name /changeme" \
    -   -e bwadm.example.com_REVERSE_PROXY_INTERCEPT_ERRORS=no \
    -   -l bunkerweb.UI \
    -   bunkerity/bunkerweb:1.4.0 && \
    -docker network connect bw-ui mybunker
    -

    + --network bw-services \ + -p 80:8080 \ + -p 443:8443 \ + -v bw-data:/data \ + -v bw-confs:/etc/nginx \ + -e SERVER_NAME=bwadm.example.com \ + -e MULTISITE=yes \ + -e "API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24" \ + -e bwadm.example.com_USE_UI=yes \ + -e bwadm.example.com_USE_REVERSE_PROXY=yes \ + -e bwadm.example.com_REVERSE_PROXY_URL=/changeme \ + -e bwadm.example.com_REVERSE_PROXY_HOST=http://myui:7000 \ + -e "bwadm.example.com_REVERSE_PROXY_HEADER=X-Script-Name /changeme" \ + -e bwadm.example.com_REVERSE_PROXY_INTERCEPT_ERRORS=no \ + -l bunkerweb.UI \ + bunkerity/bunkerweb:1.4.0 && \ +docker network connect bw-ui mybunker

    Important things to note :

    • bwadm.example.com is the dedicated (sub)domain for accessing the web UI
    • @@ -697,103 +697,99 @@ docker network connect bw-ui mybunker

    The web UI will need to access the Docker API in order to get metadata about the running containers. It can be done easily by mounting the docker.sock file into the container. But there is a security risk : if the web UI is exploited, all your container(s) and the host will be impacted because, at the moment, Docker doesn't provide any restriction feature. We highly recommend using something like a docker socket proxy to mitigate that risk (only a subset of read-only API endpoints will be available to the web UI container).

    To connect the docker socket proxy and the web UI, you will need another network : -

    docker network create bw-docker
    -

    +shell +docker network create bw-docker

    Once the network is created, you can now create the docker socket proxy container : -

    docker run -d \
    -       --name mydocker \
    -       --network bw-docker \
    -       --privileged \
    -       -v /var/run/docker.sock:/var/run/docker.sock:ro \
    -       tecnativa/docker-socket-proxy
    -

    +shell +docker run -d \ + --name mydocker \ + --network bw-docker \ + --privileged \ + -v /var/run/docker.sock:/var/run/docker.sock:ro \ + tecnativa/docker-socket-proxy

    We can finally create the web UI container : -

    docker run -d \
    -       --name myui \
    -       --network bw-ui \
    -       -v bw-data:/data \
    -       -v bw-confs:/etc/nginx \
    -       -e DOCKER_HOST=tcp://mydocker:2375 \
    -       -e ADMIN_USERNAME=admin \
    -       -e ADMIN_PASSWORD=changeme \
    -       -e ABSOLUTE_URI=http(s)://bwadm.example.com/changeme/
    -       bunkerity/bunkerweb-ui:1.4.0 && \
    -docker network connect bw-docker myui
    -

    +shell +docker run -d \ + --name myui \ + --network bw-ui \ + -v bw-data:/data \ + -v bw-confs:/etc/nginx \ + -e DOCKER_HOST=tcp://mydocker:2375 \ + -e ADMIN_USERNAME=admin \ + -e ADMIN_PASSWORD=changeme \ + -e ABSOLUTE_URI=http(s)://bwadm.example.com/changeme/ + bunkerity/bunkerweb-ui:1.4.0 && \ +docker network connect bw-docker myui

    Important things to note :

    • http(s)://bwadmin.example.com/changeme/ is the full base URL of the web UI (must match the sub(domain) and /changeme URL used when creating the BunkerWeb container)
    • Replace the username admin and password changeme with strong ones

    Here is the docker-compose equivalent : -

    version: '3'
    -
    -services:
    -
    -  mybunker:
    -    image: bunkerity/bunkerweb:1.4.0
    -    networks:
    -      - bw-services
    -      - bw-ui
    -    ports:
    -      - 80:8080
    -    volumes:
    -      - bw-data:/data
    -      - bw-confs:/etc/nginx
    -    environment:
    -      - SERVER_NAME=bwadm.example.com
    -      - MULTISITE=yes
    -      - API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
    -      - bwadm.example.com_USE_UI=yes
    -      - bwadm.example.com_USE_REVERSE_PROXY=yes
    -      - bwadm.example.com_REVERSE_PROXY_URL=/changeme/
    -      - bwadm.example.com_REVERSE_PROXY_HOST=http://myui:7000
    -      - bwadm.example.com_REVERSE_PROXY_HEADERS=X-Script-Name /changeme
    -      - bwadm.example.com_REVERSE_PROXY_INTERCEPT_ERRORS=no
    -    labels:
    -      - "bunkerweb.UI"
    -
    -  myui:
    -    image: bunkerity/bunkerweb-ui:1.4.0
    -    depends_on:
    -      - mydocker
    -    networks:
    -      - bw-ui
    -      - bw-docker
    -    volumes:
    -      - bw-data:/data
    -      - bw-confs:/etc/nginx
    -    environment:
    -      - DOCKER_HOST=tcp://mydocker:2375
    -      - ADMIN_USERNAME=admin
    -      - ADMIN_PASSWORD=changeme
    -      - ABSOLUTE_URI=http(s)://bwadm.example.com/changeme/
    -
    -  mydocker:
    -    image: tecnativa/docker-socket-proxy
    -    networks:
    -      - bw-docker
    -    volumes:
    -      - /var/run/docker.sock:/var/run/docker.sock:ro
    -
    -networks:
    -  bw-services:
    -  bw-ui:
    -    ipam:
    -      driver: default
    -      config:
    -        - subnet: 10.20.30.0/24
    -  bw-docker:
    -
    -volumes:
    -  bw-data:
    -  bw-confs:
    -

    +```yaml +version: '3'

    +

    services:

    +

    mybunker: + image: bunkerity/bunkerweb:1.4.0 + networks: + - bw-services + - bw-ui + ports: + - 80:8080 + volumes: + - bw-data:/data + - bw-confs:/etc/nginx + environment: + - SERVER_NAME=bwadm.example.com + - MULTISITE=yes + - API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24 + - bwadm.example.com_USE_UI=yes + - bwadm.example.com_USE_REVERSE_PROXY=yes + - bwadm.example.com_REVERSE_PROXY_URL=/changeme/ + - bwadm.example.com_REVERSE_PROXY_HOST=http://myui:7000 + - bwadm.example.com_REVERSE_PROXY_HEADERS=X-Script-Name /changeme + - bwadm.example.com_REVERSE_PROXY_INTERCEPT_ERRORS=no + labels: + - "bunkerweb.UI"

    +

    myui: + image: bunkerity/bunkerweb-ui:1.4.0 + depends_on: + - mydocker + networks: + - bw-ui + - bw-docker + volumes: + - bw-data:/data + - bw-confs:/etc/nginx + environment: + - DOCKER_HOST=tcp://mydocker:2375 + - ADMIN_USERNAME=admin + - ADMIN_PASSWORD=changeme + - ABSOLUTE_URI=http(s)://bwadm.example.com/changeme/

    +

    mydocker: + image: tecnativa/docker-socket-proxy + networks: + - bw-docker + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro

    +

    networks: + bw-services: + bw-ui: + ipam: + driver: default + config: + - subnet: 10.20.30.0/24 + bw-docker:

    +

    volumes: + bw-data: + bw-confs: +```

    -

    The installation of the web UI using the Linux integration is pretty straightforward because it is installed with BunkerWeb.

    +

    The installation of the web UI using the Linux integration is pretty straightforward because it is installed with BunkerWeb.

    The first thing to do is to edit the BunkerWeb configuration located at /opt/bunkerweb/variables.env to add settings related to the web UI : -

    HTTP_PORT=80
    +conf
    +HTTP_PORT=80
     HTTPS_PORT=443
     DNS_RESOLVERS=8.8.8.8 8.8.4.4
     ...
    @@ -807,29 +803,28 @@ bwadm.example.com_REVERSE_PROXY_URL=/changeme
     bwadm.example.com_REVERSE_PROXY_HOST=http://myui:7000
     bwadm.example.com_REVERSE_PROXY_HEADER=X-Script-Name /changeme
     bwadm.example.com_REVERSE_PROXY_INTERCEPT_ERRORS=no
    -...
    -

    +...

    Important things to note :

    • bwadm.example.com is the dedicated (sub)domain for accessing the web UI
    • replace the /changeme URL with a custom one of your choice

    Once the configuration file is edited, you will need to reload BunkerWeb : -

    systemctl reload bunkerweb
    -

    +shell +systemctl reload bunkerweb

    You can edit the /opt/bunkerweb/ui.env file containing the settings of the web UI : -

    ADMIN_USERNAME=admin
    +conf
    +ADMIN_USERNAME=admin
     ADMIN_PASSWORD=changeme
    -ABSOLUTE_URI=http(s)://bwadm.example.com/changeme/
    -

    +ABSOLUTE_URI=http(s)://bwadm.example.com/changeme/

    Important things to note :

    • http(s)://bwadmin.example.com/changeme/ is the full base URL of the web UI (must match the sub(domain) and /changeme URL used in /opt/bunkerweb/variables.env)
    • replace the username admin and password changeme with strong ones

    Restart the BunkerWeb UI service and you are now ready to access it : -

    systemctl restart bunkerweb-ui
    -

    +shell +systemctl restart bunkerweb-ui