From c6aec96a556e56f7faf9eeb53202dd5a1a6cefc8 Mon Sep 17 00:00:00 2001 From: tv Date: Mon, 22 Aug 2022 15:11:10 +0200 Subject: tv ejabberd: drop PermissionsStartOnly directive --- tv/3modules/ejabberd/default.nix | 1 - 1 file changed, 1 deletion(-) (limited to 'tv/3modules/ejabberd/default.nix') diff --git a/tv/3modules/ejabberd/default.nix b/tv/3modules/ejabberd/default.nix index 935df9a9c..67683b186 100644 --- a/tv/3modules/ejabberd/default.nix +++ b/tv/3modules/ejabberd/default.nix @@ -86,7 +86,6 @@ in { LoadCredential = [ "certfile:${cfg.certfile}" ]; - PermissionsStartOnly = true; PrivateTmp = true; SyslogIdentifier = "ejabberd"; StateDirectory = "ejabberd"; -- cgit v1.2.3 From 876fd5404d0bc9f838119505a4b7a9b7bdb60e9e Mon Sep 17 00:00:00 2001 From: tv Date: Mon, 22 Aug 2022 14:58:40 +0200 Subject: tv ejabberd: use dynamic user --- tv/3modules/ejabberd/default.nix | 42 ++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 23 deletions(-) (limited to 'tv/3modules/ejabberd/default.nix') diff --git a/tv/3modules/ejabberd/default.nix b/tv/3modules/ejabberd/default.nix index 67683b186..147e53d61 100644 --- a/tv/3modules/ejabberd/default.nix +++ b/tv/3modules/ejabberd/default.nix @@ -33,8 +33,11 @@ in { inherit pkgs; config = cfg; })} \ - --logs ${shell.escape cfg.user.home} \ - --spool ${shell.escape cfg.user.home} \ + --ctl-config ${toFile "ejabberdctl.cfg" /* sh */ '' + ERL_OPTIONS='-setcookie ${cfg.stateDir}/.erlang.cookie' + ''} \ + --logs ${cfg.stateDir} \ + --spool ${cfg.stateDir} \ "$@" '') pkgs.ejabberd @@ -47,12 +50,10 @@ in { config.krebs.users.tv.mail ]; }; - user = mkOption { - type = types.user; - default = { - name = "ejabberd"; - home = "/var/lib/ejabberd"; - }; + stateDir = mkOption { + type = types.absolute-pathname; + default = "/var/lib/ejabberd"; + readOnly = true; }; }; config = lib.mkIf cfg.enable { @@ -61,10 +62,13 @@ in { name = "ejabberd-sudo-wrapper"; paths = [ (pkgs.writeDashBin "ejabberdctl" '' - set -efu - cd ${shell.escape cfg.user.home} - exec /run/wrappers/bin/sudo \ - -u ${shell.escape cfg.user.name} \ + exec ${pkgs.systemd}/bin/systemd-run \ + --unit=ejabberdctl \ + --property=StateDirectory=ejabberd \ + --property=User=ejabberd \ + --collect \ + --pipe \ + --quiet \ ${cfg.pkgs.ejabberd}/bin/ejabberdctl "$@" '') cfg.pkgs.ejabberd @@ -80,7 +84,7 @@ in { serviceConfig = { ExecStart = pkgs.writeDash "ejabberd" '' ${pkgs.coreutils}/bin/ln -s "$CREDENTIALS_DIRECTORY" /tmp/credentials - ${gen-dhparam} /var/lib/ejabberd/dhfile + ${gen-dhparam} ${cfg.stateDir}/dhfile exec ${cfg.pkgs.ejabberd}/bin/ejabberdctl foreground ''; LoadCredential = [ @@ -89,18 +93,10 @@ in { PrivateTmp = true; SyslogIdentifier = "ejabberd"; StateDirectory = "ejabberd"; - User = cfg.user.name; + User = "ejabberd"; + DynamicUser = true; TimeoutStartSec = 60; }; }; - - users.users.${cfg.user.name} = { - inherit (cfg.user) home name uid; - createHome = true; - group = cfg.user.name; - isSystemUser = true; - }; - - users.groups.${cfg.user.name} = {}; }; } -- cgit v1.2.3 From 3f1a9c5375cd06dea30f3deaa36cae7125fad492 Mon Sep 17 00:00:00 2001 From: tv Date: Mon, 22 Aug 2022 17:09:53 +0200 Subject: tv ejabberd: sync service with upstream template Incorporate parts from ejabberd 21.04's ejabberd.service.template --- tv/3modules/ejabberd/default.nix | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'tv/3modules/ejabberd/default.nix') diff --git a/tv/3modules/ejabberd/default.nix b/tv/3modules/ejabberd/default.nix index 147e53d61..15736e189 100644 --- a/tv/3modules/ejabberd/default.nix +++ b/tv/3modules/ejabberd/default.nix @@ -82,20 +82,32 @@ in { wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { - ExecStart = pkgs.writeDash "ejabberd" '' - ${pkgs.coreutils}/bin/ln -s "$CREDENTIALS_DIRECTORY" /tmp/credentials - ${gen-dhparam} ${cfg.stateDir}/dhfile - exec ${cfg.pkgs.ejabberd}/bin/ejabberdctl foreground - ''; + ExecStartPre = [ + "${pkgs.coreutils}/bin/ln -s \${CREDENTIALS_DIRECTORY} /tmp/credentials" + "${gen-dhparam} ${cfg.stateDir}/dhfile" + ]; + ExecStart = "${cfg.pkgs.ejabberd}/bin/ejabberdctl foreground"; + ExecStop = [ + "${cfg.pkgs.ejabberd}/bin/ejabberdctl stop" + "${cfg.pkgs.ejabberd}/bin/ejabberdctl stopped" + ]; + ExecReload = "${cfg.pkgs.ejabberd}/bin/ejabberdctl reload_config"; LoadCredential = [ "certfile:${cfg.certfile}" ]; + LimitNOFILE = 65536; + PrivateDevices = true; PrivateTmp = true; SyslogIdentifier = "ejabberd"; StateDirectory = "ejabberd"; User = "ejabberd"; DynamicUser = true; - TimeoutStartSec = 60; + TimeoutSec = 60; + RestartSec = 5; + Restart = "on-failure"; + Type = "notify"; + NotifyAccess = "all"; + WatchdogSec = 30; }; }; }; -- cgit v1.2.3 From be14863bcf1ab9207c68dd02bc4bd94708bc3467 Mon Sep 17 00:00:00 2001 From: tv Date: Wed, 31 Aug 2022 03:39:12 +0200 Subject: tv ejabberd: admit multiple certfiles --- tv/3modules/ejabberd/default.nix | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'tv/3modules/ejabberd/default.nix') diff --git a/tv/3modules/ejabberd/default.nix b/tv/3modules/ejabberd/default.nix index 15736e189..d6573ad01 100644 --- a/tv/3modules/ejabberd/default.nix +++ b/tv/3modules/ejabberd/default.nix @@ -15,9 +15,19 @@ in { options.tv.ejabberd = { enable = mkEnableOption "tv.ejabberd"; - certfile = mkOption { - type = types.absolute-pathname; - default = toString + "/ejabberd.pem"; + certfiles = mkOption { + type = types.listOf types.absolute-pathname; + default = [ + (toString + "/ejabberd.pem") + ]; + }; + credentials.certfiles = mkOption { + internal = true; + readOnly = true; + default = + imap + (i: const /* yaml */ "/tmp/credentials/certfile${toJSON i}") + cfg.certfiles; }; hosts = mkOption { type = with types; listOf str; @@ -92,9 +102,11 @@ in { "${cfg.pkgs.ejabberd}/bin/ejabberdctl stopped" ]; ExecReload = "${cfg.pkgs.ejabberd}/bin/ejabberdctl reload_config"; - LoadCredential = [ - "certfile:${cfg.certfile}" - ]; + LoadCredential = + zipListsWith + (dst: src: "${baseNameOf dst}:${src}") + cfg.credentials.certfiles + cfg.certfiles; LimitNOFILE = 65536; PrivateDevices = true; PrivateTmp = true; -- cgit v1.2.3 From 3d821647c1de932f8e527e110ae7735f59866bfd Mon Sep 17 00:00:00 2001 From: tv Date: Sat, 8 Oct 2022 22:13:23 +0200 Subject: tv ejabberd: add structural settings --- tv/3modules/ejabberd/default.nix | 158 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 151 insertions(+), 7 deletions(-) (limited to 'tv/3modules/ejabberd/default.nix') diff --git a/tv/3modules/ejabberd/default.nix b/tv/3modules/ejabberd/default.nix index d6573ad01..2966a4f60 100644 --- a/tv/3modules/ejabberd/default.nix +++ b/tv/3modules/ejabberd/default.nix @@ -12,6 +12,8 @@ fi ''; + settingsFormat = pkgs.formats.yaml {}; + in { options.tv.ejabberd = { enable = mkEnableOption "tv.ejabberd"; @@ -21,6 +23,25 @@ in { (toString + "/ejabberd.pem") ]; }; + configFile = mkOption { + type = types.either types.package types.absolute-pathname; + default = settingsFormat.generate "ejabberd.yaml" cfg.settings; + }; + ciphers = mkOption { + type = types.listOf types.str; + default = [ + "ECDHE-ECDSA-AES256-GCM-SHA384" + "ECDHE-RSA-AES256-GCM-SHA384" + "ECDHE-ECDSA-CHACHA20-POLY1305" + "ECDHE-RSA-CHACHA20-POLY1305" + "ECDHE-ECDSA-AES128-GCM-SHA256" + "ECDHE-RSA-AES128-GCM-SHA256" + "ECDHE-ECDSA-AES256-SHA384" + "ECDHE-RSA-AES256-SHA384" + "ECDHE-ECDSA-AES128-SHA256" + "ECDHE-RSA-AES128-SHA256" + ]; + }; credentials.certfiles = mkOption { internal = true; readOnly = true; @@ -39,13 +60,8 @@ in { paths = [ (pkgs.writeDashBin "ejabberdctl" '' exec ${pkgs.ejabberd}/bin/ejabberdctl \ - --config ${toFile "ejabberd.yaml" (import ./config.nix { - inherit pkgs; - config = cfg; - })} \ - --ctl-config ${toFile "ejabberdctl.cfg" /* sh */ '' - ERL_OPTIONS='-setcookie ${cfg.stateDir}/.erlang.cookie' - ''} \ + --config /etc/ejabberd/ejabberd.yaml \ + --ctl-config /etc/ejabberd/ejabberdctl.cfg \ --logs ${cfg.stateDir} \ --spool ${cfg.stateDir} \ "$@" @@ -54,12 +70,25 @@ in { ]; }; }; + protocol_options = mkOption { + type = types.listOf types.str; + default = [ + "no_sslv2" + "no_sslv3" + "no_tlsv1" + "no_tlsv1_10" + ]; + }; registration_watchers = mkOption { type = types.listOf types.str; default = [ config.krebs.users.tv.mail ]; }; + settings = mkOption { + type = settingsFormat.type; + default = {}; + }; stateDir = mkOption { type = types.absolute-pathname; default = "/var/lib/ejabberd"; @@ -67,6 +96,13 @@ in { }; }; config = lib.mkIf cfg.enable { + + environment.etc."ejabberd/ejabberd.yaml".source = cfg.configFile; + environment.etc."ejabberd/ejabberdctl.cfg".source = + builtins.toFile "ejabberdctl.cfg" /* sh */ '' + ERL_OPTIONS='-setcookie ${cfg.stateDir}/.erlang.cookie' + ''; + environment.systemPackages = [ (pkgs.symlinkJoin { name = "ejabberd-sudo-wrapper"; @@ -91,6 +127,10 @@ in { systemd.services.ejabberd = { wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; + reloadTriggers = [ + config.environment.etc."ejabberd/ejabberd.yaml".source + config.environment.etc."ejabberd/ejabberdctl.cfg".source + ]; serviceConfig = { ExecStartPre = [ "${pkgs.coreutils}/bin/ln -s \${CREDENTIALS_DIRECTORY} /tmp/credentials" @@ -122,5 +162,109 @@ in { WatchdogSec = 30; }; }; + + # preset config values + tv.ejabberd.settings = { + access_rules = { + announce = mkDefault [{ allow = "admin"; }]; + local = mkDefault [{ allow = "local"; }]; + configure = mkDefault [{ allow = "admin"; }]; + register = mkDefault ["allow"]; + s2s = mkDefault ["allow"]; + trusted_network = mkDefault [{ allow = "loopback"; }]; + }; + + acl = { + local.user_regexp = mkDefault ""; + loopback.ip = mkDefault [ + "127.0.0.0/8" + "::1/128" + "::FFFF:127.0.0.1/128" + ]; + }; + + certfiles = mkDefault cfg.credentials.certfiles; + + hosts = mkDefault cfg.hosts; + + language = mkDefault "en"; + + listen = mkDefault [ + { + port = 5222; + ip = "::"; + module = "ejabberd_c2s"; + shaper = "c2s_shaper"; + ciphers = concatStringsSep ":" cfg.ciphers; + protocol_options = cfg.protocol_options; + starttls = true; + starttls_required = true; + tls = false; + tls_compression = false; + max_stanza_size = 65536; + } + { + port = 5269; + ip = "::"; + module = "ejabberd_s2s_in"; + shaper = "s2s_shaper"; + dhfile = "${cfg.stateDir}/dhfile"; + max_stanza_size = 131072; + } + ]; + + loglevel = mkDefault "4"; + + modules = { + mod_adhoc = mkDefault {}; + mod_admin_extra = mkDefault {}; + mod_announce.access = mkDefault "announce"; + mod_caps = mkDefault {}; + mod_carboncopy = mkDefault {}; + mod_client_state = mkDefault {}; + mod_configure = mkDefault {}; + mod_disco = mkDefault {}; + mod_echo = mkDefault {}; + mod_bosh = mkDefault {}; + mod_last = mkDefault {}; + mod_offline.access_max_user_messages = mkDefault "max_user_offline_messages"; + mod_ping = mkDefault {}; + mod_privacy = mkDefault {}; + mod_private = mkDefault {}; + mod_register = { + access_from = mkDefault "deny"; + access = mkDefault "register"; + ip_access = mkDefault "trusted_network"; + registration_watchers = mkDefault cfg.registration_watchers; + }; + mod_roster = mkDefault {}; + mod_shared_roster = mkDefault {}; + mod_stats = mkDefault {}; + mod_time = mkDefault {}; + mod_vcard.search = mkDefault false; + mod_version = mkDefault {}; + mod_http_api = mkDefault {}; + }; + + s2s_access = mkDefault "s2s"; + s2s_ciphers = concatStringsSep ":" cfg.ciphers; + s2s_dhfile = mkDefault "${cfg.stateDir}/dhfile"; + s2s_protocol_options = mkDefault cfg.protocol_options; + s2s_tls_compression = mkDefault false; + s2s_use_starttls = mkDefault "required"; + + shaper_rules = { + max_user_offline_messages = mkDefault [ + { "5000" = "admin"; } + 100 + ]; + max_user_sessions = mkDefault 10; + c2s_shaper = mkDefault [ + { "none" = "admin"; } + "normal" + ]; + s2s_shaper = mkDefault "fast"; + }; + }; }; } -- cgit v1.2.3 From 1291bb433bb32e4efe320aeb8d422aefbcfbacd1 Mon Sep 17 00:00:00 2001 From: tv Date: Sat, 8 Oct 2022 23:12:57 +0200 Subject: tv ejabberd: change YAML formatting style --- tv/3modules/ejabberd/default.nix | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'tv/3modules/ejabberd/default.nix') diff --git a/tv/3modules/ejabberd/default.nix b/tv/3modules/ejabberd/default.nix index 2966a4f60..2a87b59c0 100644 --- a/tv/3modules/ejabberd/default.nix +++ b/tv/3modules/ejabberd/default.nix @@ -25,7 +25,32 @@ in { }; configFile = mkOption { type = types.either types.package types.absolute-pathname; - default = settingsFormat.generate "ejabberd.yaml" cfg.settings; + default = + (settingsFormat.generate "ejabberd.yaml" cfg.settings) + # XXX ejabberd cannot parse MQTT topic filters enclosed in single + # quotes. By changing the YAML formatting style, double quotes will + # be used instead. + # + # Related error message: + # Invalid value of option modules->mod_mqtt->access_publish: + # Malformed topic filter + # + .overrideAttrs (old: { + nativeBuildInputs = + filter + (pkg: (parseDrvName pkg.name).name != "remarshal") + old.nativeBuildInputs + ++ + singleton (pkgs.symlinkJoin { + name = "remarshal"; + paths = [ + (pkgs.writeDashBin "json2yaml" '' + exec ${pkgs.remarshal}/bin/json2yaml --yaml-style \> "$@" + '') + pkgs.remarshal + ]; + }); + }); }; ciphers = mkOption { type = types.listOf types.str; -- cgit v1.2.3 From 8d6727eaae2486e19a461b78667baa05191b6b1c Mon Sep 17 00:00:00 2001 From: tv Date: Sat, 8 Oct 2022 23:15:19 +0200 Subject: tv ejabberd: make stateDir configurable --- tv/3modules/ejabberd/default.nix | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'tv/3modules/ejabberd/default.nix') diff --git a/tv/3modules/ejabberd/default.nix b/tv/3modules/ejabberd/default.nix index 2a87b59c0..ce736f43c 100644 --- a/tv/3modules/ejabberd/default.nix +++ b/tv/3modules/ejabberd/default.nix @@ -115,9 +115,14 @@ in { default = {}; }; stateDir = mkOption { - type = types.absolute-pathname; + type = + types.addCheck + types.absolute-pathname + (path: + hasPrefix "/var/lib/" path && + types.filename.check (removePrefix "/var/lib/" path) + ); default = "/var/lib/ejabberd"; - readOnly = true; }; }; config = lib.mkIf cfg.enable { -- cgit v1.2.3 From 2dbfd35f759702b53938b5ca4f1cd9a2fb731317 Mon Sep 17 00:00:00 2001 From: tv Date: Sat, 8 Oct 2022 23:39:00 +0200 Subject: tv ejabberd: JSON > YAML --- tv/3modules/ejabberd/default.nix | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) (limited to 'tv/3modules/ejabberd/default.nix') diff --git a/tv/3modules/ejabberd/default.nix b/tv/3modules/ejabberd/default.nix index ce736f43c..edc5296b0 100644 --- a/tv/3modules/ejabberd/default.nix +++ b/tv/3modules/ejabberd/default.nix @@ -12,7 +12,7 @@ fi ''; - settingsFormat = pkgs.formats.yaml {}; + settingsFormat = pkgs.formats.json {}; in { options.tv.ejabberd = { @@ -25,32 +25,7 @@ in { }; configFile = mkOption { type = types.either types.package types.absolute-pathname; - default = - (settingsFormat.generate "ejabberd.yaml" cfg.settings) - # XXX ejabberd cannot parse MQTT topic filters enclosed in single - # quotes. By changing the YAML formatting style, double quotes will - # be used instead. - # - # Related error message: - # Invalid value of option modules->mod_mqtt->access_publish: - # Malformed topic filter - # - .overrideAttrs (old: { - nativeBuildInputs = - filter - (pkg: (parseDrvName pkg.name).name != "remarshal") - old.nativeBuildInputs - ++ - singleton (pkgs.symlinkJoin { - name = "remarshal"; - paths = [ - (pkgs.writeDashBin "json2yaml" '' - exec ${pkgs.remarshal}/bin/json2yaml --yaml-style \> "$@" - '') - pkgs.remarshal - ]; - }); - }); + default = settingsFormat.generate "ejabberd.yaml" cfg.settings; }; ciphers = mkOption { type = types.listOf types.str; @@ -72,7 +47,7 @@ in { readOnly = true; default = imap - (i: const /* yaml */ "/tmp/credentials/certfile${toJSON i}") + (i: const "/tmp/credentials/certfile${toJSON i}") cfg.certfiles; }; hosts = mkOption { -- cgit v1.2.3