Website Integrity Scanner für kleine statische Webseiten gegen SEO-Spam
- Python 99.9%
Neue 4xx/5xx-Seiten (nicht in Baseline) werden bewertet (+20 Pkt) und lösen ab Schwelle einen Alert aus. Bekannte kaputte Links (in Baseline vorhanden) erscheinen im Report als [bekannt] ohne Score-Beitrag. Motivation: erster Crawl fand bredelar.info/www.stadtmarketing-marsberg.de (404) — CMS-Fehler durch Schema-losen href. Soll dauerhaft sichtbar sein. Änderungen: checker.find_broken_pages(), differ.compare_snapshots() mit new_broken_urls/known_broken_urls, score_diff(), Report-Abschnitt, config-Default new_broken_link:20, 4 neue Tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| config | ||
| Keller | ||
| scanner | ||
| tests | ||
| .gitignore | ||
| CLAUDE.md | ||
| config.yaml | ||
| README.md | ||
| requirements.txt | ||
Website Integrity Scanner
Unabhängiges Überwachungswerkzeug für statische Websites gegen SEO-Spam und unbefugte Manipulationen. Läuft im Verantwortungsbereich des Betreibers, nicht beim Webhoster.
Schnellstart
cd integrity_scanner_fuer_statische_Webseiten
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# 1. Erste Baseline anlegen
python -m scanner init
# 2. Ergebnis prüfen, dann freigeben
python -m scanner approve --all --note "Initiale Baseline nach Sichtprüfung"
# 3. Täglicher Betrieb (oder per Cron)
python -m scanner scan
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
# 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)
- Report lesen:
python -m scanner report - Verdächtige URLs manuell im Browser prüfen
- Quelltext der betroffenen Seiten ansehen (insb.
display:none-Bereiche) - Dienstleister kontaktieren, Zugriff auf Hosting prüfen
- Nach Bereinigung:
python -m scanner scan— muss grün sein - Dann:
python -m scanner approve --rebuild --note "Nach Incident bereinigt"
Wichtig: Niemals approve auf eine kompromittierte Seite anwenden.
Cron-Setup
# Täglich 03:00 Uhr
0 3 * * * cd /opt/scanner && /opt/scanner/venv/bin/python -m scanner scan >> /opt/scanner/logs/cron.log 2>&1
Log-Rotation (/etc/logrotate.d/scanner):
/opt/scanner/logs/*.log {
daily
rotate 30
compress
missingok
notifempty
}
Konfiguration
E-Mail aktivieren
In config.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):
export SCANNER_SMTP_PASSWORD="geheimesPasswort"
Webhook aktivieren
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:
- 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
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