{ pkgs, lib, configVars, inputs, ... }: let containerName = "xmpp"; xmppDomain = configVars.domains.xmpp; pubKeys = lib.filesystem.listFilesRecursive ../../users/keys; hostAddress = configVars.networking.addresses.xmpp.hostAddress; localAddress = configVars.networking.addresses.xmpp.localAddress; sops-nix = inputs.sops-nix; xmppPorts = [3478 5281 5280 5269 5222 5223]; in { networking = { nat = { enable = true; internalInterfaces = ["ve-+"]; externalInterface = "enp1s0"; }; firewall = { enable = true; allowedTCPPorts = xmppPorts; }; }; environment.persistence."/persist" = { hideMounts = true; directories = [ "/var/lib/nixos-containers/${containerName}" ]; }; systemd.tmpfiles.rules = [ "d /var/lib/prosody 0750" ]; containers."${containerName}" = { autoStart = true; privateNetwork = true; hostAddress = hostAddress; localAddress = localAddress; nixpkgs = pkgs.path; bindMounts = { "/etc/ssh/ssh_host_ed25519_key" = { hostPath = "/etc/ssh/ssh_host_ed25519_key"; isReadOnly = true; }; "/var/lib/prosody" = { hostPath = "/var/lib/prosody"; isReadOnly = false; }; "/var/lib/acme/${xmppDomain}/" = { hostPath = "/var/lib/acme/${xmppDomain}/"; isReadOnly = false; }; }; forwardPorts = lib.map (port: { containerPort = port; hostPort = port; }) xmppPorts; config = { pkgs, lib, config, ... }: let secretsDirectory = builtins.toString inputs.nix-secrets; secretsFile = "${secretsDirectory}/secrets.yaml"; in { users.groups.www-data = { gid = 33; }; users.users.prosody = { isSystemUser = true; uid = 149; extraGroups = ["www-data"]; }; networking = { firewall = { enable = true; rejectPackets = true; allowedTCPPorts = xmppPorts ++ [80 443]; }; useHostResolvConf = lib.mkForce false; }; services.resolved.enable = true; sops = { defaultSopsFile = "${secretsFile}"; validateSopsFiles = false; age = { sshKeyPaths = ["/etc/ssh/ssh_host_ed25519_key"]; }; secrets = { "software/coturn/static-auth-secret" = { mode = "0644"; }; }; }; imports = [ sops-nix.nixosModules.sops ]; environment.systemPackages = [ pkgs.vim pkgs.git pkgs.prosody ]; sops.templates."prosody_secrets.lua" = { mode = "644"; content = '' turn_external_secret = ${config.sops.placeholder."software/coturn/static-auth-secret"}; ''; }; services.prosody = { enable = true; package = pkgs.prosody.override { withCommunityModules = [ "turn_external" "conversejs" "admin_web" ]; }; extraModules = ["turn_external" "conversejs" "admin_web" "http" "websocket"]; allowRegistration = true; extraConfig = '' include "${config.sops.templates."prosody_secrets.lua".path}" registration_invite_only = true; allow_user_invites = true; cross_domain_bosh = true; turn_external_host = "turn.${xmppDomain}"; turn_external_port = 3478; http_default_host = "${xmppDomain}"; certificates = "certs" cross_domain_websocket = { "https://${xmppDomain}" } consider_websocket_secure = true legacy_ssl_ports = { 5223 } legacy_ssl_ssl = { certificate = "/var/lib/acme/${xmppDomain}/cert.pem"; key = "/var/lib/acme/${xmppDomain}/key.pem"; } ''; modules.bosh = true; s2sRequireEncryption = true; c2sRequireEncryption = true; s2sSecureAuth = false; admins = ["root@${xmppDomain}"]; ssl.cert = "/var/lib/acme/${xmppDomain}/fullchain.pem"; ssl.key = "/var/lib/acme/${xmppDomain}/key.pem"; virtualHosts."${xmppDomain}" = { enabled = true; ssl.cert = "/var/lib/acme/${xmppDomain}/fullchain.pem"; ssl.key = "/var/lib/acme/${xmppDomain}/key.pem"; extraConfig = '' http_external_url = "https://chat.${xmppDomain}/" invites_page = "https://chat.${xmppDomain}/register?t={invite.token}" http_paths = { invites_page = "/invite"; invites_register_web = "/register"; } ''; domain = "${xmppDomain}"; }; muc = [ { domain = "conference.${xmppDomain}"; } ]; uploadHttp = { domain = "https://upload.${xmppDomain}"; uploadFileSizeLimit = "1000000000"; # 1 gb file-size limit uploadExpireAfter = "31557600"; # files deleted after 1 year }; }; services.coturn = { enable = true; realm = "turn.${xmppDomain}"; use-auth-secret = true; static-auth-secret-file = config.sops.secrets."software/coturn/static-auth-secret".path; }; services.openssh = { enable = true; settings.PasswordAuthentication = false; }; users.users = { root = { openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key); }; }; system.stateVersion = "24.05"; }; }; }