Skip to content

Commit

Permalink
nixos/mjolnir: add configuration options for native encryption
Browse files Browse the repository at this point in the history
  • Loading branch information
999eagle committed Nov 22, 2024
1 parent dc460ec commit 06261f5
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 30 deletions.
33 changes: 27 additions & 6 deletions nixos/modules/services/matrix/mjolnir.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,31 @@ you'll need to make the Mjolnir user a Matrix server admin.

Now invite the Mjolnir user to the management room.

It is recommended to use [Pantalaimon](https://github.com/matrix-org/pantalaimon),
so your management room can be encrypted. This also applies if you are looking to moderate an encrypted room.
It is recommended to enable encryption so your management room can be encrypted. This also applies
if you are looking to moderate an encrypted room. This can be done by enabling
[services.mjolnir.encryption](#opt-services.mjolnir.encryption.enable) and configuring a password
in [services.mjolnir.passwordFile](#opt-services.mjolnir.passwordFile).

To enable the Pantalaimon E2E Proxy for mjolnir, enable
```nix
{
services.mjolnir = {
enable = true;
homeserverUrl = "https://matrix.domain.tld";
passwordFile = "/run/secrets/mjolnir-password";
encryption = {
enable = true;
username = "mjolnir";
};
protectedRooms = [
"https://matrix.to/#/!xxx:domain.tld"
];
managementRoom = "!yyy:domain.tld";
};
}
```

Alternatively, using [Pantalaimon](https://github.com/matrix-org/pantalaimon) for encryption is
still supported, but deprecated. To enable the Pantalaimon E2E Proxy for mjolnir, enable
[services.mjolnir.pantalaimon](#opt-services.mjolnir.pantalaimon.enable). This will
autoconfigure a new Pantalaimon instance, which will connect to the homeserver
set in [services.mjolnir.homeserverUrl](#opt-services.mjolnir.homeserverUrl) and Mjolnir itself
Expand All @@ -51,10 +72,10 @@ will be configured to connect to the new Pantalaimon instance.
services.mjolnir = {
enable = true;
homeserverUrl = "https://matrix.domain.tld";
passwordFile = "/run/secrets/mjolnir-password";
pantalaimon = {
enable = true;
username = "mjolnir";
passwordFile = "/run/secrets/mjolnir-password";
enable = true;
username = "mjolnir";
};
protectedRooms = [
"https://matrix.to/#/!xxx:domain.tld"
Expand Down
82 changes: 58 additions & 24 deletions nixos/modules/services/matrix/mjolnir.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,17 @@ let
rawHomeserverUrl = cfg.homeserverUrl;

pantalaimon = {
use = cfg.pantalaimon.enable;
} // lib.optionalAttrs cfg.pantalaimon.enable {
inherit (cfg.pantalaimon) username;
password = "@MJOLNIR_PASSWORD@"; # will be replaced in "generateConfig"
};

use = cfg.pantalaimon.enable;
password = "@PANTALAIMON_PASSWORD@"; # will be replaced in "generateConfig"
encryption = {
use = cfg.encryption.enable;
} // lib.optionalAttrs cfg.encryption.enable {
inherit (cfg.encryption) username;
password = "@MJOLNIR_PASSWORD@"; # will be replaced in "generateConfig"
};
};

Expand Down Expand Up @@ -55,8 +62,8 @@ let
${lib.optionalString (cfg.accessTokenFile != null) ''
${pkgs.replace-secret}/bin/replace-secret '@ACCESS_TOKEN@' '${cfg.accessTokenFile}' ${cfg.dataPath}/config/default.yaml
''}
${lib.optionalString (cfg.pantalaimon.passwordFile != null) ''
${pkgs.replace-secret}/bin/replace-secret '@PANTALAIMON_PASSWORD@' '${cfg.pantalaimon.passwordFile}' ${cfg.dataPath}/config/default.yaml
${lib.optionalString (cfg.passwordFile != null) ''
${pkgs.replace-secret}/bin/replace-secret '@MJOLNIR_PASSWORD@' '${cfg.passwordFile}' ${cfg.dataPath}/config/default.yaml
''}
''
);
Expand All @@ -81,6 +88,17 @@ in
default = null;
description = ''
File containing the matrix access token for the `mjolnir` user.
Required when neither encryption or pantalaimon is enabled.
'';
};
passwordFile = lib.mkOption {
type = with lib.types; nullOr path;
default = null;
description = ''
File containing the matrix password for the `mjolnir` user.
Required when encryption or pantalaimon is enabled.
'';
};

Expand All @@ -89,28 +107,22 @@ in
`pantalaimon` options (enables E2E Encryption support).
This will create a `pantalaimon` instance with the name "mjolnir".
Mutually exclusive with setting `config.services.mjolnir.encryption.enable`.
'';
default = { };
type = lib.types.submodule {
options = {
enable = lib.mkEnableOption ''
ignoring the accessToken. If true, accessToken is ignored and the username/password below will be
used instead. The access token of the bot will be stored in the dataPath
Ignoring the accessToken. If true, accessToken is ignored and username/password will be
used instead. The access token of the bot will be stored in the dataPath.
'';

username = lib.mkOption {
type = lib.types.str;
description = "The username to login with.";
};

passwordFile = lib.mkOption {
type = with lib.types; nullOr path;
default = null;
description = ''
File containing the matrix password for the `mjolnir` user.
'';
};

options = lib.mkOption {
type = lib.types.submodule (import ./pantalaimon-options.nix);
default = { };
Expand All @@ -122,6 +134,28 @@ in
};
};

encryption = lib.mkOption {
description = ''
`encryption` options (enables native E2E Encryption support without using pantalaimon as proxy).
Mutually exclusive with setting `config.services.mjolnir.pantalaimon.enable`.
'';
default = { };
type = lib.types.submodule {
options = {
enable = lib.mkEnableOption ''
Ignoring the accessToken. If true, accessToken is ignored and username/password will be
used instead. The access token of the bot will be stored in the dataPath.
'';

username = lib.mkOption {
type = lib.types.str;
description = "The username to login with.";
};
};
};
};

dataPath = lib.mkOption {
type = lib.types.path;
default = "/var/lib/mjolnir";
Expand Down Expand Up @@ -173,23 +207,23 @@ in
config = lib.mkIf config.services.mjolnir.enable {
assertions = [
{
assertion = !(cfg.pantalaimon.enable && cfg.pantalaimon.passwordFile == null);
message = "Specify pantalaimon.passwordFile";
assertion = (cfg.pantalaimon.enable || cfg.encryption.enable) -> cfg.passwordFile != null;
message = "Enabling pantalaimon or encryption requires setting config.services.mjolnir.passwordFile";
}
{
assertion = (cfg.pantalaimon.enable || cfg.encryption.enable) -> cfg.accessTokenFile == null;
message = "Do not specify accessTokenFile when enabling pantalaimon or encryption";
}
{
assertion = !(cfg.pantalaimon.enable && cfg.accessTokenFile != null);
message = "Do not specify accessTokenFile when using pantalaimon";
assertion = !(cfg.pantalaimon.enable && cfg.encryption.enable);
message = "Only one of encryption or pantalaimon may be enabled, not both";
}
{
assertion = !(!cfg.pantalaimon.enable && cfg.accessTokenFile == null);
message = "Specify accessTokenFile when not using pantalaimon";
assertion = !(cfg.pantalaimon.enable || cfg.encryption.enable) -> cfg.accessTokenFile != null;
message = "Specify accessTokenFile when not using pantalaimon or encryption";
}
];

# This defaults to true in the application,
# which breaks older configs using pantalaimon or access tokens
services.mjolnir.settings.encryption.use = lib.mkDefault false;

services.pantalaimon-headless.instances."mjolnir" = lib.mkIf cfg.pantalaimon.enable
{
homeserver = cfg.homeserverUrl;
Expand Down

0 comments on commit 06261f5

Please sign in to comment.