# xmpp-home.nix - XMPP server for home hosting # # Differences from VPS version: # - Uses chat.tonybtw.com (your actual domain) # - Cloudflare DNS challenge for SSL (works behind NAT) # - Less strict resource limits # - Assumes you're on a residential connection # { config, pkgs, lib, ... }: let domain = "chat.tonybtw.com"; mucDomain = "conference.chat.tonybtw.com"; uploadDomain = "upload.chat.tonybtw.com"; in { services.prosody = { enable = true; # Package with community modules package = pkgs.prosody.override { withCommunityModules = [ "http_upload" "cloud_notify" "bookmarks2" "smacks" ]; }; # Admin accounts (create these after deployment) admins = [ "tony@${domain}" ]; # CHANGE THIS to your username # SSL certificates (managed by ACME in home-server-base.nix) ssl = { cert = "/var/lib/acme/${domain}/fullchain.pem"; key = "/var/lib/acme/${domain}/key.pem"; }; # File uploads (100MB limit) uploadHttp = { domain = uploadDomain; uploadFileSizeLimit = "100 * 1024 * 1024"; uploadExpireAfter = "60 * 60 * 24 * 30"; # 30 days }; # Multi-User Chat (group chat rooms) muc = [ { domain = mucDomain; name = "Tony's Chat Rooms"; restrictRoomCreation = false; # Anyone can create rooms maxHistoryMessages = 50; } ]; # Main XMPP domain virtualHosts.${domain} = { enabled = true; domain = domain; ssl = { cert = "/var/lib/acme/${domain}/fullchain.pem"; key = "/var/lib/acme/${domain}/key.pem"; }; }; # Modern XMPP features modules = { # Core roster = true; saslauth = true; tls = true; dialback = true; disco = true; # Modern messaging carbons = true; mam = true; smacks = true; csi = true; cloud_notify = true; # Privacy blocklist = true; bookmarks = true; bookmarks2 = true; # Convenience ping = true; register = false; # Manual account creation only admin_adhoc = true; admin_telnet = true; # HTTP http_files = true; http_upload = true; # MUC muc_mam = true; }; extraConfig = '' -- Logging log = { info = "/var/log/prosody/prosody.log"; error = "/var/log/prosody/prosody.err"; "*syslog"; } -- Message history (keep for 1 year) archive_expires_after = "1y" mam_default_config = { always = true } -- Connection settings c2s_stanza_size_limit = 256 * 1024 -- 256KB -- TLS settings ssl = { protocol = "tlsv1_2+"; ciphers = "HIGH+kEDH:HIGH+kEECDH:HIGH:!PSK:!SRP:!3DES:!aNULL"; options = { "no_sslv2", "no_sslv3", "no_ticket", "no_compression", "cipher_server_preference", "single_dh_use", "single_ecdh_use" }; } -- OMEMO encryption support modules_enabled = { "omemo_all_access" } -- Disable federation if you only want private server (optional) -- Uncomment to prevent federation with other XMPP servers: -- modules_disabled = { "s2s" } ''; }; # Create log directory systemd.tmpfiles.rules = [ "d /var/log/prosody 0750 prosody prosody -" ]; # Optional: Nginx reverse proxy for XMPP web client (if you want one later) # services.nginx.virtualHosts."${domain}" = { # enableACME = true; # forceSSL = true; # locations."/" = { # # Could serve a web client like Converse.js here # root = "/var/www/xmpp"; # }; # }; }