{ zentralwerk, config, pkgs, lib, ... }: let domain = "jabber.c3d2.de"; publicIPv4 = "81.201.149.152"; inherit (pkgs.jabber-secrets) c3d2DynDns coturnUser coturnPassword; 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 IN ROSTER? PASS. LEAVING: spam BOUNCE=policy-violation (Your domain has been blacklisted due to spam.) ''; in { microvm.mem = 2048; networking = { hostName = "jabber"; firewall.allowedTCPPorts = [ # Prosody 5222 5223 5269 80 5280 443 5281 # Coturn 3478 3479 ]; firewall.allowedUDPPorts = [ # Coturn 3478 3479 ]; # TODO: allowedSCTPPorts }; c3d2 = { deployment.server = "server10"; hq.statistics.enable = true; isInHq = false; }; services.collectd.plugins.exec = '' Exec "${config.services.collectd.user}" "${pkgs.ruby}/bin/ruby" "${./prosody-stats.rb}" ''; systemd.services.collectd.requires = [ "prosody.service" ]; security.acme.certs."${domain}" = { extraDomainNames = [ "chat.c3d2.de" "*.${domain}" ]; # DynDNS method dnsProvider = "rfc2136"; credentialsFile = builtins.toFile "creds" (with c3d2DynDns; '' RFC2136_NAMESERVER=ns.c3d2.de RFC2136_TSIG_KEY=${tsigKey} RFC2136_TSIG_ALGORITHM=${tsigAlg}. RFC2136_TSIG_SECRET=${tsigSecret} ''); # Make keys accessible by putting them in prosody's group inherit (config.services.prosody) group; }; services.postgresql = { enable = true; package = pkgs.postgresql_13; ensureDatabases = [ "prosody" ]; ensureUsers = [ { name = "prosody"; ensurePermissions = { "DATABASE prosody" = "ALL PRIVILEGES"; }; } ]; }; #TODO: txt records? services.prosody = { enable = true; allowRegistration = false; admins = [ "astro@spaceboyz.net" "0@jabber.c3d2.de" "nek0@c3d2.de" ]; package = pkgs.prosody.override { withCommunityModules = [ "smacks" "csi" "cloud_notify" "extdisco" "firewall" ]; withExtraLuaPackages = luaPackages: with luaPackages; [ luadbi-postgresql ]; }; modules = { # HTTP stuff bosh = true; websocket = true; http_files = true; admin_telnet = true; announce = true; mam = true; carbons = true; proxy65 = false; }; ssl = { key = "/var/lib/acme/${domain}/key.pem"; cert = "/var/lib/acme/${domain}/fullchain.pem"; # Some TLS hardening we've had on the old setup, probably to # defend against downgrading attacks. extraOptions.options = [ "no_sslv2" "no_sslv3" "no_ticket" "no_compression" "cipher_server_preference" "single_dh_use" "single_ecdh_use" ]; }; c2sRequireEncryption = true; s2sRequireEncryption = true; virtualHosts = { "${domain}" = { enabled = true; inherit domain; }; "anon.${domain}" = { enabled = true; domain = "anon.${domain}"; extraConfig = '' authentication = "anonymous" ''; }; }; muc = [ { domain = "chat.c3d2.de"; 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 = '' legacy_ssl_ports = { 5223 } legacy_ssl_ssl = { key = "/var/lib/acme/${domain}/key.pem", certificate = "/var/lib/acme/${domain}/fullchain.pem", } certificates = "/var/lib/acme" storage = "sql" sql = { driver = "PostgreSQL", database = "prosody", username = "prosody", password = "" } log = { info = "*syslog"; } firewall_scripts = { "${prosodyFirewall}" } trusted_proxies = { "127.0.0.1", "::1", "${config.c3d2.hosts.public-access-proxy.ip4}", "${config.c3d2.hosts.public-access-proxy.ip4}", } 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 cross_domain_bosh = true -- Allow access from scripts on any site with no proxy (requires a modern browser) external_services = { ["turn.${domain}"] = { username = "${coturnUser}"; password = "${coturnPassword}"; port = "3478"; transport = "udp"; type = "turn"; }; ["${publicIPv4}"] = { username = "${coturnUser}"; password = "${coturnPassword}"; port = "3478"; transport = "udp"; type = "turn"; }; } -- -- File-transfer proxies are an outdated technology -- Component "proxy65.${domain}" "proxy65" -- proxy65_address = "proxy.${domain}" -- proxy65_acl = { "${domain}" } -- proxy65_interfaces = { "*", "::" } -- proxy65_ports = { 5000 } ''; }; systemd.services.prosody.serviceConfig = { # Allow binding ports <1024 AmbientCapabilities = "CAP_NET_BIND_SERVICE"; Restart = "always"; RestartSec = "3"; }; services.coturn = { enable = true; realm = "turn.${domain}"; lt-cred-mech = true; extraConfig = '' external-ip=${publicIPv4}/${zentralwerk.lib.config.site.net.serv.hosts4.jabber} user=${coturnUser}:${coturnPassword} ''; }; system.stateVersion = "21.05"; }