{ zentralwerk, config, hostRegistry, pkgs, lib, ... }: let domain = "jabber.c3d2.de"; in { c3d2 = { deployment.server = "server10"; hq.statistics.enable = true; }; microvm.mem = 2048; networking = { hostName = "jabber"; firewall = { allowedTCPPorts = [ # Prosody 80 443 5222 5223 5269 5270 5280 5281 # Coturn 3478 3479 ]; allowedUDPPorts = [ # Coturn 3478 3479 ]; # TODO: allowedSCTPPorts }; }; security = { acme.certs."${domain}" = { extraDomainNames = [ "chat.c3d2.de" "*.${domain}" ]; # DynDNS method dnsProvider = "rfc2136"; credentialsFile = config.sops.secrets."acme/credentials-file".path; reloadServices = [ "prosody" ]; # Make keys accessible by putting them in prosody's group inherit (config.services.prosody) group; }; dhparams = { enable = true; params.prosody = { }; }; }; services = { backup = { enable = true; paths = [ "/var/lib/prosody/" ]; }; collectd.plugins.exec = '' Exec "${config.services.collectd.user}" "${lib.getExe pkgs.ruby}" "${./prosody-stats.rb}" ''; coturn = { enable = true; realm = "turn.${domain}"; static-auth-secret-file = config.sops.secrets."coturn/static-auth-secret".path; use-auth-secret = true; extraConfig = '' external-ip=${zentralwerk.lib.dns.publicIPv4}/${zentralwerk.lib.config.site.net.serv.hosts4.jabber} # secure-stun # not supported by jabber # no old shit no-tlsv1 no-tlsv1_1 # strongly encouraged options to decrease amplification attacks no-rfc5780 no-stun-backward-compatibility response-origin-only-with-rfc5780 ''; }; postgresql = { enable = true; ensureDatabases = [ "prosody" ]; ensureUsers = [{ name = "prosody"; ensurePermissions = { "DATABASE prosody" = "ALL PRIVILEGES"; }; }]; package = pkgs.postgresql_16; upgrade.stopServices = [ "prosody" ]; }; #TODO: txt records? prosody = { enable = true; allowRegistration = false; admins = [ "astro@spaceboyz.net" "0@jabber.c3d2.de" "nek0@jabber.c3d2.de" "sandro@jabber.c3d2.de" ]; package = pkgs.prosody.override { withCommunityModules = [ "cloud_notify" "cloud_notify_extensions" "firewall" "presence_cache" ]; withExtraLuaPackages = luaPackages: with luaPackages; [ luadbi-postgresql luaossl # required by cloud_notify_extensions ]; }; modules = { # HTTP stuff bosh = true; http_altconnect = true; http_files = true; websocket = true; admin_telnet = true; announce = true; carbons = true; csi_simple = true; mam = true; # File-transfer proxies are an outdated technology proxy65 = false; server_contact_info = true; smacks = true; s2s_bidi = true; turn_external = true; }; ssl = { key = "/var/lib/acme/${domain}/key.pem"; cert = "/var/lib/acme/${domain}/fullchain.pem"; extraOptions = { dhparam = config.security.dhparams.params.nginx.path; }; }; # encryption is a must c2sRequireEncryption = true; s2sRequireEncryption = true; s2sSecureAuth = true; virtualHosts = { "${domain}" = { enabled = true; inherit domain; }; "anon.${domain}" = { enabled = true; domain = "anon.${domain}"; extraConfig = '' authentication = "anonymous" ''; }; }; muc = [{ domain = "chat.c3d2.de"; maxHistoryMessages = 100; name = "Group chats"; }]; httpPorts = [ 80 5280 ]; httpsPorts = [ 443 5281 ]; uploadHttp = { domain = "upload.${domain}"; uploadFileSizeLimit = "10 * 1024 * 1024"; userQuota = 512 * 1024 * 1024; uploadExpireAfter = "2 * 60 * 60"; }; extraConfig = let prosodyFirewall = pkgs.writeText "antispam.pfw" '' %ZONE spam: creep.im, default.rs, sj.ms, anonym.im, xmpp.jp, safetyjabber.com, im.hot-chilli.net, jabb3r.org, draugr.de, laba.im, xmpp.sh, jabber.bitactive.com, 404.city, jabber.cd, jabber.jc-otto.de, jabster.pl, jabber.no, anoxinon.me, ubuntu-jabber.net, anonarchy.im, jabber.freenet.de, exploit.im, 616.pub, omemo.im, rsocks.net, chatwith.xyz, jabber.cz, jabbim.cz, blabber.im, jabber.root.cz, jabb.im, jabber.infos.ru, jabbim.pl, jabbim.com, linuxlovers.at, jabbim.ru, jabber.sk, njs.netlab.cz, jabba.biz, chatterboxtown.us, crime.io, 0nl1ne.at, verdammung.org, im.apinc.org, 0day.la, 0day.im, xabber.de, conversations.im, jabber.de, chinwag.im, thesecure.biz, shad0w.ru, yourdata.forsale, linux.monster, xmpp.international, paranoid.network, og.im, 4ept.net, darknet.im, ubuntu-jabber.de, nixnet.services, marxist.club, dw.live, 01337.io, sqli.io, breached.im, pwned.life, jabber.fr, chatterboxtown.us, xmpp.xxx, ybgood.de, ejabber.co, jabbers.one IN ROSTER? PASS. LEAVING: spam BOUNCE=policy-violation (Your domain has been blacklisted due to spam.) ''; in /* lua */ '' c2s_direct_tls_ports = { 5223 } c2s_direct_tls_ssl = { key = "/var/lib/acme/${domain}/key.pem", certificate = "/var/lib/acme/${domain}/fullchain.pem", } s2s_direct_tls_ports = { 5270 } certificates = "/var/lib/acme" contact_info = { abuse = { "mailto:mail@c3d2.de" }; admin = { "mailto:mail@c3d2.de" }; feedback = { "mailto:mail@c3d2.de" }; -- sales = { "mailto:mail@c3d2.de" }; -- we don't sell anything ;) security = { "mailto:mail@c3d2.de" }; support = { "mailto:mail@c3d2.de" }; } storage = "sql" sql = { driver = "PostgreSQL", database = "prosody", username = "prosody", password = "" } log = { info = "*syslog"; } firewall_scripts = { "${prosodyFirewall}" } -- How to get the IPv6 from config? external_addresses = { "${zentralwerk.lib.dns.publicIPv4}", "2a00:8180:2c00:282:e058:3ff:fea2:d83a", "${hostRegistry.jabber.ip4}", "${hostRegistry.jabber.ip6}" } trusted_proxies = { "127.0.0.1", "::1", "${hostRegistry.public-access-proxy.ip4}", "${hostRegistry.public-access-proxy.ip6}" } http_cors_override = { bosh = { enabled = true; }; websocket = { enabled = true; }; } http_default_host = "${domain}" http_host = "${domain}" http_external_url = "https://${domain}/" http_upload_file_size_limit = 10 * 1024 * 1024 http_upload_expire_after = 60 * 60 * 24 * 7 -- a week in seconds turn_external_host = "turn.${domain}"; turn_external_secret = "$PROSODY_TURN_SECRET" ''; }; }; sops = { defaultSopsFile = ./secrets.yaml; secrets = { "acme/credentials-file" = { }; "coturn/static-auth-secret".owner = "turnserver"; "prosody/enviroment" = { }; }; }; systemd.services = { collectd.requires = [ "prosody.service" ]; prosody.serviceConfig = { # Allow binding ports <1024 AmbientCapabilities = "CAP_NET_BIND_SERVICE"; EnvironmentFile = config.sops.secrets."prosody/enviroment".path; }; }; system.stateVersion = "21.05"; }