feat: add CHECK_PRIVATE_IP configuration to manage session IP address changes for private networks

This commit is contained in:
Théophile Diot 2024-12-03 15:44:36 +01:00
parent 59d88bcccd
commit 94307cb3ad
No known key found for this signature in database
GPG key ID: FA995104A0BA376A
3 changed files with 8 additions and 1 deletions

View file

@ -51,6 +51,7 @@ Because the web UI is a web application, the recommended installation procedure
- `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**).
- `CHECK_PRIVATE_IP` : set it to `yes` to not disconnect users that have their IP address changed during a session if they are in a private network (default is `yes`). (Non-private IP addresses are always checked).
The web UI will use these variables to authenticate you and handle the 2FA feature.

View file

@ -325,6 +325,11 @@ def on_starting(server):
)
set_secure_permissions(UI_DATA_FILE)
LOGGER.info(
"UI will disconnect users that have their IP address changed during a session"
+ (" except for private IP addresses" if getenv("CHECK_PRIVATE_IP", "yes").lower() == "no" else "")
)
LOGGER.info("UI is ready")

View file

@ -74,6 +74,7 @@ with app.app_context():
stop(1)
FLASK_SECRET = LIB_DIR.joinpath(".flask_secret").read_text(encoding="utf-8").strip()
app.config["CHECK_PRIVATE_IP"] = getenv("CHECK_PRIVATE_IP", "yes").lower() == "yes"
app.config["SECRET_KEY"] = FLASK_SECRET
app.config["SESSION_COOKIE_NAME"] = "__Host-bw_ui_session"
@ -339,7 +340,7 @@ def before_request():
if not request.path.endswith("/login"):
return redirect(url_for("totp.totp_page", next=request.form.get("next")))
passed = False
elif not ip_address(request.remote_addr).is_private and session["ip"] != request.remote_addr:
elif (app.config["CHECK_PRIVATE_IP"] or not ip_address(request.remote_addr).is_private) and session["ip"] != request.remote_addr:
LOGGER.warning(f"User {current_user.get_id()} tried to access his session with a different IP address.")
passed = False
elif session["user_agent"] != request.headers.get("User-Agent"):