diff --git a/config/client.nix b/config/backplane-client.nix
similarity index 73%
rename from config/client.nix
rename to config/backplane-client.nix
index 2635fd8..e36cfb4 100644
--- a/config/client.nix
+++ b/config/backplane-client.nix
@@ -2,12 +2,12 @@
 
 with lib;
 let
-  make-passwd-file = hostname:
-    pkgs.lib.passwd.stablerandom-passwd-file
-      "${hostname}-fudo-client-passwd"
-      config.instance.build-seed;
+  make-passwd-file = hostname: let
+    name = "backplane-host-${hostname}-client-passwd";
+    seed = "${name}-${config.instance.build-seed}";
+  in pkgs.lib.passwd.stablerandom-passwd-file name seed;
 
-  secrets =
+  host-secrets =
     config.fudo.secrets.host-secrets.${config.instance.hostname};
 
   host-password-files = mapAttrs (hostname: hostOpts:
@@ -26,7 +26,7 @@ in {
 
       client.dns = {
         password-file =
-          secrets.backplane-client-passwd.target-file;
+          host-secrets.backplane-client-passwd.target-file;
       };
 
       backplane.client-hosts = mapAttrs (hostname: hostOpts: {
diff --git a/config/default.nix b/config/default.nix
index a98edb6..20cbb16 100644
--- a/config/default.nix
+++ b/config/default.nix
@@ -3,15 +3,18 @@
 {
         imports = [
                 ./aliases.nix
+                ./backplane-client.nix
                 ./bash.nix
-                ./client.nix
                 ./common.nix
                 ./dns.nix
                 ./groups.nix
                 ./instance.nix
                 ./kerberos.nix
+                ./system-users.nix
                 ./users.nix
                 ./user-config.nix
                 ./wireless-networks.nix
+
+                ./service/jabber.nix
         ];
 }
diff --git a/config/host-config/legatus.nix b/config/host-config/legatus.nix
index 50f29a5..6a41927 100644
--- a/config/host-config/legatus.nix
+++ b/config/host-config/legatus.nix
@@ -29,6 +29,8 @@ in {
     }];
   };
 
+  security.acme.email = "admin@legatus.fudo.org";
+
   systemd.tmpfiles.rules = [
     "L /etc/adjtime - - - - /state/etc/adjtime"
   ];
@@ -57,6 +59,14 @@ in {
 
   fudo =  {
     hosts.legatus.external-interfaces = [ "extif0" ];
+
+    services.jabber = {
+      enable = true;
+      hostname = "jabber.test.fudo.org";
+      ldap.servers = [ "nutboy3.fudo.org" ];
+      state-directory = "/state/ejabberd";
+    };
+
     secrets.host-secrets.legatus = let
       files = config.fudo.secrets.files;
     in {
@@ -72,17 +82,17 @@ in {
       #   user = config.fudo.git.user;
       # };
 
-      heimdal-master-key = {
-        source-file = files.realm-master-keys."FUDO.ORG";
-        target-file = "/run/heimdal/master-key";
-        user = config.fudo.auth.kdc.user;
-      };
+      # heimdal-master-key = {
+      #   source-file = files.realm-master-keys."FUDO.ORG";
+      #   target-file = "/run/heimdal/master-key";
+      #   user = config.fudo.auth.kdc.user;
+      # };
 
-      ipropd-keytab = {
-        source-file = files.service-keytabs.legatus.ipropd;
-        target-file = "/run/heimdal/ipropd.keytab";
-        user = config.fudo.auth.kdc.user;
-      };
+      # ipropd-keytab = {
+      #   source-file = files.service-keytabs.legatus.ipropd;
+      #   target-file = "/run/heimdal/ipropd.keytab";
+      #   user = config.fudo.auth.kdc.user;
+      # };
     };
 
     client.dns = {
@@ -92,18 +102,18 @@ in {
       external-interface = "extif0";
     };
 
-    auth.kdc = {
-      enable = true;
-      realm = "FUDO.ORG";
-      bind-addresses = [ host-ipv4 "127.0.0.1" ];
-      master-key-file =
-        secrets.heimdal-master-key.target-file;
-      state-directory = "/state/kerberos";
-      slave-config = {
-       master-host = "france";
-        ipropd-keytab = secrets.ipropd-keytab.target-file;
-      };
-    };
+    # auth.kdc = {
+    #   enable = true;
+    #   realm = "FUDO.ORG";
+    #   bind-addresses = [ host-ipv4 "127.0.0.1" ];
+    #   master-key-file =
+    #     secrets.heimdal-master-key.target-file;
+    #   state-directory = "/state/kerberos";
+    #   slave-config = {
+    #    master-host = "france";
+    #     ipropd-keytab = secrets.ipropd-keytab.target-file;
+    #   };
+    # };
 
     secure-dns-proxy = {
       enable = true;
diff --git a/config/host-config/zbox.nix b/config/host-config/zbox.nix
index bfda7ac..de99ccd 100644
--- a/config/host-config/zbox.nix
+++ b/config/host-config/zbox.nix
@@ -18,5 +18,8 @@
         fcitx5-rime
       ];
     };
+
+    hardware.bluetooth.enable = true;
+    hardware.xpadneo.enable = true;
   };
 }
diff --git a/config/service/jabber.nix b/config/service/jabber.nix
new file mode 100644
index 0000000..619d66e
--- /dev/null
+++ b/config/service/jabber.nix
@@ -0,0 +1,125 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  cfg = config.fudo.services.jabber;
+  hostname = config.instance.hostname;
+  host-secrets = config.fudo.secrets.host-secrets.${hostname};
+
+in {
+  options.fudo.services.jabber = with types; {
+    enable = mkEnableOption "Enable Jabber server on this host.";
+
+    user = mkOption {
+      type = str;
+      description = "User as which to run the ejabberd server.";
+      default = "ejabberd";
+    };
+
+    group = mkOption {
+      type = str;
+      description = "Group as which to run the ejabberd server.";
+      default = "ejabberd";
+    };
+
+    hostname = mkOption {
+      type = str;
+      description = "Hostname of the user jabber server.";
+      default = "jabber.fudo.org";
+    };
+
+    ldap = {
+      user = mkOption {
+        type = str;
+        description = "System user as which to connect to the LDAP server to authenticate users.";
+        default = "ejabberd-auth";
+      };
+
+      servers = mkOption {
+        type = listOf str;
+        description = "List of LDAP servers to use while authenticating users.";
+      };
+    };
+
+    state-directory = mkOption {
+      type = str;
+      description = "Directory at which to store Jabber state. Should be persistent.";
+      default = "/var/lib/ejabberd";
+    };
+  };
+
+  config.fudo = let
+    ejabberd-ldap-auth-passwd-file =
+      pkgs.lib.passwd.stablerandom-passwd-file "ejabberd-auth-passwd-file"
+        "ejabberd-auth-passwd-file-${config.instance.build-seed}";
+  in {
+    system-users.${cfg.ldap.user} = {
+      description = "ejabberd authentication user.";
+      ldap-hashed-password =
+        pkgs.lib.passwd.hash-ldap-passwd "ejabberd-ldap-auth-passwd"
+          ejabberd-ldap-auth-passwd-file;
+    };
+
+    jabber = mkIf cfg.enable {
+      enable = true;
+
+      state-directory = cfg.state-directory;
+
+      secret-files = {
+        "__LDAP_PASSWORD__" = ejabberd-ldap-auth-passwd-file;
+      };
+
+      sites = {
+        ${cfg.hostname} = {
+          site-config = {
+            auth_method = "ldap";
+            ldap_servers = cfg.ldap.servers;
+            ldap_port = 636;
+            ldap_rootdn = "cn=${cfg.ldap.user},dc=fudo,dc=org";
+            ldap_password = "__LDAP_PASSWORD__";
+            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 = {};
+            };
+          };
+        };
+      };
+    };
+  };
+}
diff --git a/config/system-users.nix b/config/system-users.nix
index 6e22c51..d115323 100644
--- a/config/system-users.nix
+++ b/config/system-users.nix
@@ -1,17 +1,15 @@
+{ config, lib, pkgs, ... }:
 
 {
-  replicator = {
-    description = "Database Replicator";
-    hashed-password = "{SHA}HpiRMyxLR+0ZFHz/COvG9lcNYyQ=";
-  };
+  config.fudo.system-users = {
+    auth_reader = {
+      description = "System Authenticator";
+      ldap-hashed-password = "{SSHA}J4Ihsi1apl3B2kSka8KGDz0tPhO1ipTz";
+    };
 
-  auth_reader = {
-    description = "System Authenticator";
-    hashed-password = "{MD5}N36/kQ64mev1HARddvVk7Q==";
-  };
-
-  user_db_reader = {
-    description = "User Database Reader";
-    hashed-password = "{SSHA}IVKhrB+wMOCI/CCzbJW8sNDbH67ZTMBv";
+    user_db_reader = {
+      description = "User Database Reader";
+      ldap-hashed-password = "{SSHA}IVKhrB+wMOCI/CCzbJW8sNDbH67ZTMBv";
+    };
   };
 }
diff --git a/flake.nix b/flake.nix
index 3febfe9..2183d14 100644
--- a/flake.nix
+++ b/flake.nix
@@ -16,7 +16,8 @@
     };
 
     fudo-lib = {
-      url = "git+https://git.fudo.org/fudo-nix/lib.git";
+      #url = "git+https://git.fudo.org/fudo-nix/lib.git";
+      url = "path:/state/fudo-lib";
       inputs.nixpkgs.follows = "nixpkgs";
     };