Cryptomator Hub auf Synology

Heidi

Benutzer
Mitglied seit
05. Aug 2019
Beiträge
311
Punkte für Reaktionen
55
Punkte
34
Guten Abend Community.

Aktuell haben wir einen VeryCrypt-Container auf einem Laufwerk liegen. In dem Container liegen sensible Daten, auf die diverse User vom LAN aus Zugriff haben.
Hierzu bindet der User den Container bekanntermaßen bei sich lokal ein. Solange dieser eingebunden ist, ist er jedoch für die anderen gesperrt. Das ist unschön und soll verbessert werden.

Eine Lösung wäre der Cryptomator, bei dem auf der NAS dann der Cryptomator-Tresor liegt und dieser ist temporär bei den Usern lokal eingebunden = entschlüsselt. Das hat nur den Nachteil, dass so dieselbe Datei mehrmals geöffnet werden kann. Der letzte, der dann speichert, gewinnt. Es gibt keinen Schreibschutz, sowie das z.B. Word macht und eine Sperrdatei anlegt, die dann den zweiten user warnt oder nur per Schreibschutz drauf zugreifen lässt.

Hier bietet meines Erachtens der Cryptomator Hub eine passende Lösung. Es ist ein Docker Container, der dann ein zentrales Berechtigungsmanagement führt. Ich bekomme den Cryptomator nicht zum Laufen.
Kann mir jemand eine Schritt-für-Schritt Anleitung geben, was ich wann und wo machen muss?

Bisher komme ich soweit: Auf der Cryptomator website kann man sich eine Docker Compose File erzeugen lassen, die der Container Manager auf der DSM dann kompiliert. Dabei tritt im letzten Kompilierungsschritt der Fehler auf, dass keine "nanoCPUs unterstützt werden". Wir nutzen einen SHA-Cluster aus 918+ und 920+. Was sind nanoCPUs und liegt es ggf. daran?

