From a359e0852c61f153d8e9b5a6a9a305d524b89e44 Mon Sep 17 00:00:00 2001 From: Hendrik Date: Fri, 1 May 2026 21:40:20 +0200 Subject: [PATCH] =?UTF-8?q?Remove=20docs/=20folder=20=E2=80=94=20content?= =?UTF-8?q?=20is=20in=20GitHub=20Wiki,=20link=20from=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 88 ++++++++----------------- docs/API.md | 172 ------------------------------------------------ docs/INSTALL.md | 100 ---------------------------- docs/UPDATE.md | 57 ---------------- 4 files changed, 26 insertions(+), 391 deletions(-) delete mode 100644 docs/API.md delete mode 100644 docs/INSTALL.md delete mode 100644 docs/UPDATE.md diff --git a/README.md b/README.md index 1a322a6..b19bc1b 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,18 @@ Self-hosted Domain-Redirect-Server mit Web-Admin-UI und Per-Domain-Analytics. Vi - **One-Line Install** auf Debian/Ubuntu (Caddy + Node + systemd) - **Web-Admin-UI** mit Setup-Wizard, Domain-Verwaltung, Analytics - **Auto-HTTPS** via Caddy (Let's Encrypt automatisch) -- **DNS-Validierung** beim Hinzufügen einer Domain (zeigt fehlende Records) +- **DNS-Validierung + Live-Übersicht** aller Records (A, AAAA, MX, TXT, NS, CNAME, SOA, CAA) - **Domain-Gruppen** für gleiches Ziel über mehrere Domains -- **Per-Domain-Analytics** (Hits, Geo, Top-Domains, "Tote Domains") +- **Sunset-Notice-Pages** vor Redirect (per Domain oder Bulk) +- **Per-Domain-Analytics** (Hits, eindeutige Besucher, Geo, "Tote Domains") +- **Bot-Filter** mit Browser-Signal-Heuristik (Sec-Fetch, Accept-Language) + persistenter IP-Blocklist +- **PDF-Export** (Gesamt + Per-Domain) via headless Chromium +- **CSV-Import + Export** für Domains und Hits +- **Audit-Log** aller administrativen Aktionen - **Public REST-API** mit Token-Auth und Scopes +- **Multi-User** mit Rollen (admin / user) - **Self-Update** via GitHub-Releases (UI-Banner + Auto-Update opt-in) +- **Webhook-Notifications** bei Events (Domain-Verify-Fail etc.) - **DSGVO-freundlich**: IP-Hash mit täglich rotierendem Salt, kein Klartext ## Installation @@ -20,77 +27,34 @@ Self-hosted Domain-Redirect-Server mit Web-Admin-UI und Per-Domain-Analytics. Vi curl -sSL https://raw.githubusercontent.com/CoreXManagement/CoreX-NexRedirect/main/scripts/install.sh | sudo bash ``` -Optional vorab MaxMind-Lizenz für Geo-Lookup: -```bash -export MAXMIND_LICENSE_KEY=xxx -curl ... | sudo -E bash -``` +Anschließend Setup unter `http:///setup` aufrufen. -Anschließend Setup unter `http:///setup` aufrufen und Admin-Account erstellen. +→ Vollständige Anleitung im **[Wiki](https://github.com/CoreXManagement/CoreX-NexRedirect/wiki)**. -Details: [docs/INSTALL.md](docs/INSTALL.md) +## Dokumentation -## Domain hinzufügen +Komplette Doku ist im **[GitHub Wiki](https://github.com/CoreXManagement/CoreX-NexRedirect/wiki)**: -1. **Admin-UI** → "Domains" → "+ Domain hinzufügen" -2. Domain + Ziel-URL (oder Gruppe) eingeben -3. **DNS-Records** beim DNS-Provider eintragen (A/AAAA auf Server-IP) -4. **Validieren** — Server prüft DNS, aktiviert Domain, Caddy reload - -Alternativ via API: -```bash -curl -X POST -H "Authorization: Bearer nrx_..." -H "Content-Type: application/json" \ - -d '{"domain":"alt-firma.de","target_url":"https://www.firma.de"}' \ - https://admin.firma.de/api/v1/domains -``` - -## API - -Tokens werden im Web-UI unter **Einstellungen → API-Tokens** erstellt. Tokens haben Scopes (`read:domains`, `write:domains`, `read:analytics`, `read:hits`). - -```bash -curl -H "Authorization: Bearer nrx_..." https://admin.firma.de/api/v1/domains -``` - -Vollständige Doku: [docs/API.md](docs/API.md) - -## Updates - -Standardmäßig prüft der Server stündlich auf neue Releases und zeigt einen Banner in der UI. **Keine Auto-Updates** außer aktiviert. - -- Manuell: Settings → "Update X.Y.Z installieren" -- Auto: Settings → Auto-Update-Toggle aktivieren - -Details: [docs/UPDATE.md](docs/UPDATE.md) - -## CLI - -Nach Install: `nexredirect ` auf dem Server. - -``` -nexredirect status # Service-Status -nexredirect logs # Logs streamen -nexredirect update [tag] # Update auf neueste / Tag -nexredirect version # current + latest -nexredirect restart # Service-Restart -nexredirect caddy reload # Caddy reload -nexredirect caddy show # Caddyfile dumpen -nexredirect domains # aktive Domains -nexredirect hits [N] # letzte N Hits -nexredirect tokens # API-Token-Liste -nexredirect db # SQLite-Shell -nexredirect backup [path] # DB + Caddyfile sichern -nexredirect uninstall # entfernen (DB bleibt) -nexredirect help -``` +- [Installation](https://github.com/CoreXManagement/CoreX-NexRedirect/wiki/Installation) +- [DNS Setup](https://github.com/CoreXManagement/CoreX-NexRedirect/wiki/DNS-Setup) +- [Domain Management](https://github.com/CoreXManagement/CoreX-NexRedirect/wiki/Domain-Management) +- [Sunset Pages](https://github.com/CoreXManagement/CoreX-NexRedirect/wiki/Sunset-Pages) +- [Analytics & Reports](https://github.com/CoreXManagement/CoreX-NexRedirect/wiki/Analytics-&-Reports) +- [Bot Filter](https://github.com/CoreXManagement/CoreX-NexRedirect/wiki/Bot-Filter) +- [CLI](https://github.com/CoreXManagement/CoreX-NexRedirect/wiki/CLI) +- [API](https://github.com/CoreXManagement/CoreX-NexRedirect/wiki/API) +- [Updates](https://github.com/CoreXManagement/CoreX-NexRedirect/wiki/Updates) +- [Architecture](https://github.com/CoreXManagement/CoreX-NexRedirect/wiki/Architecture) +- [Troubleshooting](https://github.com/CoreXManagement/CoreX-NexRedirect/wiki/Troubleshooting) ## Stack - Next.js 15 + TypeScript + TailwindCSS + Radix UI + Recharts - better-sqlite3 (eine Datei in `/var/lib/corex-nexredirect/nexredirect.db`) - Caddy (Auto-HTTPS, Reverse-Proxy) -- MaxMind GeoLite2-Country (lokal) +- MaxMind GeoLite2-Country (lokal, optional) - NextAuth Credentials + bcryptjs +- puppeteer-core + Chromium (PDF-Export) ## Lokale Entwicklung diff --git a/docs/API.md b/docs/API.md deleted file mode 100644 index 83bb0c8..0000000 --- a/docs/API.md +++ /dev/null @@ -1,172 +0,0 @@ -# API - -Public REST-API für CoreX NexRedirect. Versioniert unter `/api/v1`. JSON-only. - -## Auth - -Tokens erstellen unter **Einstellungen → API-Tokens** im Web-UI. Token wird nur einmalig angezeigt — sicher kopieren. - -Format: `nrx_<64-hex>`. Im Header senden: - -``` -Authorization: Bearer nrx_ -``` - -Tokens haben **Scopes**: - -| Scope | Erlaubt | -|-------|---------| -| `read:domains` | Domains lesen | -| `write:domains` | Domains anlegen/löschen | -| `read:analytics` | Aggregierte Statistiken | -| `read:hits` | Roh-Hits (nur ip_hash, kein Klartext-IP) | - -Fehler-Format: -```json -{ "error": "forbidden", "code": "missing_scope", "required": "read:domains" } -``` - -## Endpoints - -### `GET /api/v1/health` -Liveness-Check. Kein Token nötig. - -```bash -curl https://admin.firma.de/api/v1/health -# {"ok":true,"ts":1714500000000} -``` - -### `GET /api/v1/version` -Aktuelle Version + Update-Status. Kein Token nötig. - -```json -{ - "current": "0.1.0", - "latest": "0.1.1", - "update_available": true, - "release_url": "https://github.com/.../releases/tag/v0.1.1", - "auto_update": false -} -``` - -### `GET /api/v1/domains` -Scope: `read:domains` - -```bash -curl -H "Authorization: Bearer nrx_..." https://admin.firma.de/api/v1/domains -``` - -```json -{ - "domains": [ - { - "id": 1, "domain": "alt-firma.de", "status": "active", - "target_url": "https://www.firma.de", "redirect_code": 301, - "preserve_path": 1, "include_www": 1, - "total_hits": 142, "last_hit": 1714499000000 - } - ] -} -``` - -### `POST /api/v1/domains` -Scope: `write:domains` - -Body: -```json -{ - "domain": "alt-firma.de", - "target_url": "https://www.firma.de", - "redirect_code": 301, - "preserve_path": true, - "include_www": true -} -``` - -Response (`201`): -```json -{ - "domain": { "id": 5, "status": "pending", ... }, - "dns_records": [ - { "type": "A", "name": "alt-firma.de", "value": "203.0.113.42" }, - { "type": "A", "name": "www.alt-firma.de", "value": "203.0.113.42" } - ] -} -``` - -DNS muss anschließend gesetzt + verifiziert werden (über UI oder via internen `/api/domains/:id/verify`-Endpoint, der einen User-Login erfordert). - -### `GET /api/v1/domains/:id` -Scope: `read:domains` - -### `DELETE /api/v1/domains/:id` -Scope: `write:domains` - -### `GET /api/v1/domains/:id/stats?days=30` -Scope: `read:analytics` - -```json -{ - "domain_id": 1, "days": 30, "total": 412, - "daily": [{"day":"2026-04-01","hits":12}, ...], - "by_country": [{"country":"DE","hits":380},{"country":"AT","hits":18}, ...] -} -``` - -### `GET /api/v1/analytics/summary?days=30` -Scope: `read:analytics` - -```json -{ - "days": 30, "total": 12480, - "daily": [...], - "top": [{"id":1,"domain":"alt-firma.de","hits":412}, ...], - "by_country": [...] -} -``` - -### `GET /api/v1/hits?domain_id=1&limit=100` -Scope: `read:hits` - -```json -{ - "hits": [ - { - "id": 9001, "domain_id": 1, "ts": 1714499000000, - "ip_hash": "9f4a...", "country": "DE", - "user_agent": "Mozilla/5.0 ...", "referer": null, "path": "/" - } - ] -} -``` - -`ip_hash` = `sha256(ip + täglicher Salt)`. Kein Klartext-IP wird gespeichert. - -## Versionierung - -`/api/v1` ist stabil. Breaking-Changes erscheinen unter `/api/v2`. Deprecation-Hinweise im `Sunset`-Header. - -## Rate-Limits - -Kein hartes Limit aktuell. Empfehlung: max. 60 Requests/Minute pro Token. Bei Problemen Token rotieren. - -## Beispiele - -**Uptime-Check eines Tokens:** -```bash -curl -fsS -H "Authorization: Bearer $NRX" https://admin.firma.de/api/v1/health || echo "DOWN" -``` - -**Liste tote Domains (0 Hits / 90d):** -```bash -curl -s -H "Authorization: Bearer $NRX" \ - "https://admin.firma.de/api/v1/analytics/summary?days=90" \ - | jq '.top | map(select(.hits == 0))' -``` - -**Domain anlegen + DNS-Records anzeigen:** -```bash -curl -X POST -H "Authorization: Bearer $NRX" -H "Content-Type: application/json" \ - -d '{"domain":"shop.alt.de","target_url":"https://shop.firma.de"}' \ - https://admin.firma.de/api/v1/domains | jq '.dns_records' -``` diff --git a/docs/INSTALL.md b/docs/INSTALL.md deleted file mode 100644 index 2707d83..0000000 --- a/docs/INSTALL.md +++ /dev/null @@ -1,100 +0,0 @@ -# Installation - -## One-Line (Debian/Ubuntu) - -```bash -curl -sSL https://raw.githubusercontent.com/CoreXManagement/CoreX-NexRedirect/main/scripts/install.sh | sudo bash -``` - -Optional mit MaxMind-Lizenz für Geo-Lookup: -```bash -sudo MAXMIND_LICENSE_KEY=xxxxxxxx bash -c \ - "$(curl -sSL https://raw.githubusercontent.com/CoreXManagement/CoreX-NexRedirect/main/scripts/install.sh)" -``` - -Das Script: - -1. Prüft Debian/Ubuntu -2. Installiert Caddy (offizielles Repo), Node.js 20, git -3. Legt System-User `nexredirect` an -4. Cloned Repo nach `/opt/corex-nexredirect` -5. `npm ci && npm run build` -6. Holt GeoLite2-Country (falls Lizenz gesetzt) -7. Schreibt systemd-Unit `corex-nexredirect.service` -8. Schreibt minimale Caddyfile-Bootstrap-Config -9. `systemctl enable --now caddy corex-nexredirect` -10. Druckt Setup-URL - -## Manueller Install - -Wer das Curl-Pipe-Bash nicht mag: - -```bash -sudo apt-get install -y caddy nodejs git -sudo useradd --system --home /opt/corex-nexredirect --shell /usr/sbin/nologin nexredirect -sudo mkdir -p /opt/corex-nexredirect /var/lib/corex-nexredirect -sudo git clone https://github.com/CoreXManagement/CoreX-NexRedirect /opt/corex-nexredirect -sudo chown -R nexredirect:nexredirect /opt/corex-nexredirect /var/lib/corex-nexredirect -sudo -u nexredirect bash -c "cd /opt/corex-nexredirect && npm ci && npm run build" -sudo cp /opt/corex-nexredirect/systemd/corex-nexredirect.service /etc/systemd/system/ -sudo systemctl daemon-reload -sudo systemctl enable --now caddy corex-nexredirect -``` - -Bootstrap-Caddyfile in `/etc/caddy/Caddyfile`: -``` -:80 { - reverse_proxy localhost:3000 -} -``` - -## Verzeichnisse - -| Pfad | Inhalt | -|------|--------| -| `/opt/corex-nexredirect` | Code (git checkout) | -| `/var/lib/corex-nexredirect/nexredirect.db` | SQLite (alle Daten) | -| `/var/lib/corex-nexredirect/GeoLite2-Country.mmdb` | Geo-DB (optional) | -| `/etc/caddy/Caddyfile` | Caddy-Config (auto-generated) | -| `/etc/systemd/system/corex-nexredirect.service` | systemd-Unit | -| `/etc/sudoers.d/corex-nexredirect` | Sudo für update.sh | - -## Backup / Restore - -Sicherung: -```bash -sudo tar -czf nexredirect-backup-$(date +%F).tar.gz \ - /var/lib/corex-nexredirect/nexredirect.db \ - /etc/caddy/Caddyfile -``` - -Restore: -```bash -sudo systemctl stop corex-nexredirect caddy -sudo tar -xzf nexredirect-backup-XXXX.tar.gz -C / -sudo chown nexredirect:nexredirect /var/lib/corex-nexredirect/nexredirect.db -sudo systemctl start caddy corex-nexredirect -``` - -SQLite ist im WAL-Modus — Hot-Backup ohne Stop: -```bash -sqlite3 /var/lib/corex-nexredirect/nexredirect.db ".backup /tmp/db.sqlite" -``` - -## Logs - -```bash -journalctl -u corex-nexredirect -f -journalctl -u caddy -f -``` - -## Deinstallation - -```bash -sudo systemctl disable --now corex-nexredirect -sudo rm /etc/systemd/system/corex-nexredirect.service /etc/sudoers.d/corex-nexredirect -sudo systemctl daemon-reload -sudo userdel nexredirect -sudo rm -rf /opt/corex-nexredirect /var/lib/corex-nexredirect -# Caddy + Caddyfile bei Bedarf separat -``` diff --git a/docs/UPDATE.md b/docs/UPDATE.md deleted file mode 100644 index 086519f..0000000 --- a/docs/UPDATE.md +++ /dev/null @@ -1,57 +0,0 @@ -# Updates - -NexRedirect prüft alle 60 Minuten gegen die GitHub-Releases-API auf neue Versionen. **Keine Auto-Updates** außer aktiviert. - -## Update-Verhalten - -| Setting | Verhalten | -|---------|-----------| -| (Default) | Stündlicher Check, Banner in der UI bei verfügbarem Update. Nichts wird ohne Klick installiert. | -| `update_auto = true` | Bei jedem Check wird ein verfügbares Update sofort installiert. | -| `update_include_prereleases = true` | Auch Pre-Releases werden als Update angezeigt. | - -## Manuell aktualisieren - -In der UI: - -1. **Einstellungen** → "Update X.Y.Z installieren" klicken -2. Bestätigen -3. Server fährt herunter, zieht Tag, baut, startet neu (Admin-UI ~5–10s down) -4. Redirects bleiben über Caddy aktiv (Caddy-Block enthält statisches Fallback-`redir`) - -Auf der Konsole: -```bash -sudo /opt/corex-nexredirect/scripts/update.sh v0.2.0 -``` - -## Auto-Update aktivieren - -**Einstellungen → "Auto-Update aktivieren"** klicken. Ab dann wird bei jedem stündlichen Check ein verfügbares Update direkt installiert. UI-Banner erscheint nicht mehr (oder kurz). - -Empfehlung: Auto-Update nur in Test-Umgebungen, in Prod manuell prüfen. - -## Rollback - -```bash -cd /opt/corex-nexredirect -sudo -u nexredirect git tag --list | sort -V -sudo /opt/corex-nexredirect/scripts/update.sh v0.1.0 # Vorgänger-Tag -``` - -Der Update-Skript ruft `git checkout ` und rebuilt — daher gleich für Forward- und Rollback-Updates. - -## Schema-Migrationen - -`ensureSchema` in `lib/db.ts` legt fehlende Tabellen/Indizes idempotent an — `CREATE TABLE IF NOT EXISTS` für jede Tabelle. Reine additive Migrationen sind damit automatisch. - -Für **destruktive** Migrationen (Spalten umbenennen, droppen): manuelles SQL vor dem Update einspielen, Schritte werden im Release-Note dokumentiert. - -## Update-Log - -Jeder Update-Versuch wird in der `update_log`-Tabelle protokolliert: - -```sql -SELECT ts, from_version, to_version, status FROM update_log ORDER BY ts DESC LIMIT 10; -``` - -Status: `success` oder `failed` (mit Log-Auszug in der `log`-Spalte).