diff --git a/README.md b/README.md index a565824..1cd3e51 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ Documentation | + Examples + | Blog posts | Community chat @@ -36,6 +38,7 @@ Non-exhaustive list of features : - Block TOR, proxies, bad user-agents, countries, ... - Block known bad IP with DNSBL and CrowdSec - Prevent bruteforce attacks with rate limiting +- Plugins system for external security checks (e.g. : ClamAV) - Easy to configure with environment variables or web UI - Automatic configuration with container labels - Docker Swarm support @@ -365,13 +368,27 @@ docker service create --name anotherapp \ A dedicated image, *bunkerized-nginx-ui*, lets you manage bunkerized-nginx instances and services configurations through a web user interface. This feature is still in beta, feel free to open a new issue if you find a bug and/or you have an idea to improve it. -First we need a volume that will store the configurations : +First we need a volume that will store the configurations and a network because bunkerized-nginx will be used as a reverse proxy for the web UI : ```shell docker volume create nginx_conf +docker network create mynet ``` -Then, we can create the bunkerized-nginx instance with the `bunkerized-nginx.UI` label and a reverse proxy configuration for our web UI : +Let's create the bunkerized-nginx-ui container that will host the web UI behind bunkerized-nginx : + +```shell +docker run --network mynet \ + --name myui \ + -v /var/run/docker.sock:/var/run/docker.sock:ro \ + -v nginx_conf:/etc/nginx \ + -e ABSOLUTE_URI=https://admin.domain.com/webui/ \ + bunkerity/bunkerized-nginx-ui +``` + +You will need to edit the `ABSOLUTE_URI` environment variable to reflect your actual URI of the web UI. + +We can now setup the bunkerized-nginx instance with the `bunkerized-nginx.UI` label and a reverse proxy configuration for our web UI : ```shell docker network create mynet @@ -401,17 +418,7 @@ docker run -p 80:8080 \ The `AUTH_BASIC` environment variables let you define a login/password that must be provided before accessing to the web UI. At the moment, there is no authentication mechanism integrated into bunkerized-nginx-ui so **using auth basic with a strong password coupled with a "hard to guess" URI is strongly recommended**. -We can now create the bunkerized-nginx-ui container that will host the web UI behind bunkerized-nginx : - -```shell -docker run --network mynet \ - -v /var/run/docker.sock:/var/run/docker.sock:ro \ - -v nginx_conf:/etc/nginx \ - -e ABSOLUTE_URI=https://admin.domain.com/webui/ \ - bunkerity/bunkerized-nginx-ui -``` - -After that, the web UI should be accessible from https://admin.domain.com/webui/. +Web UI should now be accessible from https://admin.domain.com/webui/. # Security tuning diff --git a/confs/site/main-lua.conf b/confs/site/main-lua.conf index d30c183..f4f5a07 100644 --- a/confs/site/main-lua.conf +++ b/confs/site/main-lua.conf @@ -7,6 +7,11 @@ set $session_check_addr on; access_by_lua_block { +-- disable checks for internal requests +if ngx.req.is_internal() then + return +end + -- let's encrypt local use_lets_encrypt = {% if AUTO_LETS_ENCRYPT == "yes" %}true{% else %}false{% endif %} diff --git a/docs/introduction.md b/docs/introduction.md index 9329dee..22206d9 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -17,7 +17,7 @@ Non-exhaustive list of features : - Block TOR, proxies, bad user-agents, countries, ... - Block known bad IP with DNSBL and CrowdSec - Prevent bruteforce attacks with rate limiting -- Plugin system for external security checks (e.g. : ClamAV) +- Plugins system for external security checks (e.g. : ClamAV) - Easy to configure with environment variables or web UI - Automatic configuration with container labels - Docker Swarm support diff --git a/docs/plugins.md b/docs/plugins.md index 5846a88..b848adf 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -78,7 +78,7 @@ Under the hood, bunkerized-nginx uses the [lua nginx module](https://github.com/ ### Dependencies -Since the core already uses some external libraries you can use it in your own plugins too (see the [compile.sh](https://github.com/bunkerity/bunkerized-nginx/blob/master/compile.sh file) and the [core lua files](https://github.com/bunkerity/bunkerized-nginx/tree/master/lua)). +Since the core already uses some external libraries you can use it in your own plugins too (see the [compile.sh](https://github.com/bunkerity/bunkerized-nginx/blob/master/compile.sh) file and the [core lua files](https://github.com/bunkerity/bunkerized-nginx/tree/master/lua)). In case you need to add dependencies, you can do it by placing the corresponding files into the same folder of your main plugin code. Here is an example with a file named **dependency.lua** : diff --git a/docs/quickstart_guide.md b/docs/quickstart_guide.md index e104060..03fa199 100644 --- a/docs/quickstart_guide.md +++ b/docs/quickstart_guide.md @@ -296,13 +296,27 @@ docker service create --name anotherapp \ A dedicated image, *bunkerized-nginx-ui*, lets you manage bunkerized-nginx instances and services configurations through a web user interface. This feature is still in beta, feel free to open a new issue if you find a bug and/or you have an idea to improve it. -First we need a volume that will store the configurations : +First we need a volume that will store the configurations and a network because bunkerized-nginx will be used as a reverse proxy for the web UI : ```shell docker volume create nginx_conf +docker network create mynet ``` -Then, we can create the bunkerized-nginx instance with the `bunkerized-nginx.UI` label and a reverse proxy configuration for our web UI : +Let's create the bunkerized-nginx-ui container that will host the web UI behind bunkerized-nginx : + +```shell +docker run --network mynet \ + --name myui \ + -v /var/run/docker.sock:/var/run/docker.sock:ro \ + -v nginx_conf:/etc/nginx \ + -e ABSOLUTE_URI=https://admin.domain.com/webui/ \ + bunkerity/bunkerized-nginx-ui +``` + +You will need to edit the `ABSOLUTE_URI` environment variable to reflect your actual URI of the web UI. + +We can now setup the bunkerized-nginx instance with the `bunkerized-nginx.UI` label and a reverse proxy configuration for our web UI : ```shell docker network create mynet @@ -332,14 +346,4 @@ docker run -p 80:8080 \ The `AUTH_BASIC` environment variables let you define a login/password that must be provided before accessing to the web UI. At the moment, there is no authentication mechanism integrated into bunkerized-nginx-ui so **using auth basic with a strong password coupled with a "hard to guess" URI is strongly recommended**. -We can now create the bunkerized-nginx-ui container that will host the web UI behind bunkerized-nginx : - -```shell -docker run --network mynet \ - -v /var/run/docker.sock:/var/run/docker.sock:ro \ - -v nginx_conf:/etc/nginx \ - -e ABSOLUTE_URI=https://admin.domain.com/webui/ \ - bunkerity/bunkerized-nginx-ui -``` - -After that, the web UI should be accessible from https://admin.domain.com/webui/. +Web UI should now be accessible from https://admin.domain.com/webui/. diff --git a/docs/volumes.md b/docs/volumes.md index c26ddea..7f57bb9 100644 --- a/docs/volumes.md +++ b/docs/volumes.md @@ -89,3 +89,5 @@ Mountpoint : `/plugins` Description : This volume is used to extend bunkerized-nginx with [additional plugins](https://bunkerized-nginx.readthedocs.io/en/latest/plugins.html). Please note that you will need to have a subdirectory for each plugin you want to enable. + +Read-only : yes diff --git a/examples/certbot-cloudflare/certbot-new.sh b/examples/certbot-cloudflare/certbot-new.sh new file mode 100755 index 0000000..1298500 --- /dev/null +++ b/examples/certbot-cloudflare/certbot-new.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +# you need to run it before starting bunkerized-nginx to get the first certificate + +# edit according to your values +DOMAINS="kakou-corp.fr,*.kakou-corp.fr" +EMAIL="contact@kakou-corp.fr" +SERVICE="mywww" + +# ask for the certificate +# don't forget to first edit the cloudflare.ini file +docker run --rm \ + -v "${PWD}/cloudflare.ini:/tmp/cloudflare.ini" \ + -v "${PWD}/letsencrypt:/etc/letsencrypt" \ + certbot/dns-cloudflare \ + certonly \ + --dns-cloudflare \ + --dns-cloudflare-credentials /tmp/cloudflare.ini \ + --dns-cloudflare-propagation-seconds 60 \ + -d "$DOMAINS" \ + --email "$EMAIL" \ + --agree-tos \ + --no-eff-email +if [ $? -ne 0 ] ; then + echo "error while getting certificate for $DOMAINS" + exit 1 +fi + +# fix permissions +chgrp -R 101 "${PWD}/letsencrypt" +chmod -R 750 "${PWD}/letsencrypt" + +echo "Certificate for $DOMAINS created !" diff --git a/examples/certbot-cloudflare/certbot-renew.sh b/examples/certbot-cloudflare/certbot-renew.sh new file mode 100755 index 0000000..8b3c814 --- /dev/null +++ b/examples/certbot-cloudflare/certbot-renew.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +# you should add it to your crontab like : +# 0 0 * * * cd /your/folder && ./certbot-renew.sh + +# edit with your service name +SERVICE="mywww" + +# ask for the renew +# don't forget to first edit the cloudflare.ini file +docker run --rm \ + -v "${PWD}/cloudflare.ini:/tmp/cloudflare.ini" \ + -v "${PWD}/letsencrypt:/etc/letsencrypt" \ + certbot/dns-cloudflare \ + renew +if [ $? -ne 0 ] ; then + echo "error while getting certificate for $DOMAINS" + exit 1 +fi + +# fix permissions +chgrp -R 101 "${PWD}/letsencrypt" +chmod -R 750 "${PWD}/letsencrypt" + +# reload bunkerized-nginx +docker-compose kill -s SIGHUP mywww + +echo "Certificate(s) renewed (if needed) !" diff --git a/examples/certbot-cloudflare/cloudflare.ini b/examples/certbot-cloudflare/cloudflare.ini new file mode 100644 index 0000000..1125329 --- /dev/null +++ b/examples/certbot-cloudflare/cloudflare.ini @@ -0,0 +1,5 @@ +# Cloudflare API token used by Certbot +# More info : +# https://certbot-dns-cloudflare.readthedocs.io/en/stable/index.html#credentials +# https://developers.cloudflare.com/api/tokens/create +dns_cloudflare_api_token = YOUR-API-TOKEN-HERE diff --git a/examples/certbot-cloudflare/docker-compose.yml b/examples/certbot-cloudflare/docker-compose.yml new file mode 100644 index 0000000..1cc3fcb --- /dev/null +++ b/examples/certbot-cloudflare/docker-compose.yml @@ -0,0 +1,36 @@ +version: '3' + +services: + + mywww: + image: bunkerity/bunkerized-nginx + restart: always + ports: + - 80:8080 + - 443:8443 + # bunkerized-nginx runs as an unprivileged user with UID/GID 101 + # don't forget to edit the permissions of the files and folders accordingly + volumes: + - ./web-files:/www:ro + - ./letsencrypt:/letsencrypt:ro + environment: + - SERVER_NAME=www.website.com # replace with your domain(s) + - USE_CUSTOM_HTTPS=yes + - CUSTOM_HTTPS_CERT=/letsencrypt/live/website.com/fullchain.pem # replace with your path + - CUSTOM_HTTPS_KEY=/letsencrypt/live/website.com/privkey.pem # replace with your path + - REDIRECT_HTTP_TO_HTTPS=yes + - PROXY_REAL_IP=yes + # networks from https://www.cloudflare.com/ips-v4/ + # you should check if the networks listed are up to date + - PROXY_REAL_IP_FROM=173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 172.64.0.0/13 131.0.72.0/22 104.16.0.0/13 104.24.0.0/14 + - DISABLE_DEFAULT_SERVER=yes + - USE_CLIENT_CACHE=yes + - USE_GZIP=yes + - REMOTE_PHP=myphp + - REMOTE_PHP_PATH=/app + + myphp: + image: php:fpm + restart: always + volumes: + - ./web-files:/app diff --git a/examples/certbot-cloudflare/web-files/index.php b/examples/certbot-cloudflare/web-files/index.php new file mode 100644 index 0000000..07f07cb --- /dev/null +++ b/examples/certbot-cloudflare/web-files/index.php @@ -0,0 +1,5 @@ + diff --git a/examples/certbot-wildcard/certbot-wildcard.sh b/examples/certbot-wildcard/certbot-wildcard.sh index 49cafb3..9c12fe8 100755 --- a/examples/certbot-wildcard/certbot-wildcard.sh +++ b/examples/certbot-wildcard/certbot-wildcard.sh @@ -3,19 +3,28 @@ # you need to run it before starting bunkerized-nginx # since it's manual there is no auto renew, you need to run it again before it expires -DOMAIN="*.website.com" +# replace with your values +DOMAINS="website.com,*.website.com" SERVICE="mywww" # ask for wildcard certificate # it's interactive and you will need to add a DNS entry -docker run --rm -it -v "${PWD}/letsencrypt:/etc/letsencrypt" certbot/certbot certonly --manual -d $DOMAIN --agree-tos +docker run --rm \ + -it \ + -v "${PWD}/letsencrypt:/etc/letsencrypt" \ + certbot/certbot \ + certonly \ + --manual \ + -d "$DOMAINS" \ + --agree-tos if [ $? -ne 0 ] ; then - echo "error while getting certificate for $DOMAIN" + echo "error while getting certificate for $DOMAINS" exit 1 fi # fix permissions -chown -R 101:101 "${PWD}/letsencrypt" +chgrp -R 101 "${PWD}/letsencrypt" +chmod -R 750 "${PWD}/letsencrypt" # reload nginx if it's already running (in case of a "renew") if [ -z `docker-compose ps -q $SERVICE` ] || [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q $SERVICE)` ]; then diff --git a/settings.json b/settings.json index 4d7f148..98f3328 100644 --- a/settings.json +++ b/settings.json @@ -579,7 +579,7 @@ "env": "CUSTOM_HTTPS_CERT", "id": "custom-https-cert", "label": "Custom TLS certificate path", - "regex": "^[A-Za-z\\.0-9\\/]*$", + "regex": "^[A-Za-z\\.0-9\\/\\-]*$", "type": "text" }, { @@ -588,7 +588,7 @@ "env": "CUSTOM_HTTPS_KEY", "id": "custom-https-key", "label": "Custom TLS certificate key", - "regex": "^[A-Za-z\\.0-9\\/]*$", + "regex": "^[A-Za-z\\.0-9\\/\\-]*$", "type": "text" }, {