tv ejabberd: add structural settings

This commit is contained in:
tv 2022-10-08 22:13:23 +02:00
parent be14863bcf
commit 3d821647c1
2 changed files with 151 additions and 135 deletions

View File

@ -1,128 +0,0 @@
with import <stockholm/lib>;
{ config, ... }: let
# See https://github.com/processone/ejabberd/blob/master/ejabberd.yml.example
ciphers = concatStringsSep ":" [
"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"
];
protocol_options = [
"no_sslv2"
"no_sslv3"
"no_tlsv1"
"no_tlsv1_10"
];
in /* yaml */ ''
access_rules:
announce:
- allow: admin
local:
- allow: local
configure:
- allow: admin
register:
- allow
s2s:
- allow
trusted_network:
- allow: loopback
acl:
local:
user_regexp: ""
loopback:
ip:
- "127.0.0.0/8"
- "::1/128"
- "::FFFF:127.0.0.1/128"
certfiles: ${toJSON config.credentials.certfiles}
hosts: ${toJSON config.hosts}
language: "en"
listen:
-
port: 5222
ip: "::"
module: ejabberd_c2s
shaper: c2s_shaper
ciphers: ${toJSON ciphers}
dhfile: ${config.stateDir}/dhfile
protocol_options: ${toJSON 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
max_stanza_size: 131072
loglevel: 4
modules:
mod_adhoc: {}
mod_admin_extra: {}
mod_announce:
access: announce
mod_caps: {}
mod_carboncopy: {}
mod_client_state: {}
mod_configure: {}
mod_disco: {}
mod_echo: {}
mod_bosh: {}
mod_last: {}
mod_offline:
access_max_user_messages: max_user_offline_messages
mod_ping: {}
mod_privacy: {}
mod_private: {}
mod_register:
access_from: deny
access: register
ip_access: trusted_network
registration_watchers: ${toJSON config.registration_watchers}
mod_roster: {}
mod_shared_roster: {}
mod_stats: {}
mod_time: {}
mod_vcard:
search: false
mod_version: {}
mod_http_api: {}
s2s_access: s2s
s2s_ciphers: ${toJSON ciphers}
s2s_dhfile: ${config.stateDir}/dhfile
s2s_protocol_options: ${toJSON protocol_options}
s2s_tls_compression: false
s2s_use_starttls: required
shaper_rules:
max_user_offline_messages:
- 5000: admin
- 100
max_user_sessions: 10
c2s_shaper:
- none: admin
- normal
s2s_shaper: fast
''

View File

@ -12,6 +12,8 @@
fi fi
''; '';
settingsFormat = pkgs.formats.yaml {};
in { in {
options.tv.ejabberd = { options.tv.ejabberd = {
enable = mkEnableOption "tv.ejabberd"; enable = mkEnableOption "tv.ejabberd";
@ -21,6 +23,25 @@ in {
(toString <secrets> + "/ejabberd.pem") (toString <secrets> + "/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 { credentials.certfiles = mkOption {
internal = true; internal = true;
readOnly = true; readOnly = true;
@ -39,13 +60,8 @@ in {
paths = [ paths = [
(pkgs.writeDashBin "ejabberdctl" '' (pkgs.writeDashBin "ejabberdctl" ''
exec ${pkgs.ejabberd}/bin/ejabberdctl \ exec ${pkgs.ejabberd}/bin/ejabberdctl \
--config ${toFile "ejabberd.yaml" (import ./config.nix { --config /etc/ejabberd/ejabberd.yaml \
inherit pkgs; --ctl-config /etc/ejabberd/ejabberdctl.cfg \
config = cfg;
})} \
--ctl-config ${toFile "ejabberdctl.cfg" /* sh */ ''
ERL_OPTIONS='-setcookie ${cfg.stateDir}/.erlang.cookie'
''} \
--logs ${cfg.stateDir} \ --logs ${cfg.stateDir} \
--spool ${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 { registration_watchers = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = [ default = [
config.krebs.users.tv.mail config.krebs.users.tv.mail
]; ];
}; };
settings = mkOption {
type = settingsFormat.type;
default = {};
};
stateDir = mkOption { stateDir = mkOption {
type = types.absolute-pathname; type = types.absolute-pathname;
default = "/var/lib/ejabberd"; default = "/var/lib/ejabberd";
@ -67,6 +96,13 @@ in {
}; };
}; };
config = lib.mkIf cfg.enable { 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 = [ environment.systemPackages = [
(pkgs.symlinkJoin { (pkgs.symlinkJoin {
name = "ejabberd-sudo-wrapper"; name = "ejabberd-sudo-wrapper";
@ -91,6 +127,10 @@ in {
systemd.services.ejabberd = { systemd.services.ejabberd = {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network.target" ]; after = [ "network.target" ];
reloadTriggers = [
config.environment.etc."ejabberd/ejabberd.yaml".source
config.environment.etc."ejabberd/ejabberdctl.cfg".source
];
serviceConfig = { serviceConfig = {
ExecStartPre = [ ExecStartPre = [
"${pkgs.coreutils}/bin/ln -s \${CREDENTIALS_DIRECTORY} /tmp/credentials" "${pkgs.coreutils}/bin/ln -s \${CREDENTIALS_DIRECTORY} /tmp/credentials"
@ -122,5 +162,109 @@ in {
WatchdogSec = 30; 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";
};
};
}; };
} }