diff --git a/flake.lock b/flake.lock index f7ad199..1a207b2 100644 --- a/flake.lock +++ b/flake.lock @@ -559,11 +559,11 @@ }, "nix-secrets": { "locked": { - "lastModified": 1739387047, - "narHash": "sha256-KpogJP00vwuMIKkGJff3zp0YfV9GfOG//UzMK4nWWUw=", + "lastModified": 1740164526, + "narHash": "sha256-lpKNY9qLoIT1XbLzeY+tmkV1DjQQ3mWYWjko+necYhM=", "ref": "refs/heads/master", - "rev": "be51e237b5b3d441a194f3e516175f6a543aee35", - "revCount": 280, + "rev": "ddf31a3a72504f36577ec341fbc84aa8f3dd3318", + "revCount": 283, "type": "git", "url": "ssh://git@git.bitlab21.com/sam/nix-secrets.git" }, diff --git a/hosts/cloudnix/default.nix b/hosts/cloudnix/default.nix index bddaabd..3772ec0 100644 --- a/hosts/cloudnix/default.nix +++ b/hosts/cloudnix/default.nix @@ -30,10 +30,27 @@ in { ../common/optional/openssh.nix ../common/optional/distributed-builds/local-machine.nix + # ../common/optional/nixos-containers/semitamaps.nix + # ../common/optional/nixos-containers/vaultwarden.nix + # ../common/optional/nixos-containers/xmpp.nix + + ../common/optional/fail2ban.nix + ../common/optional/restic-backup.nix + ../common/optional/forgejo.nix outputs.nixosModules.nixosAutoUpgrade ]; + services.restic.backups = { + daily = { + paths = [ + "/persist/" + ]; + exclude = [ + ]; + }; + }; + boot = { loader = { efi.canTouchEfiVariables = false; @@ -62,6 +79,15 @@ in { user = "admin"; }; + environment.persistence."/persist" = { + directories = [ + "/var/lib/tailscale" + ]; + }; + + # enable tailscale + services.tailscale.enable = true; + networking = { hostName = "cloudnix"; nameservers = ["8.8.8.8"]; diff --git a/hosts/common/optional/fail2ban.nix b/hosts/common/optional/fail2ban.nix new file mode 100644 index 0000000..5811fcc --- /dev/null +++ b/hosts/common/optional/fail2ban.nix @@ -0,0 +1,34 @@ +{pkgs, ...}: { + + environment.systemPackages = [pkgs.fail2ban]; + + environment.etc = { + "fail2ban/filter.d/nginx-bruteforce.conf".text = '' + [Definition] + failregex = ^.*(GET|POST).* (404|444|403|400) .*$ + ''; + }; + + services.fail2ban = { + enable = true; + maxretry = 5; + ignoreIP = [ + ]; + bantime-increment = { + enable = true; + multipliers = "1 2 4 8 16 32 64"; + maxtime = "168h"; + }; + jails = { + nginx-spam.settings = { + filter = "nginx-bruteforce"; + action = "iptables-allports"; + logpath = "/var/log/nginx/access.log"; + backend = "auto"; + findtime = 600; + bantime = 600; + maxretry = 10; + }; + }; + }; +} diff --git a/hosts/common/optional/forgejo.nix b/hosts/common/optional/forgejo.nix new file mode 100644 index 0000000..77e60f5 --- /dev/null +++ b/hosts/common/optional/forgejo.nix @@ -0,0 +1,57 @@ +{ + pkgs, + configVars, + lib, + ... +}: let + forgejoDomain = configVars.domains.forgejo; + forgejoPort = configVars.networking.addresses.forgejo.port; +in { + + imports = [./nginx/forgejo.nix]; + + environment.persistence."/persist" = { + hideMounts = true; + directories = [ + "/var/lib/forgejo" + ]; + }; + + users.groups.git = { + gid = 1009; + }; + + users.users.git = { + isNormalUser = true; + home = "/var/lib/forgejo"; + uid = 1009; + extraGroups = ["git"]; + }; + + services.openssh = { + authorizedKeysFiles = lib.mkForce [ "/var/lib/forgejo/.ssh/authorized_keys" ]; + }; + + services.forgejo = { + enable = true; + package = pkgs.forgejo; + database.type = "sqlite3"; + lfs.enable = true; + user = "git"; + group = "git"; + settings = { + server = { + RUN_USER = "git"; + DOMAIN = "git.${forgejoDomain}"; + ROOT_URL = "https://git.${forgejoDomain}/"; + HTTP_PORT = forgejoPort; + SSH_USER = "git"; + }; + service.DISABLE_REGISTRATION = false; + actions = { + ENABLED = true; + DEFAULT_ACTIONS_URL = "github"; + }; + }; + }; +} diff --git a/hosts/common/optional/nginx/forgejo.nix b/hosts/common/optional/nginx/forgejo.nix new file mode 100644 index 0000000..694eb8d --- /dev/null +++ b/hosts/common/optional/nginx/forgejo.nix @@ -0,0 +1,27 @@ +{configVars, ...}: let + email = configVars.email.user; + domain = configVars.domains.forgejo; + forgejoIp = configVars.networking.addresses.forgejo.localAddress; + forgejoPort = configVars.networking.addresses.forgejo.port; +in { + networking.firewall.allowedTCPPorts = [80 443]; + security.acme = { + acceptTerms = true; + defaults.email = email; + }; + services.nginx = { + enable = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + virtualHosts."git.${domain}" = { + enableACME = true; + forceSSL = true; + extraConfig = '' + client_max_body_size 1024M; + ''; + locations."/" = { + proxyPass = "http://${forgejoIp}:${toString forgejoPort}"; + }; + }; + }; +} diff --git a/hosts/common/optional/nginx/semitamaps.nix b/hosts/common/optional/nginx/semitamaps.nix new file mode 100644 index 0000000..9e1deef --- /dev/null +++ b/hosts/common/optional/nginx/semitamaps.nix @@ -0,0 +1,20 @@ +{configVars, ...}: let + email = configVars.email.user; + domain = configVars.domains.xmpp; +in { + security.acme = { + acceptTerms = true; + defaults.email = email; + }; + networking.firewall.allowedTCPPorts = [80 443]; + services.nginx = { + enable = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + virtualHosts."${domain}" = { + enableACME = true; + forceSSL = true; + root = "/srv/hello/"; + }; + }; +} diff --git a/hosts/common/optional/nginx/vaultwarden.nix b/hosts/common/optional/nginx/vaultwarden.nix new file mode 100644 index 0000000..a4f7dd3 --- /dev/null +++ b/hosts/common/optional/nginx/vaultwarden.nix @@ -0,0 +1,24 @@ +{configVars, ...}: let + email = configVars.email.user; + domain = configVars.domains.vaultwarden; + vaultwardenIp = configVars.networking.addresses.vaultwarden.localAddress; + vaultwardenPort = configVars.networking.addresses.vaultwarden.port; +in { + networking.firewall.allowedTCPPorts = [80 443]; + security.acme = { + acceptTerms = true; + defaults.email = email; + }; + services.nginx = { + enable = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + virtualHosts."password.${domain}" = { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://${vaultwardenIp}:${toString vaultwardenPort}"; + }; + }; + }; +} diff --git a/hosts/common/optional/nginx/xmpp.nix b/hosts/common/optional/nginx/xmpp.nix new file mode 100644 index 0000000..beefc8f --- /dev/null +++ b/hosts/common/optional/nginx/xmpp.nix @@ -0,0 +1,92 @@ +{configVars, ...}: let + email = configVars.email.user; + xmppDomain = configVars.domains.xmpp; + xmppIp = configVars.networking.addresses.xmpp.localAddress; + xmppPort = configVars.networking.addresses.xmpp.ports.xmpp-http; +in { + networking.firewall.allowedTCPPorts = [80 443]; + users.groups.www-data = { + gid = 33; + }; + + users.users.nginx = { + isSystemUser = true; + uid = 60; + extraGroups = ["www-data"]; + }; + + systemd.tmpfiles.rules = [ + "d /var/www/${xmppDomain} 0777 root root" + ]; + + services.httpd.virtualHosts."root" = { + hostName = "${xmppDomain}"; + documentRoot = "/var/www/${xmppDomain}"; + }; + + security.acme = { + acceptTerms = true; + defaults.email = email; + certs = { + "${xmppDomain}" = { + webroot = "/var/www/${xmppDomain}"; + email = email; + extraDomainNames = [ + "chat.${xmppDomain}" + ]; + group = "www-data"; + }; + }; + }; + + services.nginx = { + enable = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + virtualHosts."chat.${xmppDomain}" = { + # enableACME = true; + forceSSL = true; + extraConfig = '' + client_max_body_size 10G; + ''; + sslCertificate = "/var/lib/acme/${xmppDomain}/fullchain.pem"; + sslCertificateKey = "/var/lib/acme/${xmppDomain}/key.pem"; + locations = { + "/" = { + proxyPass = "http://${xmppIp}:${toString xmppPort}"; + extraConfig = '' + proxy_set_header Host "${xmppDomain}"; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_buffering off; + tcp_nodelay on; + ''; + }; + "/xmpp-websocket" = { + proxyPass = "http://${xmppIp}:${toString xmppPort}/xmpp-websocket"; + extraConfig = '' + proxy_http_version 1.1; + proxy_set_header Connection "Upgrade"; + proxy_set_header Upgrade $http_upgrade; + + proxy_set_header Host "${xmppDomain}"; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 900s; + ''; + }; + "/upload/" = { + extraConfig = '' + proxy_buffering off; + proxy_set_header Host $host; + # pass PUT requests to mod_http_upload for processing + if ($request_method = PUT) { + proxy_pass http://${xmppIp}:${toString xmppPort}; + } + alias /var/lib/prosody/http_upload; # storage path of mod_http_upload. NGINX will serve these files to the clients. + ''; + }; + }; + }; + }; +} diff --git a/hosts/common/optional/nixos-containers/forgejo.nix b/hosts/common/optional/nixos-containers/forgejo.nix new file mode 100644 index 0000000..3875a2c --- /dev/null +++ b/hosts/common/optional/nixos-containers/forgejo.nix @@ -0,0 +1,119 @@ +{ + pkgs, + lib, + configVars, + inputs, + ... +}: let + containerName = "forgejo"; + pubKeys = lib.filesystem.listFilesRecursive ../../users/keys; + hostAddress = configVars.networking.addresses.forgejo.hostAddress; + localAddress = configVars.networking.addresses.forgejo.localAddress; + forgejoPort = configVars.networking.addresses.forgejo.port; + forgejoDomain = configVars.domains.forgejo; + cloudnixIp = configVars.networking.addresses.cloudnix.ip; + sops-nix = inputs.sops-nix; +in { + networking = { + nat = { + enable = true; + internalInterfaces = ["ve-+"]; + externalInterface = "enp1s0"; + }; + }; + + environment.persistence."/persist" = { + hideMounts = true; + directories = [ + "/var/lib/nixos-containers/${containerName}" + ]; + }; + imports = [../nginx/forgejo.nix]; + + 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; + }; + }; + + config = { + pkgs, + lib, + ... + }: let + secretsDirectory = builtins.toString inputs.nix-secrets; + secretsFile = "${secretsDirectory}/secrets.yaml"; + in { + networking = { + defaultGateway = cloudnixIp; + firewall = { + enable = true; + allowedTCPPorts = [ + forgejoPort + ]; + }; + useHostResolvConf = lib.mkForce false; + }; + + services.resolved.enable = true; + + sops = { + defaultSopsFile = "${secretsFile}"; + validateSopsFiles = false; + + age = { + sshKeyPaths = ["/etc/ssh/ssh_host_ed25519_key"]; + }; + }; + + imports = [ + sops-nix.nixosModules.sops + ]; + + environment.systemPackages = [ + pkgs.vim + pkgs.git + pkgs.lsof + ]; + + services.forgejo = { + enable = true; + package = pkgs.forgejo; + database.type = "sqlite3"; + lfs.enable = true; + settings = { + server = { + DOMAIN = "git.${forgejoDomain}"; + ROOT_URL = "https://git.${forgejoDomain}/"; + HTTP_PORT = forgejoPort; + }; + service.DISABLE_REGISTRATION = false; + actions = { + ENABLED = true; + DEFAULT_ACTIONS_URL = "github"; + }; + }; + }; + + 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"; + }; + }; +} diff --git a/hosts/common/optional/nixos-containers/semitamaps.nix b/hosts/common/optional/nixos-containers/semitamaps.nix new file mode 100644 index 0000000..419602d --- /dev/null +++ b/hosts/common/optional/nixos-containers/semitamaps.nix @@ -0,0 +1,126 @@ +{ + pkgs, + lib, + configVars, + ... +}: let + containerName = "semitamaps"; + pubKeys = lib.filesystem.listFilesRecursive ../../users/keys; + hostAddress = configVars.networking.addresses.semitamaps.hostAddress; + localAddress = configVars.networking.addresses.semitamaps.localAddress; + workingDirectory = "/var/www/semitamaps"; +in { + systemd.tmpfiles.rules = [ + "d /var/run/sockets 0660 www-data www-data -" + ]; + + networking = { + nat = { + enable = true; + internalInterfaces = ["ve-+"]; + externalInterface = "enp1s0"; + }; + }; + + environment.persistence."/persist" = { + hideMounts = true; + directories = [ + "/var/lib/nixos-containers/${containerName}" + ]; + }; + + imports = [ + ../nginx/semitamaps.nix + ]; + + 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/run/sockets" = { + hostPath = "/var/run/sockets"; + isReadOnly = false; + }; + }; + + config = { + pkgs, + lib, + ... + }: { + networking = { + firewall = { + enable = true; + rejectPackets = true; + allowedTCPPorts = [ + 80 + 443 + ]; + }; + useHostResolvConf = lib.mkForce false; + }; + + systemd.tmpfiles.rules = [ + "d ${workingDirectory} 0750 www-data www-data" + "d ${workingDirectory}/.venv 0750 www-data www-data" + "d ${workingDirectory}/public/uploads 0775 www-data www-data" + ]; + + services.resolved.enable = true; + + environment.systemPackages = [ + pkgs.vim + pkgs.git + ]; + + services.openssh = { + enable = true; + settings.PasswordAuthentication = false; + }; + + systemd.services.semitamaps = { + wantedBy = ["multi-user.target"]; + after = ["network.target"]; + description = "Deploys and serves semitamaps"; + environment = { + }; + serviceConfig = { + WorkingDirectory = "${workingDirectory}"; + ExecStartPre = pkgs.writeShellScript "semitamaps-prestart" '' + set -e + + GITCMD="${pkgs.openssh}/bin/ssh -i /etc/ssh/ssh_host_ed25519_key" + if [ ! -d ${workingDirectory}/.git ]; then + export GIT_SSH_COMMAND=$GITCMD + ${pkgs.git}/bin/git clone git@git.bitlab21.com:sam/semitamaps.com.git ${workingDirectory} + fi + ${pkgs.poetry}/bin/poetry install + ''; + ExecStart = pkgs.writeShellScript "semitamaps-start" '' + .venv/bin/python .venv/bin/uvicorn --workers 4 --uds /var/run/sockets/semitamaps.sock app:app + ''; + Restart = "on-failure"; + }; + }; + + programs.ssh.knownHosts = { + "git.bitlab21.com".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIALNd2BGf64heYjWT9yt0fVmngepiHRIMsL7au/MRteg"; + }; + + users.users = { + root = { + openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key); + }; + }; + + system.stateVersion = "24.05"; + }; + }; +} diff --git a/hosts/common/optional/nixos-containers/vaultwarden.nix b/hosts/common/optional/nixos-containers/vaultwarden.nix new file mode 100644 index 0000000..1e8478f --- /dev/null +++ b/hosts/common/optional/nixos-containers/vaultwarden.nix @@ -0,0 +1,110 @@ +{ + pkgs, + lib, + configVars, + inputs, + ... +}: let + containerName = "vaultwarden"; + pubKeys = lib.filesystem.listFilesRecursive ../../users/keys; + hostAddress = configVars.networking.addresses.vaultwarden.hostAddress; + localAddress = configVars.networking.addresses.vaultwarden.localAddress; + vaultwardenPort = configVars.networking.addresses.vaultwarden.port; + cloudnixIp = configVars.networking.addresses.cloudnix.ip; + sops-nix = inputs.sops-nix; +in { + networking = { + nat = { + enable = true; + internalInterfaces = ["ve-+"]; + externalInterface = "enp1s0"; + }; + }; + + environment.persistence."/persist" = { + hideMounts = true; + directories = [ + "/var/lib/nixos-containers/${containerName}" + ]; + }; + + imports = [../nginx/vaultwarden.nix]; + + 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; + }; + }; + + config = { + pkgs, + lib, + ... + }: let + secretsDirectory = builtins.toString inputs.nix-secrets; + secretsFile = "${secretsDirectory}/secrets.yaml"; + in { + networking = { + defaultGateway = cloudnixIp; + firewall = { + enable = true; + allowedTCPPorts = [ + vaultwardenPort + ]; + }; + useHostResolvConf = lib.mkForce false; + }; + + services.resolved.enable = true; + + sops = { + defaultSopsFile = "${secretsFile}"; + validateSopsFiles = false; + + age = { + sshKeyPaths = ["/etc/ssh/ssh_host_ed25519_key"]; + }; + }; + + imports = [ + sops-nix.nixosModules.sops + ]; + + environment.systemPackages = [ + pkgs.vim + pkgs.git + pkgs.lsof + ]; + + services.vaultwarden = { + enable = true; + dbBackend = "sqlite"; + config = { + ROCKET_ADDRESS = "0.0.0.0"; + ROCKET_PORT = vaultwardenPort; + ROCKET_LOG = "critical"; + }; + }; + + 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"; + }; + }; +} diff --git a/hosts/common/optional/nixos-containers/xmpp.nix b/hosts/common/optional/nixos-containers/xmpp.nix new file mode 100644 index 0000000..3c450d6 --- /dev/null +++ b/hosts/common/optional/nixos-containers/xmpp.nix @@ -0,0 +1,281 @@ +{ + pkgs, + lib, + configVars, + inputs, + ... +}: let + containerName = "xmpp"; + xmppDomain = configVars.domains.xmpp; + pubKeys = lib.filesystem.listFilesRecursive ../../users/keys; + hostAddress = configVars.networking.addresses.xmpp.hostAddress; + externalIp = configVars.networking.addresses.cloudnix.ip; + localAddress = configVars.networking.addresses.xmpp.localAddress; + sops-nix = inputs.sops-nix; + xmppPorts = configVars.networking.addresses.xmpp.ports; + xmppUDPPorts = + [ + xmppPorts.coturn + xmppPorts.coturn-tls + ] + ++ lib.range xmppPorts.coturn-min-udp xmppPorts.coturn-max-udp; + xmppTCPPorts = [ + xmppPorts.coturn + xmppPorts.coturn-tls + xmppPorts.xmpp-https + xmppPorts.xmpp-http + xmppPorts.xmpp-s2s + xmppPorts.xmpp-c2s + xmppPorts.xmpp-c2s-legacy-tls + xmppPorts.xmpp-s2s-tls + ]; +in { + networking = { + nat = { + enable = true; + internalInterfaces = ["ve-+"]; + externalInterface = "enp1s0"; + }; + firewall = { + enable = true; + allowedTCPPorts = xmppTCPPorts; + allowedUDPPorts = xmppUDPPorts; + }; + }; + + imports = [ + ../nginx/xmpp.nix + ]; + + 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: { + protocol = "tcp"; + containerPort = port; + hostPort = port; + }) + xmppTCPPorts + ++ lib.map (port: { + protocol = "udp"; + containerPort = port; + hostPort = port; + }) + xmppUDPPorts; + 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"]; + }; + + users.users.turnserver = { + isSystemUser = true; + uid = 249; + extraGroups = ["www-data"]; + }; + + networking = { + firewall = { + enable = true; + rejectPackets = true; + allowedTCPPorts = xmppTCPPorts ++ [80 443]; + allowedUDPPorts = xmppUDPPorts; + }; + 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 + pkgs.coturn + ]; + + sops.templates."prosody_secrets.lua" = { + mode = "444"; + 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" + "external_services" + "http_altconnect" + ]; + }; + extraModules = [ + "server_contact_info" + "http_file_share" + "external_services" + "turn_external" + "conversejs" + "admin_web" + "http" + "websocket" + "http_altconnect" + ]; + allowRegistration = true; + extraConfig = '' + Include "${config.sops.templates."prosody_secrets.lua".path}" + registration_invite_only = true; + allow_user_invites = true; + cross_domain_bosh = true; + cross_domain_websocket = true; + turn_external_host = "turn.${xmppDomain}"; + turn_external_port = ${toString xmppPorts.coturn}; + http_default_host = "${xmppDomain}"; + certificates = "certs" + consider_websocket_secure = true + external_services = { + { + port="${toString xmppPorts.coturn}"; + transport="tcp"; + type="stun"; + host="turn.${xmppDomain}" + }; + { + port="${toString xmppPorts.coturn}"; + transport="udp"; + type="turn"; + host="turn.${xmppDomain}" + }; + } + s2s_direct_tls_ports = { ${toString xmppPorts.xmpp-s2s-tls} } + legacy_ssl_ports = { ${toString xmppPorts.xmpp-c2s-legacy-tls} } + legacy_ssl_ssl = { + certificate = "/var/lib/acme/${xmppDomain}/cert.pem"; + key = "/var/lib/acme/${xmppDomain}/key.pem"; + } + contact_info = { + admin = { "mailto:admin@${xmppDomain}", "xmpp:admin@${xmppDomain}" }; + } + ''; + 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"; + httpFileShare.domain = "upload.${xmppDomain}"; + 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"; + } + disco_items = { + { "upload.${xmppDomain}.com" }, + { "rooms.${xmppDomain}.com" }, + { "turn.${xmppDomain}.com" }, + } + + ''; + 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; + tls-listening-port = xmppPorts.coturn-tls; + cert = "/var/lib/acme/${xmppDomain}/cert.pem"; + pkey = "/var/lib/acme/${xmppDomain}/key.pem"; + min-port = xmppPorts.coturn-min-udp; + max-port = xmppPorts.coturn-max-udp; + extraConfig = '' + external-ip = ${externalIp}/${localAddress} + log = /var/log/turnserver.log + verbose + ''; + }; + + system.stateVersion = "24.05"; + }; + }; +} diff --git a/vars/default.nix b/vars/default.nix index 82b6969..77172bf 100644 --- a/vars/default.nix +++ b/vars/default.nix @@ -5,6 +5,7 @@ email metrics-server xmpp + domains ; locations = { mediaDataMountPoint = "/media/media";