{ config, pkgs, lib, ... }: let domain = "xmpp.tonybtw.com"; mucDomain = "conference.${domain}"; uploadDomain = "upload.${domain}"; in { services.prosody = { enable = true; package = pkgs.prosody.override { withCommunityModules = [ "cloud_notify" "bookmarks2" "smacks" ]; }; admins = ["admin@${domain}"]; ssl = { cert = "/var/lib/acme/${domain}/fullchain.pem"; key = "/var/lib/acme/${domain}/key.pem"; }; httpFileShare = { domain = uploadDomain; uploadFileSizeLimit = 100 * 1024 * 1024; uploadExpireAfter = 60 * 60 * 24 * 30; }; muc = [ { domain = mucDomain; name = "Chat Rooms"; restrictRoomCreation = false; maxHistoryMessages = 50; } ]; virtualHosts.${domain} = { enabled = true; domain = domain; ssl = { cert = "/var/lib/acme/${domain}/fullchain.pem"; key = "/var/lib/acme/${domain}/key.pem"; }; }; modules = { roster = true; saslauth = true; tls = true; dialback = true; disco = true; carbons = true; mam = true; csi = true; blocklist = true; bookmarks = true; ping = true; register = true; admin_adhoc = true; admin_telnet = true; http_files = true; }; extraConfig = '' archive_expires_after = "1y" mam_default_config = { always = true } c2s_stanza_size_limit = 256 * 1024 certificates = "/var/lib/acme" ''; }; security.acme = { acceptTerms = true; defaults.email = "tony@tonybtw.com"; certs.${domain} = { group = "certs"; webroot = "/var/lib/acme/acme-challenge"; postRun = "systemctl reload prosody.service"; extraDomainNames = [mucDomain uploadDomain]; }; }; users.groups.certs.members = ["prosody" "nginx"]; services.nginx.virtualHosts.${domain} = { locations."/.well-known/acme-challenge" = { root = "/var/lib/acme/acme-challenge"; }; }; networking.firewall.allowedTCPPorts = [ 5222 5269 5281 ]; systemd.tmpfiles.rules = [ "d /var/log/prosody 0750 prosody prosody -" ]; 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 ''; }