nixos-config/hosts/france/jabber.nix

263 lines
7.6 KiB
Nix

{ pkgs, lib, config, ... }:
with lib;
let
backplane-auth = "/etc/nixos/static/backplane-auth.scm";
host-passwd-file = "/srv/jabber/secret/hosts-passwd.scm";
service-passwd-file = "/srv/jabber/secret/services-passwd.scm";
cert-basedir = "/var/lib/ejabberd/certs";
target-certs = ["key" "cert" "chain" "fullchain"];
cert-origin = hostname: filename: "/var/lib/acme/${hostname}/${filename}.pem";
cert-target = hostname: filename: "${cert-basedir}/${hostname}-${filename}.pem";
move-server-certs = hostnames:
let
move-server-cert = hostname:
map (filename: ''
ensure_exists ${cert-origin hostname filename}
cp -L ${cert-origin hostname filename} ${cert-target hostname filename}
'')
target-certs;
in pkgs.writeShellScript "move-server-certs" ''
function ensure_exists() {
FILENAME=$1
if [ ! -e $FILENAME ]; then
echo "file does not exist: $FILENAME"
exit 1
fi
}
if [ -d ${cert-basedir} ]; then
mkdir ${cert-basedir}
fi
${concatStringsSep "\n" (concatMap move-server-cert hostnames)}
chown -R ${config.services.ejabberd.user}:${config.services.ejabberd.group} ${cert-basedir}
exit 0
'';
remove-server-certs = pkgs.writeShellScript "ejabberd-rm-combined-certs" ''
rm ${cert-basedir}/*.pem
'';
in {
config = {
security.acme.certs."fudo.im".email = "admin@fudo.org";
security.acme.certs."backplane.fudo.org".email = "admin@fudo.org";
systemd = {
services = {
ejabberd-generate-certs = {
enable = true;
description = "Generate required SSL certs for ejabberd.";
wantedBy = [ "ejabberd.service" ];
after = [
"acme-backplane.fudo.org.service"
"acme-fudo.im.service"
];
serviceConfig = {
Type = "oneshot";
ExecStart = "${move-server-certs ["fudo.im" "backplane.fudo.org"]}";
RemainAfterExit = true;
ExecStop = remove-server-certs;
StandardOutput = "journal";
};
};
ejabberd = {
requires = [ "ejabberd-generate-certs.service" ];
environment = {
FUDO_HOST_PASSWD_FILE = host-passwd-file;
FUDO_SERVICE_PASSWD_FILE = service-passwd-file;
};
};
ejabberd-hostfile-watcher = {
description = "Watch the ejabberd host file and restart if changes occur.";
serviceConfig.Type = "oneshot";
after = [ "ejabberd.service" ];
script = ''
SYSCTL=${pkgs.systemd}/bin/systemctl
if $SYSCTL is-active --quiet ejabberd.service; then
echo "restarting ejabberd.service because hostfile has changed."
$SYSCTL restart ejabberd.service
fi
'';
};
ejabberd-servicefile-watcher = {
description = "Watch the ejabberd service file and restart if changes occur.";
serviceConfig.Type = "oneshot";
after = [ "ejabberd.service" ];
script = ''
SYSCTL=${pkgs.systemd}/bin/systemctl
if $SYSCTL is-active --quiet ejabberd.service; then
echo "restarting ejabberd.service because servicefile has changed."
$SYSCTL restart ejabberd.service
fi
'';
};
};
paths = {
ejabberd-hostfile-watcher = {
pathConfig.PathChanged = host-passwd-file;
};
ejabberd-servicefile-watcher = {
pathConfig.PathChanged = service-passwd-file;
};
};
};
services = {
nginx = {
virtualHosts = {
"backplane.fudo.org" = {
enableACME = true;
};
"fudo.im" = {
enableACME = true;
};
};
};
ejabberd = {
enable = true;
configFile = pkgs.writeText "ejabberd-config.yml" (builtins.toJSON {
loglevel = 4;
access_rules = {
c2s = { allow = "all"; };
announce = { allow = "admin"; };
configure = { allow = "admin"; };
pubsub_createnode = { allow = "local"; };
};
acl = {
admin = {
user = [
"niten@fudo.org"
];
};
};
hosts = [
"fudo.im"
"backplane.fudo.org"
];
listen = [
{
port = 5222;
module = "ejabberd_c2s";
ip = "0.0.0.0";
starttls = true;
starttls_required = true;
}
];
certfiles =
concatMap (hostname: map (filename: cert-target hostname filename) target-certs)
["fudo.im" "backplane.fudo.org"];
host_config = {
"fudo.im" = {
auth_method = "ldap";
ldap_servers = ["auth.fudo.org"];
ldap_port = 389;
ldap_rootdn = "cn=jabber,dc=fudo,dc=org";
ldap_password = fileContents /srv/jabber/secret/ldap.passwd;
ldap_base = "ou=members,dc=fudo,dc=org";
ldap_filter = "(objectClass=posixAccount)";
ldap_uids = { uid = "%u"; };
modules = {
mod_adhoc = {};
mod_announce = {};
mod_avatar = {};
mod_blocking = {};
mod_caps = {};
mod_carboncopy = {};
mod_client_state = {};
mod_configure = {};
mod_disco = {};
mod_fail2ban = {};
mod_last = {};
mod_offline = {
access_max_user_messages = 5000;
};
mod_ping = {};
mod_privacy = {};
mod_private = {};
mod_pubsub = {
access_createnode = "pubsub_createnode";
ignore_pep_from_offline = true;
last_item_cache = false;
plugins = [
"flat"
"pep"
];
};
mod_roster = {};
mod_stream_mgmt = {};
mod_time = {};
mod_vcard = {
search = false;
};
mod_vcard_xupdate = {};
mod_version = {};
};
};
"backplane.fudo.org" = {
auth_method = "external";
extauth_program = "${pkgs.guile}/bin/guile -s ${backplane-auth}";
extauth_pool_size = 3;
auth_use_cache = true;
modules = {
mod_adhoc = {};
mod_caps = {};
mod_carboncopy = {};
mod_client_state = {};
mod_configure = {};
mod_disco = {};
mod_fail2ban = {};
mod_last = {};
mod_offline = {
access_max_user_messages = 5000;
};
mod_ping = {};
mod_pubsub = {
access_createnode = "pubsub_createnode";
ignore_pep_from_offline = true;
last_item_cache = false;
plugins = [
"flat"
"pep"
];
};
mod_roster = {};
mod_stream_mgmt = {};
mod_time = {};
mod_version = {};
};
};
};
});
};
};
};
}