# xmpp.nix - Prosody XMPP server configuration # A modern, privacy-focused alternative to Discord # # Usage: # 1. Import this module in your configuration.nix # 2. Update "yourdomain.com" to your actual domain # 3. nixos-rebuild switch # 4. Create user accounts: prosodyctl adduser user@yourdomain.com # { config, pkgs, lib, ... }: let domain = "yourdomain.com"; # CHANGE THIS to your domain mucDomain = "conference.${domain}"; uploadDomain = "upload.${domain}"; in { services.prosody = { enable = true; # Package with community modules for modern XMPP features package = pkgs.prosody.override { withCommunityModules = [ "http_upload" "cloud_notify" "bookmarks2" "smacks" ]; }; # Admin users (can create/delete rooms, manage users, see server stats) # Add accounts here AFTER you create them with prosodyctl admins = [ "admin@${domain}" ]; # SSL/TLS certificates (Let's Encrypt) ssl = { cert = "/var/lib/acme/${domain}/fullchain.pem"; key = "/var/lib/acme/${domain}/key.pem"; }; # File uploads (for images, documents, etc.) # Users can share files up to 100MB uploadHttp = { domain = uploadDomain; uploadFileSizeLimit = "100 * 1024 * 1024"; # 100MB uploadExpireAfter = "60 * 60 * 24 * 30"; # 30 days }; # Group chat (Multi-User Chat / MUC) # This is where your channels/rooms live muc = [ { domain = mucDomain; name = "Chat Rooms"; restrictRoomCreation = false; # Anyone can create rooms maxHistoryMessages = 50; # Room history sent to new joiners } ]; # Your main XMPP domain virtualHosts.${domain} = { enabled = true; domain = domain; ssl = { cert = "/var/lib/acme/${domain}/fullchain.pem"; key = "/var/lib/acme/${domain}/key.pem"; }; }; # Enable modern XMPP features modules = { # Core features roster = true; # Contact lists saslauth = true; # Authentication tls = true; # Encryption in transit dialback = true; # Server-to-server auth disco = true; # Service discovery # Modern messaging features carbons = true; # Sync messages across devices mam = true; # Message history (Message Archive Management) smacks = true; # Stream management (better mobile connections) csi = true; # Client state indication (battery saving) cloud_notify = true; # Push notifications # Privacy and security blocklist = true; # Block unwanted users bookmarks = true; # Save favorite rooms bookmarks2 = true; # Modern bookmarks (XEP-0402) # Convenience ping = true; # Keep-alive register = false; # Disable public registration (you create accounts manually) admin_adhoc = true; # Admin commands via client admin_telnet = true; # Admin console (telnet to localhost:5582) # HTTP http_files = true; # Serve files over HTTP http_upload = true; # File upload support # Room features muc_mam = true; # Message history in group chats }; # Extra configuration (Lua) extraConfig = '' -- Logging log = { info = "/var/log/prosody/prosody.log"; error = "/var/log/prosody/prosody.err"; "*syslog"; } -- Message Archive Management (history) settings archive_expires_after = "1y" -- Keep messages for 1 year mam_default_config = { always = true } -- Enable history by default -- Connection limits c2s_stanza_size_limit = 256 * 1024 -- 256KB (for file upload stanzas) -- TLS/SSL 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" }; } -- Certificates for additional domains certificates = "/var/lib/acme" -- Enable OMEMO encryption support modules_enabled = { "omemo_all_access" } ''; }; # Let's Encrypt for SSL certificates security.acme = { acceptTerms = true; defaults.email = "admin@${domain}"; # CHANGE THIS to your email certs.${domain} = { group = "prosody"; # Reload Prosody after certificate renewal postRun = "systemctl reload prosody.service"; # Extra domain names (for MUC and uploads) extraDomainNames = [ mucDomain uploadDomain ]; }; }; # Open firewall ports networking.firewall.allowedTCPPorts = [ 5222 # Client-to-server (C2S) - your friends connect here 5269 # Server-to-server (S2S) - federation with other XMPP servers (optional) 5281 # HTTPS for file uploads and admin interface ]; # Create log directory systemd.tmpfiles.rules = [ "d /var/log/prosody 0750 prosody prosody -" ]; # Optional: Firewall rules to rate-limit connection attempts # Uncomment to prevent brute-force attacks # networking.firewall.extraCommands = '' # iptables -A INPUT -p tcp --dport 5222 -m state --state NEW -m recent --set # iptables -A INPUT -p tcp --dport 5222 -m state --state NEW -m recent --update --seconds 60 --hitcount 10 -j DROP # ''; }