Files
timer-app/deploy/bondrucker/bondrucker.service
T
Kerim (portable/claudecode)andClaude Opus 5 e68daee457 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>
2026-09-12 13:37:26 +02:00

50 lines
1.4 KiB
Desktop File

[Unit]
Description=Bondrucker-Bruecke (ESC/POS ueber HTTP an den USB-Kassendrucker)
Documentation=file:///opt/bondrucker/README.md
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/python3 /opt/bondrucker/print-server.py
# Laeuft NICHT als root. Der Dienstbenutzer ist nur deshalb in der Gruppe "lp",
# weil /dev/usb/lp0 dem Besitzer root und der Gruppe lp gehoert (Rechte 660).
User=bondrucker
Group=bondrucker
SupplementaryGroups=lp
# Konfiguration. Das Token steht in /etc/bondrucker/env, damit es nicht in der
# Versionsverwaltung landet - die Datei legt einrichten.sh an.
Environment=PRINT_DEVICE=/dev/usb/lp0
Environment=PRINT_HOST=0.0.0.0
Environment=PRINT_PORT=9100
EnvironmentFile=-/etc/bondrucker/env
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
# --- Haertung ---------------------------------------------------------------
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictSUIDSGID=true
RestrictNamespaces=true
RestrictAddressFamilies=AF_INET AF_INET6
LockPersonality=true
MemoryDenyWriteExecute=true
# Der Dienst braucht nirgends Schreibrecht - er schreibt ausschliesslich in die
# Geraetedatei, und die ist von ProtectSystem nicht betroffen.
PrivateDevices=false
[Install]
WantedBy=multi-user.target