From 02dc9aef4958db89bc00fc730ea39ad14548d34a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Diot?= Date: Wed, 27 Nov 2024 14:50:25 +0100 Subject: [PATCH] fix: enhance web UI configuration with new environment variables for listening address, port, and worker settings --- docs/web-ui.md | 5 +++++ src/linux/scripts/bunkerweb-ui.sh | 4 +++- src/ui/entrypoint.sh | 7 +------ src/ui/gunicorn.conf.py | 11 +++++++++-- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/docs/web-ui.md b/docs/web-ui.md index c48b30578..283bb2df5 100644 --- a/docs/web-ui.md +++ b/docs/web-ui.md @@ -46,6 +46,11 @@ Because the web UI is a web application, the recommended installation procedure - `ADMIN_PASSWORD` : password to access the web UI. - `FLASK_SECRET` : a secret key used to encrypt the session cookie (if not set, a random key will be generated). - `TOTP_SECRETS` : a list of TOTP secrets separated by spaces or a dictionary (e.g. : `{"1": "mysecretkey"}` or `mysecretkey` or `mysecretkey mysecretkey1`). **We strongly recommend you to set this variable if you want to use 2FA, as it will be used to encrypt the TOTP secret keys** (if not set, a random number of secret keys will be generated). Check out the [passlib documentation](https://passlib.readthedocs.io/en/stable/narr/totp-tutorial.html#application-secrets) for more information. + - `LISTEN_ADDR` : the address where the web UI will listen (default is `0.0.0.0` in **Docker images** and `127.0.0.1` on **Linux installations**). + - `LISTEN_PORT` : the port where the web UI will listen (default is `7000`). + - `MAX_WORKERS` : the number of workers used by the web UI (default is the number of CPUs). + - `MAX_THREADS` : the number of threads used by the web UI (default is `MAX_WORKERS` * 2). + - `FORWARDED_ALLOW_IPS` : a list of IP addresses or networks that are allowed to be used in the `X-Forwarded-For` header (default is `*` in **Docker images** and `127.0.0.1` on **Linux installations**). The web UI will use these variables to authenticate you and handle the 2FA feature. diff --git a/src/linux/scripts/bunkerweb-ui.sh b/src/linux/scripts/bunkerweb-ui.sh index a4bc7d992..83fd5bba2 100644 --- a/src/linux/scripts/bunkerweb-ui.sh +++ b/src/linux/scripts/bunkerweb-ui.sh @@ -14,9 +14,11 @@ start() { stop echo "Starting UI" + export LISTEN_ADDR="127.0.0.1" + export FORWARDED_ALLOW_IPS="127.0.0.1" # shellcheck disable=SC2046 export $(cat /etc/bunkerweb/ui.env) - sudo -E -u nginx -g nginx /bin/bash -c "PYTHONPATH=$PYTHONPATH python3 -m gunicorn --chdir /usr/share/bunkerweb/ui --config /usr/share/bunkerweb/ui/gunicorn.conf.py --pythonpath /usr/share/bunkerweb/deps/python,/usr/share/bunkerweb/ui --bind \"127.0.0.1:7000\"" + sudo -E -u nginx -g nginx /bin/bash -c "PYTHONPATH=$PYTHONPATH python3 -m gunicorn --chdir /usr/share/bunkerweb/ui --config /usr/share/bunkerweb/ui/gunicorn.conf.py" } # Function to stop the UI diff --git a/src/ui/entrypoint.sh b/src/ui/entrypoint.sh index 172c74abe..8c6d6023b 100644 --- a/src/ui/entrypoint.sh +++ b/src/ui/entrypoint.sh @@ -37,12 +37,7 @@ else echo "Docker" > /usr/share/bunkerweb/INTEGRATION fi -python3 -m gunicorn --config gunicorn.conf.py --user ui --group ui --bind 0.0.0.0:7000 & -pid="$!" -wait "$pid" -while [ -f /var/run/bunkerweb/ui.pid ] ; do - wait "$pid" -done +python3 -m gunicorn --config gunicorn.conf.py if [ -f /var/tmp/bunkerweb/ui.healthy ] ; then rm /var/tmp/bunkerweb/ui.healthy diff --git a/src/ui/gunicorn.conf.py b/src/ui/gunicorn.conf.py index 8643b8b38..6495d6e19 100644 --- a/src/ui/gunicorn.conf.py +++ b/src/ui/gunicorn.conf.py @@ -36,12 +36,18 @@ TOTP_HASH_FILE = TOTP_SECRETS_FILE.with_suffix(".hash") # File to store hash of MAX_WORKERS = int(getenv("MAX_WORKERS", max((cpu_count() or 1) - 1, 1))) LOG_LEVEL = getenv("CUSTOM_LOG_LEVEL", getenv("LOG_LEVEL", "info")) +LISTEN_ADDR = getenv("LISTEN_ADDR", "0.0.0.0") +LISTEN_PORT = getenv("LISTEN_PORT", "7000") +FORWARDED_ALLOW_IPS = getenv("FORWARDED_ALLOW_IPS", "*") wsgi_app = "main:app" proc_name = "bunkerweb-ui" accesslog = join(sep, "var", "log", "bunkerweb", "ui-access.log") access_log_format = '%({x-forwarded-for}i)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"' errorlog = join(sep, "var", "log", "bunkerweb", "ui.log") +limit_request_line = 0 +limit_request_fields = 32768 +limit_request_field_size = 0 reuse_port = True chdir = join(sep, "usr", "share", "bunkerweb", "ui") umask = 0x027 @@ -49,11 +55,12 @@ pidfile = PID_FILE.as_posix() worker_tmp_dir = join(sep, "dev", "shm") tmp_upload_dir = join(sep, "var", "tmp", "bunkerweb", "ui") secure_scheme_headers = {} -forwarded_allow_ips = "*" -pythonpath = join(sep, "usr", "share", "bunkerweb", "deps", "python") +forwarded_allow_ips = FORWARDED_ALLOW_IPS +pythonpath = join(sep, "usr", "share", "bunkerweb", "deps", "python") + "," + join(sep, "usr", "share", "bunkerweb", "ui") proxy_allow_ips = "*" casefold_http_method = True workers = MAX_WORKERS +bind = f"{LISTEN_ADDR}:{LISTEN_PORT}" worker_class = "gthread" threads = int(getenv("MAX_THREADS", MAX_WORKERS * 2)) max_requests_jitter = min(8, MAX_WORKERS)