From d53d528df2a5973ed55bb0a39dbac89c5ff72c79 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Sat, 3 Feb 2024 23:19:58 +0100 Subject: [PATCH] nixos/matrix-synapse: add UNIX domain socket listener support Exposes two options, `path` and `mode`, to configure the location and permissions on the socket file. Adds an assertion, that either `path` or `bind_addresses` and `port` are configured on every listener. Migrates the default replication listener of the main instance to a UNIX domain socket, because it is more efficient. --- .../manual/release-notes/rl-2405.section.md | 2 + nixos/modules/services/matrix/synapse.nix | 71 ++++++++++++++++--- 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md index 06c3e1949b70ab5..ac2c2d515f762d1 100644 --- a/nixos/doc/manual/release-notes/rl-2405.section.md +++ b/nixos/doc/manual/release-notes/rl-2405.section.md @@ -239,6 +239,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `services.postgresql.extraPlugins` changed its type from just a list of packages to also a function that returns such a list. For example a config line like ``services.postgresql.extraPlugins = with pkgs.postgresql_11.pkgs; [ postgis ];`` is recommended to be changed to ``services.postgresql.extraPlugins = ps: with ps; [ postgis ];``; +- The Matrix homeserver [Synapse](https://element-hq.github.io/synapse/) can now, through the `path` option, bind its [listeners](#opt-services.matrix-synapse.settings.listeners) to UNIX domain sockets. + - Programs written in [Nim](https://nim-lang.org/) are built with libraries selected by lockfiles. The `nimPackages` and `nim2Packages` sets have been removed. See https://nixos.org/manual/nixpkgs/unstable#nim for more information. diff --git a/nixos/modules/services/matrix/synapse.nix b/nixos/modules/services/matrix/synapse.nix index 4c1c396eac05649..344172a12db1e0a 100644 --- a/nixos/modules/services/matrix/synapse.nix +++ b/nixos/modules/services/matrix/synapse.nix @@ -195,7 +195,8 @@ in { listenerType = workerContext: types.submodule { options = { port = mkOption { - type = types.port; + type = types.nullOr types.port; + default = null; example = 8448; description = lib.mdDoc '' The port to listen for HTTP(S) requests on. @@ -203,7 +204,7 @@ in { }; bind_addresses = mkOption { - type = types.listOf types.str; + type = types.nullOr (types.listOf types.str); default = [ "::1" "127.0.0.1" @@ -219,6 +220,33 @@ in { ''; }; + path = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + Unix domain socket path to bind this listener to. + + ::: {.note} + This option is incompatible with {option}`bind_addresses`, {option}`port`, {option}`tls` + and also does not support the `metrics` and `manhole` listener {option}`type`. + ''; + }; + + mode = mkOption { + type = types.nullOr types.int; + default = if path != null then 660 else null; + defaultText = literalExpression '' + if path != null then + 660 + else + null + ''; + example = 660; + description = '' + File permissions on the UNIX domain socket. + ''; + }; + type = mkOption { type = types.enum [ "http" @@ -244,11 +272,17 @@ in { x_forwarded = mkOption { type = types.bool; - default = false; + default = path != null; + defaultText = literalExpression '' + path != null + ''; example = true; description = lib.mdDoc '' Use the X-Forwarded-For (XFF) header as the client IP and not the actual client IP. + + ::: {.note} + Defaults to `true`, when {option}`path` is configured. ''; }; @@ -616,8 +650,7 @@ in { compress = false; }]; }] ++ lib.optional hasWorkers { - port = 9093; - bind_addresses = [ "127.0.0.1" ]; + path = "/run/matrix-synapse/main_replication.sock"; type = "http"; tls = false; x_forwarded = false; @@ -630,7 +663,7 @@ in { List of ports that Synapse should listen on, their purpose and their configuration. By default, synapse will be configured for client and federation traffic on port 8008, and - for worker replication traffic on port 9093. See [`services.matrix-synapse.workers`](#opt-services.matrix-synapse.workers) + for use a UNIX domain socket for worker replication. See [`services.matrix-synapse.workers`](#opt-services.matrix-synapse.workers) for more details. ''; }; @@ -992,6 +1025,17 @@ in { by synapse in `services.matrix-synapse.settings.listeners` or in one of the workers! ''; } + { + assertion = lib.all + ( + listener: + listener.path != null || (listener.bind_addresses != null && listener.port != null) + ) cfg.settings.listeners; + message = '' + Listener configurations require either `bind_addresses` and `port` for TCP sockets, + or `path` for UNIX domain sockets. + ''; + } { assertion = hasWorkers -> cfg.settings.redis.enabled; message = '' @@ -1006,9 +1050,15 @@ in { listener = lib.findFirst ( listener: - listener.port == main.port + ( + lib.hasAttr "port" main && listener.port or null == main.port + || lib.hasAttr "path" main && listener.path or null == main.path + ) && listenerSupportsResource "replication" listener - && (lib.any (bind: bind == main.host || bind == "0.0.0.0" || bind == "::") listener.bind_addresses) + && ( + lib.hasAttr "host" main && lib.any (bind: bind == main.host || bind == "0.0.0.0" || bind == "::") listener.bind_addresses + || lib.hasAttr "path" main + ) ) null cfg.settings.listeners; @@ -1029,8 +1079,7 @@ in { path = config.services.redis.servers.matrix-synapse.unixSocket; }; services.matrix-synapse.settings.instance_map.main = lib.mkIf hasWorkers (lib.mkDefault { - host = "127.0.0.1"; - port = 9093; + path = "/run/matrix-synapse/main_replication.sock"; }); services.matrix-synapse.serviceUnit = if hasWorkers then "matrix-synapse.target" else "matrix-synapse.service"; @@ -1086,6 +1135,8 @@ in { User = "matrix-synapse"; Group = "matrix-synapse"; WorkingDirectory = cfg.dataDir; + RuntimeDirectory = "matrix-synapse"; + RuntimeDirectoryPreserve = true; ExecReload = "${pkgs.util-linux}/bin/kill -HUP $MAINPID"; Restart = "on-failure"; UMask = "0077";