Rolle veyon: Einrichtung aus Server-Optionen (Schluessel je OE, Lehrer/Schueler, Raumliste, ufw, Dienst)

Bauplan Schritt 2 (platform-docs roadmap/veyon-schluesselverteilung-
diskussion-2026-10-14.md), stellt den Handtest vom 15.10.2026 nach:
Methode 1, Schluessel als Dateien (oeffentlich 444, privat 440 root:gast,
no_log), alte tuxflotte*-Schluessel weg, Raumliste nur auf Lehrern und nur
bei Aenderung (Pruefsumme), ufw 11100 Schueler / 11400 Lehrer, Konfigurator
immer und Master auf Schuelern ausgeblendet, veyon.service an. absent
raeumt nur dort auf, wo die Rolle eingerichtet hatte.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5.5 committed 2026-10-15 14:00:02 +02:00
1 parent 2aa8bbdb03
commit 9e5bc1e4f8
3 files changed
+332 -3

No files matched your search

+68
View File
@@ -0,0 +1,68 @@
# Veyon-Einrichtung zuruecknehmen (15.10.2026). "absent" geht an JEDES
# Geraet ohne Veyon - deshalb nur dort aufraeumen, wo die Rolle vorher
# eingerichtet hat (Zustandsverzeichnis /var/lib/tuxflotte/veyon), und nur
# das, was sie selbst angelegt hat. Laeuft vor dem Entfernen des Pakets,
# solange veyon-cli noch da ist.
- name: Prüfen, ob die Rolle hier eingerichtet hatte
ansible.builtin.stat:
path: /var/lib/tuxflotte/veyon
register: tuxflotte_veyon_zustand
- name: Veyon-Einrichtung entfernen
when: tuxflotte_veyon_zustand.stat.exists
environment:
QT_QPA_PLATFORM: offscreen
LC_ALL: C
block:
- name: Raumliste leeren
ansible.builtin.shell: |
command -v veyon-cli >/dev/null || exit 0
veyon-cli networkobjects clear
args:
executable: /bin/bash
failed_when: false
- name: Tuxflotte-Schlüssel finden
ansible.builtin.find:
paths:
- /etc/veyon/keys/public
- /etc/veyon/keys/private
patterns: "tuxflotte*"
file_type: directory
register: tuxflotte_veyon_alle
- name: Tuxflotte-Schlüssel entfernen
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ tuxflotte_veyon_alle.files }}"
loop_control:
label: "{{ item.path }}"
- name: ufw-Status lesen
ansible.builtin.command: ufw status
register: tuxflotte_veyon_ufw
changed_when: false
failed_when: false
check_mode: false
- name: Veyon-Ports in ufw schließen
ansible.builtin.command: "ufw delete allow {{ item }}/tcp"
loop: ["11100", "11400"]
register: tuxflotte_veyon_ufw_weg
changed_when: "'non-existent' not in tuxflotte_veyon_ufw_weg.stdout"
when: "'Status: active' in tuxflotte_veyon_ufw.stdout"
- name: Starter-Überdeckungen entfernen
ansible.builtin.file:
path: "/usr/local/share/applications/{{ item }}"
state: absent
loop:
- veyon-configurator.desktop
- veyon-master.desktop
- name: Zustandsverzeichnis entfernen
ansible.builtin.file:
path: /var/lib/tuxflotte/veyon
state: absent
+249
View File
@@ -0,0 +1,249 @@
# Veyon-Einrichtung (15.10.2026). Stellt nach, was am 15.10.2026 auf
# Liebherr-83 (Lehrer) und Liebherr-35 (Schueler) von Hand getestet wurde:
# - Schluesseldatei-Authentifizierung (Authentication/Method 1)
# - Schluessel als Dateien wie `veyon-cli authkeys create/import`
# (oeffentlich 444 root, privat 440 root:gast) - so steht kein Schluessel
# in einer Kommandozeile (waere per ps fuer gast lesbar)
# - Raumliste (eingebautes Verzeichnis) nur auf dem Lehrergeraet; Veyon
# Master laedt sie ohne Neustart nach (UpdateInterval 60 s, getestet)
# - ufw: Schueler 11100/tcp (Veyon-Dienst), Lehrer 11400/tcp (Demo)
# - veyon.service ist nach der Paketinstallation deaktiviert
# Optionen (vom Server angereichert): veyon_schluesselname, veyon_public_pem,
# veyon_raum, veyon_lehrer; nur Lehrer: veyon_private_pem, veyon_rechner.
# Unter Linux heisst das Werkzeug veyon-cli (nicht veyon-ctl); ohne Display
# braucht es QT_QPA_PLATFORM=offscreen.
- name: Veyon-Optionen auswerten
ansible.builtin.set_fact:
tuxflotte_veyon_name: "{{ tuxflotte_optionen.get('veyon_schluesselname') | default('', true) }}"
tuxflotte_veyon_lehrer: "{{ tuxflotte_optionen.get('veyon_lehrer', false) | bool }}"
tuxflotte_veyon_raum: "{{ tuxflotte_optionen.get('veyon_raum') | default('Raum', true) }}"
tuxflotte_veyon_rechner: "{{ tuxflotte_optionen.get('veyon_rechner') | default([], true) }}"
no_log: true
- name: Veyon ohne Schlüssel vom Server nur installieren
ansible.builtin.debug:
msg: "veyon: kein Schlüssel in den Optionen (Server ohne Veyon-Anreicherung?) - Einrichtung übersprungen."
when: tuxflotte_veyon_name | length == 0
- name: Veyon einrichten
when: tuxflotte_veyon_name | length > 0
environment:
QT_QPA_PLATFORM: offscreen
LC_ALL: C
block:
- name: Zustandsverzeichnis der Rolle
ansible.builtin.file:
path: /var/lib/tuxflotte/veyon
state: directory
mode: "0700"
- name: Zugriffsgruppe für den privaten Schlüssel ermitteln (gast, sonst root)
ansible.builtin.getent:
database: group
key: gast
fail_key: false
- name: Zugriffsgruppe festlegen
ansible.builtin.set_fact:
tuxflotte_veyon_gruppe: "{{ 'gast' if (ansible_facts.getent_group.gast | default(none)) else 'root' }}"
- name: Authentifizierungsmethode lesen
ansible.builtin.command: veyon-cli config get Authentication/Method
register: tuxflotte_veyon_methode
changed_when: false
failed_when: false
check_mode: false
- name: Schlüsseldatei-Authentifizierung einstellen
ansible.builtin.command: veyon-cli config set Authentication/Method 1
register: tuxflotte_veyon_methode_gesetzt
when: (tuxflotte_veyon_methode.stdout | trim) != "1"
- name: Verzeichnis für den öffentlichen Schlüssel
ansible.builtin.file:
path: "/etc/veyon/keys/public/{{ tuxflotte_veyon_name }}"
state: directory
owner: root
group: root
mode: "0755"
- name: Öffentlichen Schlüssel ablegen
ansible.builtin.copy:
dest: "/etc/veyon/keys/public/{{ tuxflotte_veyon_name }}/key"
content: "{{ tuxflotte_optionen.veyon_public_pem }}"
owner: root
group: root
mode: "0444"
register: tuxflotte_veyon_public
- name: Verzeichnis für den privaten Schlüssel (Lehrer)
ansible.builtin.file:
path: "/etc/veyon/keys/private/{{ tuxflotte_veyon_name }}"
state: directory
owner: root
group: root
mode: "0755"
when: tuxflotte_veyon_lehrer
- name: Privaten Schlüssel ablegen (Lehrer)
ansible.builtin.copy:
dest: "/etc/veyon/keys/private/{{ tuxflotte_veyon_name }}/key"
content: "{{ tuxflotte_optionen.veyon_private_pem }}"
owner: root
group: "{{ tuxflotte_veyon_gruppe }}"
mode: "0440"
no_log: true
register: tuxflotte_veyon_private
when: tuxflotte_veyon_lehrer
- name: Privaten Schlüssel entfernen (kein Lehrergerät mehr)
ansible.builtin.file:
path: "/etc/veyon/keys/private/{{ tuxflotte_veyon_name }}"
state: absent
register: tuxflotte_veyon_private_weg
when: not tuxflotte_veyon_lehrer
# Nur Schluessel mit dem Tuxflotte-Praefix anfassen - von Hand angelegte
# Schluessel anderer Namen bleiben (Regel: absent/Aufraeumen nimmt nur
# zurueck, was Tuxflotte selbst angelegt hat).
- name: Alte Tuxflotte-Schlüssel finden
ansible.builtin.find:
paths:
- /etc/veyon/keys/public
- /etc/veyon/keys/private
patterns: "tuxflotte*"
file_type: directory
register: tuxflotte_veyon_alte
- name: Alte Tuxflotte-Schlüssel entfernen
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ tuxflotte_veyon_alte.files | rejectattr('path', 'search', '/' ~ tuxflotte_veyon_name ~ '$') | list }}"
loop_control:
label: "{{ item.path }}"
register: tuxflotte_veyon_alte_weg
# Raumliste: nur neu schreiben, wenn sie sich geaendert hat (Pruefsumme),
# sonst baute jeder Lauf das Verzeichnis neu.
- name: Soll-Raumliste berechnen
ansible.builtin.set_fact:
tuxflotte_veyon_raumliste_sha: "{{ ([tuxflotte_veyon_raum] + tuxflotte_veyon_rechner) | to_json | hash('sha256') }}"
- name: Gespeicherte Prüfsumme der Raumliste lesen
ansible.builtin.slurp:
src: /var/lib/tuxflotte/veyon/raumliste.sha256
register: tuxflotte_veyon_raumliste_ist
failed_when: false
- name: Raumliste schreiben (Lehrer, bei Änderung)
ansible.builtin.shell: |
set -euo pipefail
veyon-cli networkobjects clear
veyon-cli networkobjects add location {{ tuxflotte_veyon_raum | quote }}
{% for r in tuxflotte_veyon_rechner %}
veyon-cli networkobjects add computer {{ r.name | quote }} {{ r.host | quote }} '' {{ tuxflotte_veyon_raum | quote }}
{% endfor %}
args:
executable: /bin/bash
when:
- tuxflotte_veyon_lehrer
- (tuxflotte_veyon_raumliste_ist.content | default('') | b64decode | trim) != tuxflotte_veyon_raumliste_sha
- name: Prüfsumme der Raumliste merken (Lehrer)
ansible.builtin.copy:
dest: /var/lib/tuxflotte/veyon/raumliste.sha256
content: "{{ tuxflotte_veyon_raumliste_sha }}\n"
mode: "0600"
when: tuxflotte_veyon_lehrer
- name: Raumliste leeren (kein Lehrergerät mehr)
ansible.builtin.shell: |
veyon-cli networkobjects clear
rm -f /var/lib/tuxflotte/veyon/raumliste.sha256
args:
executable: /bin/bash
when:
- not tuxflotte_veyon_lehrer
- tuxflotte_veyon_raumliste_ist.content is defined
# Firewall nur, wenn ufw aktiv ist (Merkmal firewall). Ausgabe mit
# LC_ALL=C (siehe environment oben), sonst "Status: Aktiv".
- name: ufw-Status lesen
ansible.builtin.command: ufw status
register: tuxflotte_veyon_ufw
changed_when: false
failed_when: false
check_mode: false
- name: Veyon-Ports in ufw freigeben
ansible.builtin.command: "ufw allow {{ item }}/tcp comment tuxflotte-veyon"
loop: "{{ ['11400'] if tuxflotte_veyon_lehrer else ['11100'] }}"
register: tuxflotte_veyon_ufw_neu
changed_when: "'Skipping' not in tuxflotte_veyon_ufw_neu.stdout"
when: "'Status: active' in tuxflotte_veyon_ufw.stdout"
- name: Nicht mehr passenden Veyon-Port in ufw schließen (Rolle gewechselt)
ansible.builtin.command: "ufw delete allow {{ item }}/tcp"
loop: "{{ ['11100'] if tuxflotte_veyon_lehrer else ['11400'] }}"
register: tuxflotte_veyon_ufw_weg
changed_when: "'non-existent' not in tuxflotte_veyon_ufw_weg.stdout"
when: "'Status: active' in tuxflotte_veyon_ufw.stdout"
# Starter ausblenden: Konfigurator fuer alle (braucht root, die Rolle
# konfiguriert), Master auf Schuelergeraeten. Eintrag gleichen Namens in
# /usr/local/share/applications ueberdeckt den des Pakets.
- name: Verzeichnis für Starter-Überdeckungen
ansible.builtin.file:
path: /usr/local/share/applications
state: directory
mode: "0755"
- name: Veyon-Konfigurator ausblenden
ansible.builtin.copy:
dest: /usr/local/share/applications/veyon-configurator.desktop
content: |
# Tuxflotte (Rolle veyon): Konfiguration uebernimmt die Rolle.
[Desktop Entry]
Type=Application
Name=Veyon Configurator
Exec=veyon-configurator
NoDisplay=true
mode: "0644"
- name: Veyon Master auf Schülergeräten ausblenden
ansible.builtin.copy:
dest: /usr/local/share/applications/veyon-master.desktop
content: |
# Tuxflotte (Rolle veyon): Schuelergeraet, kein Veyon Master.
[Desktop Entry]
Type=Application
Name=Veyon Master
Exec=veyon-master
NoDisplay=true
mode: "0644"
when: not tuxflotte_veyon_lehrer
- name: Veyon Master auf Lehrergeräten zeigen
ansible.builtin.file:
path: /usr/local/share/applications/veyon-master.desktop
state: absent
when: tuxflotte_veyon_lehrer
- name: Veyon-Dienst einschalten
ansible.builtin.systemd:
name: veyon
enabled: true
state: started
- name: Veyon-Dienst neu starten (Schlüssel oder Methode geändert)
ansible.builtin.systemd:
name: veyon
state: restarted
when: >-
(tuxflotte_veyon_methode_gesetzt is changed) or
(tuxflotte_veyon_public is changed) or
(tuxflotte_veyon_private is changed) or
(tuxflotte_veyon_private_weg is changed) or
(tuxflotte_veyon_alte_weg is changed)
+15 -3
View File
@@ -13,9 +13,8 @@
# - ubuntu-image (Ubuntu 26.04/resolute) -> ubuntu.26.04
# Codename-Erkennung über /etc/os-release: UBUNTU_CODENAME ist bei Ubuntu
# UND bei Mint gesetzt (Mint trägt den Ubuntu-Codename der Basis ein), bei
# reinem Debian fehlt es, dort zählt VERSION_CODENAME. NICHT live auf allen
# drei Golden-VMs gegengeprüft (nur Debian/trixie an dieser Stelle real
# bestätigt, siehe Session-Notizen) - vor breitem Rollout nachholen.
# reinem Debian fehlt es, dort zählt VERSION_CODENAME. Live bestätigt:
# Debian/trixie und Mint (15.10.2026, Liebherr-35/-83); Ubuntu offen.
- name: Distro-Codename ermitteln (UBUNTU_CODENAME bevorzugt, sonst VERSION_CODENAME)
ansible.builtin.shell: |
set -euo pipefail
@@ -51,6 +50,14 @@
bekannten Zuordnung - Installation übersprungen, bitte Rolle aktualisieren.
when: tuxflotte_state == "present" and tuxflotte_veyon_deb is not defined
# Einrichtung (15.10.2026, Bauplan Schritt 2, platform-docs roadmap/
# veyon-schluesselverteilung-diskussion-2026-10-14.md): Schluessel je OE,
# Lehrer/Schueler, Raumliste, Firewall, Dienst - alles aus den vom Server
# angereicherten Optionen (provisioning-server veyon_optionen_anreichern()).
- name: Veyon einrichten (Schlüssel, Raumliste, Firewall, Dienst)
ansible.builtin.include_tasks: einrichtung.yml
when: tuxflotte_state == "present" and tuxflotte_veyon_deb is defined
- name: Record that the veyon role ran
ansible.builtin.copy:
dest: /run/tuxflotte/agent/applied/veyon.marker
@@ -58,6 +65,11 @@
mode: "0644"
when: tuxflotte_state == "present" and tuxflotte_veyon_deb is defined
# Vor dem Paket entfernen, solange veyon-cli noch da ist.
- name: Veyon-Einrichtung zurücknehmen (Auftrag abgewählt)
ansible.builtin.include_tasks: aufraeumen.yml
when: tuxflotte_state == "absent"
- name: Veyon entfernen (Auftrag abgewählt)
ansible.builtin.apt:
name: veyon