Remove docs/ folder — content is in GitHub Wiki, link from README
This commit is contained in:
parent
9fce2e9db6
commit
a359e0852c
4 changed files with 26 additions and 391 deletions
88
README.md
88
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://<server-ip>/setup` aufrufen.
|
||||
|
||||
Anschließend Setup unter `http://<server-ip>/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 <befehl>` 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
|
||||
|
||||
|
|
|
|||
172
docs/API.md
172
docs/API.md
|
|
@ -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_<your-token>
|
||||
```
|
||||
|
||||
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'
|
||||
```
|
||||
100
docs/INSTALL.md
100
docs/INSTALL.md
|
|
@ -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
|
||||
```
|
||||
|
|
@ -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 <tag>` 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).
|
||||
Loading…
Reference in a new issue