Files
zwischenablage-server/README.md
T
2026-10-16 15:55:14 +02:00

8.9 KiB
Raw Blame History

NetClip – Netzwerk-Zwischenablage

Eine gemeinsame Zwischenablage für alle eigenen Geräte (Windows, Linux, macOS, Android) – im Stil von CopyQ, aber über das Netzwerk. Text, Bilder und Dateien/Ordner werden übertragen: Wird auf dem einen Rechner ein Ordner kopiert (Strg+C im Explorer/Finder/Dolphin), fügt Strg+V auf dem anderen Rechner den Ordner in den gerade geöffneten Zielordner ein. Mit Verlauf, um Einträge später erneut einzufügen.

 PC (Windows)        Laptop (Linux)        Mac            Handy (Android)
      │                    │                 │                    │
      └──────── WebSocket + HTTPS (Ende-zu-Ende verschlüsselt) ───┘
                               │
                    NetClip-Server (Docker)
             verbindet nur Clients mit gleichem Token

Funktionsweise

  • Alle Geräte mit demselben Token bilden einen gemeinsamen „Raum“.
  • Der Token verlässt das Gerät nie. Aus ihm werden per PBKDF2 eine Raum-ID (sieht der Server) und ein AES-256-Schlüssel abgeleitet (sieht der Server nicht). Inhalte, Dateinamen, Vorschauen und Gerätenamen sind Ende-zu-Ende verschlüsselt – der Server speichert und verteilt nur undurchsichtige Blobs.
  • Der Server hält einen Verlauf pro Raum (Anzahl, Alter, Speicherplatz begrenzt, siehe .env).
  • Optional schützt ein SERVER_KEY den Server davor, von Fremden benutzt zu werden.

Server (Docker)

cp .env.example .env      # Werte anpassen (CERT_CN, CERT_SAN, SERVER_KEY, ...)
docker compose up -d --build

Die .env ist kommentiert. Die wichtigsten Schalter:

Variable Bedeutung
COMPOSE_PROFILES=nginx nginx als HTTPS-Proxy mit selbstsigniertem Zertifikat mitstarten. Leer lassen, wenn schon ein Reverse-Proxy vorhanden ist (siehe docs/eigener-reverse-proxy.md).
CERT_CN, CERT_SAN Hostname bzw. weitere Namen/IPs im Zertifikat
CERT_DAYS, CERT_RENEW_DAYS Gültigkeit; so viele Tage vor Ablauf wird beim Containerstart automatisch erneuert
CERT_KEY_BITS, CERT_COUNTRY … CERT_OU weitere Zertifikatsfelder
SERVER_KEY optionaler Zugangsschlüssel für den Server
MAX_CLIP_MB maximale Größe eines Clips
HISTORY_MAX, HISTORY_DAYS, ROOM_QUOTA_MB Verlaufsgrenzen pro Token
BIND_ADDR, PORT direkter HTTP-Port des Servers (mit nginx am besten BIND_ADDR=127.0.0.1)

Ändert man CERT_*-Werte, wird das Zertifikat beim nächsten Start neu erzeugt. Eigene Zertifikate: fullchain.pem + privkey.pem nach ./certs legen und ./certs/.selfsigned löschen.

Selbstsignierte Zertifikate in den Clients: entweder „TLS-Zertifikat prüfen“ abschalten (nur im eigenen Netz) oder im Desktop-Client unter „Zertifikat“ die certs/fullchain.pem des Servers hinterlegen.

Mit dem alten docker-compose (v1) funktioniert es genauso: docker-compose up -d --build.

Desktop-Client (Windows, Linux, macOS)

Python + Qt (PySide6), eine Codebasis für alle drei Systeme. Läuft im System-Tray.

  • Tray-Menü: die letzten 10 Einträge zum schnellen Einfügen, Verlauf, Pausieren, Einstellungen
  • Verlaufsfenster: Suche, Doppelklick/Enter = in die Zwischenablage, „Speichern unter …“, Löschen
  • Einstellungen: Server, Token (Erzeugen), Server-Schlüssel, Zertifikat, Gerätename, was synchronisiert wird, Größenlimits, Autostart
  • Verbindung teilen: QR-Code für Android · Exportieren (.netclip-Datei) · Importieren
  • Passwort-Manager-Einträge (KeePassXC, Bitwarden, 1Password …), die als „geheim“ markiert sind, werden nicht synchronisiert.

Empfangene Dateien/Ordner werden in den Cache entpackt (%LOCALAPPDATA%\NetClip\cache, ~/Library/Caches/NetClip, ~/.cache/netclip) und als Datei-Referenz in die Zwischenablage gelegt – Strg+V im Dateimanager kopiert sie dann an den gewünschten Ort. Der Cache wird nach keep_received_days (Standard 7 Tage) aufgeräumt.

Starten aus dem Quellcode

cd client-desktop
python -m venv .venv && . .venv/bin/activate      # Windows: .venv\Scripts\activate
pip install -r requirements.txt
python -m netclip

Pakete bauen

PyInstaller baut immer für das System, auf dem es läuft – also einmal je Betriebssystem:

