Drucker-Pi holt sich die Einrichtung, statt sie geschickt zu bekommen

Bisher richtete die App den Pi per SSH ein: Adresse, Benutzer und Passwort ins
Webformular, Knopf druecken. Das verlangte ein SSH-Passwort in einem Browser,
ein weiteres Paket (ssh2) und eine Verbindung vom Server zum Pi.

Jetzt andersherum. Die App legt einen Link bereit und wartet. Auf dem Pi wird
das Skript geholt und gestartet, dort wird der Drucker ausgewaehlt, und am
Ende meldet sich der Pi von selbst an. Wer einen Drucker ansteckt, steht
ohnehin am Pi - dort gehoert auch die Frage hin, welcher es sein soll.

Die Auswahl zeigt Klartextnamen aus dem sysfs: "EPSON TM-T88IV" statt "lp0".
Bei mehreren Druckern ist das der Unterschied zwischen Wissen und Raten.

Das ausgelieferte Skript ist zusammengesetzt, nicht statisch: einrichten.sh ist
eine Vorlage, in die setup.js Adresse, Code, print-server.py und die
systemd-Unit einsetzt. Heraus kommt EINE Datei - auf dem Pi ist nichts
nachzuladen, und eine halb geglueckte Uebertragung kann es nicht geben.

Zwei Endpunkte muessen ohne Anmeldung auskommen, weil der Pi sich bei Authentik
nicht anmelden kann. Der Einrichtungscode ist dort der einzige Schluessel: 32
Zeichen, gilt einmal und 30 Minuten, nur im Arbeitsspeicher, zeitkonstant
verglichen, hinter einem eigenen Zaehler.

Die Adresse des Pi wird der Verbindung entnommen und nicht dem Rumpf der
Anmeldung - was der Pi ueber sich behauptet, koennte auch jemand anders
behaupten. Die eigene Adresse leitet die App aus dem Host-Kopf ab und prueft
sie streng, statt sie zu maskieren: der Wert landet in einem Shell-Skript.

Geprueft am echten Pi (Debian 13, TM-T88IV): Link erzeugen, am Pi abholen,
Drucker aus der Liste waehlen, Anmeldung, Uebernahme, Probedruck. Dazu die
Abweise: verbrauchter Code, falscher Code, Abholung ohne Code, und dass die
uebrige API weiterhin 401 liefert.

Entfaellt: provision.js, install.sh, die Abhaengigkeit ssh2, das SSH-Formular.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kerim (portable/claudecode)andClaude Opus 5 committed 2026-09-12 13:37:26 +02:00
1 parent 8c5cdf16c4
commit e68daee457
14 files changed
+834 -605

No files matched your search

