Compare commits

..

No commits in common. "671e3db9cfb8f5d55c795fdd0226d4487c008bc0" and "333d829a6f5430335396b7a591c6621f251aec40" have entirely different histories.

4 changed files with 17 additions and 323 deletions

View File

@ -1,32 +0,0 @@
# Mautrix-Signal {#module-services-mautrix-signal}
[Mautrix-Signal](https://github.com/mautrix/signal) is a Matrix-Signal puppeting bridge.
## Configuration {#module-services-mautrix-signal-configuration}
1. Set [](#opt-services.mautrix-signal.enable) to `true`. The service will use
SQLite by default.
2. To create your configuration check the default configuration for
[](#opt-services.mautrix-signal.settings). To obtain the complete default
configuration, run
`nix-shell -p mautrix-signal --run "mautrix-signal -c default.yaml -e"`.
::: {.warning}
Mautrix-Signal allows for some options like `encryption.pickle_key`,
`provisioning.shared_secret`, allow the value `generate` to be set.
Since the configuration file is regenerated on every start of the
service, the generated values would be discarded and might break your
installation. Instead, set those values via
[](#opt-services.mautrix-signal.environmentFile).
:::
## Migrating from an older configuration {#module-services-mautrix-signal-migrate-configuration}
With Mautrix-Signal v0.7.0 the configuration has been rearranged. Mautrix-Signal
performs an automatic configuration migration so your pre-0.7.0 configuration
should just continue to work.
In case you want to update your NixOS configuration, compare the migrated configuration
at `/var/lib/mautrix-signal/config.yaml` with the default configuration
(`nix-shell -p mautrix-signal --run "mautrix-signal -c example.yaml -e"`) and
update your module configuration accordingly.

View File

@ -1,280 +0,0 @@
{
lib,
config,
pkgs,
...
}:
let
cfg = config.services.kabbone_mautrix-whatsapp;
dataDir = "/var/lib/mautrix-whatsapp";
registrationFile = "${dataDir}/whatsapp-registration.yaml";
settingsFile = "${dataDir}/config.yaml";
settingsFileUnsubstituted = settingsFormat.generate "mautrix-whatsapp-config-unsubstituted.json" cfg.settings;
settingsFormat = pkgs.formats.json { };
appservicePort = 29318;
# to be used with a list of lib.mkIf values
optOneOf = lib.lists.findFirst (value: value.condition) (lib.mkIf false null);
mkDefaults = lib.mapAttrsRecursive (n: v: lib.mkDefault v);
defaultConfig = {
network = {
displayname_template = "{{or .BusinessName .PushName .Phone}} (WA)";
identity_change_notices = true;
history_sync = {
request_full_sync = true;
};
};
bridge = {
command_prefix = "!wa";
relay.enabled = true;
permissions."*" = "relay";
};
database = {
type = "sqlite3";
uri = "file:${dataDir}/mautrix-whatsapp.db?_txlock=immediate";
};
homeserver.address = "http://localhost:8448";
appservice = {
hostname = "[::]";
port = appservicePort;
id = "whatsapp";
bot = {
username = "whatsappbot";
displayname = "WhatsApp Bridge Bot";
};
as_token = "";
hs_token = "";
username_template = "whatsapp_{{.}}";
};
double_puppet = {
servers = { };
secrets = { };
};
# By default, the following keys/secrets are set to `generate`. This would break when the service
# is restarted, since the previously generated configuration will be overwritten everytime.
# If encryption is enabled, it's recommended to set those keys via `environmentFile`.
encryption.pickle_key = "";
provisioning.shared_secret = "";
public_media.signing_key = "";
direct_media.server_key = "";
logging = {
min_level = "info";
writers = lib.singleton {
type = "stdout";
format = "pretty-colored";
time_format = " ";
};
};
};
in
{
options.services.kabbone_mautrix-whatsapp = {
enable = lib.mkEnableOption "mautrix-whatsapp, a Matrix-Whatsapp puppeting bridge";
package = lib.mkPackageOption pkgs "mautrix-whatsapp" { };
settings = lib.mkOption {
apply = lib.recursiveUpdate defaultConfig;
type = settingsFormat.type;
default = defaultConfig;
description = ''
{file}`config.yaml` configuration as a Nix attribute set.
Configuration options should match those described in the example configuration.
Get an example configuration by executing `mautrix-whatsapp -c example.yaml --generate-example-config`
Secret tokens should be specified using {option}`environmentFile`
instead of this world-readable attribute set.
'';
example = {
bridge = {
private_chat_portal_meta = true;
mute_only_on_create = false;
permissions = {
"example.com" = "user";
};
};
database = {
type = "postgres";
uri = "postgresql:///mautrix_whatsapp?host=/run/postgresql";
};
homeserver = {
address = "http://[::1]:8008";
domain = "my-domain.tld";
};
appservice = {
id = "whatsapp";
ephemeral_events = false;
};
matrix.message_status_events = true;
provisioning = {
shared_secret = "disable";
};
backfill.enabled = true;
encryption = {
allow = true;
default = true;
require = true;
pickle_key = "$ENCRYPTION_PICKLE_KEY";
};
};
};
environmentFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = ''
File containing environment variables to be passed to the mautrix-signal service.
If an environment variable `MAUTRIX_WHATSAPP_BRIDGE_LOGIN_SHARED_SECRET` is set,
then its value will be used in the configuration file for the option
`double_puppet.secrets` without leaking it to the store, using the configured
`homeserver.domain` as key.
'';
};
serviceDependencies = lib.mkOption {
type = with lib.types; listOf str;
default =
(lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit)
++ (lib.optional config.services.matrix-conduit.enable "conduit.service");
defaultText = lib.literalExpression ''
(optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit)
++ (optional config.services.matrix-conduit.enable "conduit.service")
'';
description = ''
List of systemd units to require and wait for when starting the application service.
'';
};
registerToSynapse = lib.mkOption {
type = lib.types.bool;
default = config.services.matrix-synapse.enable;
defaultText = lib.literalExpression ''
config.services.matrix-synapse.enable
'';
description = ''
Whether to add the bridge's app service registration file to
`services.matrix-synapse.settings.app_service_config_files`.
'';
};
};
config = lib.mkIf cfg.enable {
users.users.mautrix-whatsapp = {
isSystemUser = true;
group = "mautrix-whatsapp";
home = dataDir;
description = "Mautrix-Whatsapp bridge user";
};
users.groups.mautrix-whatsapp = { };
services.matrix-synapse = lib.mkIf cfg.registerToSynapse {
settings.app_service_config_files = [ registrationFile ];
};
systemd.services.matrix-synapse = lib.mkIf cfg.registerToSynapse {
serviceConfig.SupplementaryGroups = [ "mautrix-whatsapp" ];
};
# Note: this is defined here to avoid the docs depending on `config`
services.kabbone_mautrix-whatsapp.settings.homeserver = optOneOf (
with config.services;
[
(lib.mkIf matrix-synapse.enable (mkDefaults {
domain = matrix-synapse.settings.server_name;
}))
(lib.mkIf matrix-conduit.enable (mkDefaults {
domain = matrix-conduit.settings.global.server_name;
address = "http://localhost:${toString matrix-conduit.settings.global.port}";
}))
]
);
systemd.services.kabbone_mautrix-whatsapp = {
description = "mautrix-whatsapp, a Matrix-Whatsapp puppeting bridge.";
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ] ++ cfg.serviceDependencies;
after = [ "network-online.target" ] ++ cfg.serviceDependencies;
# ffmpeg is required for conversion of voice messages
path = [ pkgs.ffmpeg-headless ];
preStart = ''
# substitute the settings file by environment variables
# in this case read from EnvironmentFile
test -f '${settingsFile}' && rm -f '${settingsFile}'
old_umask=$(umask)
umask 0177
${pkgs.envsubst}/bin/envsubst \
-o '${settingsFile}' \
-i '${settingsFileUnsubstituted}'
umask $old_umask
# generate the appservice's registration file if absent
if [ ! -f '${registrationFile}' ]; then
${cfg.package}/bin/mautrix-whatsapp \
--generate-registration \
--config='${settingsFile}' \
--registration='${registrationFile}'
fi
chmod 640 ${registrationFile}
umask 0177
# 1. Overwrite registration tokens in config
# 2. If environment variable MAUTRIX_SIGNAL_BRIDGE_LOGIN_SHARED_SECRET
# is set, set it as the login shared secret value for the configured
# homeserver domain.
${pkgs.yq}/bin/yq -s '.[0].appservice.as_token = .[1].as_token
| .[0].appservice.hs_token = .[1].hs_token
| .[0]
| if env.MAUTRIX_WHATSAPP_BRIDGE_LOGIN_SHARED_SECRET then .double_puppet.secrets.[.homeserver.domain] = env.MAUTRIX_WHATSAPP_BRIDGE_LOGIN_SHARED_SECRET else . end' \
'${settingsFile}' '${registrationFile}' > '${settingsFile}.tmp'
mv '${settingsFile}.tmp' '${settingsFile}'
umask $old_umask
'';
serviceConfig = {
User = "mautrix-whatsapp";
Group = "mautrix-whatsapp";
EnvironmentFile = cfg.environmentFile;
StateDirectory = baseNameOf dataDir;
WorkingDirectory = dataDir;
ExecStart = ''
${cfg.package}/bin/mautrix-whatsapp \
--config='${settingsFile}' \
--registration='${registrationFile}'
'';
LockPersonality = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectSystem = "strict";
Restart = "on-failure";
RestartSec = "30s";
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallErrorNumber = "EPERM";
SystemCallFilter = [ "@system-service" ];
Type = "simple";
UMask = 27;
};
restartTriggers = [ settingsFileUnsubstituted ];
};
};
meta = {
buildDocsInSandbox = false;
doc = ./mautrix-whatsapp.md;
maintainers = with lib.maintainers; [
kabbone
];
};
}

View File

@ -54,8 +54,6 @@ in {
};
};
imports = [ ../../kabbone/mautrix-whatsapp.nix ];
services.matrix-synapse = {
enable = true;
settings = {
@ -191,7 +189,7 @@ in {
};
};
};
kabbone_mautrix-whatsapp = {
mautrix-whatsapp = {
enable = true;
registerToSynapse = true;
environmentFile = config.age.secrets."services/matrix/mautrix-whatsapp.env".path;
@ -205,10 +203,10 @@ in {
id = "whatsapp";
as_token = "$MAUTRIX_WHATSAPP_AS_TOKEN";
hs_token = "$MAUTRIX_WHATSAPP_HS_TOKEN";
};
database = {
type = "postgres";
uri = "$MAUTRIX_WHATSAPP_APPSERVICE_DATABASE";
database = {
type = "postgres";
uri = "$MAUTRIX_WHATSAPP_APPSERVICE_DATABASE";
};
};
encryption = {
allow = true;
@ -219,10 +217,18 @@ in {
};
pickle_key = "$MAUTRIX_WHATSAPP_ENCRYPTION_PICKLE_KEY";
};
network = {
history_sync.request_full_sync = true;
};
bridge = {
history_sync.request_full_sync = true;
encryption = {
allow = true;
default = true;
verification_levels = {
receive = "cross-signed-untrusted";
send = "cross-signed-untrusted";
};
pickle_key = "$MAUTRIX_WHATSAPP_ENCRYPTION_PICKLE_KEY";
};
private_chat_portal_meta = true;
permissions = {
"@kabbone:kabtop.de" = "admin";
};

View File

@ -5,7 +5,7 @@
{ config, lib, pkgs, ... }:
{
# imports = [ ./postgresql_upgrade.nix ];
imports = [ ./postgresql_upgrade.nix ];
services.postgresql = {
enable = true;
package = pkgs.postgresql_16;