From 66a8acd7f903be439bcc4ed8b2d79d97a85103ff Mon Sep 17 00:00:00 2001 From: SchiWaGoA Date: Sun, 25 Oct 2026 17:40:14 +0100 Subject: [PATCH] Fix GeoIP download (HTTP 403) and clarify host setup - db-ip.com rejects Python's default "Python-urllib" user agent with 403; the download now sends "fail2ban-webui/ (+repo URL)" - README quick start: edit .env and replace the example hosts in config/hosts.yaml; hosts.yaml.example marks its entries as examples Co-Authored-By: Claude Opus 5.5 --- README.md | 2 ++ app/webui/backend.py | 5 ++++- examples/hosts.yaml.example | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4149844..8c6fc79 100644 --- a/README.md +++ b/README.md @@ -107,8 +107,10 @@ chown -R 10050:10050 data ```bash docker compose run --rm -it fail2ban-webui hash-password # Zeile in die .env übernehmen +nano .env # PUBLIC_URL, Hash, DEFAULT_LANG=de … docker compose run --rm fail2ban-webui keygen # öffentlicher Schlüssel für die Agenten # auf jedem fail2ban-Host den Agenten installieren (docs/agent.md), danach: +nano config/hosts.yaml # Beispiel-Hosts durch deine ersetzen! docker compose run --rm -it fail2ban-webui keyscan docker compose run --rm fail2ban-webui check docker compose up -d diff --git a/app/webui/backend.py b/app/webui/backend.py index dfd52ab..9e5d220 100644 --- a/app/webui/backend.py +++ b/app/webui/backend.py @@ -24,6 +24,7 @@ from datetime import date, datetime, timedelta import maxminddb log = logging.getLogger("webui") +USER_AGENT = "fail2ban-webui/{} (+https://git.retronerd.at/schiwagoa/fail2ban-webui)" def fail(key, **args): @@ -93,8 +94,10 @@ class Geo: first = date.today().replace(day=1) for month in (first, (first - timedelta(days=1)).replace(day=1)): url = f"https://download.db-ip.com/free/dbip-city-lite-{month:%Y-%m}.mmdb.gz" + # db-ip.com answers 403 to Python's default "Python-urllib" user agent + req = urllib.request.Request(url, headers={"User-Agent": USER_AGENT.format(self.settings.version)}) try: - with urllib.request.urlopen(url, timeout=300) as resp, \ + with urllib.request.urlopen(req, timeout=300) as resp, \ tempfile.NamedTemporaryFile(dir=os.path.dirname(path), delete=False) as tmp: with gzip.GzipFile(fileobj=resp) as gz: shutil.copyfileobj(gz, tmp) diff --git a/examples/hosts.yaml.example b/examples/hosts.yaml.example index 6f92761..782c630 100644 --- a/examples/hosts.yaml.example +++ b/examples/hosts.yaml.example @@ -8,6 +8,8 @@ # # After changes: docker compose run --rm -it fail2ban-webui keyscan # docker compose restart +# +# The three entries below are EXAMPLES – replace them with your own hosts. # ===================================================================== hosts: - name: web01