+46 -31
View File
@@ -14,54 +14,69 @@ Nur Python-Standardbibliothek, kein pip, kein CUPS, kein node.
## Installation — der übliche Weg
**Aus der Oberfläche:** ⚙️ Einstellungen → **🔧 Drucker einrichten**. Dort IP,
Benutzer und Passwort des Pi eintragen und auf **🚀 Jetzt einrichten** klicken.
Die App macht dann per SSH genau das, was unten von Hand steht: Dateien
übertragen, `install.sh` mit einem frisch erzeugten Token starten, aufräumen
und nachsehen, ob der Dienst antwortet. Anschließend übernimmt sie den Drucker
selbst — es ist **nichts** mehr in der `.env` einzutragen. Das Protokoll zeigt
Schritt für Schritt, was passiert ist.
Der Pi braucht dafür nur: SSH, Python 3, systemd, einen Benutzer mit sudo — und
den Drucker am USB-Anschluss. Ein frisch aufgesetztes Raspberry Pi OS erfüllt
das ab Werk.
Die Zugangsdaten werden einmal benutzt und danach verworfen. Gespeichert wird
allein das erzeugte Drucker-Token.
## Installation von Hand
Falls die App den Pi nicht erreicht (anderes Netz, kein sudo per Passwort):
**In der Timer-App:** ⚙️ Einstellungen → **🔧 Drucker einrichten** →
**🔗 Einrichtungslink erzeugen**. Die App zeigt einen Befehl an. Der wird auf
dem Pi in ein Terminal getippt:
```bash
# Dateien auf den Pi kopieren
scp print-server.py bondrucker.service install.sh README.md pi@<PI-IP>:/tmp/bondrucker/
# Dort einrichten
ssh pi@<PI-IP>
cd /tmp/bondrucker && sudo bash install.sh
curl -fsSL "<Link aus der Timer-App>" -o bondrucker.sh
sudo bash bondrucker.sh
```
`install.sh` legt an:
Das Skript fragt, welcher Drucker verwendet werden soll, richtet alles ein und
meldet den Pi anschließend selbst bei der Timer-App an. In der Oberfläche
springt die Anzeige von „wartet auf den Pi" auf den fertigen Drucker um. In der
`.env` ist **nichts** einzutragen.
Der Pi braucht dafür nur Python 3, systemd, `curl` und den Drucker am
USB-Anschluss. Ein frisch aufgesetztes Raspberry Pi OS erfüllt das ab Werk.
### Warum der Pi sich meldet und nicht umgekehrt
Früher hat die App den Pi per SSH eingerichtet. Das verlangte ein SSH-Passwort
in einem Webformular und eine Verbindung vom Server zum Pi. Beides ist jetzt
weg: kein Passwort verlässt den Laden, und die Verbindung muss nur in eine
Richtung funktionieren. Wer einen Drucker anschließt, steht ohnehin am Pi.
Der Link enthält einen Einrichtungscode. Er gilt **einmal** und **30 Minuten**,
liegt nur im Arbeitsspeicher der App und ist nach einem Neustart der App
ungültig. Wer den Code hat, kann den Drucker der App umbiegen — er gehört
deshalb nicht in einen Chatverlauf.
## Was das Skript anlegt
| Was | Wo |
|---|---|
| Dienstbenutzer `bondrucker` (Gruppe `lp`) | — |
| Programm | `/opt/bondrucker/print-server.py` |
| Token | `/etc/bondrucker/env` (`0640`, root:bondrucker) |
| Token und Gerät | `/etc/bondrucker/env` (`0640`, root:bondrucker) |
| udev-Regel | `/etc/udev/rules.d/99-bondrucker.rules` |
| Dienst | `bondrucker.service`, aktiviert und gestartet |
Am Ende gibt das Skript den Wert für das Token aus.
`install.sh` ist wiederholbar: ein erneuter Aufruf überschreibt Programm und
Das Skript ist wiederholbar: ein erneuter Aufruf überschreibt Programm und
Token und **startet den Dienst neu**. Ohne den Neustart liefe er mit dem alten
Token weiter und würde jeden Druckauftrag mit HTTP 403 ablehnen.
Schalter für den Fall, dass nicht gefragt werden soll:
```bash
sudo bash bondrucker.sh --device /dev/usb/lp1 --port 9100
```
## Installation ohne die Timer-App
`einrichten.sh` im Quelltext ist eine Vorlage: die Stellen `@@APP_URL@@`,
`@@SETUP_CODE@@`, `@@PRINT_SERVER@@` und `@@SERVICE@@` füllt die App beim
Ausliefern. Direkt ausführbar ist sie deshalb nicht.
Ohne die App werden die Dateien von Hand abgelegt — `print-server.py` nach
`/opt/bondrucker/`, `bondrucker.service` nach `/etc/systemd/system/`, dazu
`/etc/bondrucker/env` mit `PRINT_TOKEN=` und `PRINT_DEVICE=`. Adresse, Port und
Token kommen anschließend von Hand in die Einstellungen der Timer-App.
## Timer-Server konfigurieren
Nach der Einrichtung aus der Oberfläche: nichts zu tun.
Nach der Einrichtung über den Link: nichts zu tun.
Nach der Einrichtung von Hand: in ⚙️ Einstellungen unter „Drucker einrichten"
lassen sich Adresse, Port und Token auch direkt eintragen. Der Druckerzugang