- python -m scanner https://domain.de scan (URL as first positional arg) - On first use, the domain directory is auto-created from the meine-seite.de template with all paths and target URL substituted - scanner.sh wrapper script for convenient ./scanner.sh usage - --config syntax fully preserved (cron jobs unchanged) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
244 lines
6.7 KiB
Markdown
244 lines
6.7 KiB
Markdown
# Website Integrity Scanner
|
|
|
|
## Was macht dieses Programm?
|
|
|
|
Es überwacht Ihre Website und meldet Ihnen, wenn sich etwas verändert hat —
|
|
besonders heimliche Manipulationen wie versteckten Spam, fremde Links oder
|
|
ausgetauschte Dateien. So merken Sie früh, wenn jemand unbefugt in Ihre Seite
|
|
eingegriffen hat.
|
|
|
|
Das Programm läuft bei Ihnen, nicht beim Webhoster. Sie brauchen kein IT-Wissen:
|
|
Es zeigt eine **Ampel** (🟢 / 🟡 / 🔴) und erklärt jeden Fund in einfachen Worten.
|
|
|
|
## In 3 Schritten startklar
|
|
|
|
```bash
|
|
# Einmalig: Programm einrichten
|
|
cd integrity_scanner_fuer_statische_Webseiten
|
|
python -m venv venv
|
|
source venv/bin/activate
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
```bash
|
|
# Schritt 1: Erste Prüfung — Scanner legt das Zielverzeichnis automatisch an:
|
|
python -m scanner https://ihre-website.de init
|
|
|
|
# Schritt 2: Wenn die Website in Ordnung ist, Zustand als Referenz speichern:
|
|
python -m scanner https://ihre-website.de approve --all --note "Erststand geprüft"
|
|
|
|
# Schritt 3: Ab jetzt täglich prüfen (am besten automatisch, siehe unten):
|
|
python -m scanner https://ihre-website.de scan
|
|
|
|
# Bei Gelb/Rot den Bericht ansehen:
|
|
python -m scanner https://ihre-website.de report
|
|
```
|
|
|
|
Das Verzeichnis `ihre-website.de/` wird beim ersten Aufruf automatisch angelegt.
|
|
|
|
**Gut zu wissen:** Die selteneren Prüfungen (Tarnung, externe Links, Dateien)
|
|
laufen **automatisch einmal pro Woche** beim täglichen `scan` mit. Sie brauchen
|
|
dafür **nichts** extra einzurichten — ein täglicher Aufruf genügt für alles.
|
|
|
|
---
|
|
|
|
## Subcommands
|
|
|
|
| Befehl | Funktion |
|
|
|---|---|
|
|
| `init` | Erstcrawl + Vorschau, kein Baseline-Update |
|
|
| `crawl` | Crawlt die Website, speichert Snapshot |
|
|
| `check` | Vergleicht letzten Snapshot mit Baseline |
|
|
| `scan` | `crawl` + `check` in einem (für Cron) |
|
|
| `approve --all` | Alle Snapshot-URLs als neue Baseline freigeben |
|
|
| `approve --url URL` | Einzelne URL freigeben |
|
|
| `approve --rebuild` | Gesamte Baseline ersetzen (nach großer Änderung) |
|
|
| `report` | Letzten Report anzeigen |
|
|
| `status` | Baseline-Datum, letzter Scan, Risiko-Level |
|
|
|
|
Alle Befehle akzeptieren `--config path/to/config.yaml` und `--verbose`.
|
|
|
|
---
|
|
|
|
## Workflow: Erstinitialisierung
|
|
|
|
```
|
|
python -m scanner init
|
|
```
|
|
|
|
Ausgabe zeigt:
|
|
- alle gefundenen internen URLs
|
|
- alle externen Links (mit Whitelist-Status)
|
|
- potenzielle Auffälligkeiten (Hidden Content, Meta-Refresh, ...)
|
|
|
|
**Wichtig**: Die Ausgabe manuell prüfen, bevor die Baseline gesetzt wird.
|
|
Insbesondere externe Links in `config/allowed_external.yaml` eintragen.
|
|
|
|
```
|
|
python -m scanner approve --all --note "Initiale Baseline, geprüft am $(date)"
|
|
```
|
|
|
|
---
|
|
|
|
## Workflow: Täglicher Betrieb (Cron)
|
|
|
|
```
|
|
python -m scanner scan
|
|
```
|
|
|
|
Exit-Codes:
|
|
- `0` = Grün (keine Auffälligkeiten)
|
|
- `1` = Gelb (Warnung, manuelle Prüfung empfohlen)
|
|
- `2` = Rot (Alarm, sofortige Prüfung notwendig)
|
|
|
|
---
|
|
|
|
## Workflow: Legitime Änderung freigeben
|
|
|
|
```bash
|
|
# 1. Scan durchgeführt, Warnung auf /impressum/
|
|
python -m scanner report # Report ansehen
|
|
python -m scanner approve --url https://bredelar.info/impressum/ --note "Impressum aktualisiert"
|
|
|
|
# 2. Oder alle Änderungen auf einmal (wenn alles geprüft)
|
|
python -m scanner approve --all --note "Redesign vom 2026-06-12 freigegeben"
|
|
|
|
# 3. Nach großem Redesign: komplette neue Baseline
|
|
python -m scanner approve --rebuild --note "Komplettes Redesign, alle Seiten neu"
|
|
```
|
|
|
|
---
|
|
|
|
## Workflow: Incident (Alarm)
|
|
|
|
1. Report lesen: `python -m scanner report`
|
|
2. Verdächtige URLs manuell im Browser prüfen
|
|
3. Quelltext der betroffenen Seiten ansehen (insb. `display:none`-Bereiche)
|
|
4. Dienstleister kontaktieren, Zugriff auf Hosting prüfen
|
|
5. Nach Bereinigung: `python -m scanner scan` — muss grün sein
|
|
6. Dann: `python -m scanner approve --rebuild --note "Nach Incident bereinigt"`
|
|
|
|
**Wichtig**: Niemals `approve` auf eine kompromittierte Seite anwenden.
|
|
|
|
---
|
|
|
|
## Cron-Setup
|
|
|
|
Einrichten mit `crontab -e`, folgende Zeilen einfügen — je eine pro überwachter Website,
|
|
mit **Zeitversatz von mindestens 15 Minuten**. Ein Scan lädt alle Seiten einer Website herunter;
|
|
laufen mehrere Scans gleichzeitig, konkurrieren sie um Netzwerk und CPU und können die
|
|
überwachten Server unnötig belasten.
|
|
|
|
```cron
|
|
# Täglich 03:00 — bredelar.info
|
|
0 3 * * * cd /home/dschlueter/Python_Programs/integrity_scanner_fuer_statische_Webseiten && python -m scanner --config bredelar.info/config.yaml scan >> bredelar.info/logs/cron.log 2>&1
|
|
|
|
# Täglich 03:15 — jamulix.de
|
|
15 3 * * * cd /home/dschlueter/Python_Programs/integrity_scanner_fuer_statische_Webseiten && python -m scanner --config jamulix.de/config.yaml scan >> jamulix.de/logs/cron.log 2>&1
|
|
```
|
|
|
|
**Wichtig:** Der `cd`-Befehl ist nötig, damit `python -m scanner` das Paket findet.
|
|
Das Log landet je Site in `<site>/logs/cron.log`.
|
|
|
|
Nach dem Einrichten prüfen: `crontab -l`
|
|
|
|
### Neue Website hinzufügen
|
|
|
|
```bash
|
|
cp -r meine-seite.de neue-domain.de
|
|
# In neue-domain.de/config.yaml: target + alle 4 Pfade anpassen
|
|
python -m scanner --config neue-domain.de/config.yaml init
|
|
# Dann einen weiteren Cron-Eintrag ergänzen
|
|
# neue-domain.de/data|reports|logs in .gitignore eintragen
|
|
```
|
|
|
|
Log-Rotation (`/etc/logrotate.d/scanner`):
|
|
```
|
|
/home/dschlueter/Python_Programs/integrity_scanner_fuer_statische_Webseiten/*/logs/*.log {
|
|
daily
|
|
rotate 30
|
|
compress
|
|
missingok
|
|
notifempty
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Konfiguration
|
|
|
|
### E-Mail aktivieren
|
|
|
|
In `config.yaml`:
|
|
```yaml
|
|
alerting:
|
|
email:
|
|
enabled: true
|
|
smtp_host: mail.example.com
|
|
smtp_port: 587
|
|
smtp_user: scanner@example.com
|
|
smtp_password_env: SCANNER_SMTP_PASSWORD
|
|
from: scanner@bredelar.info
|
|
to:
|
|
- admin@bredelar.info
|
|
```
|
|
|
|
Passwort als Umgebungsvariable setzen (nicht in config.yaml):
|
|
```bash
|
|
export SCANNER_SMTP_PASSWORD="geheimesPasswort"
|
|
```
|
|
|
|
### Webhook aktivieren
|
|
|
|
```yaml
|
|
alerting:
|
|
webhook:
|
|
enabled: true
|
|
url: "https://hooks.slack.com/services/..."
|
|
```
|
|
|
|
### Externe Domains whitelisten
|
|
|
|
Nach dem ersten `init` alle legitimen externen Domains in
|
|
`config/allowed_external.yaml` eintragen:
|
|
|
|
```yaml
|
|
- fonts.googleapis.com
|
|
- maps.googleapis.com
|
|
```
|
|
|
|
---
|
|
|
|
## Verzeichnisstruktur
|
|
|
|
```
|
|
data/
|
|
baseline/ Aktuell freigegebene Referenz (NIEMALS automatisch aktualisiert)
|
|
manifest.json Wer/was/wann freigegeben hat
|
|
pages/ Pro URL eine JSON-Datei
|
|
snapshots/ Zeitgestempelte Crawl-Ergebnisse
|
|
YYYYMMDD_HHMMSS/
|
|
reports/ Generierte Reports (JSON + Markdown)
|
|
logs/ scanner.log
|
|
config/
|
|
allowed_external.yaml
|
|
allowed_paths.yaml
|
|
ignore_rules.yaml
|
|
```
|
|
|
|
---
|
|
|
|
## Tests
|
|
|
|
```bash
|
|
pytest tests/ -v
|
|
```
|
|
|
|
---
|
|
|
|
## Erweiterungen (optional, nicht implementiert)
|
|
|
|
- Ollama-Integration: Neue Textblöcke semantisch auf Spam-Kategorien prüfen
|
|
- Telegram-Bot: direkter Alert-Kanal
|
|
- Diff-Anzeige im Terminal: `python -m scanner report --diff-only`
|
|
- Automatische Archivierung alter Snapshots nach N Tagen
|