From afc9c3914881dd7ee4e134f89cdef78a6338870d Mon Sep 17 00:00:00 2001
From: Pascal Scholz
Date: Mon, 2 Nov 2026 22:10:08 +0000
Subject: [PATCH] =?UTF-8?q?SFTP-Zugang=20zu=20/shared=20f=C3=BCr=20gro?=
=?UTF-8?q?=C3=9Fe=20Dateien=20(Skript=20f=C3=BCr=20Pascal,=20Anleitung=20?=
=?UTF-8?q?f=C3=BCr=20Lara)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-Authored-By: Claude Opus 5.5
---
DEPLOYMENT_CLAUDE.md | 26 +++++++++++++++
ONBOARDING_LARA.md | 34 +++++++++++++++++++
claude-remote/sftp-upload.sh | 65 ++++++++++++++++++++++++++++++++++++
3 files changed, 125 insertions(+)
create mode 100644 claude-remote/sftp-upload.sh
diff --git a/DEPLOYMENT_CLAUDE.md b/DEPLOYMENT_CLAUDE.md
index 62412db..d4d3e5b 100644
--- a/DEPLOYMENT_CLAUDE.md
+++ b/DEPLOYMENT_CLAUDE.md
@@ -87,6 +87,32 @@ Start einer Sitzung und bei jedem Prompt. Die Nachrichten liegen im Volume
Ihr könnt Claude auch direkt bitten, z. B.: „Schreib Lara ins Postfach,
dass die Startseite überarbeitet ist."
+## Dateien hochladen (SFTP zu `/shared`)
+
+Für große Dateien vom eigenen Rechner (Videos, Hörproben) gibt es einen
+reinen SFTP-Zugang: nur Dateien, keine Shell, kein Docker, eingesperrt auf
+`/shared`. Er startet im Eingangsordner `/shared/youtube/upload`.
+
+**Einrichten (Pascal, einmalig je Person):** Die Person erzeugt einen
+Schlüssel (siehe `ONBOARDING_LARA.md`, Abschnitt 9) und schickt den
+**öffentlichen** Teil (`.pub`). Dann auf dem Server:
+```
+scp claude-remote/sftp-upload.sh :~/claude-stack/ # oder nach dem Kopieren von claude-remote/
+ssh
+sudo bash ~/claude-stack/sftp-upload.sh "ssh-ed25519 AAAA… lara"
+```
+Das Skript legt den Nutzer `lara-upload` an (Gruppe wie die Container, damit
+hochgeladene Dateien dort beschreibbar sind), hängt das Volume
+`claude_shared` unter `/srv/sftp/lara-upload/shared` ein (Eintrag in
+`/etc/fstab`) und schreibt `/etc/ssh/sshd_config.d/sftp-lara-upload.conf`.
+Es prüft die sshd-Konfiguration vor dem Neuladen. Port 22 wie bei deinem
+SSH-Zugang.
+
+**Schlüssel tauschen:** Skript mit dem neuen Schlüssel erneut ausführen.
+**Entfernen:** `/etc/ssh/sshd_config.d/sftp-lara-upload.conf` löschen,
+`systemctl reload ssh`, Zeile in `/etc/fstab` entfernen,
+`umount /srv/sftp/lara-upload/shared`, `userdel lara-upload`.
+
## Betrieb
```
diff --git a/ONBOARDING_LARA.md b/ONBOARDING_LARA.md
index ede8dba..a0b9ae4 100644
--- a/ONBOARDING_LARA.md
+++ b/ONBOARDING_LARA.md
@@ -123,3 +123,37 @@ So arbeitest du damit:
`/shared/youtube/`, nicht ins Git.
- **Nutzungslimit:** Du nutzt dein eigenes Claude-Kontingent. Lange
Video- oder Recherche-Aufgaben verbrauchen viel davon.
+
+## 9. Große Dateien auf den Server hochladen (SFTP)
+
+Videos, Hörproben und Rohmaterial gehören nach `/shared/youtube/` auf dem
+VPS, damit Pascal und beide Claude-Container sie sehen. Dafür gibt es einen
+reinen Datei-Zugang (kein Server-Login).
+
+**Einmalig: Schlüssel erzeugen** (Windows, Eingabeaufforderung `cmd`):
+```
+ssh-keygen -t ed25519 -f %USERPROFILE%\.ssh\pino_upload -C lara
+type %USERPROFILE%\.ssh\pino_upload.pub
+```
+Die angezeigte Zeile (`ssh-ed25519 AAAA… lara`) ist der **öffentliche**
+Schlüssel – den schickst du Pascal (darf in Chat/Postfach). Die Datei
+**ohne** `.pub` bleibt bei dir und wird nie weitergegeben. Pascal richtet
+damit den Zugang ein.
+
+**Hochladen:**
+```
+sftp -i %USERPROFILE%\.ssh\pino_upload lara-upload@larpaso.de
+put -r "C:\Users\lk-lo\Pino-Kanal\Stimmen-Entwuerfe"
+bye
+```
+Du landest im Ordner `upload`; die Dateien liegen danach in
+`/shared/youtube/upload/` (in den Claude-Containern genauso). Mit `ls`
+siehst du, was da ist, mit `get` holst du Dateien vom Server. Lieber mit
+der Maus: [WinSCP](https://winscp.net), Protokoll SFTP, Rechner
+`larpaso.de`, Benutzer `lara-upload`, unter „Erweitert → SSH →
+Authentifizierung“ die Schlüsseldatei wählen (WinSCP bietet an, sie
+umzuwandeln).
+
+Arbeitest du mit Claude auf deinem PC, kann Claude das auch für dich
+erledigen („lade den Ordner … nach /shared/youtube/upload hoch“).
+
diff --git a/claude-remote/sftp-upload.sh b/claude-remote/sftp-upload.sh
new file mode 100644
index 0000000..a5eb137
--- /dev/null
+++ b/claude-remote/sftp-upload.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# Richtet einen reinen SFTP-Zugang zum gemeinsamen Ordner /shared der
+# Claude-Container ein (für große Dateien: Videos, Audio, Hörproben).
+# Keine Shell, kein Docker, nur Dateien hoch- und herunterladen.
+#
+# sudo bash sftp-upload.sh "ssh-ed25519 AAAA… lara" Nutzer lara-upload
+# sudo bash sftp-upload.sh "ssh-ed25519 AAAA… …" anderer-name
+#
+# Nochmal ausführen ersetzt den Schlüssel. Entfernen siehe DEPLOYMENT_CLAUDE.md.
+set -euo pipefail
+
+SCHLUESSEL=${1:?Öffentlichen SSH-Schlüssel (Inhalt der .pub-Datei) angeben}
+NUTZER=${2:-lara-upload}
+VOLUME=/var/lib/docker/volumes/claude_shared/_data
+CHROOT=/srv/sftp/$NUTZER
+
+[[ $SCHLUESSEL == ssh-* || $SCHLUESSEL == ecdsa-* ]] || { echo "Das sieht nicht nach einem öffentlichen Schlüssel aus (ssh-ed25519 …)."; exit 1; }
+[ -d "$VOLUME" ] || { echo "Volume $VOLUME fehlt – läuft der Claude-Stack?"; exit 1; }
+
+# Gleiche Gruppe wie die Dateien im Volume (Container-Nutzer node, gid 1000),
+# damit hochgeladene Dateien in den Containern les- und schreibbar sind.
+GID=$(stat -c %g "$VOLUME")
+getent group "$GID" >/dev/null || groupadd -g "$GID" claude-shared
+id "$NUTZER" >/dev/null 2>&1 || useradd --system --no-create-home --home-dir / --shell /usr/sbin/nologin -g "$GID" "$NUTZER"
+
+# Chroot muss root gehören; darin /shared als Bind-Mount auf das Volume
+install -d -o root -g root -m 755 /srv/sftp "$CHROOT"
+# (nicht anfassen, wenn schon eingehängt – sonst gehörte das Volume danach root)
+mountpoint -q "$CHROOT/shared" || install -d -o root -g root -m 755 "$CHROOT/shared"
+if ! grep -q " $CHROOT/shared " /etc/fstab; then
+ echo "$VOLUME $CHROOT/shared none bind 0 0" >>/etc/fstab
+fi
+mountpoint -q "$CHROOT/shared" || mount "$CHROOT/shared"
+
+# Eingangsordner, in den die Container-Dateien schreibbar sind
+install -d -o "$(stat -c %u "$VOLUME")" -g "$GID" -m 2775 "$VOLUME/youtube/upload"
+
+# Schlüssel außerhalb des Chroot
+install -d -o root -g root -m 755 /etc/ssh/authorized_keys
+echo "$SCHLUESSEL" >"/etc/ssh/authorized_keys/$NUTZER"
+chmod 644 "/etc/ssh/authorized_keys/$NUTZER"
+
+cat >"/etc/ssh/sshd_config.d/sftp-$NUTZER.conf" </dev/null | grep -qi '^allowusers'; then
+ echo "Hinweis: In der sshd-Konfiguration steht AllowUsers. $NUTZER dort ergänzen, sonst wird der Zugang abgelehnt."
+fi
+
+sshd -t
+systemctl reload ssh 2>/dev/null || systemctl reload sshd
+echo "Fertig. Test: sftp $NUTZER@$(hostname -f) (Start im Ordner /shared/youtube/upload)"