Skip to content

Commit

Permalink
nixos/matrix-synapse: add UNIX domain socket listener support
Browse files Browse the repository at this point in the history
Exposes two options, `path` and `mode`, to configure the location and
permissions on the socket file.

The `mode` needs to be specified as string in octal and will be converted
into a decimal integer, so it correctly passes through the YAML parser
and arrives at the `os.chmod` call in the Twisted codebase. What a fun
detour.

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.
  • Loading branch information
mweinelt committed Feb 4, 2024
1 parent add041d commit fa1adb5
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 10 deletions.
2 changes: 2 additions & 0 deletions nixos/doc/manual/release-notes/rl-2405.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
79 changes: 69 additions & 10 deletions nixos/modules/services/matrix/synapse.nix
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ let
SYSLOG_IDENTIFIER = logName;
};
});

toIntBase8 = str:
lib.pipe str [
lib.stringToCharacters
(map lib.toInt)
(lib.foldl (acc: digit: acc * 8 + digit) 0)
];
in {

imports = [
Expand Down Expand Up @@ -195,15 +202,16 @@ 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.
'';
};

bind_addresses = mkOption {
type = types.listOf types.str;
type = types.nullOr (types.listOf types.str);
default = [
"::1"
"127.0.0.1"
Expand All @@ -219,6 +227,34 @@ 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.str;
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.
'';
apply = toIntBase8;
};

type = mkOption {
type = types.enum [
"http"
Expand All @@ -244,11 +280,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.
'';
};

Expand Down Expand Up @@ -616,8 +658,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;
Expand All @@ -630,7 +671,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.
'';
};
Expand Down Expand Up @@ -992,6 +1033,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 = ''
Expand All @@ -1006,9 +1058,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;
Expand All @@ -1029,8 +1087,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";
Expand Down Expand Up @@ -1086,6 +1143,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";
Expand Down

0 comments on commit fa1adb5

Please sign in to comment.