cd client-desktop
python build.py
System Ergebnis
Windows dist/NetClip/NetClip.exe, danach packaging/windows-installer.iss mit Inno Setup kompilieren → dist/NetClip-Setup-1.0.0.exe
macOS dist/NetClip.app und dist/NetClip-macos.zip (Menüleisten-App ohne Dock-Symbol)
Linux dist/NetClip-linux-x86_64.tar.gz mit install-linux.sh

Ausrollen

Kommandozeile (alle Systeme):

NetClip --configure-only --server https://clip.example.de --token XYZ [--server-key K] [--insecure] [--autostart]
NetClip --import verbindung.netclip
NetClip --show        # Verlauf der laufenden Instanz öffnen – z.B. auf ein Tastenkürzel legen

Vorgaben für alle Benutzer: eine config.default.json neben die Programmdatei legen, z.B. {"server": "https://clip.example.de", "token": "...", "verify_tls": false}. Sie wird beim ersten Start jedes Benutzers übernommen (Gerätename und Geräte-ID bleiben pro Gerät eindeutig).

  • Windows (GPO/Intune/PDQ): NetClip-Setup-1.0.0.exe /VERYSILENT /SUPPRESSMSGBOXES /SERVER=https://clip.example.de /TOKEN=xyz [/SERVERKEY=k] [/INSECURE=1] – schreibt config.default.json und richtet den Autostart für alle Benutzer ein.
  • Linux: sudo ./install-linux.sh --server https://clip.example.de --token xyz [--insecure]
  • macOS: NetClip.app nach /Applications kopieren, config.default.json nach NetClip.app/Contents/MacOS/ legen.

Hinweis: Wer den Token kennt, sieht die Zwischenablage. Ein gemeinsamer Token für mehrere Personen bedeutet eine gemeinsame Zwischenablage – pro Person/Team einen eigenen Token verwenden.

Plattform-Hinweise

  • Linux/X11: funktioniert direkt (Dolphin, Nautilus, Nemo, Thunar, Caja).
  • Linux/Wayland: Wayland gibt Programmen im Hintergrund keinen Zugriff auf die Zwischenablage. NetClip nutzt dann automatisch wl-clipboard (apt install wl-clipboard). Das funktioniert unter KDE Plasma und wlroots-Desktops (Sway, Hyprland), nicht unter GNOME – dort eine X11-Sitzung nutzen. Mit NETCLIP_BACKEND=qt lässt sich das Qt-Backend erzwingen.
  • macOS: beim ersten Start ggf. in den Systemeinstellungen „Öffnen“ bestätigen (unsigniert).
  • Windows: keine Besonderheiten; Dateien werden als „Kopieren“ (nicht „Ausschneiden“) eingefügt.

Android-Client

Kotlin, ab Android 8. Läuft als Vordergrunddienst mit dauerhafter Benachrichtigung.

  • Einrichten: Einstellungen → QR-Code vom PC scannen (Desktop: Einstellungen → QR-Code für Android) oder .netclip-Datei importieren. Ein netclip://-Link aus einer beliebigen QR-App öffnet ebenfalls direkt die Einstellungen.
  • Empfangen: Text und Bilder landen automatisch in der Zwischenablage. Dateien/Ordner kommen per Benachrichtigung mit Speichern (→ Download/NetClip/, Ordnerstruktur bleibt erhalten) und Teilen.
  • Senden: Android erlaubt Apps im Hintergrund nicht, die Zwischenablage zu lesen. Deshalb:
    • Button Zwischenablage senden in der App oder in der Benachrichtigung
    • Schnelleinstellungs-Kachel „Zwischenablage senden“ (Kacheln bearbeiten → hinzufügen)
    • Teilen → An NetClip senden aus jeder App (Text, Bilder, mehrere Dateien)
    • Text markieren → An NetClip senden im Auswahlmenü
  • Verlauf: antippen = in die Zwischenablage; lange drücken = Speichern, Teilen, Löschen.

Bauen

cd client-android
./gradlew assembleRelease     # app/build/outputs/apk/release/app-release.apk

Das Release-APK ist zum Testen mit dem Debug-Schlüssel signiert; für die Verteilung in app/build.gradle einen eigenen Keystore eintragen.

Tests

# Kompatibilität der Verschlüsselung Python <-> Kotlin
python tools/interop.py gen /tmp/interop
(cd client-android && ./gradlew testDebugUnitTest -Pinterop=/tmp/interop)
python tools/interop.py check /tmp/interop

Protokoll (für eigene Clients)

Methode Pfad Beschreibung
GET /healthz Status
GET /api/v1/info Server-Limits
GET /api/v1/rooms/{room}/clips Verlauf (id, ts, device, size, meta)
POST /api/v1/rooms/{room}/clips Body: 4 Byte Länge (BE) + Meta (Base64) + verschlüsselter Blob; Header X-Device
GET /api/v1/rooms/{room}/clips/{id}/blob verschlüsselten Inhalt laden
DELETE /api/v1/rooms/{room}/clips[/{id}] Verlauf leeren bzw. Eintrag löschen
WS /api/v1/rooms/{room}/ws?device=… Ereignisse hello, clip, deleted, cleared, devices

Mit SERVER_KEY ist bei allen /api/-Aufrufen Authorization: Bearer <key> nötig. Verschlüsselungsformat: siehe Kopf von client-desktop/netclip/crypto.py.