Alternativ ziehe ich mir ein Docker-Container über den Container Manager. z.b. den vh13294/cryptomator-synology. Hier das Protokoll:
Code:
vh13294-cryptomator-synology-1
date    stream    content
2025/01/22 18:35:10    stdout    at org.cryptomator.cli.CryptomatorCli.main(CryptomatorCli.java:43)
2025/01/22 18:35:10    stdout    at org.cryptomator.cli.CryptomatorCli.startup(CryptomatorCli.java:101)
2025/01/22 18:35:10    stdout    at org.cryptomator.cryptofs.CryptoFileSystemProvider.newFileSystem(CryptoFileSystemProvider.java:126)
2025/01/22 18:35:10    stdout    at java.base/java.nio.file.FileSystems.newFileSystem(FileSystems.java:288)
2025/01/22 18:35:10    stdout    at java.base/java.nio.file.FileSystems.newFileSystem(FileSystems.java:339)
2025/01/22 18:35:10    stdout    at org.cryptomator.cryptofs.CryptoFileSystemProvider.newFileSystem(CryptoFileSystemProvider.java:86)
2025/01/22 18:35:10    stdout    at org.cryptomator.cryptofs.CryptoFileSystemProvider.newFileSystem(CryptoFileSystemProvider.java:194)
2025/01/22 18:35:10    stdout    at org.cryptomator.cryptofs.CryptoFileSystems.create(CryptoFileSystems.java:49)
2025/01/22 18:35:10    stdout    at org.cryptomator.cryptofs.CryptoFileSystems.readVaultConfigFile(CryptoFileSystems.java:113)
2025/01/22 18:35:10    stdout    at java.base/java.nio.file.Files.readString(Files.java:3366)
2025/01/22 18:35:10    stdout    at java.base/java.nio.file.Files.readAllBytes(Files.java:3288)
2025/01/22 18:35:10    stdout    at java.base/java.nio.file.Files.newByteChannel(Files.java:432)
2025/01/22 18:35:10    stdout    at java.base/java.nio.file.Files.newByteChannel(Files.java:380)
2025/01/22 18:35:10    stdout    at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:219)
2025/01/22 18:35:10    stdout    at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
2025/01/22 18:35:10    stdout    at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
2025/01/22 18:35:10    stdout    at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
2025/01/22 18:35:10    stdout    Exception in thread "main" java.nio.file.NoSuchFileException: /cryptomatorDir/vault.cryptomator
2025/01/22 18:35:10    stdout    17:35:10.703 [main] [34mINFO [0;39m o.c.c.p.PasswordFromPropertyStrategy - Vault 'demoVault' password from property.
2025/01/22 18:35:10    stdout    17:35:10.702 [main] [34mINFO [0;39m org.cryptomator.cli.CryptomatorCli - Unlocking vault "demoVault" located at /cryptomatorDir
2025/01/22 18:35:10    stdout    17:35:10.623 [main] [34mINFO [0;39m org.cryptomator.cli.frontend.WebDav - WebDAV server started: 0.0.0.0:8181
2025/01/22 18:35:10    stdout    17:35:10.623 [main] [34mINFO [0;39m o.c.frontend.webdav.WebDavServer - WebDavServer started.
2025/01/22 18:35:10    stdout    17:35:10.623 [main] [34mINFO [0;39m org.eclipse.jetty.server.Server - Started Server@10db82ae{STARTING}[10.0.6,sto=0] @1582ms
2025/01/22 18:35:10    stdout    17:35:10.466 [main] [34mINFO [0;39m o.e.j.server.handler.ContextHandler - Started o.e.j.s.ServletContextHandler@382db087{/,null,AVAILABLE}
2025/01/22 18:35:10    stdout    17:35:10.363 [main] [34mINFO [0;39m org.eclipse.jetty.server.Server - jetty-10.0.6; built: 2021-06-29T15:28:56.259Z; git: 37e7731b4b142a882d73974ff3bec78d621bd674; jvm 17.0.1+12-39
2025/01/22 18:35:10    stdout    17:35:10.342 [main] [34mINFO [0;39m o.e.jetty.server.AbstractConnector - Started ServerConnector@7bc1a03d{HTTP/1.1, (http/1.1)}{0.0.0.0:8181}
2025/01/22 18:35:10    stdout    17:35:10.280 [main] [34mINFO [0;39m o.c.frontend.webdav.WebDavServer - Binding serve



Gäbe es eine praktikable Alternative?
 
Zuletzt bearbeitet:
nanoCPU ist ein anderer Ausdruck für SoC (System-on-Chip).
 
Guten Abend. Danke zusammen für die Hinweise.

@ctrlaltdelete Die Anleitung hatte ich schon durchgelesen. Da sind aber viel zu viele Fremdwörter für mich drin, so dass ich denke, das packe ich nicht alleine. Daher meine Frage nach eine Schritt-für-Schritt Anleitung für Dummies.

@maxblank heißt dass, dass es mit dem Docker Compose nicht auf einer Syno läuft? Wie bekomme ich das anderweitig zum laufen. Wie gesagt, mit dem auf github verfügbaren Container vh13294/cryptomator-synology hab ichs auch nicht hinbekommen..........😩
 
Dann musst du dir jemanden suchen der sich mit Dicker auskennt.
 
........ich dachte, das habe ich mit diesem Foren-Eintrag gemacht ..... 🤯
 
  • Haha
Reaktionen: ctrlaltdelete
Auf der Cryptomator website kann man sich eine Docker Compose File erzeugen lassen, die der Container Manager auf der DSM dann kompiliert.
Könntest du das bitte hier mit bereitstellen (idealerweise formatiert als Codeblock [YAML])?
Wichtig ist, dass der Docker-Container keinen Cryptomator-Container erstellen kann. Der muss also bereits vorhanden sein. So war es jedenfalls damals bei mir.

Ich bin mir noch nicht sicher, ob dich diese Version weiterbringt. Wie möchtest du denn von deinen Clients auf den Cryptomator-Container zugreifen? Er stellt den Container-Inhalt ja per WebDAV-Laufwerk bereit. Wenn sich dann aber mehrere Clients von dir einklinken, läufst du ja wahrscheinlich wieder in das gleiche Problem. Wenn es geht, ist es umso besser. Der Gedanke kam mir nur …

PS: Ich nutze Cryptomator für meine Backup USB-Sticks, die ich immer dabei habe. Der Cryptomator-Container auf dem Stick wird mit dem Docker-Container gemountet und synchronisiere meine gewünschten Daten. Mit dem USB-Stick kann keiner etwas anfangen, aber ich kann über die mobile App auf meinem iPhone oder iPad darauf zugreifen.
 
Zuletzt bearbeitet:
Ich dachte, GENAU das wäre die Idee hinter dem cryptomator-HUB... Dass alle gleichzeitig auf einem Container arbeiten können.
Wenn man es mit der normalen non-Hub Version macht, dann liegt der Container auf einem Netzwerklaufwerk und jeder hat übers Netzwerk drauf Zugriff (über SMB-Protokoll also). Das sorgt für das beschriebene Problem, dass bei mehrerem gleichzeitigen Zugriff es zu Versionskonflikten kommt.

Vielleicht habe ich den Cryptomator-Hub falsch verstanden...?
 
Ich weiß es nicht. Ausprobieren …
Könntest du das bitte hier mit bereitstellen (idealerweise formatiert als Codeblock [YAML])?
Wichtig ist, dass der Docker-Container keinen Cryptomator-Container erstellen kann. Der muss also bereits vorhanden sein. So war es jedenfalls damals bei mir.
 
Es ist der Standard Test-Decompose von der Website

YAML:
# Template for Cryptomator Hub deployment according to your specifications.

# Generated using script version 6

services:
  init-config:
    image: bash:5
    volumes:
      - kc-config:/kc-config
      - db-init:/db-init
    command:
      - bash
      - '-c'
      - |-
        cat >/db-init/initdb.sql << 'EOF'
        CREATE USER keycloak WITH ENCRYPTED PASSWORD '4005c940-c9af-434f-85b4-0134664b74c3';
        CREATE DATABASE keycloak WITH ENCODING 'UTF8';
        GRANT ALL PRIVILEGES ON DATABASE keycloak TO keycloak;
        CREATE USER hub WITH ENCRYPTED PASSWORD '92f9ebac-d9f0-4790-8044-962c00acafd7';
        CREATE DATABASE hub WITH ENCODING 'UTF8';
        GRANT ALL PRIVILEGES ON DATABASE hub TO hub;
        EOF
        cat >/kc-config/realm.json << 'EOF'
        {
          "id": "db2b4906-b0cc-4ca6-a4bb-2dd75b41f2e9",
          "realm": "cryptomator",
          "displayName": "Cryptomator Hub",
          "loginTheme": "cryptomator",
          "enabled": true,
          "sslRequired": "external",
          "defaultRole": {
            "name": "user",
            "description": "User"
          },
          "roles": {
            "realm": [
              {
                "name": "user",
                "description": "User",
                "composite": false
              },
              {
                "name": "create-vaults",
                "description": "Can create vaults",
                "composite": false
              },
              {
                "name": "admin",
                "description": "Administrator",
                "composite": true,
                "composites": {
                  "realm": [
                    "user",
                    "create-vaults"
                  ],
                  "client": {
                    "realm-management": [
                      "realm-admin"
                    ]
                  }
                }
              },
              {
                "name": "syncer",
                "description": "syncer",
                "composite": true,
                "composites": {
                  "client": {
                    "realm-management": [
                      "view-users"
                    ]
                  }
                }
              }
            ]
          },
          "users": [
            {
              "username": "admin",
              "enabled": true,
              "credentials": [
                {
                  "type": "password",
                  "value": "admin",
                  "temporary": true
                }
              ],
              "requiredActions": [
                "UPDATE_PASSWORD"
              ],
              "realmRoles": [
                "admin"
              ]
            },
            {
              "username": "syncer",
              "firstName": "syncer",
              "lastName": "syncer",
              "email": "syncer@localhost",
              "enabled": true,
              "credentials": [
                {
                  "type": "password",
                  "value": "f9f25b3d-574a-4f05-9bce-370abea1023a",
                  "temporary": false
                }
              ],
              "realmRoles": [
                "syncer"
              ]
            }
          ],
          "scopeMappings": [
            {
              "client": "cryptomatorhub",
              "roles": [
                "user",
                "admin"
              ]
            }
          ],
          "clients": [
            {
              "clientId": "cryptomatorhub",
              "serviceAccountsEnabled": false,
              "publicClient": true,
              "name": "Cryptomator Hub",
              "enabled": true,
              "redirectUris": [
                "http://localhost:30000/*"
              ],
              "webOrigins": [
                "+"
              ],
              "bearerOnly": false,
              "frontchannelLogout": false,
              "protocol": "openid-connect",
              "attributes": {
                "pkce.code.challenge.method": "S256"
              },
              "protocolMappers": [
                {
                  "name": "realm roles",
                  "protocol": "openid-connect",
                  "protocolMapper": "oidc-usermodel-realm-role-mapper",
                  "consentRequired": false,
                  "config": {
                    "access.token.claim": "true",
                    "claim.name": "realm_access.roles",
                    "jsonType.label": "String",
                    "multivalued": "true"
                  }
                },
                {
                  "name": "client roles",
                  "protocol": "openid-connect",
                  "protocolMapper": "oidc-usermodel-client-role-mapper",
                  "consentRequired": false,
                  "config": {
                    "access.token.claim": "true",
                    "claim.name": "resource_access.$${client_id}.roles",
                    "jsonType.label": "String",
                    "multivalued": "true"
                  }
                }
              ]
            },
            {
              "clientId": "cryptomator",
              "serviceAccountsEnabled": false,
              "publicClient": true,
              "name": "Cryptomator App",
              "enabled": true,
              "redirectUris": [
                "http://127.0.0.1/*",
                "org.cryptomator.ios:/hub/auth",
                "org.cryptomator.android:/hub/auth"
              ],
              "webOrigins": [
                "+"
              ],
              "bearerOnly": false,
              "frontchannelLogout": false,
              "protocol": "openid-connect",
              "attributes": {
                "pkce.code.challenge.method": "S256"
              }
            }
          ],
          "browserSecurityHeaders": {
            "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self' http://localhost:30000/; object-src 'none';"
          }
        }
        EOF
  postgres:
    depends_on:
      init-config:
        condition: service_completed_successfully
    image: postgres:14-alpine
    volumes:
      - db-init:/docker-entrypoint-initdb.d
      - db-data:/var/lib/postgresql/data
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 256M
    healthcheck:
      test:
        - CMD
        - pg_isready
        - '-U'
        - postgres
      interval: 10s
      timeout: 3s
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: c25d3578-c262-4d21-b67a-bfd1684ce424
      POSTGRES_INITDB_ARGS: '--encoding=UTF8'
  keycloak:
    depends_on:
      init-config:
        condition: service_completed_successfully
      postgres:
        condition: service_healthy
    image: ghcr.io/cryptomator/keycloak:24.0.4
    command: start-dev --import-realm
    volumes:
      - kc-config:/opt/keycloak/data/import
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 1024M
    ports:
      - '31000:8080'
    healthcheck:
      test:
        - CMD
        - curl
        - '-f'
        - http://localhost:8080/health/live
      interval: 60s
      timeout: 3s
    restart: unless-stopped
    environment:
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin
      KC_DB: postgres
      KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
      KC_DB_USERNAME: keycloak
      KC_DB_PASSWORD: 4005c940-c9af-434f-85b4-0134664b74c3
      KC_HEALTH_ENABLED: 'true'
      KC_HOSTNAME: null
      KC_HTTP_ENABLED: 'true'
      KC_PROXY: edge
      KC_HTTP_RELATIVE_PATH: /
  hub:
    depends_on:
      keycloak:
        condition: service_healthy
      postgres:
        condition: service_healthy
    image: ghcr.io/cryptomator/hub:stable
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
    ports:
      - '30000:8080'
    healthcheck:
      test:
        - CMD-SHELL
        - (curl -f http://localhost:8080/q/health/live && curl -f http://localhost:8080/api/config) || exit 1
      interval: 10s
      timeout: 3s
    restart: unless-stopped
    environment:
      HUB_PUBLIC_ROOT_PATH: /
      HUB_KEYCLOAK_PUBLIC_URL: http://localhost:31000
      HUB_KEYCLOAK_LOCAL_URL: http://keycloak:8080/
      HUB_KEYCLOAK_REALM: cryptomator
      HUB_KEYCLOAK_SYNCER_USERNAME: syncer
      HUB_KEYCLOAK_SYNCER_PASSWORD: f9f25b3d-574a-4f05-9bce-370abea1023a
      HUB_KEYCLOAK_SYNCER_CLIENT_ID: admin-cli
      HUB_KEYCLOAK_SYNCER_PERIOD: 5m
      HUB_KEYCLOAK_OIDC_CRYPTOMATOR_CLIENT_ID: cryptomator
      QUARKUS_OIDC_AUTH_SERVER_URL: http://keycloak:8080/realms/cryptomator
      QUARKUS_OIDC_TOKEN_ISSUER: http://localhost:31000/realms/cryptomator
      QUARKUS_OIDC_CLIENT_ID: cryptomatorhub
      QUARKUS_DATASOURCE_JDBC_URL: jdbc:postgresql://postgres:5432/hub
      QUARKUS_DATASOURCE_USERNAME: hub
      QUARKUS_DATASOURCE_PASSWORD: 92f9ebac-d9f0-4790-8044-962c00acafd7
      QUARKUS_HTTP_HEADER__CONTENT_SECURITY_POLICY__VALUE: default-src 'self'; connect-src 'self' api.cryptomator.org http://localhost:31000/; object-src 'none'; child-src 'self'; img-src * data:; frame-ancestors 'none'
volumes:
  kc-config: {}
  db-init: {}
  db-data: {}
 
Das ist aber schon etwas ganz anderes, als das von dir erwähnte standalone Image vh13294/cryptomator-synology (welches ich auch nutze).

Da bin ich leider raus.
 
Ah, ja. das o.g. ist der Decompose-Text den Cryptomator ausgibt. Das ist nicht das vh-image. Das habe ich wieder rückabgewickelt, weil es nicht funktioniert hatte.

Nutzt du den Hub, auf deiner NAS gehostet? Kannst du mir dann nicht beantworten, ob ein Zugriff von mehreren Geräten gleichzeitig einen Dateikonflikt durch Sperrung/Schreibschutz verhindert?
 
Nein, ich nutze nur das einfache Image, zum Erstellen meiner USB-Backups. Und das unterscheidet sich nicht von einer lokalen Installation.

Bei dem komplexen Compose-File bin ich raus. Ich hab aber mal bei ChatGPT gefragt. Das Ergebnis habe ich jetzt allerdings nicht analysiert. Vielleicht hat unser Dockerprofi @haydibe auch eine Idee.

Der Fehler mit den "nanoCPUs" tritt auf, weil Docker Compose auf eurem Synology NAS Cluster versucht, CPU-Limits zu setzen, die von der DSM-Implementation (insbesondere bei Docker auf Synology-Geräten) nicht unterstützt werden. Das betrifft in diesem Fall die deploy.resources.limits.cpus-Einträge.

DSM (insbesondere bei SHA-Clustern) unterstützt keine vollständige Docker-Implementierung, sondern eine eingeschränkte Version, die einige Features (wie deploy-Optionen) nicht akzeptiert. Stattdessen sollte man alternative Ansätze wählen, die DSM unterstützt.

Lösungsmöglichkeiten​

1. Entferne die deploy.resources-Optionen

In der docker-compose.yml können die deploy-Abschnitte komplett entfernt werden, da sie für Ressourcenlimits auf DSM nicht erforderlich und nicht kompatibel sind. Beispiel:
YAML:
deploy:
  resources:
    limits:
      cpus: '1.0'
      memory: 256M

Entferne diesen Block für alle Services (z. B. postgres, keycloak, hub). Danach sollte die Datei so aussehen (Ausschnitt für postgres):
YAML:
postgres:
  depends_on:
    init-config:
      condition: service_completed_successfully
  image: postgres:14-alpine
  volumes:
    - db-init:/docker-entrypoint-initdb.d
    - db-data:/var/lib/postgresql/data
  healthcheck:
    test:
      - CMD
      - pg_isready
      - '-U'
      - postgres
    interval: 10s
    timeout: 3s
  restart: unless-stopped
  environment:
    POSTGRES_PASSWORD: c25d3578-c262-4d21-b67a-bfd1684ce424
    POSTGRES_INITDB_ARGS: '--encoding=UTF8'


2. Alternative: Nutzung von resource-Optionen über DSM

Falls ihr Ressourcenlimits benötigt, könnt ihr diese direkt in der Synology DSM-Oberfläche unter den Einstellungen der Container-Manager-Oberfläche setzen.

3. Kompatibilität sicherstellen

  • Nutze eine aktuelle Docker-Version, die für den DSM (Cluster) verfügbar ist.
  • Stelle sicher, dass keine anderen Kompatibilitätsprobleme durch andere deploy-Optionen (wie condition) auftreten.

Zusammensetzung des Clusters (918+ und 920+)​

Ein SHA-Cluster hat zusätzliche Anforderungen:

  • Überprüfe, ob der Cluster vollständig synchronisiert ist.
  • Stelle sicher, dass auf allen Knoten dieselbe Docker-Version und DSM-Version läuft.
  • Falls der Container auf dem falschen Node gestartet wird, prüfe, ob alle Knoten denselben Zugang zu den erforderlichen Volumes (z. B. db-init, db-data) haben.
Teste die Änderungen und starte die Container erneut. Wenn es weiterhin Probleme gibt, teile bitte den genauen Fehler mit.
 
Das Problem scheint mir eher an der fachlichen Konfiguration zu liegen, und weniger an Docker als Container Runtime..
Ich fürchte hier wird ein "scharfer Blick" nicht ausreichen, um zu verstehen was, wie getan werden muss. Ich muss hier leider kneifen.
 
Schmeiß alle resources limits für die CPU raus. Damit kann Synology nicht umgehen.
Code:
deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 1024M

Nachtrag: Hab gerade gesehen, dass genau der Vorschlag von geimist schon gemacht wurde.
Das ist aber faktisch die Lösung, wie ich schon beim Schnelltest festhalten konnte.
1738092524923.png
 
Zuletzt bearbeitet:
  • Like
Reaktionen: geimist und haydibe
 

Kaffeautomat

Wenn du das Forum hilfreich findest oder uns unterstützen möchtest, dann gib uns doch einfach einen Kaffee aus.

Als Dankeschön schalten wir deinen Account werbefrei.

:coffee:

Hier gehts zum Kaffeeautomat