# 13 — Server-Administration: Continuwuity > **Gilt für:** Continuwuity 0.5.x (Fork von Conduwuit, welches ein Fork von Conduit ist) > **Homeserver:** `steggi-matrix.work` > **WICHTIG:** Continuwuity hat KEINE Synapse Admin API (`/_synapse/admin/` existiert nicht!) --- ## Inhaltsverzeichnis - [Server-Admin vs. Room Power Level](#server-admin-vs-room-power-level) - [Admin Room — Befehle](#admin-room--befehle) - [Continuwuity Admin HTTP API](#continuwuity-admin-http-api) - [Power Level in Räumen erzwingen (als Server-Admin)](#power-level-in-räumen-erzwingen) - [MSC3083: Restricted Join Rules auf Continuwuity](#msc3083-restricted-join-rules-auf-continuwuity) - [Diagnose: Warum M_FORBIDDEN?](#diagnose-warum-m_forbidden) - [User-Admin-Status prüfen/setzen](#user-admin-status-prüfensetzen) - [Raum-Administration via Matrix API](#raum-administration-via-matrix-api) - [Wichtige Unterschiede: Continuwuity vs. Synapse](#wichtige-unterschiede-continuwuity-vs-synapse) - [Continuwuity `homeserver.yaml` — relevante Einstellungen](#continuwuity-homeserveryaml--relevante-einstellungen) --- ## Server-Admin vs. Room Power Level ``` Continuwuity Server-Admin ├── Ermöglicht: Admin-Room-Befehle, Server-API ├── Ermöglicht: User deaktivieren, Räume löschen (Server-Level) └── NICHT: Automatisch PL 100 in jedem Matrix-Raum! Matrix Room Power Level 100 ├── Gilt pro Raum (in m.room.power_levels State-Event gespeichert) ├── Ermöglicht: Name/Topic/Avatar setzen, Join-Rules ändern, User kicken/bannen └── Unabhängig vom Server-Admin-Status ``` **Beispiel-Problem:** - Du bist Server-Admin auf `steggi-matrix.work` ✅ - Du hast PL 100 im Space `!xyz:steggi-matrix.work` ✅ - Du erstellst einen neuen Channel → Server gibt dir PL 100 als Ersteller ✅ - Du versuchst `join_rules: restricted` zu setzen → M_FORBIDDEN ❌ - **Grund:** Continuwuity 0.5.x unterstützt MSC3083 möglicherweise nicht vollständig --- ## Admin Room — Befehle Continuwuity hat einen speziellen Admin-Raum. Als Server-Admin kannst du dort Befehle eingeben: ``` # Admin-Raum beitreten (normalerweise automatisch eingeladen) # Raum-Alias: #admins:steggi-matrix.work # Befehle im Admin-Raum (als Nachricht senden): !admin help # Alle Befehle anzeigen !admin make_user_admin @user:server # User zu Server-Admin machen !admin deactivate_user @user:server # User deaktivieren !admin list_users # Alle User auflisten !admin get_room_state !roomId:server # Room-State anzeigen !admin delete_room !roomId:server # Raum löschen !admin get_mem_usage # Server-Speicherverbrauch !admin server_version # Server-Version ``` ```bash # Als curl (Admin-Token erforderlich): # Admin-Room-ID herausfinden: curl -s "https://steggi-matrix.work/_matrix/client/v3/directory/room/%23admins%3Asteggi-matrix.work" \ -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" # → {"room_id": "!adminRoomId:steggi-matrix.work", ...} ``` --- ## Continuwuity Admin HTTP API ```bash # Basis-URL: https://steggi-matrix.work/_conduwuit/admin/v1/ # (Nicht /_synapse/admin/ — das ist Synapse-only!) # User zu Server-Admin machen curl -X POST "https://steggi-matrix.work/_conduwuit/admin/v1/make_user_admin" \ -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" \ -H "Content-Type: application/json" \ -d '{"user_id": "@todesneutron:steggi-matrix.work"}' # Server-Status abfragen curl "https://steggi-matrix.work/_conduwuit/server/version" \ -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" # Alternativ — Standard Matrix-Whoami (prüft ob Token gültig): curl "https://steggi-matrix.work/_matrix/client/v3/account/whoami" \ -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" # → {"user_id": "@todesneutron:steggi-matrix.work", "is_guest": false} # Prüfen ob User Server-Admin ist (Conduwuit-spezifisch): curl "https://steggi-matrix.work/_conduwuit/admin/v1/users/@todesneutron:steggi-matrix.work" \ -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" ``` --- ## Power Level in Räumen erzwingen (als Server-Admin) Als Server-Admin kannst du via Matrix Client API Power Levels in jedem Raum setzen, **auch wenn du kein Mitglied bist** (Continuwuity erlaubt das für Server-Admins): ```bash # Schritt 1: Aktuelles Power-Level-Event lesen ROOM_ID="!raumId:steggi-matrix.work" TOKEN="J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" SERVER="https://steggi-matrix.work" curl "${SERVER}/_matrix/client/v3/rooms/${ROOM_ID}/state/m.room.power_levels/" \ -H "Authorization: Bearer ${TOKEN}" # Schritt 2: Power Level setzen (users-Map ändern) curl -X PUT "${SERVER}/_matrix/client/v3/rooms/${ROOM_ID}/state/m.room.power_levels/" \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "users": { "@todesneutron:steggi-matrix.work": 100 }, "users_default": 0, "events_default": 0, "state_default": 50, "ban": 50, "kick": 50, "invite": 0, "redact": 50 }' ``` ```dart // In Flutter / Dart (mit Admin-Token): // Zuerst aktuellen PL-State lesen: final currentPl = await client.getRoomStateWithKey( roomId, EventTypes.RoomPowerLevels, '', ); // Users-Map erweitern und zurückschreiben: final users = Map.from( (currentPl['users'] as Map?)?.cast() ?? {}, ); users['@todesneutron:steggi-matrix.work'] = 100; await client.setRoomStateWithKey( roomId, EventTypes.RoomPowerLevels, '', { ...currentPl, 'users': users, }, ); ``` --- ## MSC3083: Restricted Join Rules auf Continuwuity `join_rules: restricted` (MSC3083) erlaubt Räumen, nur Space-Mitglieder beizutreten. **Continuwuity 0.5.x unterstützt MSC3083 möglicherweise nicht vollständig.** ```bash # Testen ob restricted join rules funktionieren: ROOM_ID="!testRaum:steggi-matrix.work" TOKEN="J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" SPACE_ID="!spaceId:steggi-matrix.work" curl -X PUT "https://steggi-matrix.work/_matrix/client/v3/rooms/${ROOM_ID}/state/m.room.join_rules/" \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "join_rule": "restricted", "allow": [ { "type": "m.room_membership", "room_id": "'"${SPACE_ID}"'" } ] }' # → 200 OK: Unterstützt! # → M_FORBIDDEN oder M_UNRECOGNIZED: Nicht unterstützt oder PL zu niedrig ``` **Workaround wenn restricted nicht funktioniert:** ```bash # Fallback: invite-only (explizit jeden User einladen) curl -X PUT "https://steggi-matrix.work/_matrix/client/v3/rooms/${ROOM_ID}/state/m.room.join_rules/" \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d '{"join_rule": "invite"}' ``` ```dart // In space_admin_dialog.dart — Fallback wenn restricted nicht supported: try { await room.setJoinRules( JoinRules.restricted, allow: [ SpaceRoomJoinRulesAllowInner( roomId: spaceId, type: SpaceRoomJoinRulesAllowInnerType.mRoomMembership, ), ], ); } on MatrixException catch (e) { if (e.error == MatrixError.M_FORBIDDEN || e.error == MatrixError.M_UNKNOWN) { // Continuwuity unterstützt restricted join rules nicht // Fallback zu invite-only: await room.setJoinRules(JoinRules.invite); } else { rethrow; } } ``` --- ## Diagnose: Warum M_FORBIDDEN? ```bash # 1. Prüfen: Welchen Power Level hat mein User in diesem Raum? ROOM_ID="!raumId:steggi-matrix.work" TOKEN="J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" curl "https://steggi-matrix.work/_matrix/client/v3/rooms/${ROOM_ID}/state/m.room.power_levels/" \ -H "Authorization: Bearer ${TOKEN}" # Antwort zeigt 'users' Map — prüfen ob '@todesneutron:steggi-matrix.work' drin ist # 2. Prüfen: Was ist state_default? # Im Antwort-JSON: "state_default": 50 bedeutet: PL 50 nötig für State-Events # "m.room.join_rules": 100 in events-Map = PL 100 für Join-Rule-Änderung # 3. Prüfen: Bin ich Mitglied des Raums? curl "https://steggi-matrix.work/_matrix/client/v3/rooms/${ROOM_ID}/state/m.room.member/%40todesneutron%3Asteggi-matrix.work/" \ -H "Authorization: Bearer ${TOKEN}" # → {"membership": "join"} = Mitglied ✅ # → {"errcode": "M_NOT_FOUND"} = Nicht Mitglied ❌ (Server-Admin kann trotzdem State setzen) # 4. Prüfen: Unterstützt der Server restricted join rules? curl "https://steggi-matrix.work/_matrix/client/v3/capabilities" \ -H "Authorization: Bearer ${TOKEN}" # Antwort: capabilities-Objekt — MSC3083 ist nicht explizit gelistet (kein Standard-Capability) ``` **Häufige Ursachen und Lösungen:** | Fehler | Ursache | Lösung | |---|---|---| | M_FORBIDDEN beim State-Event | PL zu niedrig im Raum | Power Level via curl erhöhen (s.o.) | | M_FORBIDDEN bei join_rules: restricted | MSC3083 nicht unterstützt | Fallback zu `invite` nutzen | | M_FORBIDDEN beim Channel erstellen | Bug in space_admin_dialog.dart | Raum manuell erstellen, dann Space-Child setzen | | M_NOT_FOUND | Raum nicht bekannt | Raum beitreten oder Admin-Join | | M_FORBIDDEN bei Power-Level-Änderung | PL darf nur gleich/höher gesetzt werden | Als Ersteller oder via Admin-API | --- ## User-Admin-Status prüfen/setzen ```bash # Prüfen ob User Server-Admin ist: curl "https://steggi-matrix.work/_matrix/client/v3/account/whoami" \ -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" # Auf Pi (SSH): User-Datenbank direkt abfragen (Conduwuit/Continuwuity nutzt RocksDB) # Alternativ: Über Admin-Room-Befehl # (Im Admin-Room als Nachricht senden:) # !admin make_user_admin @todesneutron:steggi-matrix.work # Über HTTP (Conduwuit Admin-Endpoint): curl -X POST "https://steggi-matrix.work/_conduwuit/admin/v1/make_user_admin" \ -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" \ -H "Content-Type: application/json" \ -d '{"user_id": "@todesneutron:steggi-matrix.work"}' ``` --- ## Raum-Administration via Matrix API Da kein Synapse-Admin-API existiert, nutze die Standard-Matrix-Client-API mit Admin-Token: ```bash # Raum beitreten (als Admin, auch wenn invite-only): curl -X POST "https://steggi-matrix.work/_matrix/client/v3/join/!roomId%3Asteggi-matrix.work" \ -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" \ -H "Content-Type: application/json" \ -d '{}' # User in Raum einladen: curl -X POST "https://steggi-matrix.work/_matrix/client/v3/rooms/!roomId%3Asteggi-matrix.work/invite" \ -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" \ -H "Content-Type: application/json" \ -d '{"user_id": "@user:steggi-matrix.work"}' # Space-Child-Relation setzen (Channel einem Space hinzufügen): curl -X PUT "https://steggi-matrix.work/_matrix/client/v3/rooms/!spaceId%3Asteggi-matrix.work/state/m.space.child/!channelId%3Asteggi-matrix.work/" \ -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" \ -H "Content-Type: application/json" \ -d '{ "via": ["steggi-matrix.work"], "suggested": false }' # Space-Parent-Relation setzen (im Channel-Raum): curl -X PUT "https://steggi-matrix.work/_matrix/client/v3/rooms/!channelId%3Asteggi-matrix.work/state/m.space.parent/!spaceId%3Asteggi-matrix.work/" \ -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" \ -H "Content-Type: application/json" \ -d '{ "via": ["steggi-matrix.work"], "canonical": true }' # Alle Mitglieder eines Raums auflisten: curl "https://steggi-matrix.work/_matrix/client/v3/rooms/!roomId%3Asteggi-matrix.work/members" \ -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" # Raum verlassen (als User, nicht löschen): curl -X POST "https://steggi-matrix.work/_matrix/client/v3/rooms/!roomId%3Asteggi-matrix.work/leave" \ -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" \ -H "Content-Type: application/json" \ -d '{}' ``` --- ## Wichtige Unterschiede: Continuwuity vs. Synapse | Feature | Synapse | Continuwuity 0.5.x | |---|---|---| | Admin API URL | `/_synapse/admin/v1/` | `/_conduwuit/admin/v1/` | | Admin Room | Optional | Standard | | MSC3083 (restricted join rules) | ✅ Vollständig | ⚠️ Teilweise / experimentell | | Spaces (MSC1772) | ✅ | ✅ Grundfunktionen | | MatrixRTC / MSC3401 | ✅ (Element Call) | ⚠️ Eingeschränkt | | Push-Gateway | ✅ | ✅ | | Server-side search | ✅ | ✅ Grundfunktionen | | E2EE / Cross-Signing | ✅ | ✅ | | Presence | ✅ | ✅ | | Account Deactivation | Admin API | Admin Room / API | | Room Deletion/Purge | Admin API | Admin Room / API | | User Listing | Admin API | Admin Room / API | | Federation | ✅ | ✅ | | Application Services | ✅ | ⚠️ Eingeschränkt | --- ## Continuwuity `homeserver.yaml` — relevante Einstellungen ```yaml # /etc/continuwuity/homeserver.yaml (oder /etc/conduwuit/conduwuit.toml je nach Version) # Matrix-RTC / LiveKit # MSC3266: Room Summary # MSC3401: MatrixRTC allow_unstable_room_versions: true # Federation (für Multi-Server-Calls nötig) allow_federation: true allow_public_room_directory_without_auth: false # Push (für Notifications) # Kein spezieller Config — nutzt Standard-Matrix-Push-API # TURN-Server für WebRTC turn_uris: - "turn:steggi-matrix.work:3478?transport=udp" - "turn:steggi-matrix.work:3478?transport=tcp" turn_secret: "dein-turn-secret" turn_username: "" # leer = HMAC-basiert turn_password: "" turn_ttl: 86400 # Registrierung allow_registration: false # Kein offener Signup registration_token: "dein-token" # Oder token-basiert # Log-Level log: "warn,conduwuit=info" # Performance rocksdb_parallelism_threads: 4 # Pi 5 hat 4 Cores # Unter Continuwuity: Admin-User beim ersten Start setzen # Erster registrierter User wird automatisch Server-Admin ``` ```bash # Auf dem Pi: Config-Datei editieren ssh steggi@192.168.178.71 sudo nano /etc/continuwuity/homeserver.yaml # oder: sudo nano /etc/conduwuit/conduwuit.toml # Falls TOML-Format # Service neu starten: sudo systemctl restart continuwuity # oder: sudo systemctl restart conduwuit # Logs prüfen: sudo journalctl -u continuwuity -f ``` --- ## Schnell-Diagnose Checkliste Wenn du M_FORBIDDEN bekommst: ```bash # 1. Token gültig? curl "https://steggi-matrix.work/_matrix/client/v3/account/whoami" \ -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" # 2. PL im betroffenen Raum prüfen: curl "https://steggi-matrix.work/_matrix/client/v3/rooms/!ROOM_ID/state/m.room.power_levels/" \ -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" # 3. Mitglied des Raums? curl "https://steggi-matrix.work/_matrix/client/v3/rooms/!ROOM_ID/state/m.room.member/%40todesneutron%3Asteggi-matrix.work/" \ -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" # 4. Was genau schlägt fehl? (Antwort-Body lesen!) # M_FORBIDDEN + "Power level too low" → PL erhöhen # M_FORBIDDEN + "Not a member" → Raum beitreten # M_UNRECOGNIZED → Feature nicht unterstützt # M_FORBIDDEN + "..." → join_rules restricted Problem ```