commit
535f1a0552
|
@ -3,7 +3,7 @@
|
|||
## Overview
|
||||
|
||||
<figure markdown>
|
||||
![Overview](assets/img/intro-overview.svg){ align=center }
|
||||
![Overview](assets/img/intro-overview.svg){ align=center, width="800" }
|
||||
<figcaption>Make your web services secure by default !</figcaption>
|
||||
</figure>
|
||||
|
||||
|
@ -38,7 +38,7 @@ Learn more about the core security features in the [security tuning](security-tu
|
|||
## Demo
|
||||
|
||||
<figure markdown>
|
||||
![Overwiew](assets/img/demo.gif){ align=center }
|
||||
![Demo](assets/img/demo.gif){ align=center }
|
||||
<figcaption>Fooling automated tools/scanners</figcaption>
|
||||
</figure>
|
||||
|
||||
|
|
256
docs/settings.md
256
docs/settings.md
|
@ -12,44 +12,48 @@ When settings are considered as "multiple", it means that you can have multiple
|
|||
|
||||
## Global settings
|
||||
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|-----------------------|------------------------------------------------------------------------------------------------------------------------|---------|--------|--------------------------------------------------|
|
||||
|`IS_LOADING` |`no` |global |no |Internal use : set to yes when BW is loading. |
|
||||
|`NGINX_PREFIX` |`/etc/nginx/` |global |no |Where nginx will search for configurations. |
|
||||
|`HTTP_PORT` |`8080` |global |no |HTTP port number which bunkerweb binds to. |
|
||||
|`HTTPS_PORT` |`8443` |global |no |HTTPS port number which bunkerweb binds to. |
|
||||
|`MULTISITE` |`no` |global |no |Multi site activation. |
|
||||
|`SERVER_NAME` |`www.example.com` |multisite|no |List of the virtual hosts served by bunkerweb. |
|
||||
|`WORKER_PROCESSES` |`auto` |global |no |Number of worker processes. |
|
||||
|`WORKER_RLIMIT_NOFILE` |`2048` |global |no |Maximum number of open files for worker processes.|
|
||||
|`WORKER_CONNECTIONS` |`1024` |global |no |Maximum number of connections per worker. |
|
||||
|`LOG_FORMAT` |`$host $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"`|global |no |The format to use for access logs. |
|
||||
|`LOG_LEVEL` |`notice` |global |no |The level to use for error logs. |
|
||||
|`DNS_RESOLVERS` |`127.0.0.11` |global |no |DNS addresses of resolvers to use. |
|
||||
|`DATASTORE_MEMORY_SIZE`|`256m` |global |no |Size of the internal datastore. |
|
||||
|`USE_API` |`yes` |global |no |Activate the API to control BunkerWeb. |
|
||||
|`API_HTTP_PORT` |`5000` |global |no |Listen port number for the API. |
|
||||
|`API_SERVER_NAME` |`bwapi` |global |no |Server name (virtual host) for the API. |
|
||||
|`API_WHITELIST_IP` |`127.0.0.0/8` |global |no |List of IP/network allowed to contact the API. |
|
||||
|`AUTOCONF_MODE` |`no` |global |no |Enable Autoconf Docker integration. |
|
||||
|`SWARM_MODE` |`no` |global |no |Enable Docker Swarm integration. |
|
||||
|`KUBERNETES_MODE` |`no` |global |no |Enable Kubernetes integration. |
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|------------------------|------------------------------------------------------------------------------------------------------------------------|---------|--------|--------------------------------------------------|
|
||||
|`IS_LOADING` |`no` |global |no |Internal use : set to yes when BW is loading. |
|
||||
|`NGINX_PREFIX` |`/etc/nginx/` |global |no |Where nginx will search for configurations. |
|
||||
|`HTTP_PORT` |`8080` |global |no |HTTP port number which bunkerweb binds to. |
|
||||
|`HTTPS_PORT` |`8443` |global |no |HTTPS port number which bunkerweb binds to. |
|
||||
|`MULTISITE` |`no` |global |no |Multi site activation. |
|
||||
|`SERVER_NAME` |`www.example.com` |multisite|no |List of the virtual hosts served by bunkerweb. |
|
||||
|`WORKER_PROCESSES` |`auto` |global |no |Number of worker processes. |
|
||||
|`WORKER_RLIMIT_NOFILE` |`2048` |global |no |Maximum number of open files for worker processes.|
|
||||
|`WORKER_CONNECTIONS` |`1024` |global |no |Maximum number of connections per worker. |
|
||||
|`LOG_FORMAT` |`$host $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"`|global |no |The format to use for access logs. |
|
||||
|`LOG_LEVEL` |`notice` |global |no |The level to use for error logs. |
|
||||
|`DNS_RESOLVERS` |`127.0.0.11` |global |no |DNS addresses of resolvers to use. |
|
||||
|`DATASTORE_MEMORY_SIZE` |`256m` |global |no |Size of the internal datastore. |
|
||||
|`USE_API` |`yes` |global |no |Activate the API to control BunkerWeb. |
|
||||
|`API_HTTP_PORT` |`5000` |global |no |Listen port number for the API. |
|
||||
|`API_LISTEN_IP` |`0.0.0.0` |global |no |Listen IP address for the API. |
|
||||
|`API_SERVER_NAME` |`bwapi` |global |no |Server name (virtual host) for the API. |
|
||||
|`API_WHITELIST_IP` |`127.0.0.0/8` |global |no |List of IP/network allowed to contact the API. |
|
||||
|`AUTOCONF_MODE` |`no` |global |no |Enable Autoconf Docker integration. |
|
||||
|`SWARM_MODE` |`no` |global |no |Enable Docker Swarm integration. |
|
||||
|`KUBERNETES_MODE` |`no` |global |no |Enable Kubernetes integration. |
|
||||
|`SERVER_TYPE` |`http` |multisite|no |Server type : http or stream. |
|
||||
|`LISTEN_STREAM` |`yes` |multisite|no |Enable listening for non-ssl (passthrough). |
|
||||
|`LISTEN_STREAM_PORT` |`1337` |multisite|no |Listening port for non-ssl (passthrough). |
|
||||
|`LISTEN_STREAM_PORT_SSL`|`4242` |multisite|no |Listening port for ssl (passthrough). |
|
||||
|`USE_UDP` |`no` |multisite|no |UDP listen instead of TCP (stream). |
|
||||
|
||||
## Core settings
|
||||
|
||||
### Antibot
|
||||
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|---------------------------|------------|---------|--------|---------------------------------------------------------------------------------|
|
||||
|`USE_ANTIBOT` |`no` |multisite|no |Activate antibot feature. |
|
||||
|`ANTIBOT_URI` |`/challenge`|multisite|no |Unused URI that clients will be redirected to to solve the challenge. |
|
||||
|`ANTIBOT_SESSION_SECRET` |`random` |global |no |Secret used to encrypt sessions variables for storing data related to challenges.|
|
||||
|`ANTIBOT_SESSION_NAME` |`random` |global |no |Name of the cookie used by the antibot feature. |
|
||||
|`ANTIBOT_RECAPTCHA_SCORE` |`0.7` |multisite|no |Minimum score required for reCAPTCHA challenge. |
|
||||
|`ANTIBOT_RECAPTCHA_SITEKEY`| |multisite|no |Sitekey for reCAPTCHA challenge. |
|
||||
|`ANTIBOT_RECAPTCHA_SECRET` | |multisite|no |Secret for reCAPTCHA challenge. |
|
||||
|`ANTIBOT_HCAPTCHA_SITEKEY` | |multisite|no |Sitekey for hCaptcha challenge. |
|
||||
|`ANTIBOT_HCAPTCHA_SECRET` | |multisite|no |Secret for hCaptcha challenge. |
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|---------------------------|------------|---------|--------|---------------------------------------------------------------------|
|
||||
|`USE_ANTIBOT` |`no` |multisite|no |Activate antibot feature. |
|
||||
|`ANTIBOT_URI` |`/challenge`|multisite|no |Unused URI that clients will be redirected to to solve the challenge.|
|
||||
|`ANTIBOT_RECAPTCHA_SCORE` |`0.7` |multisite|no |Minimum score required for reCAPTCHA challenge. |
|
||||
|`ANTIBOT_RECAPTCHA_SITEKEY`| |multisite|no |Sitekey for reCAPTCHA challenge. |
|
||||
|`ANTIBOT_RECAPTCHA_SECRET` | |multisite|no |Secret for reCAPTCHA challenge. |
|
||||
|`ANTIBOT_HCAPTCHA_SITEKEY` | |multisite|no |Sitekey for hCaptcha challenge. |
|
||||
|`ANTIBOT_HCAPTCHA_SECRET` | |multisite|no |Secret for hCaptcha challenge. |
|
||||
|
||||
### Auth basic
|
||||
|
||||
|
@ -69,26 +73,26 @@ When settings are considered as "multiple", it means that you can have multiple
|
|||
|`BAD_BEHAVIOR_STATUS_CODES`|`400 401 403 404 405 429 444`|multisite|no |List of HTTP status codes considered as 'bad'. |
|
||||
|`BAD_BEHAVIOR_BAN_TIME` |`86400` |multisite|no |The duration time (in seconds) of a ban when the corresponding IP has reached the threshold.|
|
||||
|`BAD_BEHAVIOR_THRESHOLD` |`10` |multisite|no |Maximum number of 'bad' HTTP status codes within the period of time before IP is banned. |
|
||||
|`BAD_BEHAVIOR_COUNT_TIME` |`60` |multisite|no |Period of time during which we count 'bad' HTTP status codes. |
|
||||
|`BAD_BEHAVIOR_COUNT_TIME` |`60` |multisite|no |Period of time (in seconds) during which we count 'bad' HTTP status codes. |
|
||||
|
||||
### Blacklist
|
||||
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|----------------------------------|------------------------------------------------------------------------------------------------------------------------------|---------|--------|------------------------------------------------------------------------------------------------|
|
||||
|`USE_BLACKLIST` |`yes` |multisite|no |Activate blacklist feature. |
|
||||
|`BLACKLIST_IP_URLS` |`https://www.dan.me.uk/torlist/?exit` |global |no |List of URLs, separated with spaces, containing bad IP/network to block. |
|
||||
|`BLACKLIST_IP` | |multisite|no |List of IP/network, separated with spaces, to block. |
|
||||
|`BLACKLIST_IP_URLS` |`https://www.dan.me.uk/torlist/?exit` |global |no |List of URLs, separated with spaces, containing bad IP/network to block. |
|
||||
|`BLACKLIST_RDNS_GLOBAL` |`yes` |multisite|no |Only perform RDNS blacklist checks on global IP addresses. |
|
||||
|`BLACKLIST_RDNS` |`.shodan.io .censys.io` |multisite|no |List of reverse DNS suffixes, separated with spaces, to block. |
|
||||
|`BLACKLIST_RDNS_URLS` | |global |no |List of URLs, separated with spaces, containing reverse DNS suffixes to block. |
|
||||
|`BLACKLIST_RDNS_GLOBAL` |`yes` |multisite|no |Only perform RDNS blacklist checks on global IP addresses. |
|
||||
|`BLACKLIST_ASN` | |multisite|no |List of ASN numbers, separated with spaces, to block. |
|
||||
|`BLACKLIST_ASN_URLS` | |global |no |List of URLs, separated with spaces, containing ASN to block. |
|
||||
|`BLACKLIST_USER_AGENT` | |multisite|no |List of User-Agent, separated with spaces, to block. |
|
||||
|`BLACKLIST_USER_AGENT_URLS` |`https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/_generator_lists/bad-user-agents.list`|global |no |List of URLs, separated with spaces, containing bad User-Agent to block. |
|
||||
|`BLACKLIST_URI` | |multisite|no |List of URI, separated with spaces, to block. |
|
||||
|`BLACKLIST_URI_URLS` | |global |no |List of URLs, separated with spaces, containing bad URI to block. |
|
||||
|`BLACKLIST_IGNORE_IP_URLS` | |global |no |List of URLs, separated with spaces, containing IP/network to ignore in the blacklist. |
|
||||
|`BLACKLIST_IGNORE_IP` | |multisite|no |List of IP/network, separated with spaces, to ignore in the blacklist. |
|
||||
|`BLACKLIST_IGNORE_IP_URLS` | |global |no |List of URLs, separated with spaces, containing IP/network to ignore in the blacklist. |
|
||||
|`BLACKLIST_IGNORE_RDNS` | |multisite|no |List of reverse DNS suffixes, separated with spaces, to ignore in the blacklist. |
|
||||
|`BLACKLIST_IGNORE_RDNS_URLS` | |global |no |List of URLs, separated with spaces, containing reverse DNS suffixes to ignore in the blacklist.|
|
||||
|`BLACKLIST_IGNORE_ASN` | |multisite|no |List of ASN numbers, separated with spaces, to ignore in the blacklist. |
|
||||
|
@ -128,12 +132,12 @@ When settings are considered as "multiple", it means that you can have multiple
|
|||
|
||||
### Client cache
|
||||
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|-------------------------|------------------------------------------------------------|---------|--------|-----------------------------------------------|
|
||||
|`USE_CLIENT_CACHE` |`no` |multisite|no |Tell client to store locally static files. |
|
||||
|`CLIENT_CACHE_EXTENSIONS`|`jpg\|jpeg\|png\|bmp\|ico\|svg\|tif\|css\|js\|otf\|ttf\|eot\|woff\|woff2`|global |no |List of file extensions that should be cached. |
|
||||
|`CLIENT_CACHE_ETAG` |`yes` |multisite|no |Send the HTTP ETag header for static resources.|
|
||||
|`CLIENT_CACHE_CONTROL` |`public, max-age=15552000` |multisite|no |Value of the Cache-Control HTTP header. |
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|-------------------------|------------------------------------------------------------|---------|--------|--------------------------------------------------------------------|
|
||||
|`USE_CLIENT_CACHE` |`no` |multisite|no |Tell client to store locally static files. |
|
||||
|`CLIENT_CACHE_EXTENSIONS`|`jpg\|jpeg\|png\|bmp\|ico\|svg\|tif\|css\|js\|otf\|ttf\|eot\|woff\|woff2`|global |no |List of file extensions, separated with pipes that should be cached.|
|
||||
|`CLIENT_CACHE_ETAG` |`yes` |multisite|no |Send the HTTP ETag header for static resources. |
|
||||
|`CLIENT_CACHE_CONTROL` |`public, max-age=15552000` |multisite|no |Value of the Cache-Control HTTP header. |
|
||||
|
||||
### Country
|
||||
|
||||
|
@ -144,17 +148,17 @@ When settings are considered as "multiple", it means that you can have multiple
|
|||
|
||||
### Custom HTTPS certificate
|
||||
|
||||
| Setting |Default| Context |Multiple| Description |
|
||||
|-------------------|-------|---------|--------|--------------------------------------------|
|
||||
|`USE_CUSTOM_HTTPS` |`no` |multisite|no |Use custom HTTPS certificate. |
|
||||
|`CUSTOM_HTTPS_CERT`| |multisite|no |Full path of the certificate or bundle file.|
|
||||
|`CUSTOM_HTTPS_KEY` | |multisite|no |Full path of the key file. |
|
||||
| Setting |Default| Context |Multiple| Description |
|
||||
|-----------------|-------|---------|--------|--------------------------------------------|
|
||||
|`USE_CUSTOM_SSL` |`no` |multisite|no |Use custom HTTPS certificate. |
|
||||
|`CUSTOM_SSL_CERT`| |multisite|no |Full path of the certificate or bundle file.|
|
||||
|`CUSTOM_SSL_KEY` | |multisite|no |Full path of the key file. |
|
||||
|
||||
### DB
|
||||
|
||||
| Setting | Default |Context|Multiple| Description |
|
||||
|--------------|----------------------------|-------|--------|--------------------------------------------------|
|
||||
|`DATABASE_URI`|`sqlite:////data/db.sqlite3`|global |no |The database URI, following the sqlalchemy format.|
|
||||
| Setting | Default |Context|Multiple| Description |
|
||||
|--------------|-----------------------------------------|-------|--------|--------------------------------------------------|
|
||||
|`DATABASE_URI`|`sqlite:////var/lib/bunkerweb/db.sqlite3`|global |no |The database URI, following the sqlalchemy format.|
|
||||
|
||||
### DNSBL
|
||||
|
||||
|
@ -165,20 +169,21 @@ When settings are considered as "multiple", it means that you can have multiple
|
|||
|
||||
### Errors
|
||||
|
||||
|Setting |Default| Context |Multiple| Description |
|
||||
|--------|-------|---------|--------|-------------------------------------------------------------------------------------------------|
|
||||
|`ERRORS`| |multisite|no |List of HTTP error code and corresponding error pages (404=/my404.html 403=/errors/403.html ...).|
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|-------------------------|-------------------------------------------------|---------|--------|------------------------------------------------------------------------------------------------------------------------|
|
||||
|`ERRORS` | |multisite|no |List of HTTP error code and corresponding error pages, separated with spaces (404=/my404.html 403=/errors/403.html ...).|
|
||||
|`INTERCEPTED_ERROR_CODES`|`400 401 403 404 405 413 429 500 501 502 503 504`|multisite|no |List of HTTP error code intercepted by Bunkerweb |
|
||||
|
||||
### Greylist
|
||||
|
||||
| Setting |Default| Context |Multiple| Description |
|
||||
|--------------------------|-------|---------|--------|----------------------------------------------------------------------------------------------|
|
||||
|`USE_GREYLIST` |`no` |multisite|no |Activate greylist feature. |
|
||||
|`GREYLIST_IP_URLS` | |global |no |List of URLs, separated with spaces, containing good IP/network to put into the greylist. |
|
||||
|`GREYLIST_IP` | |multisite|no |List of IP/network, separated with spaces, to put into the greylist. |
|
||||
|`GREYLIST_IP_URLS` | |global |no |List of URLs, separated with spaces, containing good IP/network to put into the greylist. |
|
||||
|`GREYLIST_RDNS_GLOBAL` |`yes` |multisite|no |Only perform RDNS greylist checks on global IP addresses. |
|
||||
|`GREYLIST_RDNS` | |multisite|no |List of reverse DNS suffixes, separated with spaces, to put into the greylist. |
|
||||
|`GREYLIST_RDNS_URLS` | |global |no |List of URLs, separated with spaces, containing reverse DNS suffixes to put into the greylist.|
|
||||
|`GREYLIST_RDNS_GLOBAL` |`yes` |multisite|no |Only perform RDNS greylist checks on global IP addresses. |
|
||||
|`GREYLIST_ASN` | |multisite|no |List of ASN numbers, separated with spaces, to put into the greylist. |
|
||||
|`GREYLIST_ASN_URLS` | |global |no |List of URLs, separated with spaces, containing ASN to put into the greylist. |
|
||||
|`GREYLIST_USER_AGENT` | |multisite|no |List of User-Agent, separated with spaces, to put into the greylist. |
|
||||
|
@ -203,20 +208,20 @@ When settings are considered as "multiple", it means that you can have multiple
|
|||
|
||||
### Headers
|
||||
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|---------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|----------------------------------------------------------------------------------------------|
|
||||
|`CUSTOM_HEADER` | |multisite|yes |Custom header to add (HeaderName: HeaderValue). |
|
||||
|`REMOVE_HEADERS` |`Server X-Powered-By X-AspNet-Version X-AspNetMvc-Version` |multisite|no |Headers to remove (Header1 Header2 Header3 ...) |
|
||||
|`STRICT_TRANSPORT_SECURITY`|`max-age=31536000` |multisite|no |Value for the Strict-Transport-Security header. |
|
||||
|`COOKIE_FLAGS` |`* HttpOnly SameSite=Lax` |multisite|no |Cookie flags automatically added to all cookies (value accepted for nginx_cookie_flag_module).|
|
||||
|`COOKIE_AUTO_SECURE_FLAG` |`yes` |multisite|no |Automatically add the Secure flag to all cookies. |
|
||||
|`CONTENT_SECURITY_POLICY` |`object-src 'none'; form-action 'self'; frame-ancestors 'self';` |multisite|no |Value for the Content-Security-Policy header. |
|
||||
|`REFERRER_POLICY` |`strict-origin-when-cross-origin` |multisite|no |Value for the Referrer-Policy header. |
|
||||
|`PERMISSIONS_POLICY` |`accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), serial=(), usb=(), web-share=(), xr-spatial-tracking=()` |multisite|no |Value for the Permissions-Policy header. |
|
||||
|`FEATURE_POLICY` |`accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; execution-while-not-rendered 'none'; execution-while-out-of-viewport 'none'; fullscreen 'none'; 'none'; geolocation 'none'; gyroscope 'none'; layout-animation 'none'; legacy-image-formats 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; navigation-override 'none'; payment 'none'; picture-in-picture 'none'; publickey-credentials-get 'none'; speaker-selection 'none'; sync-xhr 'none'; unoptimized-images 'none'; unsized-media 'none'; usb 'none'; screen-wake-lock 'none'; web-share 'none'; xr-spatial-tracking 'none';`|multisite|no |Value for the Feature-Policy header. |
|
||||
|`X_FRAME_OPTIONS` |`SAMEORIGIN` |multisite|no |Value for the X-Frame-Options header. |
|
||||
|`X_CONTENT_TYPE_OPTIONS` |`nosniff` |multisite|no |Value for the X-Content-Type-Options header. |
|
||||
|`X_XSS_PROTECTION` |`1; mode=block` |multisite|no |Value for the X-XSS-Protection header. |
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|---------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|----------------------------------------------------------------------------------------------|
|
||||
|`CUSTOM_HEADER` | |multisite|yes |Custom header to add (HeaderName: HeaderValue). |
|
||||
|`REMOVE_HEADERS` |`Server X-Powered-By X-AspNet-Version X-AspNetMvc-Version` |multisite|no |Headers to remove (Header1 Header2 Header3 ...) |
|
||||
|`STRICT_TRANSPORT_SECURITY`|`max-age=31536000` |multisite|no |Value for the Strict-Transport-Security header. |
|
||||
|`COOKIE_FLAGS` |`* HttpOnly SameSite=Lax` |multisite|yes |Cookie flags automatically added to all cookies (value accepted for nginx_cookie_flag_module).|
|
||||
|`COOKIE_AUTO_SECURE_FLAG` |`yes` |multisite|no |Automatically add the Secure flag to all cookies. |
|
||||
|`CONTENT_SECURITY_POLICY` |`object-src 'none'; form-action 'self'; frame-ancestors 'self';` |multisite|no |Value for the Content-Security-Policy header. |
|
||||
|`REFERRER_POLICY` |`strict-origin-when-cross-origin` |multisite|no |Value for the Referrer-Policy header. |
|
||||
|`PERMISSIONS_POLICY` |`accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), serial=(), usb=(), web-share=(), xr-spatial-tracking=()` |multisite|no |Value for the Permissions-Policy header. |
|
||||
|`FEATURE_POLICY` |`accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; execution-while-not-rendered 'none'; execution-while-out-of-viewport 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; layout-animation 'none'; legacy-image-formats 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; navigation-override 'none'; payment 'none'; picture-in-picture 'none'; publickey-credentials-get 'none'; speaker-selection 'none'; sync-xhr 'none'; unoptimized-images 'none'; unsized-media 'none'; usb 'none'; screen-wake-lock 'none'; web-share 'none'; xr-spatial-tracking 'none';`|multisite|no |Value for the Feature-Policy header. |
|
||||
|`X_FRAME_OPTIONS` |`SAMEORIGIN` |multisite|no |Value for the X-Frame-Options header. |
|
||||
|`X_CONTENT_TYPE_OPTIONS` |`nosniff` |multisite|no |Value for the X-Content-Type-Options header. |
|
||||
|`X_XSS_PROTECTION` |`1; mode=block` |multisite|no |Value for the X-XSS-Protection header. |
|
||||
|
||||
### Let's Encrypt
|
||||
|
||||
|
@ -244,11 +249,11 @@ When settings are considered as "multiple", it means that you can have multiple
|
|||
|`DISABLE_DEFAULT_SERVER` |`no` |global |no |Close connection if the request vhost is unknown. |
|
||||
|`REDIRECT_HTTP_TO_HTTPS` |`no` |multisite|no |Redirect all HTTP request to HTTPS. |
|
||||
|`AUTO_REDIRECT_HTTP_TO_HTTPS`|`yes` |multisite|no |Try to detect if HTTPS is used and activate HTTP to HTTPS redirection if that's the case. |
|
||||
|`ALLOWED_METHODS` |`GET\|POST\|HEAD` |multisite|no |Allowed HTTP methods to be sent by clients. |
|
||||
|`ALLOWED_METHODS` |`GET\|POST\|HEAD` |multisite|no |Allowed HTTP and WebDAV methods, separated with pipes to be sent by clients. |
|
||||
|`MAX_CLIENT_SIZE` |`10m` |multisite|no |Maximum body size (0 for infinite). |
|
||||
|`SERVE_FILES` |`yes` |multisite|no |Serve files from the local folder. |
|
||||
|`ROOT_FOLDER` | |multisite|no |Root folder containing files to serve (/var/www/html/{server_name} if unset). |
|
||||
|`HTTPS_PROTOCOLS` |`TLSv1.2 TLSv1.3` |multisite|no |The supported version of TLS. We recommend the default value TLSv1.2 TLSv1.3 for compatibility reasons. |
|
||||
|`SSL_PROTOCOLS` |`TLSv1.2 TLSv1.3` |multisite|no |The supported version of TLS. We recommend the default value TLSv1.2 TLSv1.3 for compatibility reasons. |
|
||||
|`HTTP2` |`yes` |multisite|no |Support HTTP2 protocol when HTTPS is enabled. |
|
||||
|`LISTEN_HTTP` |`yes` |multisite|no |Respond to (insecure) HTTP requests. |
|
||||
|`USE_OPEN_FILE_CACHE` |`no` |multisite|no |Enable open file cache feature |
|
||||
|
@ -280,14 +285,14 @@ When settings are considered as "multiple", it means that you can have multiple
|
|||
|
||||
### Real IP
|
||||
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|--------------------|-----------------------------------------|---------|--------|--------------------------------------------------------------------------------------|
|
||||
|`USE_REAL_IP` |`no` |multisite|no |Retrieve the real IP of client. |
|
||||
|`USE_PROXY_PROTOCOL`|`no` |multisite|no |Enable PROXY protocol communication. |
|
||||
|`REAL_IP_FROM` |`192.168.0.0/16 172.16.0.0/12 10.0.0.0/8`|multisite|no |List of trusted IPs / networks where proxied requests come from. |
|
||||
|`REAL_IP_FROM_URLS` | |global |no |List of URLs containing trusted IPs / networks where proxied requests come from. |
|
||||
|`REAL_IP_HEADER` |`X-Forwarded-For` |multisite|no |HTTP header containing the real IP or special value proxy_protocol for PROXY protocol.|
|
||||
|`REAL_IP_RECURSIVE` |`yes` |multisite|no |Perform a recursive search in the header container IP address. |
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|--------------------|-----------------------------------------|---------|--------|--------------------------------------------------------------------------------------------------------|
|
||||
|`USE_REAL_IP` |`no` |multisite|no |Retrieve the real IP of client. |
|
||||
|`USE_PROXY_PROTOCOL`|`no` |multisite|no |Enable PROXY protocol communication. |
|
||||
|`REAL_IP_FROM` |`192.168.0.0/16 172.16.0.0/12 10.0.0.0/8`|multisite|no |List of trusted IPs / networks, separated with spaces, where proxied requests come from. |
|
||||
|`REAL_IP_FROM_URLS` | |global |no |List of URLs containing trusted IPs / networks, separated with spaces, where proxied requests come from.|
|
||||
|`REAL_IP_HEADER` |`X-Forwarded-For` |multisite|no |HTTP header containing the real IP or special value proxy_protocol for PROXY protocol. |
|
||||
|`REAL_IP_RECURSIVE` |`yes` |multisite|no |Perform a recursive search in the header container IP address. |
|
||||
|
||||
### Redirect
|
||||
|
||||
|
@ -296,44 +301,75 @@ When settings are considered as "multiple", it means that you can have multiple
|
|||
|`REDIRECT_TO` | |multisite|no |Redirect a whole site to another one. |
|
||||
|`REDIRECT_TO_REQUEST_URI`|`no` |multisite|no |Append the requested URI to the redirect address.|
|
||||
|
||||
### Redis
|
||||
|
||||
| Setting |Default|Context|Multiple| Description |
|
||||
|----------------------|-------|-------|--------|------------------------------------------------------------------|
|
||||
|`USE_REDIS` |`no` |global |no |Activate Redis. |
|
||||
|`REDIS_HOST` | |global |no |Redis server IP or hostname. |
|
||||
|`REDIS_PORT` |`6379` |global |no |Redis server port. |
|
||||
|`REDIS_DATABASE` |`0` |global |no |Redis database number. |
|
||||
|`REDIS_SSL` |`no` |global |no |Use SSL/TLS connection with Redis server. |
|
||||
|`REDIS_TIMEOUT` |`1000` |global |no |Redis server timeout (in ms) for connect, read and write. |
|
||||
|`REDIS_KEEPALIVE_IDLE`|`30000`|global |no |Max idle time (in ms) before closing redis connection in the pool.|
|
||||
|`REDIS_KEEPALIVE_POOL`|`10` |global |no |Max number of redis connection(s) kept in the pool. |
|
||||
|
||||
### Reverse proxy
|
||||
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|---------------------------------------|----------------------------------|---------|--------|--------------------------------------------------------------------------------------------------------------------|
|
||||
|`USE_REVERSE_PROXY` |`no` |multisite|no |Activate reverse proxy mode. |
|
||||
|`REVERSE_PROXY_INTERCEPT_ERRORS` |`yes` |multisite|no |Intercept and rewrite errors. |
|
||||
|`REVERSE_PROXY_HOST` | |multisite|yes |Full URL of the proxied resource (proxy_pass). |
|
||||
|`REVERSE_PROXY_URL` | |multisite|yes |Location URL that will be proxied. |
|
||||
|`REVERSE_PROXY_WS` |`no` |multisite|yes |Enable websocket on the proxied resource. |
|
||||
|`REVERSE_PROXY_HEADERS` | |multisite|yes |List of HTTP headers to send to proxied resource separated with ; (values for proxy_set_header directive). |
|
||||
|`REVERSE_PROXY_HEADERS_CLIENT` | |multisite|yes |List of HTTP headers to send to client separated with ; (values for add_header directive). |
|
||||
|`REVERSE_PROXY_BUFFERING` |`yes` |multisite|yes |Enable or disable buffering of responses from proxied resource. |
|
||||
|`REVERSE_PROXY_KEEPALIVE` |`no` |multisite|yes |Enable or disable keepalive connections with the proxied resource. |
|
||||
|`REVERSE_PROXY_AUTH_REQUEST` | |multisite|yes |Enable authentication using an external provider (value of auth_request directive). |
|
||||
|`REVERSE_PROXY_AUTH_REQUEST_SIGNIN_URL`| |multisite|yes |Redirect clients to sign-in URL when using REVERSE_PROXY_AUTH_REQUEST (used when auth_request call returned 401). |
|
||||
|`REVERSE_PROXY_AUTH_REQUEST_SET` | |multisite|yes |List of variables to set from the authentication provider, separated with ; (values of auth_request_set directives).|
|
||||
|`USE_PROXY_CACHE` |`no` |multisite|no |Enable or disable caching of the proxied resources. |
|
||||
|`PROXY_CACHE_PATH_LEVELS` |`1:2` |global |no |Hierarchy levels of the cache. |
|
||||
|`PROXY_CACHE_PATH_ZONE_SIZE` |`10m` |global |no |Maximum size of cached metadata when caching proxied resources. |
|
||||
|`PROXY_CACHE_PATH_PARAMS` |`max_size=100m` |global |no |Additional parameters to add to the proxy_cache directive. |
|
||||
|`PROXY_CACHE_METHODS` |`GET HEAD` |multisite|no |HTTP methods that should trigger a cache operation. |
|
||||
|`PROXY_CACHE_MIN_USES` |`2` |multisite|no |The minimum number of requests before a response is cached. |
|
||||
|`PROXY_CACHE_KEY` |`$scheme$host$request_uri` |multisite|no |The key used to uniquely identify a cached response. |
|
||||
|`PROXY_CACHE_VALID` |`200=24h 301=1h 302=24h` |multisite|no |Define the caching time depending on the HTTP status code (list of status=time). |
|
||||
|`PROXY_NO_CACHE` |`$http_pragma $http_authorization`|multisite|no |Conditions to disable caching of responses. |
|
||||
|`PROXY_CACHE_BYPASS` |`0` |multisite|no |Conditions to bypass caching of responses. |
|
||||
|`REVERSE_PROXY_CONNECT_TIMEOUT` |`60s` |multisite|yes |Timeout when connecting to the proxied resource. |
|
||||
|`REVERSE_PROXY_READ_TIMEOUT` |`60s` |multisite|yes |Timeout when reading from the proxied resource. |
|
||||
|`REVERSE_PROXY_SEND_TIMEOUT` |`60s` |multisite|yes |Timeout when sending to the proxied resource. |
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|---------------------------------------|----------------------------------|---------|--------|-----------------------------------------------------------------------------------------------------------------------------|
|
||||
|`USE_REVERSE_PROXY` |`no` |multisite|no |Activate reverse proxy mode. |
|
||||
|`REVERSE_PROXY_INTERCEPT_ERRORS` |`yes` |multisite|no |Intercept and rewrite errors. |
|
||||
|`REVERSE_PROXY_HOST` | |multisite|yes |Full URL of the proxied resource (proxy_pass). |
|
||||
|`REVERSE_PROXY_URL` | |multisite|yes |Location URL that will be proxied. |
|
||||
|`REVERSE_PROXY_WS` |`no` |multisite|yes |Enable websocket on the proxied resource. |
|
||||
|`REVERSE_PROXY_HEADERS` | |multisite|yes |List of HTTP headers to send to proxied resource separated with semicolons (values for proxy_set_header directive). |
|
||||
|`REVERSE_PROXY_HEADERS_CLIENT` | |multisite|yes |List of HTTP headers to send to client separated with semicolons (values for add_header directive). |
|
||||
|`REVERSE_PROXY_BUFFERING` |`yes` |multisite|yes |Enable or disable buffering of responses from proxied resource. |
|
||||
|`REVERSE_PROXY_KEEPALIVE` |`no` |multisite|yes |Enable or disable keepalive connections with the proxied resource. |
|
||||
|`REVERSE_PROXY_AUTH_REQUEST` | |multisite|yes |Enable authentication using an external provider (value of auth_request directive). |
|
||||
|`REVERSE_PROXY_AUTH_REQUEST_SIGNIN_URL`| |multisite|yes |Redirect clients to sign-in URL when using REVERSE_PROXY_AUTH_REQUEST (used when auth_request call returned 401). |
|
||||
|`REVERSE_PROXY_AUTH_REQUEST_SET` | |multisite|yes |List of variables to set from the authentication provider, separated with semicolons (values of auth_request_set directives).|
|
||||
|`USE_PROXY_CACHE` |`no` |multisite|no |Enable or disable caching of the proxied resources. |
|
||||
|`PROXY_CACHE_PATH_LEVELS` |`1:2` |global |no |Hierarchy levels of the cache. |
|
||||
|`PROXY_CACHE_PATH_ZONE_SIZE` |`10m` |global |no |Maximum size of cached metadata when caching proxied resources. |
|
||||
|`PROXY_CACHE_PATH_PARAMS` |`max_size=100m` |global |no |Additional parameters to add to the proxy_cache directive. |
|
||||
|`PROXY_CACHE_METHODS` |`GET HEAD` |multisite|no |HTTP methods that should trigger a cache operation. |
|
||||
|`PROXY_CACHE_MIN_USES` |`2` |multisite|no |The minimum number of requests before a response is cached. |
|
||||
|`PROXY_CACHE_KEY` |`$scheme$host$request_uri` |multisite|no |The key used to uniquely identify a cached response. |
|
||||
|`PROXY_CACHE_VALID` |`200=24h 301=1h 302=24h` |multisite|no |Define the caching time depending on the HTTP status code (list of status=time), separated with spaces. |
|
||||
|`PROXY_NO_CACHE` |`$http_pragma $http_authorization`|multisite|no |Conditions to disable caching of responses. |
|
||||
|`PROXY_CACHE_BYPASS` |`0` |multisite|no |Conditions to bypass caching of responses. |
|
||||
|`REVERSE_PROXY_CONNECT_TIMEOUT` |`60s` |multisite|yes |Timeout when connecting to the proxied resource. |
|
||||
|`REVERSE_PROXY_READ_TIMEOUT` |`60s` |multisite|yes |Timeout when reading from the proxied resource. |
|
||||
|`REVERSE_PROXY_SEND_TIMEOUT` |`60s` |multisite|yes |Timeout when sending to the proxied resource. |
|
||||
|
||||
### Reverse scan
|
||||
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|----------------------|--------------------------|---------|--------|------------------------------------------------------------------|
|
||||
|`USE_REVERSE_SCAN` |`no` |multisite|no |Enable scanning of clients ports and deny access if one is opened.|
|
||||
|`REVERSE_SCAN_PORTS` |`22 80 443 3128 8000 8080`|multisite|no |List of port to scan when using reverse scan feature. |
|
||||
|`REVERSE_SCAN_TIMEOUT`|`500` |multisite|no |Specify the maximum timeout (in ms) when scanning a port. |
|
||||
|
||||
### Self-signed certificate
|
||||
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|--------------------------|----------------------|---------|--------|-----------------------------------------|
|
||||
|`GENERATE_SELF_SIGNED_SSL`|`no` |multisite|no |Generate and use self-signed certificate.|
|
||||
|`SELF_SIGNED_SSL_EXPIRY` |`365` |multisite|no |Self-signed certificate expiry. |
|
||||
|`SELF_SIGNED_SSL_EXPIRY` |`365` |multisite|no |Self-signed certificate expiry in days. |
|
||||
|`SELF_SIGNED_SSL_SUBJ` |`/CN=www.example.com/`|multisite|no |Self-signed certificate subject. |
|
||||
|
||||
### Sessions
|
||||
|
||||
| Setting |Default |Context|Multiple| Description |
|
||||
|---------------------------|--------|-------|--------|---------------------------------------------------------------------------------|
|
||||
|`SESSIONS_SECRET` |`random`|global |no |Secret used to encrypt sessions variables for storing data related to challenges.|
|
||||
|`SESSIONS_NAME` |`random`|global |no |Name of the cookie given to clients. |
|
||||
|`SESSIONS_IDLING_TIMEOUT` |`1800` |global |no |Maximum time (in seconds) of inactivity before the session is invalidated. |
|
||||
|`SESSIONS_ROLLING_TIMEOUT` |`3600` |global |no |Maximum time (in seconds) before a session must be renewed. |
|
||||
|`SESSIONS_ABSOLUTE_TIMEOUT`|`86400` |global |no |Maximum time (in seconds) before a session is destroyed. |
|
||||
|
||||
### UI
|
||||
|
||||
|Setting |Default| Context |Multiple|Description|
|
||||
|
@ -345,11 +381,11 @@ When settings are considered as "multiple", it means that you can have multiple
|
|||
| Setting | Default | Context |Multiple| Description |
|
||||
|---------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|----------------------------------------------------------------------------------|
|
||||
|`USE_WHITELIST` |`yes` |multisite|no |Activate whitelist feature. |
|
||||
|`WHITELIST_IP` |`20.191.45.212 40.88.21.235 40.76.173.151 40.76.163.7 20.185.79.47 52.142.26.175 20.185.79.15 52.142.24.149 40.76.162.208 40.76.163.23 40.76.162.191 40.76.162.247 54.208.102.37 107.21.1.8`|multisite|no |List of IP/network, separated with spaces, to put into the whitelist. |
|
||||
|`WHITELIST_IP_URLS` | |global |no |List of URLs, separated with spaces, containing good IP/network to whitelist. |
|
||||
|`WHITELIST_IP` |`20.191.45.212 40.88.21.235 40.76.173.151 40.76.163.7 20.185.79.47 52.142.26.175 20.185.79.15 52.142.24.149 40.76.162.208 40.76.163.23 40.76.162.191 40.76.162.247 54.208.102.37 107.21.1.8`|multisite|no |List of IP/network, separated with spaces, to whitelist. |
|
||||
|`WHITELIST_RDNS_GLOBAL` |`yes` |multisite|no |Only perform RDNS whitelist checks on global IP addresses. |
|
||||
|`WHITELIST_RDNS` |`.google.com .googlebot.com .yandex.ru .yandex.net .yandex.com .search.msn.com .baidu.com .baidu.jp .crawl.yahoo.net .fwd.linkedin.com .twitter.com .twttr.com .discord.com` |multisite|no |List of reverse DNS suffixes, separated with spaces, to whitelist. |
|
||||
|`WHITELIST_RDNS_URLS` | |global |no |List of URLs, separated with spaces, containing reverse DNS suffixes to whitelist.|
|
||||
|`WHITELIST_RDNS_GLOBAL` |`yes` |multisite|no |Only perform RDNS whitelist checks on global IP addresses. |
|
||||
|`WHITELIST_ASN` |`32934` |multisite|no |List of ASN numbers, separated with spaces, to whitelist. |
|
||||
|`WHITELIST_ASN_URLS` | |global |no |List of URLs, separated with spaces, containing ASN to whitelist. |
|
||||
|`WHITELIST_USER_AGENT` | |multisite|no |List of User-Agent, separated with spaces, to whitelist. |
|
||||
|
|
309
docs/web-ui.md
309
docs/web-ui.md
|
@ -1,8 +1,5 @@
|
|||
# Web UI
|
||||
|
||||
!!! note "Supported integrations"
|
||||
At the moment, the web UI is only supported with the [Docker](/1.4/integrations/#docker), [Linux](/1.4/integrations/#linux) and [Ansible](/1.4/integrations/#ansible) integrations. It's not possible to use the web UI with other integrations like [Docker autoconf](/1.4/integrations/#docker-autoconf), [Swarm](/1.4/integrations/#swarm) or [Kubernetes](/1.4/integrations/#kubernetes). Please note that we plan to support more integrations as the project evolves.
|
||||
|
||||
## Overview
|
||||
|
||||
<p align="center">
|
||||
|
@ -39,53 +36,50 @@ Because the web UI is a web application, the recommended installation procedure
|
|||
!!! info "UI specific env variables"
|
||||
|
||||
* Don't forget to add `USE_UI` environnement variable as it adds the security rules needed for `Modsecurity` to work with the UI.
|
||||
* Also add the `REVERSE_PROXY_INTERCEPT_ERRORS` environnement variable to stop Bunkerweb from intercepting HTTP errors.
|
||||
* Also it is advised to tweak the `INTERCEPTED_ERROR_CODES` setting to stop Bunkerweb from intercepting certain HTTP errors.
|
||||
|
||||
=== "Docker"
|
||||
|
||||
When using the [Docker integration](/1.4/integrations/#docker), 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](https://hub.docker.com/r/bunkerity/bunkerweb-ui).
|
||||
When using the [Docker integration](/1.4/integrations/#docker), we recommend you to connect BunkerWeb and web UI using a dedicated network like with the scheduler 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](https://hub.docker.com/r/bunkerity/bunkerweb-ui).
|
||||
|
||||
Let's start by creating the networks (replace 10.20.30.0/24 with an unused network of your choice) :
|
||||
```shell
|
||||
docker network create --subnet 10.20.30.0/24 bw-ui && \
|
||||
docker network create --subnet 10.20.30.0/24 bw-universe && \
|
||||
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 :
|
||||
You will also need the data volume, which where BunkerWeb's data will be stored :
|
||||
```shell
|
||||
docker volume create bw-data && \
|
||||
docker volume create bw-confs
|
||||
docker volume create bw-data
|
||||
```
|
||||
|
||||
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 :
|
||||
You can now create the BunkerWeb container with specific settings related to the web UI, please note the special `bunkerweb.INSTANCE` label which is mandatory for the scheduler as well as the web UI to work properly :
|
||||
```shell
|
||||
docker run -d \
|
||||
--name mybunker \
|
||||
--name bunkerweb \
|
||||
--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_HOST=http://bw-ui:7000 \
|
||||
-e "bwadm.example.com_REVERSE_PROXY_HEADERS=X-Script-Name /changeme" \
|
||||
-e bwadm.example.com_REVERSE_PROXY_INTERCEPT_ERRORS=no \
|
||||
-l bunkerweb.UI \
|
||||
-e bwadm.example.com_INTERCEPTED_ERROR_CODES="400 401 405 413 429 500 501 502 503 504" \
|
||||
-l bunkerweb.INSTANCE \
|
||||
bunkerity/bunkerweb:1.4.6 && \
|
||||
docker network connect bw-ui mybunker
|
||||
docker network connect bw-universe bunkerweb
|
||||
```
|
||||
|
||||
Important things to note :
|
||||
|
||||
* `bwadm.example.com` is the dedicated (sub)domain for accessing the web UI
|
||||
* replace `10.20.30.0/24` with the same network address used for the `bw-ui` network
|
||||
* replace `10.20.30.0/24` with the same network address used for the `bw-universe` network
|
||||
* replace the `/changeme` URL with a custom one of your choice
|
||||
* the `bunkerweb.UI` label is mandatory
|
||||
* the `bunkerweb.INSTANCE` label is mandatory
|
||||
|
||||
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](https://github.com/Tecnativa/docker-socket-proxy) to mitigate that risk (only a subset of read-only API endpoints will be available to the web UI container).
|
||||
|
||||
|
@ -97,26 +91,36 @@ Because the web UI is a web application, the recommended installation procedure
|
|||
Once the network is created, you can now create the docker socket proxy container :
|
||||
```shell
|
||||
docker run -d \
|
||||
--name mydocker \
|
||||
--name bw-docker \
|
||||
--network bw-docker \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock:ro \
|
||||
-e CONTAINERS=1 \
|
||||
tecnativa/docker-socket-proxy
|
||||
```
|
||||
|
||||
You can then create the scheduler container with the bw-data volume and the docker socket proxy network :
|
||||
```shell
|
||||
docker run -d \
|
||||
--name bw-scheduler \
|
||||
--network bw-universe \
|
||||
-v bw-data:/data \
|
||||
-e DOCKER_HOST=tcp://bw-docker:2375 \
|
||||
bunkerity/bunkerweb-scheduler:1.4.6 && \
|
||||
docker network connect bw-docker bw-scheduler
|
||||
```
|
||||
|
||||
We can finally create the web UI container :
|
||||
```shell
|
||||
docker run -d \
|
||||
--name myui \
|
||||
--network bw-ui \
|
||||
--name bw-ui \
|
||||
--network bw-universe \
|
||||
-v bw-data:/data \
|
||||
-v bw-confs:/etc/nginx \
|
||||
-e DOCKER_HOST=tcp://mydocker:2375 \
|
||||
-e DOCKER_HOST=tcp://bw-docker:2375 \
|
||||
-e ADMIN_USERNAME=admin \
|
||||
-e ADMIN_PASSWORD=changeme \
|
||||
-e ABSOLUTE_URI=http(s)://bwadm.example.com/changeme/ \
|
||||
bunkerity/bunkerweb-ui:1.4.6 && \
|
||||
docker network connect bw-docker myui
|
||||
docker network connect bw-docker bw-ui
|
||||
```
|
||||
|
||||
Important things to note :
|
||||
|
@ -126,20 +130,14 @@ Because the web UI is a web application, the recommended installation procedure
|
|||
|
||||
Here is the docker-compose equivalent :
|
||||
```yaml
|
||||
version: '3'
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
mybunker:
|
||||
bunkerweb:
|
||||
image: bunkerity/bunkerweb:1.4.6
|
||||
networks:
|
||||
- bw-services
|
||||
- bw-ui
|
||||
ports:
|
||||
- 80:8080
|
||||
volumes:
|
||||
- bw-data:/data
|
||||
- bw-confs:/etc/nginx
|
||||
- "80:8080"
|
||||
- "443:8443"
|
||||
environment:
|
||||
- SERVER_NAME=bwadm.example.com
|
||||
- MULTISITE=yes
|
||||
|
@ -147,51 +145,258 @@ Because the web UI is a web application, the recommended installation procedure
|
|||
- 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_HOST=http://bw-ui: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.6
|
||||
depends_on:
|
||||
- mydocker
|
||||
- "bunkerweb.INSTANCE"
|
||||
networks:
|
||||
- bw-ui
|
||||
- bw-docker
|
||||
- bw-universe
|
||||
- bw-services
|
||||
|
||||
bw-scheduler:
|
||||
image: bunkerity/bunkerweb-scheduler:1.4.6
|
||||
volumes:
|
||||
- bw-data:/data
|
||||
- bw-confs:/etc/nginx
|
||||
environment:
|
||||
- DOCKER_HOST=tcp://mydocker:2375
|
||||
- DOCKER_HOST=tcp://bw-docker:2375
|
||||
networks:
|
||||
- bw-universe
|
||||
- bw-docker
|
||||
|
||||
bw-ui:
|
||||
image: bunkerity/bunkerweb-ui:1.4.6
|
||||
volumes:
|
||||
- bw-data:/data
|
||||
environment:
|
||||
- DOCKER_HOST=tcp://bw-docker:2375
|
||||
- ADMIN_USERNAME=admin
|
||||
- ADMIN_PASSWORD=changeme
|
||||
- ABSOLUTE_URI=http(s)://bwadm.example.com/changeme/
|
||||
|
||||
mydocker:
|
||||
image: tecnativa/docker-socket-proxy
|
||||
networks:
|
||||
- bw-docker
|
||||
- bw-universe
|
||||
|
||||
bw-docker:
|
||||
image: tecnativa/docker-socket-proxy
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
environment:
|
||||
- CONTAINERS=1
|
||||
networks:
|
||||
- bw-docker
|
||||
|
||||
volumes:
|
||||
bw-data:
|
||||
|
||||
networks:
|
||||
bw-services:
|
||||
bw-ui:
|
||||
bw-universe:
|
||||
name: bw-universe
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: 10.20.30.0/24
|
||||
bw-services:
|
||||
bw-docker:
|
||||
```
|
||||
|
||||
=== "Docker autoconf"
|
||||
|
||||
When using the [Docker autoconf integration](/1.4/integrations/#docker-autoconf), we recommend you to connect the Autoconf and web UI containers using a dedicated network like with the scheduler 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](https://hub.docker.com/r/bunkerity/bunkerweb-ui).
|
||||
|
||||
Let's start by creating the networks (replace 10.20.30.0/24 with an unused network of your choice) :
|
||||
```shell
|
||||
docker network create --subnet 10.20.30.0/24 bw-universe && \
|
||||
docker network create bw-services
|
||||
```
|
||||
|
||||
You will also need the data volume, which where BunkerWeb's data will be stored :
|
||||
```shell
|
||||
docker volume create bw-data
|
||||
```
|
||||
|
||||
You can now create the BunkerWeb container, please note the special `bunkerweb.INSTANCE` label which is mandatory for the scheduler as well as the web UI to work properly :
|
||||
```shell
|
||||
docker run -d \
|
||||
--name bunkerweb \
|
||||
--network bw-universe \
|
||||
-p 80:8080 \
|
||||
-p 443:8443 \
|
||||
-e SERVER_NAME= \
|
||||
-e MULTISITE=yes \
|
||||
-e "API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24" \
|
||||
-l bunkerweb.INSTANCE \
|
||||
bunkerity/bunkerweb:1.4.6
|
||||
```
|
||||
|
||||
Important things to note :
|
||||
|
||||
* replace `10.20.30.0/24` with the same network address used for the `bw-universe` network
|
||||
* the `bunkerweb.INSTANCE` label is mandatory
|
||||
|
||||
The Autoconf and 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](https://github.com/Tecnativa/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 :
|
||||
```shell
|
||||
docker network create bw-docker
|
||||
```
|
||||
|
||||
Once the network is created, you can now create the docker socket proxy container :
|
||||
```shell
|
||||
docker run -d \
|
||||
--name bw-docker \
|
||||
--network bw-docker \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock:ro \
|
||||
-e CONTAINERS=1 \
|
||||
tecnativa/docker-socket-proxy
|
||||
```
|
||||
|
||||
You can then create the autoconf container connected to the docker socket proxy network :
|
||||
```shell
|
||||
docker run -d \
|
||||
--name bw-autoconf \
|
||||
--network bw-universe \
|
||||
-v bw-data:/data \
|
||||
-e DOCKER_HOST=tcp://bw-docker:2375 \
|
||||
bunkerity/bunkerweb-autoconf:1.4.6 && \
|
||||
docker network connect bw-docker bw-autoconf
|
||||
```
|
||||
|
||||
You can then create the scheduler container with the bw-data volume and the docker socket proxy network :
|
||||
```shell
|
||||
docker run -d \
|
||||
--name bw-scheduler \
|
||||
--network bw-universe \
|
||||
-v bw-data:/data \
|
||||
-e DOCKER_HOST=tcp://bw-docker:2375 \
|
||||
bunkerity/bunkerweb-scheduler:1.4.6 && \
|
||||
docker network connect bw-docker bw-scheduler
|
||||
```
|
||||
|
||||
We can finally create the web UI container :
|
||||
```shell
|
||||
docker run -d \
|
||||
--name bw-ui \
|
||||
--network bw-universe \
|
||||
-v bw-data:/data \
|
||||
-e DOCKER_HOST=tcp://bw-docker:2375 \
|
||||
-e ADMIN_USERNAME=admin \
|
||||
-e ADMIN_PASSWORD=changeme \
|
||||
-e ABSOLUTE_URI=http(s)://bwadm.example.com/changeme/ \
|
||||
-l "bunkerweb.SERVER_NAME=bwadm.example.com" \
|
||||
-l "bunkerweb.USE_UI=yes" \
|
||||
-l "bunkerweb.USE_REVERSE_PROXY=yes" \
|
||||
-l "bunkerweb.REVERSE_PROXY_URL=/changeme" \
|
||||
-l "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000" \
|
||||
-l "bunkerweb.REVERSE_PROXY_HEADERS=X-Script-Name /changeme" \
|
||||
-l "bunkerweb.INTERCEPTED_ERROR_CODES=400 401 404 405 413 429 500 501 502 503 504" \
|
||||
bunkerity/bunkerweb-ui:1.4.6 && \
|
||||
docker network connect bw-docker bw-ui
|
||||
```
|
||||
|
||||
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
|
||||
* `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 :
|
||||
```yaml
|
||||
version: "3.5"
|
||||
|
||||
services:
|
||||
bunkerweb:
|
||||
image: bunkerity/bunkerweb:1.4.6
|
||||
ports:
|
||||
- 80:8080
|
||||
- 443:8443
|
||||
labels:
|
||||
- "bunkerweb.INSTANCE"
|
||||
environment:
|
||||
- SERVER_NAME=
|
||||
- MULTISITE=yes
|
||||
- API_WHITELIST_IP=127.0.0.0/8 10.20.30.0/24
|
||||
- AUTOCONF_MODE=yes
|
||||
networks:
|
||||
- bw-universe
|
||||
- bw-services
|
||||
|
||||
bw-autoconf:
|
||||
image: bunkerity/bunkerweb-autoconf:1.4.6
|
||||
volumes:
|
||||
- bw-data:/data
|
||||
environment:
|
||||
- DOCKER_HOST=tcp://bw-docker:2375
|
||||
networks:
|
||||
- bw-universe
|
||||
- bw-docker
|
||||
|
||||
bw-scheduler:
|
||||
image: bunkerity/bunkerweb-scheduler:1.4.6
|
||||
volumes:
|
||||
- bw-data:/data
|
||||
environment:
|
||||
- DOCKER_HOST=tcp://bw-docker:2375
|
||||
- AUTOCONF_MODE=yes
|
||||
networks:
|
||||
- bw-universe
|
||||
- bw-docker
|
||||
|
||||
bw-docker:
|
||||
image: tecnativa/docker-socket-proxy
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
environment:
|
||||
- CONTAINERS=1
|
||||
networks:
|
||||
- bw-docker
|
||||
|
||||
bw-ui:
|
||||
image: bunkerity/bunkerweb-ui:1.4.6
|
||||
networks:
|
||||
bw-docker:
|
||||
bw-universe:
|
||||
aliases:
|
||||
- bw-ui
|
||||
volumes:
|
||||
- bw-data:/data
|
||||
environment:
|
||||
- DOCKER_HOST=tcp://bw-docker:2375
|
||||
- AUTOCONF_MODE=yes
|
||||
- ADMIN_USERNAME=admin
|
||||
- ADMIN_PASSWORD=changeme
|
||||
- ABSOLUTE_URI=http://bwadm.example.com/changeme/
|
||||
labels:
|
||||
- "bunkerweb.SERVER_NAME=bwadm.example.com"
|
||||
- "bunkerweb.USE_UI=yes"
|
||||
- "bunkerweb.USE_REVERSE_PROXY=yes"
|
||||
- "bunkerweb.REVERSE_PROXY_URL=/changeme"
|
||||
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
|
||||
- "bunkerweb.REVERSE_PROXY_HEADERS=X-Script-Name /changeme"
|
||||
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 401 404 405 413 429 500 501 502 503 504"
|
||||
|
||||
volumes:
|
||||
bw-data:
|
||||
bw-confs:
|
||||
|
||||
networks:
|
||||
bw-universe:
|
||||
name: bw-universe
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: 10.20.30.0/24
|
||||
bw-services:
|
||||
name: bw-services
|
||||
bw-docker:
|
||||
name: bw-docker
|
||||
|
||||
```
|
||||
|
||||
=== "Swarm"
|
||||
|
||||
=== "Kubernetes"
|
||||
|
||||
=== "Linux"
|
||||
|
||||
The installation of the web UI using the [Linux integration](/1.4/integrations/#linux) is pretty straightforward because it is installed with BunkerWeb.
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
{% if USE_UI == "yes" +%}
|
||||
SecRule REQUEST_FILENAME "@rx /services$" "id:1001,ctl:ruleRemoveByTag=attack-rce,ctl:ruleRemoveByTag=attack-xss,ctl:ruleRemoveByTag=attack-generic,nolog"
|
||||
SecRule REQUEST_FILENAME "@rx /global_config$" "id:1002,ctl:ruleRemoveByTag=platform-pgsql,nolog"
|
||||
{% endif +%}
|
||||
|
|
|
@ -208,6 +208,7 @@ try:
|
|||
SEND_FILE_MAX_AGE_DEFAULT=86400,
|
||||
PLUGIN_ARGS={},
|
||||
RELOADING=False,
|
||||
LAST_RELOAD=0,
|
||||
TO_FLASH=[],
|
||||
DARK_MODE=False,
|
||||
)
|
||||
|
@ -249,8 +250,10 @@ def manage_bunkerweb(method: str, operation: str = "reloads", *args):
|
|||
operation = app.config["INSTANCES"].stop_instance(args[0])
|
||||
elif operation == "restart":
|
||||
operation = app.config["INSTANCES"].restart_instance(args[0])
|
||||
else:
|
||||
elif Path("/usr/sbin/nginx").is_file():
|
||||
operation = app.config["INSTANCES"].reload_instances()
|
||||
else:
|
||||
operation = "The scheduler will be in charge of reloading the instances."
|
||||
|
||||
if isinstance(operation, list):
|
||||
for op in operation:
|
||||
|
@ -387,6 +390,7 @@ def instances():
|
|||
return redirect(url_for("loading", next=url_for("instances")))
|
||||
|
||||
app.config["RELOADING"] = True
|
||||
app.config["LAST_RELOAD"] = time()
|
||||
Thread(
|
||||
target=manage_bunkerweb,
|
||||
name="Reloading instances",
|
||||
|
@ -500,6 +504,7 @@ def services():
|
|||
|
||||
# Reload instances
|
||||
app.config["RELOADING"] = True
|
||||
app.config["LAST_RELOAD"] = time()
|
||||
Thread(
|
||||
target=manage_bunkerweb,
|
||||
name="Reloading instances",
|
||||
|
@ -581,6 +586,7 @@ def global_config():
|
|||
|
||||
# Reload instances
|
||||
app.config["RELOADING"] = True
|
||||
app.config["LAST_RELOAD"] = time()
|
||||
Thread(
|
||||
target=manage_bunkerweb,
|
||||
name="Reloading instances",
|
||||
|
@ -1203,6 +1209,7 @@ def plugins():
|
|||
|
||||
# Reload instances
|
||||
app.config["RELOADING"] = True
|
||||
app.config["LAST_RELOAD"] = time()
|
||||
Thread(
|
||||
target=manage_bunkerweb,
|
||||
name="Reloading instances",
|
||||
|
@ -1773,7 +1780,12 @@ def darkmode():
|
|||
@app.route("/check_reloading")
|
||||
@login_required
|
||||
def check_reloading():
|
||||
if app.config["RELOADING"] is False:
|
||||
if not app.config["RELOADING"] or app.config["LAST_RELOAD"] + 60 < time():
|
||||
if app.config["RELOADING"]:
|
||||
logger.warning("Reloading took too long, forcing the state to be reloaded")
|
||||
flash("Forced the status to be reloaded", "error")
|
||||
app.config["RELOADING"] = False
|
||||
|
||||
for f in app.config["TO_FLASH"]:
|
||||
if f["type"] == "error":
|
||||
flash(f["content"], "error")
|
||||
|
|
|
@ -3,7 +3,7 @@ version: "3.5"
|
|||
services:
|
||||
mybunker:
|
||||
build:
|
||||
context: .
|
||||
context: ../..
|
||||
dockerfile: src/bw/Dockerfile
|
||||
ports:
|
||||
- 80:80
|
||||
|
@ -29,7 +29,6 @@ services:
|
|||
www.example.com_REVERSE_PROXY_HEADERS: "X-Script-Name /admin"
|
||||
www.example.com_CUSTOM_CONF_MODSEC_CRS_config: 'SecRule REQUEST_FILENAME "@rx /global_config$$" "id:999,ctl:ruleRemoveByTag=platform-pgsql,nolog"'
|
||||
www.example.com_INTERCEPTED_ERROR_CODES: "400 405 413 429 500 501 502 503 504"
|
||||
CUSTOM_CONF_SERVER_HTTP_port-redirect: "port_in_redirect on;"
|
||||
labels:
|
||||
- "bunkerweb.INSTANCE"
|
||||
networks:
|
||||
|
@ -39,7 +38,7 @@ services:
|
|||
|
||||
bw-scheduler:
|
||||
build:
|
||||
context: .
|
||||
context: ../..
|
||||
dockerfile: src/scheduler/Dockerfile
|
||||
depends_on:
|
||||
- mybunker
|
||||
|
@ -53,7 +52,7 @@ services:
|
|||
|
||||
bw-ui:
|
||||
build:
|
||||
context: .
|
||||
context: ../..
|
||||
dockerfile: src/ui/Dockerfile
|
||||
depends_on:
|
||||
- mybunker
|
||||
|
@ -83,17 +82,16 @@ services:
|
|||
networks:
|
||||
bw-services:
|
||||
ipv4_address: 192.168.0.4
|
||||
|
||||
ui-tests:
|
||||
build: tests/ui
|
||||
environment:
|
||||
- PYTHONUNBUFFERED=1
|
||||
extra_hosts:
|
||||
- "www.example.com:192.168.0.2"
|
||||
- "app1.example.com:192.168.0.2"
|
||||
networks:
|
||||
bw-services:
|
||||
ipv4_address: 192.168.0.3
|
||||
# ui-tests:
|
||||
# build: .
|
||||
# environment:
|
||||
# - PYTHONUNBUFFERED=1
|
||||
# extra_hosts:
|
||||
# - "www.example.com:192.168.0.2"
|
||||
# - "app1.example.com:192.168.0.2"
|
||||
# networks:
|
||||
# bw-services:
|
||||
# ipv4_address: 192.168.0.3
|
||||
|
||||
volumes:
|
||||
bw-data:
|
||||
|
|
|
@ -81,7 +81,6 @@ services:
|
|||
volumes:
|
||||
bw-data:
|
||||
|
||||
|
||||
networks:
|
||||
bw-universe:
|
||||
name: bw-universe
|
||||
|
|
Loading…
Reference in New Issue