README vervollständigen und geoip2-Abhängigkeit deklarieren
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,21 +1,158 @@
|
||||
# logfile Country resolver
|
||||
# country-resolve — Logfile Country Resolver
|
||||
|
||||
## Use like
|
||||
Ein kleiner Stream-Filter, der Logzeilen von **stdin** liest, die **erste Spalte als IP-Adresse**
|
||||
interpretiert und die Zeile um **Kontinent** und **Land** anreichert wieder auf **stdout** ausgibt.
|
||||
|
||||
```bash
|
||||
Die Auflösung erfolgt offline über eine lokale
|
||||
[DB-IP Country Lite](https://db-ip.com/db/download/ip-to-country-lite) MMDB-Datenbank
|
||||
(gelesen via [`geoip2`](https://pypi.org/project/geoip2/)).
|
||||
|
||||
head -1 access_crowdsec.log
|
||||
93.229.122.46 - - [27/Feb/2025:00:00:02 +0100] "GET /pages/images/website/home/2502-01.jpg HTTP/1.1" 200 60233 "https://www.plainpicture.com/de" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"
|
||||
Typischer Einsatzzweck: Webserver-Access-Logs nach Herkunftsland filtern und daraus
|
||||
z. B. [CrowdSec](https://www.crowdsec.net/)-Blockentscheidungen ableiten.
|
||||
|
||||
head -1 access_crowdsec.log | ./resolver
|
||||
EU|Germany|93.229.122.46|-|-|[27/Feb/2025:00:00:02|+0100]|"GET|/pages/images/website/home/2502-01.jpg|HTTP/1.1"|200|60233|"https://www.plainpicture.com/de"|"Mozilla/5.0|(Macintosh;|Intel|Mac|OS|X|10_15_7)|AppleWebKit/537.36|(KHTML,|like|Gecko)|Chrome/133.0.0.0|Safari/537.36"
|
||||
---
|
||||
|
||||
# or
|
||||
## Funktionsweise
|
||||
|
||||
cat access_crowdsec.log | stdbuf -o0 grep "/search" | grep -v "Safari/" | stdbuf -o0 /tmp/resolver | stdbuf -o0 egrep "Russia|Belarus|^SA|^AS|^AF" > block_20250227.txt
|
||||
cscli decisions delete --all; cat block_20250227.txt | cut -d"|" -f3 | perl -ne 's/(\d+)\.(\d+)\..*/$1.$2/; print ' | uniq | perl -ne 'chomp;print $_,".0.0/16\n"' | cscli decisions import -i - --format values -d48h -R toomuch_AS_SA_AF
|
||||
Für jede Eingabezeile:
|
||||
|
||||
1. Zeile an Leerzeichen zerlegen, `parts[0]` ist die IP.
|
||||
2. IP gegen die MMDB auflösen → `continent.code` (z. B. `EU`) und `country.name` (z. B. `Germany`).
|
||||
3. Nicht auflösbare IPs (`AddressNotFoundError`) werden als Land `Unknown` markiert.
|
||||
4. Ausgabe: alle Felder **pipe-separiert** (`|`), mit Kontinent und Land vorangestellt:
|
||||
|
||||
```
|
||||
<Kontinent>|<Land>|<originalfeld1>|<originalfeld2>|...
|
||||
```
|
||||
|
||||
## packaging
|
||||
`pyinstaller --onefile resolv.py`
|
||||
Fehlerhafte Einzelzeilen werden übersprungen (kein Abbruch des Streams).
|
||||
|
||||
### Ausgabeformat
|
||||
|
||||
```
|
||||
EU|Germany|93.229.122.46|-|-|[27/Feb/2025:00:00:02|+0100]|"GET|/pages/...|HTTP/1.1"|200|...
|
||||
```
|
||||
|
||||
| Feld 1 | Feld 2 | ab Feld 3 |
|
||||
| ---------- | ------ | -------------------------------------------- |
|
||||
| Kontinent-Code (`EU`, `AS`, `NA`, …) | Ländername (`Germany`, `Unknown`, …) | die ursprünglichen, an Leerzeichen getrennten Felder |
|
||||
|
||||
---
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
- Python **≥ 3.13** (siehe `.python-version`)
|
||||
- Python-Paket **`geoip2`** (als Abhängigkeit in `pyproject.toml` deklariert)
|
||||
- Eine **MMDB-Datei** namens `dbip-country-lite-2025-02.mmdb` im Arbeitsverzeichnis
|
||||
(Pfad ist in `resolver.py` fest verdrahtet). MMDB-Dateien sind per `.gitignore`
|
||||
vom Repository ausgeschlossen und müssen separat bezogen werden.
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
Mit [uv](https://docs.astral.sh/uv/) — installiert die in `pyproject.toml` deklarierten Abhängigkeiten:
|
||||
|
||||
```bash
|
||||
uv sync
|
||||
```
|
||||
|
||||
Oder klassisch mit pip:
|
||||
|
||||
```bash
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install geoip2
|
||||
```
|
||||
|
||||
### MMDB-Datenbank besorgen
|
||||
|
||||
Die Lite-Datenbank kostenlos bei DB-IP herunterladen und passend benennen:
|
||||
|
||||
```bash
|
||||
# Beispiel (Dateiname muss zur Konstante in resolver.py passen)
|
||||
mv dbip-country-lite-2025-02.mmdb ./dbip-country-lite-2025-02.mmdb
|
||||
```
|
||||
|
||||
Für eine andere/aktuellere DB den Pfad in `resolver.py` (Zeile mit `geoip2.database.Reader(...)`)
|
||||
anpassen.
|
||||
|
||||
---
|
||||
|
||||
## Benutzung
|
||||
|
||||
### Einzelne Zeile auflösen
|
||||
|
||||
```bash
|
||||
head -1 access_crowdsec.log
|
||||
# 93.229.122.46 - - [27/Feb/2025:00:00:02 +0100] "GET /pages/images/website/home/2502-01.jpg HTTP/1.1" 200 60233 "https://www.plainpicture.com/de" "Mozilla/5.0 ..."
|
||||
|
||||
head -1 access_crowdsec.log | ./resolver
|
||||
# EU|Germany|93.229.122.46|-|-|[27/Feb/2025:00:00:02|+0100]|"GET|/pages/images/website/home/2502-01.jpg|HTTP/1.1"|200|...
|
||||
```
|
||||
|
||||
`./resolver` ist das gepackte Binary (siehe [Packaging](#packaging)). Alternativ direkt über Python:
|
||||
|
||||
```bash
|
||||
head -1 access_crowdsec.log | python3 resolver.py
|
||||
```
|
||||
|
||||
### Anwendungsbeispiel: Länder-basiertes Blocking mit CrowdSec
|
||||
|
||||
Access-Log streamen, auf interessante Requests filtern, Herkunft auflösen und nach
|
||||
bestimmten Ländern/Kontinenten filtern:
|
||||
|
||||
```bash
|
||||
cat access_crowdsec.log \
|
||||
| stdbuf -o0 grep "/search" \
|
||||
| grep -v "Safari/" \
|
||||
| stdbuf -o0 /tmp/resolver \
|
||||
| stdbuf -o0 egrep "Russia|Belarus|^SA|^AS|^AF" \
|
||||
> block_20250227.txt
|
||||
```
|
||||
|
||||
Aus den Treffern /16-Netze ableiten und als CrowdSec-Decisions importieren:
|
||||
|
||||
```bash
|
||||
cscli decisions delete --all
|
||||
cat block_20250227.txt \
|
||||
| cut -d"|" -f3 \
|
||||
| perl -ne 's/(\d+)\.(\d+)\..*/$1.$2/; print ' \
|
||||
| uniq \
|
||||
| perl -ne 'chomp; print $_,".0.0/16\n"' \
|
||||
| cscli decisions import -i - --format values -d48h -R toomuch_AS_SA_AF
|
||||
```
|
||||
|
||||
> `stdbuf -o0` erzwingt ungepuffertes Streaming, damit die Pipeline zeilenweise (nahezu
|
||||
> in Echtzeit) durchläuft.
|
||||
|
||||
---
|
||||
|
||||
## Packaging
|
||||
|
||||
Ein eigenständiges Binary (ohne Python-Runtime auf dem Zielsystem) mit
|
||||
[PyInstaller](https://pyinstaller.org/) erzeugen:
|
||||
|
||||
```bash
|
||||
pyinstaller --onefile resolver.py
|
||||
# oder mit der mitgelieferten Spec-Datei:
|
||||
pyinstaller resolver.spec
|
||||
```
|
||||
|
||||
Das Ergebnis liegt anschließend unter `dist/resolver` und kann z. B. nach `/tmp/resolver`
|
||||
kopiert und in Pipelines eingesetzt werden.
|
||||
|
||||
> Die MMDB-Datei wird **nicht** ins Binary eingebettet — sie muss zur Laufzeit im
|
||||
> Arbeitsverzeichnis liegen (bzw. der Pfad in `resolver.py` entsprechend gesetzt sein).
|
||||
|
||||
---
|
||||
|
||||
## Projektdateien
|
||||
|
||||
| Datei | Zweck |
|
||||
| -------------------- | ------------------------------------------------- |
|
||||
| `resolver.py` | Der eigentliche Stream-Filter |
|
||||
| `resolver.spec` | PyInstaller-Spezifikation für das `--onefile`-Binary |
|
||||
| `pyproject.toml` | Projekt-Metadaten (Python ≥ 3.13) |
|
||||
| `.python-version` | Fixierte Python-Version (3.13) |
|
||||
| `*.mmdb` | GeoIP-Datenbank (nicht im Repo, per `.gitignore`) |
|
||||
|
||||
Reference in New Issue
Block a user