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. 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. Introduces the `enableRegistrationScript` option, to gracefully disable the user registration script, when the client listener listens on a UNIX domain socket, which is something the script does not support.
This commit is contained in:
parent
2565ab7b53
commit
143d266f0d
|
@ -246,6 +246,9 @@ 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.
|
- `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 ];``;
|
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/) module now supports configuring UNIX domain socket [listeners](#opt-services.matrix-synapse.settings.listeners) through the `path` option.
|
||||||
|
The default replication worker on the main instance has been migrated away from TCP sockets to UNIX domain sockets.
|
||||||
|
|
||||||
- Programs written in [Nim](https://nim-lang.org/) are built with libraries selected by lockfiles.
|
- Programs written in [Nim](https://nim-lang.org/) are built with libraries selected by lockfiles.
|
||||||
The `nimPackages` and `nim2Packages` sets have been removed.
|
The `nimPackages` and `nim2Packages` sets have been removed.
|
||||||
See https://nixos.org/manual/nixpkgs/unstable#nim for more information.
|
See https://nixos.org/manual/nixpkgs/unstable#nim for more information.
|
||||||
|
|
|
@ -126,8 +126,9 @@ then enable `services.matrix-synapse.settings.enable_registration = true;`.
|
||||||
Otherwise, or you can generate a registration secret with
|
Otherwise, or you can generate a registration secret with
|
||||||
{command}`pwgen -s 64 1` and set it with
|
{command}`pwgen -s 64 1` and set it with
|
||||||
[](#opt-services.matrix-synapse.settings.registration_shared_secret).
|
[](#opt-services.matrix-synapse.settings.registration_shared_secret).
|
||||||
To create a new user or admin, run the following after you have set the secret
|
To create a new user or admin from the terminal your client listener
|
||||||
and have rebuilt NixOS:
|
must be configured to use TCP sockets. Then you can run the following
|
||||||
|
after you have set the secret and have rebuilt NixOS:
|
||||||
```ShellSession
|
```ShellSession
|
||||||
$ nix-shell -p matrix-synapse
|
$ nix-shell -p matrix-synapse
|
||||||
$ register_new_matrix_user -k your-registration-shared-secret http://localhost:8008
|
$ register_new_matrix_user -k your-registration-shared-secret http://localhost:8008
|
||||||
|
|
|
@ -105,6 +105,19 @@ let
|
||||||
SYSLOG_IDENTIFIER = logName;
|
SYSLOG_IDENTIFIER = logName;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
toIntBase8 = str:
|
||||||
|
lib.pipe str [
|
||||||
|
lib.stringToCharacters
|
||||||
|
(map lib.toInt)
|
||||||
|
(lib.foldl (acc: digit: acc * 8 + digit) 0)
|
||||||
|
];
|
||||||
|
|
||||||
|
toDecimalFilePermission = value:
|
||||||
|
if value == null then
|
||||||
|
null
|
||||||
|
else
|
||||||
|
toIntBase8 value;
|
||||||
in {
|
in {
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
|
@ -192,10 +205,11 @@ in {
|
||||||
];
|
];
|
||||||
|
|
||||||
options = let
|
options = let
|
||||||
listenerType = workerContext: types.submodule {
|
listenerType = workerContext: types.submodule ({ config, ... }: {
|
||||||
options = {
|
options = {
|
||||||
port = mkOption {
|
port = mkOption {
|
||||||
type = types.port;
|
type = types.nullOr types.port;
|
||||||
|
default = null;
|
||||||
example = 8448;
|
example = 8448;
|
||||||
description = lib.mdDoc ''
|
description = lib.mdDoc ''
|
||||||
The port to listen for HTTP(S) requests on.
|
The port to listen for HTTP(S) requests on.
|
||||||
|
@ -203,11 +217,20 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
bind_addresses = mkOption {
|
bind_addresses = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.nullOr (types.listOf types.str);
|
||||||
default = [
|
default = if config.path != null then null else [
|
||||||
"::1"
|
"::1"
|
||||||
"127.0.0.1"
|
"127.0.0.1"
|
||||||
];
|
];
|
||||||
|
defaultText = literalExpression ''
|
||||||
|
if path != null then
|
||||||
|
null
|
||||||
|
else
|
||||||
|
[
|
||||||
|
"::1"
|
||||||
|
"127.0.0.1"
|
||||||
|
]
|
||||||
|
'';
|
||||||
example = literalExpression ''
|
example = literalExpression ''
|
||||||
[
|
[
|
||||||
"::"
|
"::"
|
||||||
|
@ -219,6 +242,35 @@ 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.strMatching "^[0,2-7]{3,4}$");
|
||||||
|
default = if config.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 = toDecimalFilePermission;
|
||||||
|
};
|
||||||
|
|
||||||
type = mkOption {
|
type = mkOption {
|
||||||
type = types.enum [
|
type = types.enum [
|
||||||
"http"
|
"http"
|
||||||
|
@ -234,17 +286,30 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
tls = mkOption {
|
tls = mkOption {
|
||||||
type = types.bool;
|
type = types.nullOr types.bool;
|
||||||
default = !workerContext;
|
default = if config.path != null then
|
||||||
|
null
|
||||||
|
else
|
||||||
|
!workerContext;
|
||||||
|
defaultText = ''
|
||||||
|
Enabled for the main instance listener, unless it is configured with a UNIX domain socket path.
|
||||||
|
'';
|
||||||
example = false;
|
example = false;
|
||||||
description = lib.mdDoc ''
|
description = lib.mdDoc ''
|
||||||
Whether to enable TLS on the listener socket.
|
Whether to enable TLS on the listener socket.
|
||||||
|
|
||||||
|
::: {.note}
|
||||||
|
This option will be ignored for UNIX domain sockets.
|
||||||
|
:::
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
x_forwarded = mkOption {
|
x_forwarded = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = config.path != null;
|
||||||
|
defaultText = ''
|
||||||
|
Enabled if the listener is configured with a UNIX domain socket path
|
||||||
|
'';
|
||||||
example = true;
|
example = true;
|
||||||
description = lib.mdDoc ''
|
description = lib.mdDoc ''
|
||||||
Use the X-Forwarded-For (XFF) header as the client IP and not the
|
Use the X-Forwarded-For (XFF) header as the client IP and not the
|
||||||
|
@ -291,11 +356,28 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
});
|
||||||
in {
|
in {
|
||||||
services.matrix-synapse = {
|
services.matrix-synapse = {
|
||||||
enable = mkEnableOption (lib.mdDoc "matrix.org synapse");
|
enable = mkEnableOption (lib.mdDoc "matrix.org synapse");
|
||||||
|
|
||||||
|
enableRegistrationScript = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = clientListener.bind_addresses != [];
|
||||||
|
example = false;
|
||||||
|
defaultText = ''
|
||||||
|
Enabled if the client listener uses TCP sockets
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Whether to install the `register_new_matrix_user` script, that
|
||||||
|
allows account creation on the terminal.
|
||||||
|
|
||||||
|
::: {.note}
|
||||||
|
This script does not work when the client listener uses UNIX domain sockets
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
serviceUnit = lib.mkOption {
|
serviceUnit = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
readOnly = true;
|
readOnly = true;
|
||||||
|
@ -616,11 +698,8 @@ in {
|
||||||
compress = false;
|
compress = false;
|
||||||
}];
|
}];
|
||||||
}] ++ lib.optional hasWorkers {
|
}] ++ lib.optional hasWorkers {
|
||||||
port = 9093;
|
path = "/run/matrix-synapse/main_replication.sock";
|
||||||
bind_addresses = [ "127.0.0.1" ];
|
|
||||||
type = "http";
|
type = "http";
|
||||||
tls = false;
|
|
||||||
x_forwarded = false;
|
|
||||||
resources = [{
|
resources = [{
|
||||||
names = [ "replication" ];
|
names = [ "replication" ];
|
||||||
compress = false;
|
compress = false;
|
||||||
|
@ -630,7 +709,7 @@ in {
|
||||||
List of ports that Synapse should listen on, their purpose and their configuration.
|
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
|
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)
|
use a UNIX domain socket for worker replication. See [`services.matrix-synapse.workers`](#opt-services.matrix-synapse.workers)
|
||||||
for more details.
|
for more details.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
@ -1006,9 +1085,15 @@ in {
|
||||||
listener = lib.findFirst
|
listener = lib.findFirst
|
||||||
(
|
(
|
||||||
listener:
|
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
|
&& 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
|
null
|
||||||
cfg.settings.listeners;
|
cfg.settings.listeners;
|
||||||
|
@ -1022,15 +1107,44 @@ in {
|
||||||
This is done by default unless you manually configure either of those settings.
|
This is done by default unless you manually configure either of those settings.
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
];
|
{
|
||||||
|
assertion = cfg.enableRegistrationScript -> clientListener.path == null;
|
||||||
|
message = ''
|
||||||
|
The client listener on matrix-synapse is configured to use UNIX domain sockets.
|
||||||
|
This configuration is incompatible with the `register_new_matrix_user` script.
|
||||||
|
|
||||||
|
Disable `services.mastrix-synapse.enableRegistrationScript` to continue.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
]
|
||||||
|
++ (map (listener: {
|
||||||
|
assertion = (listener.path == null) != (listener.bind_addresses == null);
|
||||||
|
message = ''
|
||||||
|
Listeners require either a UNIX domain socket `path` or `bind_addresses` for a TCP socket.
|
||||||
|
'';
|
||||||
|
}) cfg.settings.listeners)
|
||||||
|
++ (map (listener: {
|
||||||
|
assertion = listener.path != null -> (listener.bind_addresses == null && listener.port == null && listener.tls == null);
|
||||||
|
message = let
|
||||||
|
formatKeyValue = key: value: lib.optionalString (value != null) " - ${key}=${toString value}\n";
|
||||||
|
in ''
|
||||||
|
Listener configured with UNIX domain socket (${toString listener.path}) ignores the following options:
|
||||||
|
${formatKeyValue "bind_addresses" listener.bind_addresses}${formatKeyValue "port" listener.port}${formatKeyValue "tls" listener.tls}
|
||||||
|
'';
|
||||||
|
}) cfg.settings.listeners)
|
||||||
|
++ (map (listener: {
|
||||||
|
assertion = listener.path == null || listener.type == "http";
|
||||||
|
message = ''
|
||||||
|
Listener configured with UNIX domain socket (${toString listener.path}) only supports the "http" listener type.
|
||||||
|
'';
|
||||||
|
}) cfg.settings.listeners);
|
||||||
|
|
||||||
services.matrix-synapse.settings.redis = lib.mkIf cfg.configureRedisLocally {
|
services.matrix-synapse.settings.redis = lib.mkIf cfg.configureRedisLocally {
|
||||||
enabled = true;
|
enabled = true;
|
||||||
path = config.services.redis.servers.matrix-synapse.unixSocket;
|
path = config.services.redis.servers.matrix-synapse.unixSocket;
|
||||||
};
|
};
|
||||||
services.matrix-synapse.settings.instance_map.main = lib.mkIf hasWorkers (lib.mkDefault {
|
services.matrix-synapse.settings.instance_map.main = lib.mkIf hasWorkers (lib.mkDefault {
|
||||||
host = "127.0.0.1";
|
path = "/run/matrix-synapse/main_replication.sock";
|
||||||
port = 9093;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
services.matrix-synapse.serviceUnit = if hasWorkers then "matrix-synapse.target" else "matrix-synapse.service";
|
services.matrix-synapse.serviceUnit = if hasWorkers then "matrix-synapse.target" else "matrix-synapse.service";
|
||||||
|
@ -1086,6 +1200,8 @@ in {
|
||||||
User = "matrix-synapse";
|
User = "matrix-synapse";
|
||||||
Group = "matrix-synapse";
|
Group = "matrix-synapse";
|
||||||
WorkingDirectory = cfg.dataDir;
|
WorkingDirectory = cfg.dataDir;
|
||||||
|
RuntimeDirectory = "matrix-synapse";
|
||||||
|
RuntimeDirectoryPreserve = true;
|
||||||
ExecReload = "${pkgs.util-linux}/bin/kill -HUP $MAINPID";
|
ExecReload = "${pkgs.util-linux}/bin/kill -HUP $MAINPID";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
UMask = "0077";
|
UMask = "0077";
|
||||||
|
@ -1178,7 +1294,9 @@ in {
|
||||||
user = "matrix-synapse";
|
user = "matrix-synapse";
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.systemPackages = [ registerNewMatrixUser ];
|
environment.systemPackages = lib.optionals cfg.enableRegistrationScript [
|
||||||
|
registerNewMatrixUser
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user