From bcf5ae5da77bebd3b480129459c178a7b78a5e63 Mon Sep 17 00:00:00 2001 From: yukkop Date: Sun, 24 May 2026 14:54:01 +0000 Subject: [PATCH] fix: element --- flake.lock | 8 +-- nixos/module/generic/matrix-cluster.nix | 83 ++++++++++++++++++++++--- nixos/system/hectic-lab/hectic-lab.nix | 8 +++ sus/matrix-cluster.yaml | 8 +-- 4 files changed, 89 insertions(+), 18 deletions(-) diff --git a/flake.lock b/flake.lock index 403114d..221b5d1 100644 --- a/flake.lock +++ b/flake.lock @@ -675,11 +675,11 @@ ] }, "locked": { - "lastModified": 1779566710, - "narHash": "sha256-O9fsA+loiwp1YboemijM2uQM2D2UPCwfsok+cgHeEEE=", + "lastModified": 1779576166, + "narHash": "sha256-5bSuXkQs7KdbaYwDTdwUFlqOccVjPI2y42TZVq8lsNg=", "ref": "refs/heads/master", - "rev": "e15b89a28ee001fb80bfc5fc2cba2dff5eee1841", - "revCount": 103, + "rev": "f00295225c0dade61fe18b32262970c2665fb5fe", + "revCount": 110, "type": "git", "url": "ssh://git@github.com/LysmiMx/mechabellum-replay-analysis.git" }, diff --git a/nixos/module/generic/matrix-cluster.nix b/nixos/module/generic/matrix-cluster.nix index 25d6fb4..56473ee 100644 --- a/nixos/module/generic/matrix-cluster.nix +++ b/nixos/module/generic/matrix-cluster.nix @@ -112,6 +112,24 @@ in { ''; }; + turnSecretFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = '' + Shared secret file used by coturn for Matrix voice/video calls. + When set together with `publicIp`, the active Synapse node also enables + coturn and publishes TURN URIs to clients. + ''; + }; + + publicIp = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = '' + Public IP address advertised to coturn for listening and relaying. + ''; + }; + maxUploadSize = lib.mkOption { type = lib.types.str; default = "2G"; @@ -228,9 +246,8 @@ in { systemd.services.matrix-cluster-signing-key = { description = "Install Matrix Synapse signing key from secrets"; wantedBy = [ "multi-user.target" ]; - after = [ "sops-install-secrets.service" ]; - requires = [ "sops-install-secrets.service" ]; before = lib.optional synapseEnabled "matrix-synapse.service"; + requiredBy = lib.optional synapseEnabled "matrix-synapse.service"; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; @@ -257,8 +274,31 @@ in { assertion = cfg.secretsFile != null; message = "hectic.generic.matrix-cluster.secretsFile must be set when Synapse runs on this node."; } + { + assertion = (cfg.turnSecretFile == null) == (cfg.publicIp == null); + message = "hectic.generic.matrix-cluster.turnSecretFile and publicIp must be set together."; + } ]; + services.coturn = lib.mkIf (cfg.turnSecretFile != null) rec { + enable = true; + realm = cfg.matrixDomain; + use-auth-secret = true; + static-auth-secret-file = cfg.turnSecretFile; + cert = "${config.security.acme.certs.${realm}.directory}/full.pem"; + pkey = "${config.security.acme.certs.${realm}.directory}/key.pem"; + listening-ips = [ cfg.publicIp ]; + no-tcp-relay = true; + relay-ips = [ cfg.publicIp ]; + listening-port = 3478; + tls-listening-port = 5349; + no-cli = true; + + extraConfig = '' + verbose + ''; + }; + services.matrix-synapse = { enable = true; plugins = [ s3Plugin ]; @@ -278,6 +318,15 @@ in { msc4222_enabled = true; }; + matrix_rtc = { + transports = [ + { + type = "livekit"; + livekit_service_url = "https://${cfg.matrixDomain}/livekit/jwt"; + } + ]; + }; + listeners = [ { port = 8008; @@ -295,6 +344,15 @@ in { enable_registration = cfg.enableRegistration; enable_registration_without_verification = cfg.enableRegistration; + } // lib.optionalAttrs (cfg.turnSecretFile != null) { + turn_uris = [ + "turn:${cfg.matrixDomain}:3478?transport=udp" + "turn:${cfg.matrixDomain}:3478?transport=tcp" + "turns:${cfg.matrixDomain}:5349?transport=udp" + "turns:${cfg.matrixDomain}:5349?transport=tcp" + ]; + turn_user_lifetime = 86400000; + turn_allow_guests = true; }; }; @@ -302,8 +360,6 @@ in { systemd.services.matrix-synapse-s3-config = { description = "Generate Synapse S3 media storage config"; - after = [ "sops-install-secrets.service" ]; - requires = [ "sops-install-secrets.service" ]; before = [ "matrix-synapse.service" ]; requiredBy = [ "matrix-synapse.service" ]; serviceConfig.Type = "oneshot"; @@ -333,6 +389,17 @@ in { }; }; + networking.firewall = lib.mkIf (cfg.turnSecretFile != null) { + allowedUDPPorts = [ 3478 5349 ]; + allowedTCPPorts = [ 3478 5349 ]; + allowedUDPPortRanges = [ + { + from = 49152; + to = 65535; + } + ]; + }; + systemd.services.matrix-synapse-users = lib.mkIf (matrixUsers != []) { description = "Provision Matrix Synapse users"; wantedBy = [ "multi-user.target" ]; @@ -405,8 +472,8 @@ ${lib.concatStringsSep "\n" (map mkUserRegistration matrixUsers)} systemd.services.matrix-cluster-replication-password = { description = "Set Postgres replication role password from SOPS"; wantedBy = [ "multi-user.target" ]; - after = [ "postgresql.service" "sops-install-secrets.service" ]; - requires = [ "postgresql.service" "sops-install-secrets.service" ]; + after = [ "postgresql.service" ]; + requires = [ "postgresql.service" ]; serviceConfig = { Type = "oneshot"; User = "postgres"; @@ -428,8 +495,6 @@ ${lib.concatStringsSep "\n" (map mkUserRegistration matrixUsers)} systemd.services.matrix-cluster-standby-bootstrap = { description = "Configure Matrix Postgres hot standby"; wantedBy = [ "postgresql.service" ]; - after = [ "sops-install-secrets.service" ]; - requires = [ "sops-install-secrets.service" ]; before = [ "postgresql.service" ]; serviceConfig = { Type = "oneshot"; @@ -484,8 +549,6 @@ ${lib.concatStringsSep "\n" (map mkUserRegistration matrixUsers)} systemd.services.matrix-cluster-acme-env = { description = "Assemble Porkbun ACME environment file"; wantedBy = [ "multi-user.target" ]; - after = [ "sops-install-secrets.service" ]; - requires = [ "sops-install-secrets.service" ]; before = [ "acme-${cfg.matrixDomain}.service" ]; requiredBy = [ "acme-${cfg.matrixDomain}.service" ]; serviceConfig = { diff --git a/nixos/system/hectic-lab/hectic-lab.nix b/nixos/system/hectic-lab/hectic-lab.nix index 6cefeb6..c55a285 100644 --- a/nixos/system/hectic-lab/hectic-lab.nix +++ b/nixos/system/hectic-lab/hectic-lab.nix @@ -66,6 +66,8 @@ in { inherit matrixDomain; signingKeyFile = config.sops.secrets."matrix/signing-key".path; secretsFile = config.sops.secrets."matrix/secrets".path; + turnSecretFile = config.sops.secrets."matrix/turn-secret".path; + publicIp = "128.140.75.58"; users = { yukkop = { passwordFile = config.sops.secrets."matrix/users/yukkop/password".path; @@ -182,6 +184,12 @@ in { key = "matrix/secrets"; owner = "matrix-synapse"; }; + sops.secrets."matrix/turn-secret" = { + key = "matrix/turn-secret"; + owner = "turnserver"; + group = "turnserver"; + mode = "0400"; + }; sops.secrets."matrix/users/yukkop/password" = { key = "matrix/users/yukkop/password"; owner = "matrix-synapse"; diff --git a/sus/matrix-cluster.yaml b/sus/matrix-cluster.yaml index 5a6c558..e01ad54 100644 --- a/sus/matrix-cluster.yaml +++ b/sus/matrix-cluster.yaml @@ -17,8 +17,8 @@ # #ENC[AES256_GCM,data:EMxRfCZ/gq8vS2pOUlxnDO2pxrW/Pjrms0Mk6xQSS9oEWj0g80z0BgOAG2pMvNreLfDHepdLCmaSn/tTefuH3QVaPz0C,iv:Q0sJ/97fm0YZjduAija53Dm94SPvT4jr7CxCySkH4xM=,tag:p2fNrTC7hiGFWI3AsjYoQg==,type:comment] matrix: - signing-key: ENC[AES256_GCM,data:HAhg/QBQyXiv/1dMru95b+4v5IybMn4TaeAuYKk=,iv:R/hYs/HrlIXLWzJv67O0DKrix8tJ50LoNNbwnaMXCQc=,tag:3dMOWxyFqWLeUkWR51ccKw==,type:str] - postgres-replication-password: ENC[AES256_GCM,data:0KT0CRSaNzrUbTd5S4D7pxfjf+zazdtZcXsbvdoOHhk9dBz5f441ouO0Gv7O14W8eayxMUz19YD9Ww==,iv:BozluZt/Ll3kqeWSbA1H2+BKp5a/AR5u/P38Gk8VSR8=,tag:iy0qGPmYAK74BgIkglpfgw==,type:str] + signing-key: ENC[AES256_GCM,data:0vvD7KbLKHcqiF3K8SjsKdBY/EvpGpx906AshA5zh650PPuNvO9o1GEInnW4e1KZTxIRwVF47vbLzg==,iv:9yQ94ko1RkPoEL9K7Y8C0ODWvPj6EifPf9XX7So5GqY=,tag:fx7KZrlXz7uktkzhChDeJw==,type:str] + postgres-replication-password: ENC[AES256_GCM,data:LbnvZCu5Bx9bUB2xP81jMm/OwuWTFtWGCA==,iv:VAp6pv42FIhe07oU7Sce4nuJkzPEktX76hhA95M7WcA=,tag:UcfGW8G1olt8xmexggqF/Q==,type:str] object-storage: credentials: ENC[AES256_GCM,data:qgrBzVZGS7HeaLHQpi8xiqSkZcw8zwirb5/p6ArcXkuT0FdFH2ucl+o+BQkC4z/bVqpOw0ZiQt19sXzAvC4U4Y7it4i05+9g2Bs+flYutjswBE7YO/DvEspNywsfKQ==,iv:8n5PVz1yKnKe5oJnCK7ywJkFj+33eDVxiFmt9T3Q3TU=,tag:CoDkxdQqg0S4ebOCPX8y+w==,type:str] porkbun-api-key: ENC[AES256_GCM,data:kQlmH3v6mdkXNaqXGt4V0MpOxrgPtSF/8YQ7jzJ0GtECbJzo+eF6VreguWDu3VMX2TpP1tah0m/ZaiHyAogKZSZS32c=,iv:pPTiQ0GMlndQvuBzoNj2SHtwxCiQuZdG2DOkMAiT+RA=,tag:pUiaq9OzoSft+vHO5/MkgQ==,type:str] @@ -88,7 +88,7 @@ sops: T29jSG0va3g2NE4zbklyWS9BN2hKUW8KDl3jMTCeEgNBsu+Krs/lB8iXlnZu8zxB iNX4GegOxmlgJOA6jMCh8AlwUzz7HIex9jJ5MunZ9/6V/Aubqjb1Ug== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-05-23T22:14:25Z" - mac: ENC[AES256_GCM,data:omw2csf8/F8Ob2znjBL6/4Et2NCxu7yaMLsCfy3gP/qM8kzGW8Z7bo2gx0C7pX3qkKbersBJ/CMLaZNyEdjYnt4OsFfN2LyhBITsRID7ASt4BWXgnQ0p2jM8AV8Qb4Mxz4VMLcuDjdhtITcsPKu1z60BYomJmnLFzVVy2UYPw94=,iv:1s68DQfNCFxK6Bte7Km3V0FyopMV5DJ6EVdZ+1stgf8=,tag:ZNJ59SVV/4WqgIaEYBMRJQ==,type:str] + lastmodified: "2026-05-24T14:47:51Z" + mac: ENC[AES256_GCM,data:gNJLTB8Lb9n5t50GPatLmTkarp+QF3CzTTp8D0tj29qeTXWsf1Fbq3r4nMAxZYiH9lDmAr5qzXZbfPG38VspXC1bUr3xctnjTGCC1mp+liCbNDC1A1pJUMBVQVcuDR6pyMV8PrtmbCXKkSECntVVR5VTzFYG9lldEuLvEoczMwg=,iv:6IpuGHLmpEhwkCZh/0rYX18YBqgr5sUEUC6mcrv//JE=,tag:Yo3wNB5jNUa8r272q3Q23Q==,type:str] unencrypted_suffix: _unencrypted version: 3.10.2